214 lines
5.2 KiB
TypeScript
214 lines
5.2 KiB
TypeScript
// components/status/StatusCard.tsx
|
|
import React, { useState } from 'react';
|
|
import {
|
|
StyleSheet,
|
|
Modal,
|
|
TouchableOpacity,
|
|
TouchableWithoutFeedback,
|
|
KeyboardAvoidingView,
|
|
Platform,
|
|
View,
|
|
ActivityIndicator,
|
|
Alert
|
|
} from 'react-native';
|
|
import { supabase } from '@/lib/supabase';
|
|
import { ThemedView, ThemedText, ThemedTextInput, ThemedTextButton } from '@/components/theme';
|
|
import ProfileAvatar from '@/components/auth/Profile_Avatar';
|
|
|
|
interface StatusCardProps {
|
|
visible: boolean;
|
|
user: {
|
|
user_id: string;
|
|
status: string;
|
|
profiles: {
|
|
full_name: string;
|
|
avatar_url: string | null;
|
|
};
|
|
};
|
|
onClose: () => void;
|
|
onUpdate: () => void;
|
|
}
|
|
|
|
export default function StatusCard({ visible, user, onClose, onUpdate }: StatusCardProps) {
|
|
const [newStatus, setNewStatus] = useState('');
|
|
const [updating, setUpdating] = useState(false);
|
|
|
|
const handleUpdateStatus = async () => {
|
|
if (!newStatus.trim() || newStatus.trim().length < 3) {
|
|
Alert.alert('Invalid Status', 'Status must be at least 3 characters long.');
|
|
return;
|
|
}
|
|
|
|
setUpdating(true);
|
|
try {
|
|
const { data: { user: currentUser } } = await supabase.auth.getUser();
|
|
|
|
if (!currentUser) throw new Error('Not authenticated');
|
|
|
|
// Insert new status
|
|
const { error } = await supabase
|
|
.from('statuses')
|
|
.insert({
|
|
user_id: user.user_id,
|
|
status: newStatus.trim()
|
|
});
|
|
|
|
if (error) throw error;
|
|
|
|
setNewStatus('');
|
|
onUpdate();
|
|
|
|
} catch (error) {
|
|
Alert.alert('Error', error instanceof Error ? error.message : 'Failed to update status');
|
|
console.error('Status update error:', error);
|
|
} finally {
|
|
setUpdating(false);
|
|
}
|
|
};
|
|
|
|
return (
|
|
<Modal
|
|
animationType="slide"
|
|
transparent={true}
|
|
visible={visible}
|
|
onRequestClose={onClose}
|
|
>
|
|
<TouchableWithoutFeedback onPress={onClose}>
|
|
<View style={styles.modalOverlay} />
|
|
</TouchableWithoutFeedback>
|
|
|
|
<KeyboardAvoidingView
|
|
behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
|
|
style={styles.keyboardAvoidingView}
|
|
>
|
|
<ThemedView style={styles.modalContent}>
|
|
<View style={styles.handle} />
|
|
|
|
<View style={styles.userInfoContainer}>
|
|
<ProfileAvatar
|
|
url={user.profiles.avatar_url}
|
|
size={60}
|
|
disabled={true}
|
|
/>
|
|
<ThemedText style={styles.userName}>
|
|
{user.profiles.full_name}
|
|
</ThemedText>
|
|
<ThemedText style={styles.currentStatus}>
|
|
Current: {user.status}
|
|
</ThemedText>
|
|
</View>
|
|
|
|
<ThemedView style={styles.inputContainer}>
|
|
<ThemedText style={styles.inputLabel}>New Status</ThemedText>
|
|
<ThemedTextInput
|
|
value={newStatus}
|
|
onChangeText={setNewStatus}
|
|
placeholder="What's happening?"
|
|
maxLength={80}
|
|
multiline
|
|
style={styles.input}
|
|
editable={!updating}
|
|
/>
|
|
<ThemedText style={styles.charCount}>
|
|
{newStatus.length}/80
|
|
</ThemedText>
|
|
</ThemedView>
|
|
|
|
<ThemedTextButton
|
|
text={updating ? 'Updating...' : 'Update Status'}
|
|
onPress={handleUpdateStatus}
|
|
disabled={updating || newStatus.trim().length < 3}
|
|
fontSize={18}
|
|
fontWeight='semibold'
|
|
width='100%'
|
|
style={styles.updateButton}
|
|
/>
|
|
|
|
<TouchableOpacity
|
|
style={styles.cancelButton}
|
|
onPress={onClose}
|
|
disabled={updating}
|
|
>
|
|
<ThemedText style={styles.cancelText}>Cancel</ThemedText>
|
|
</TouchableOpacity>
|
|
</ThemedView>
|
|
</KeyboardAvoidingView>
|
|
</Modal>
|
|
);
|
|
}
|
|
|
|
const styles = StyleSheet.create({
|
|
modalOverlay: {
|
|
flex: 1,
|
|
backgroundColor: 'rgba(0,0,0,0.5)',
|
|
},
|
|
keyboardAvoidingView: {
|
|
position: 'absolute',
|
|
bottom: 0,
|
|
left: 0,
|
|
right: 0,
|
|
},
|
|
modalContent: {
|
|
borderTopLeftRadius: 20,
|
|
borderTopRightRadius: 20,
|
|
padding: 20,
|
|
paddingBottom: Platform.OS === 'ios' ? 40 : 20,
|
|
},
|
|
handle: {
|
|
width: 40,
|
|
height: 5,
|
|
borderRadius: 3,
|
|
backgroundColor: '#ccc',
|
|
alignSelf: 'center',
|
|
marginBottom: 20,
|
|
},
|
|
userInfoContainer: {
|
|
alignItems: 'center',
|
|
marginBottom: 20,
|
|
},
|
|
userName: {
|
|
fontSize: 18,
|
|
fontWeight: '600',
|
|
marginTop: 10,
|
|
},
|
|
currentStatus: {
|
|
fontSize: 16,
|
|
marginTop: 5,
|
|
opacity: 0.7,
|
|
},
|
|
inputContainer: {
|
|
marginBottom: 20,
|
|
},
|
|
inputLabel: {
|
|
fontSize: 16,
|
|
fontWeight: '500',
|
|
marginBottom: 8,
|
|
},
|
|
input: {
|
|
fontSize: 16,
|
|
paddingVertical: 12,
|
|
paddingHorizontal: 10,
|
|
borderRadius: 8,
|
|
minHeight: 80,
|
|
textAlignVertical: 'top',
|
|
},
|
|
charCount: {
|
|
fontSize: 12,
|
|
alignSelf: 'flex-end',
|
|
marginTop: 4,
|
|
opacity: 0.6,
|
|
},
|
|
updateButton: {
|
|
borderRadius: 8,
|
|
marginBottom: 15,
|
|
},
|
|
cancelButton: {
|
|
alignItems: 'center',
|
|
padding: 10,
|
|
},
|
|
cancelText: {
|
|
fontSize: 16,
|
|
color: '#FF3B30',
|
|
},
|
|
});
|