import React, { useEffect, useMemo, useRef, useState } from 'react'; import { View, Text, StyleSheet, TouchableOpacity, StatusBar, Platform, Animated, Easing, TextInput, ActivityIndicator } from 'react-native'; import FastImage from '@d11/react-native-fast-image'; import { useNavigation } from '@react-navigation/native'; import { useSafeAreaInsets } from 'react-native-safe-area-context'; import { MaterialIcons } from '@expo/vector-icons'; import { useAccount } from '../contexts/AccountContext'; import { useTheme } from '../contexts/ThemeContext'; import { LinearGradient } from 'expo-linear-gradient'; import * as Haptics from 'expo-haptics'; import CustomAlert from '../components/CustomAlert'; const AccountManageScreen: React.FC = () => { const navigation = useNavigation(); const insets = useSafeAreaInsets(); const { user, signOut, updateProfile } = useAccount(); const { currentTheme } = useTheme(); const headerOpacity = useRef(new Animated.Value(0)).current; const headerTranslateY = useRef(new Animated.Value(8)).current; const contentOpacity = useRef(new Animated.Value(0)).current; const contentTranslateY = useRef(new Animated.Value(8)).current; useEffect(() => { Animated.parallel([ Animated.timing(headerOpacity, { toValue: 1, duration: 260, easing: Easing.out(Easing.cubic), useNativeDriver: true }), Animated.timing(headerTranslateY, { toValue: 0, duration: 260, easing: Easing.out(Easing.cubic), useNativeDriver: true }), Animated.timing(contentOpacity, { toValue: 1, duration: 320, delay: 80, easing: Easing.out(Easing.cubic), useNativeDriver: true }), Animated.timing(contentTranslateY, { toValue: 0, duration: 320, delay: 80, easing: Easing.out(Easing.cubic), useNativeDriver: true }), ]).start(); }, [headerOpacity, headerTranslateY, contentOpacity, contentTranslateY]); const initial = useMemo(() => (user?.email?.[0]?.toUpperCase() || 'U'), [user?.email]); const [displayName, setDisplayName] = useState(user?.displayName || ''); const [avatarUrl, setAvatarUrl] = useState(user?.avatarUrl || ''); const [saving, setSaving] = useState(false); const [avatarError, setAvatarError] = useState(false); const [alertVisible, setAlertVisible] = useState(false); const [alertTitle, setAlertTitle] = useState(''); const [alertMessage, setAlertMessage] = useState(''); const [alertActions, setAlertActions] = useState([]); useEffect(() => { // Reset image error state when URL changes setAvatarError(false); }, [avatarUrl]); const handleSave = async () => { if (saving) return; setSaving(true); const err = await updateProfile({ displayName: displayName.trim() || undefined, avatarUrl: avatarUrl.trim() || undefined }); if (err) { setAlertTitle('Error'); setAlertMessage(err); setAlertActions([{ label: 'OK', onPress: () => {} }]); setAlertVisible(true); } setSaving(false); }; const handleSignOut = () => { setAlertTitle('Sign out'); setAlertMessage('Are you sure you want to sign out?'); setAlertActions([ { label: 'Cancel', onPress: () => {} }, { label: 'Sign out', onPress: async () => { try { await signOut(); // @ts-ignore navigation.goBack(); } catch (_) {} }, style: { opacity: 1 }, }, ]); setAlertVisible(true); }; return ( {/* Header */} navigation.goBack()} style={styles.headerBack} hitSlop={{ top: 8, bottom: 8, left: 8, right: 8 }}> Account {/* Content */} {/* Profile Badge */} {avatarUrl && !avatarError ? ( setAvatarError(true)} /> ) : ( {(displayName?.[0] || initial)} )} {/* Account details card */} Display name Avatar URL Email {user?.email || '—'} User ID {user?.id} {/* Save and Sign out */} {saving ? ( ) : ( <> Save changes )} Sign out setAlertVisible(false)} /> ); }; const styles = StyleSheet.create({ container: { flex: 1, }, header: { paddingHorizontal: 16, paddingBottom: 14, flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', }, headerBack: { padding: 4, }, headerTitle: { fontSize: 18, fontWeight: '800', }, content: { flex: 1, paddingHorizontal: 16, paddingTop: 10, }, profileContainer: { alignItems: 'center', marginBottom: 12, }, avatar: { width: 72, height: 72, borderRadius: 36, alignItems: 'center', justifyContent: 'center', }, avatarImage: { width: '100%', height: '100%', }, avatarText: { color: '#fff', fontWeight: '800', fontSize: 24, }, card: { borderRadius: 14, borderWidth: StyleSheet.hairlineWidth, paddingHorizontal: 14, paddingVertical: 10, }, itemRow: { flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', paddingVertical: 10, }, itemRowCompact: { paddingVertical: 6, }, input: { flex: 1, textAlign: 'right', paddingVertical: 6, marginLeft: 12, }, itemLeft: { flexDirection: 'row', alignItems: 'center', gap: 8, }, itemTitle: { fontSize: 14, fontWeight: '600', }, itemValue: { fontSize: 14, maxWidth: '65%', }, divider: { height: StyleSheet.hairlineWidth, backgroundColor: 'rgba(255,255,255,0.08)', }, signOutButton: { marginTop: 16, height: 48, borderRadius: 12, alignItems: 'center', justifyContent: 'center', flexDirection: 'row', }, signOutText: { color: '#fff', fontWeight: '700', }, saveButton: { marginTop: 12, height: 46, borderRadius: 12, alignItems: 'center', justifyContent: 'center', flexDirection: 'row', borderWidth: StyleSheet.hairlineWidth, }, saveText: { color: '#fff', fontWeight: '700', }, }); export default AccountManageScreen;