add edit profile feature
This commit is contained in:
parent
0bde09ad5c
commit
51064d95e3
131
mobile/src/screens/EditProfileScreen.tsx
Normal file
131
mobile/src/screens/EditProfileScreen.tsx
Normal 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>
|
||||
);
|
||||
}
|
||||
@ -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 }),
|
||||
}),
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user