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
>
)}
);
};