import React, { useState, useEffect } from 'react'; import { View, Text, ScrollView, TouchableOpacity, KeyboardAvoidingView, Platform, Alert, Image, ActivityIndicator, } from 'react-native'; import AsyncStorage from '@react-native-async-storage/async-storage'; import Icon from 'react-native-vector-icons/Ionicons'; import { useNavigation } from '@react-navigation/native'; import { useTheme } from '@theme'; import { FormInput, Loader } from '@components'; import { useAppDispatch, useAppSelector, RootState, updateUserData } from '@store'; import { getStyles } from './editProfile.styles'; import { updateProfile, getStaffDetails, resetEditProfileState } from './thunk'; import ImagePicker from 'react-native-image-crop-picker'; export const EditProfileScreen = () => { const navigation = useNavigation(); const { theme: colors } = useTheme(); const styles = getStyles(colors); const dispatch = useAppDispatch(); const userData = useAppSelector((state: RootState) => state.auth.user_data); const { loading, loadingDetails, successMessage, error, staffDetails } = useAppSelector( (state: RootState) => state.editProfile, ); // Form state const [firstname, setFirstname] = useState(userData?.firstname || ''); const [lastname, setLastname] = useState(userData?.lastname || ''); const [email, setEmail] = useState(userData?.email || ''); const [phone, setPhone] = useState(userData?.phonenumber || ''); const [emailSignature, setEmailSignature] = useState(userData?.email_signature || ''); const [password, setPassword] = useState(''); const [passwordr, setPasswordr] = useState(''); const [profileImageUri, setProfileImageUri] = useState(''); const [profileImageMime, setProfileImageMime] = useState('image/jpeg'); const [profileImageName, setProfileImageName] = useState('profile_image.jpg'); const [isImageChanged, setIsImageChanged] = useState(false); const resolveServerUrl = async (path?: string | null) => { if (!path) return ''; const cleanPath = path.replace(/"/g, '').trim(); if (!cleanPath) return ''; if ( cleanPath.startsWith('http') || cleanPath.startsWith('file://') || cleanPath.startsWith('content://') ) { return cleanPath; } const storedBaseUrl = await AsyncStorage.getItem('base_url'); const baseUrl = storedBaseUrl || 'https://demo-convexcrm.convexsol.co'; const cleanBase = baseUrl.replace(/\/+$/, ''); const cleanRelPath = cleanPath.replace(/^\/+/, ''); return `${cleanBase}/${cleanRelPath}`; }; useEffect(() => { resolveServerUrl(userData?.profile_image).then((url) => { setProfileImageUri(url); }); }, [userData?.profile_image]); // UI toggle state const [showPassword, setShowPassword] = useState(false); const [showConfirmPassword, setShowConfirmPassword] = useState(false); // Fetch staff details on mount // useEffect(() => { // if (userData?.staffid) { // dispatch(getStaffDetails(userData.staffid)); // } // }, [dispatch, userData?.staffid]); // Update local form state when details are loaded from the server // useEffect(() => { // if (staffDetails) { // setFirstname(staffDetails.firstname || ''); // setLastname(staffDetails.lastname || ''); // setEmail(staffDetails.email || ''); // setPhone(staffDetails.phonenumber || ''); // setEmailSignature(staffDetails.email_signature || ''); // resolveServerUrl(userData?.profile_image).then((url) => { // setProfileImageUri(url); // }); // } // }, [staffDetails, userData?.profile_image]); // Reset edit profile state on unmount useEffect(() => { return () => { dispatch(resetEditProfileState()); }; }, [dispatch]); const handleCameraLaunch = () => { ImagePicker.openCamera({ width: 400, height: 400, cropping: true, mediaType: 'photo', }) .then((image) => { setProfileImageUri(image.path); setProfileImageMime(image.mime || 'image/jpeg'); setProfileImageName(image.path.split('/').pop() || 'profile_image.jpg'); setIsImageChanged(true); }) .catch((err) => { if (err.message && !err.message.includes('cancel')) { Alert.alert('Error', err.message || 'Failed to open camera'); } }); }; const handleGalleryLaunch = () => { ImagePicker.openPicker({ width: 400, height: 400, cropping: true, mediaType: 'photo', }) .then((image) => { setProfileImageUri(image.path); setProfileImageMime(image.mime || 'image/jpeg'); setProfileImageName(image.path.split('/').pop() || 'profile_image.jpg'); setIsImageChanged(true); }) .catch((err) => { if (err.message && !err.message.includes('cancel')) { Alert.alert('Error', err.message || 'Failed to open gallery'); } }); }; const handleChooseImage = () => { Alert.alert( 'Change Profile Picture', 'Choose an option to update your photo.', [ { text: 'Take Photo', onPress: handleCameraLaunch, }, { text: 'Choose from Gallery', onPress: handleGalleryLaunch, }, // { // text: 'Remove Photo', // style: 'destructive', // onPress: () => setProfileImageUri(''), // }, { text: 'Cancel', style: 'cancel' }, ], ); }; const handleSave = () => { if (!email.trim()) { Alert.alert('Validation Error', 'Email address is required.'); return; } if (password && password !== passwordr) { Alert.alert('Validation Error', 'New passwords do not match.'); return; } const staffId = userData?.staffid || ''; // Build the profile_image payload if a local file URI is selected and changed in this session let profileImagePayload = undefined; if (isImageChanged && profileImageUri) { const isLocal = !profileImageUri.startsWith('http://') && !profileImageUri.startsWith('https://'); const formattedUri = isLocal && !profileImageUri.startsWith('file://') && !profileImageUri.startsWith('content://') ? `file://${profileImageUri}` : profileImageUri; profileImagePayload = { uri: formattedUri, name: profileImageName, type: profileImageMime, }; } dispatch( updateProfile({ id: staffId, email, firstname: firstname || undefined, lastname: lastname || undefined, phone: phone || undefined, email_signature: emailSignature || undefined, password: password || undefined, passwordr: passwordr || undefined, profile_image: profileImagePayload, }), ) .unwrap() .then((response) => { // Success const updatedImage = response.user_data?.profile_image || userData?.profile_image; dispatch( updateUserData({ firstname, lastname, email, phonenumber: phone, email_signature: emailSignature, profile_image: updatedImage, }), ); Alert.alert('Success', 'Profile updated successfully.', [ { text: 'OK', onPress: () => { dispatch(resetEditProfileState()); navigation.goBack(); }, }, ]); }) .catch((err) => { Alert.alert('Error', err || 'Failed to update profile'); }); }; const staffId = userData?.staffid || ''; const initials = `${firstname.substring(0, 1)}${lastname.substring(0, 1)}`.toUpperCase() || 'U'; const hasProfileImage = !!profileImageUri; if (loadingDetails && !staffDetails) { return ; } return ( {/* ── Avatar Edit Section ── */} {hasProfileImage ? ( ) : ( {initials} )} {/* ── Personal Info Card ── */} Basic Information {/* Staff ID (Read-only) */} {}} editable={false} selectTextOnFocus={false} leftIcon={} inputStyle={{ color: colors.textMuted }} /> {/* First & Last Name */} } /> } /> {/* Email (Required) */} } /> {/* Phone */} } /> {/* ── Email Signature Card ── */} {/* Email Signature */} {/* ── Security Card ── */} Change Password Leave password fields empty if you don't wish to change your current password. } rightIcon={ setShowPassword(!showPassword)} activeOpacity={0.7}> } /> } rightIcon={ setShowConfirmPassword(!showConfirmPassword)} activeOpacity={0.7}> } /> {/* ── Save Button ── */} {loading ? ( ) : ( <> Save Changes )} ); };