add edit profile feature

This commit is contained in:
Joseph D'Souza 2026-02-11 12:58:14 +01:00
parent 0bde09ad5c
commit 51064d95e3
2 changed files with 145 additions and 1 deletions

View File

@ -0,0 +1,131 @@
import React from 'react';
import { View, Text, TextInput, TouchableOpacity, ScrollView, ActivityIndicator, useColorScheme, KeyboardAvoidingView, Platform, Image } from 'react-native';
import { Ionicons } from '@expo/vector-icons';
import { useAuthStore } from '../store/useAuthStore';
import { getThemeStyles, commonStyles } from '../theme/styles';
import { COLORS } from '../theme/colors';
import { useProfileManager } from '../hooks/useProfileManager';
export default function EditProfileScreen() {
const { user } = useAuthStore();
const colorScheme = useColorScheme();
const isDark = colorScheme === 'dark';
const themeStyles = getThemeStyles(isDark);
const themeColors = isDark ? COLORS.DARK : COLORS.LIGHT;
const {
loading,
avatar,
firstName,
lastName,
phone,
address,
setFirstName,
setLastName,
setPhone,
setAddress,
pickImage,
handleSave,
} = useProfileManager();
return (
<KeyboardAvoidingView
style={themeStyles.container}
behavior={Platform.OS === 'ios' ? 'padding' : undefined}
keyboardVerticalOffset={Platform.OS === 'ios' ? 100 : 0}
>
<ScrollView contentContainerStyle={{ padding: 20 }}>
<Text style={[commonStyles.title, themeStyles.text, { textAlign: 'left', marginBottom: 20 }]}>
Edit Profile
</Text>
<View style={{ alignItems: 'center', marginBottom: 30 }}>
<TouchableOpacity onPress={pickImage} style={{ position: 'relative' }}>
<View style={{
width: 100,
height: 100,
borderRadius: 50,
backgroundColor: themeColors.brand,
alignItems: 'center',
justifyContent: 'center',
overflow: 'hidden',
}}>
{avatar ? (
<Image source={{ uri: avatar }} style={{ width: '100%', height: '100%' }} />
) : (
<Text style={{ fontSize: 40, fontWeight: 'bold', color: 'white' }}>
{user?.user?.first_name?.charAt(0).toUpperCase() || user?.user?.email?.charAt(0).toUpperCase() || 'U'}
</Text>
)}
</View>
<View style={{
position: 'absolute',
bottom: 0,
right: 0,
backgroundColor: themeColors.card,
borderRadius: 15,
padding: 6,
borderWidth: 1,
borderColor: isDark ? '#2d3748' : '#e2e8f0',
}}>
<Ionicons name="camera" size={18} color={themeColors.text} />
</View>
</TouchableOpacity>
</View>
<View style={commonStyles.form}>
<Text style={[commonStyles.label, themeStyles.subtitle]}>First Name</Text>
<TextInput
style={themeStyles.input}
value={firstName}
onChangeText={setFirstName}
placeholder="Enter first name"
placeholderTextColor={isDark ? '#a0aec0' : '#a0aec0'}
/>
<Text style={[commonStyles.label, themeStyles.subtitle]}>Last Name</Text>
<TextInput
style={themeStyles.input}
value={lastName}
onChangeText={setLastName}
placeholder="Enter last name"
placeholderTextColor={isDark ? '#a0aec0' : '#a0aec0'}
/>
<Text style={[commonStyles.label, themeStyles.subtitle]}>Phone</Text>
<TextInput
style={themeStyles.input}
value={phone}
onChangeText={setPhone}
placeholder="Enter phone number"
keyboardType="phone-pad"
placeholderTextColor={isDark ? '#a0aec0' : '#a0aec0'}
/>
<Text style={[commonStyles.label, themeStyles.subtitle]}>Address</Text>
<TextInput
style={[themeStyles.input, { height: 100, textAlignVertical: 'top' }]}
value={address}
onChangeText={setAddress}
placeholder="Enter address"
multiline
placeholderTextColor={isDark ? '#a0aec0' : '#a0aec0'}
/>
<TouchableOpacity
style={[themeStyles.button, loading && commonStyles.buttonDisabled, { marginTop: 40 }]}
onPress={handleSave}
disabled={loading}
>
{loading ? (
<ActivityIndicator color="white" />
) : (
<Text style={themeStyles.buttonText}>Save Changes</Text>
)}
</TouchableOpacity>
</View>
</ScrollView>
</KeyboardAvoidingView>
);
}

View File

@ -7,7 +7,13 @@ interface User {
user: {
id: number;
email: string;
// Add other user fields as needed
first_name?: string;
last_name?: string;
phone?: string;
address?: string;
username?: string;
email_verified_at?: string | null;
avatar?: string;
};
}
@ -15,6 +21,7 @@ interface AuthState {
user: User | null;
isLoading: boolean;
login: (userData: User) => void;
updateUser: (updates: Partial<User['user']>) => void;
logout: () => void;
setLoading: (loading: boolean) => void;
}
@ -25,6 +32,12 @@ export const useAuthStore = create<AuthState>()(
user: null,
isLoading: true,
login: (userData) => set({ user: userData }),
updateUser: (updates) =>
set((state) => ({
user: state.user
? { ...state.user, user: { ...state.user.user, ...updates } }
: null,
})),
logout: () => set({ user: null }),
setLoading: (loading) => set({ isLoading: loading }),
}),