170 lines
3.9 KiB
TypeScript
170 lines
3.9 KiB
TypeScript
import React, { useState, useEffect } from 'react';
|
|
import { StyleSheet, TouchableOpacity, Image, Alert, ActivityIndicator } from 'react-native';
|
|
import * as ImagePicker from 'expo-image-picker';
|
|
import { supabase } from '@/lib/supabase';
|
|
import { ThemedView, ThemedText, ThemedTextButton, ThemedTextInput } from '@/components/theme';
|
|
import { IconSymbol } from '@/components/ui/IconSymbol';
|
|
import Avatar from '@/components/auth/Profile_Avatar';
|
|
import { Session } from '@supabase/supabase-js'
|
|
import Logout_Button from '@/components/auth/Logout_Button';
|
|
|
|
export default function ProfileScreen() {
|
|
const [loading, setLoading] = useState(false);
|
|
const [fullName, setFullName] = useState('');
|
|
const [email, setEmail] = useState('');
|
|
const [avatar, setAvatar] = useState(null);
|
|
|
|
useEffect(() => {
|
|
fetchUserProfile();
|
|
}, []);
|
|
|
|
const fetchUserProfile = async () => {
|
|
setLoading(true);
|
|
try {
|
|
const { data: { user } } = await supabase.auth.getUser();
|
|
|
|
if (user) {
|
|
const { data, error } = await supabase
|
|
.from('profiles')
|
|
.select('*')
|
|
.eq('id', user.id)
|
|
.single();
|
|
|
|
if (data) {
|
|
setFullName(data.full_name || '');
|
|
setEmail(data.email || '');
|
|
setAvatar(data.avatar_url || null);
|
|
}
|
|
}
|
|
} catch (error) {
|
|
console.error('Error fetching profile:', error);
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
};
|
|
|
|
const updateProfile = async () => {
|
|
setLoading(true);
|
|
try {
|
|
const { data: { user } } = await supabase.auth.getUser();
|
|
|
|
if (!user) throw new Error('User not found');
|
|
|
|
const updates = {
|
|
id: user.id,
|
|
full_name: fullName,
|
|
email,
|
|
updated_at: new Date(),
|
|
};
|
|
|
|
const { error } = await supabase
|
|
.from('profiles')
|
|
.upsert(updates);
|
|
|
|
if (error) throw error;
|
|
|
|
Alert.alert('Success', 'Profile updated successfully!');
|
|
} catch (error) {
|
|
Alert.alert('Error updating profile', error.message);
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
};
|
|
|
|
// Add image picking functionality here (similar to previous example)
|
|
|
|
return (
|
|
<ThemedView style={styles.container}>
|
|
|
|
<Avatar
|
|
size={50}
|
|
url={avatar}
|
|
onUpload={updateProfile}
|
|
/>
|
|
|
|
<ThemedView style={styles.formSection}>
|
|
<ThemedText style={styles.label}>Full Name</ThemedText>
|
|
<ThemedTextInput
|
|
value={fullName}
|
|
onChangeText={setFullName}
|
|
placeholder="Enter your full name"
|
|
style={styles.input}
|
|
/>
|
|
|
|
</ThemedView>
|
|
|
|
<ThemedTextButton
|
|
text='Save Changes'
|
|
onPress={updateProfile}
|
|
disabled={loading}
|
|
fontSize={18}
|
|
fontWeight='semibold'
|
|
width='90%'
|
|
style={styles.saveButton}
|
|
/>
|
|
<Logout_Button
|
|
fontSize={18}
|
|
fontWeight='semibold'
|
|
width='90%'
|
|
style={styles.logoutButton}
|
|
/>
|
|
|
|
</ThemedView>
|
|
);
|
|
}
|
|
|
|
const styles = StyleSheet.create({
|
|
container: {
|
|
flex: 1,
|
|
padding: 16,
|
|
alignItems: 'center',
|
|
},
|
|
avatarContainer: {
|
|
alignItems: 'center',
|
|
marginTop: 20,
|
|
marginBottom: 30,
|
|
},
|
|
avatar: {
|
|
width: 120,
|
|
height: 120,
|
|
borderRadius: 60,
|
|
},
|
|
avatarPlaceholder: {
|
|
width: 120,
|
|
height: 120,
|
|
borderRadius: 60,
|
|
backgroundColor: '#E1E1E1',
|
|
justifyContent: 'center',
|
|
alignItems: 'center',
|
|
},
|
|
changePhotoText: {
|
|
marginTop: 8,
|
|
color: '#007AFF',
|
|
fontSize: 16,
|
|
},
|
|
formSection: {
|
|
marginBottom: 30,
|
|
},
|
|
label: {
|
|
marginBottom: 8,
|
|
fontSize: 16,
|
|
},
|
|
input: {
|
|
fontSize: 16,
|
|
paddingVertical: 12,
|
|
paddingHorizontal: 10,
|
|
borderRadius: 8,
|
|
marginBottom: 20,
|
|
},
|
|
saveButton: {
|
|
borderRadius: 8,
|
|
alignItems: 'center',
|
|
},
|
|
logoutButton: {
|
|
backgroundColor: 'red',
|
|
marginTop: 50,
|
|
borderRadius: 8,
|
|
alignItems: 'center',
|
|
},
|
|
});
|