feat: add navigation to forger password page, show password icon, toasts for different situations and changes of some styles

This commit is contained in:
Koosha Lahouti
2025-08-20 01:00:20 +03:30
parent 58c044542a
commit 8ed4aab666
23 changed files with 503 additions and 376 deletions

View File

@@ -1,4 +1,4 @@
import { useState, useEffect } from 'react';
import { useState, useEffect, useRef } from 'react';
import { Box, Button, Typography, CircularProgress } from '@mui/material';
import { useTranslation } from 'react-i18next';
import { CardContainer } from '@/components/CardContainer';
@@ -25,13 +25,13 @@ export function PersonalInformation() {
});
const [originalData, setOriginalData] = useState<InfoRowData | null>(null);
const showToast = useToast();
const infoRowEditRef = useRef<{ validateFields: () => boolean }>(null);
const {
data: profileData,
loading: isLoadingProfile,
error: fetchProfileError,
} = useApi(fetchProfile, { immediate: true });
const {
data: saveData,
loading: isSavingProfile,
@@ -50,18 +50,14 @@ export function PersonalInformation() {
: Gender.None,
country: profileData.countryCode ?? '',
};
setData(fetchedData);
setOriginalData(fetchedData);
const imageBaseUrl = process.env.IMAGE_BASE_URL;
if (profileData.profileImageUrl) {
setUploadedImageUrl(`${imageBaseUrl}${profileData.profileImageUrl}`);
} else {
setUploadedImageUrl(null);
}
const imageBaseUrl = import.meta.env.IMAGE_BASE_URL;
setUploadedImageUrl(
profileData.profileImageUrl
? `${imageBaseUrl}${profileData.profileImageUrl}`
: null,
);
setUploadedImageFile(null);
}
}, [profileData]);
@@ -80,21 +76,18 @@ export function PersonalInformation() {
const initials = `${data?.firstName?.trim()[0] || ''}${data?.lastName?.trim()[0] || ''}`;
const handleEditClick = () => {
setIsEditing(true);
setOriginalData(data);
};
const handleEditClick = () => setIsEditing(true);
const handleCancelClick = () => {
setIsEditing(false);
if (originalData) {
setData(originalData);
}
if (originalData) setData(originalData);
setUploadedImageFile(null);
};
const handleSaveClick = async () => {
const handleSaveClick = () => {
if (!data) return;
const isValid = infoRowEditRef.current?.validateFields?.();
if (!isValid) return;
executeSaveProfile({ data, imageUrl: uploadedImageFile });
};
@@ -105,23 +98,21 @@ export function PersonalInformation() {
};
useEffect(() => {
if (saveProfileError) {
if (saveProfileError)
showToast({
message:
getErrorMessage(saveProfileError) || t('settingForm.errorSave'),
severity: 'error',
});
}
}, [saveProfileError, showToast, t]);
useEffect(() => {
if (fetchProfileError) {
if (fetchProfileError)
showToast({
message:
getErrorMessage(fetchProfileError) || t('settingForm.errorFetch'),
severity: 'error',
});
}
}, [fetchProfileError, showToast, t]);
return (
@@ -131,12 +122,7 @@ export function PersonalInformation() {
subtitle={t('settingForm.descriptionPersonalInfo')}
highlighted={isEditing}
action={
<Box
sx={{
display: 'flex',
gap: 1,
}}
>
<Box sx={{ display: 'flex', gap: 1 }}>
{isEditing ? (
<>
<Button
@@ -159,7 +145,6 @@ export function PersonalInformation() {
textTransform: 'none',
width: { xs: '100%', sm: 'auto' },
}}
disabled={isSavingProfile}
>
{isSavingProfile ? (
<CircularProgress size={24} color="inherit" />
@@ -174,7 +159,6 @@ export function PersonalInformation() {
size="large"
variant="outlined"
sx={{ borderRadius: 1 }}
disabled={isLoadingProfile}
>
{t('settingForm.editButton')}
</Button>
@@ -210,46 +194,48 @@ export function PersonalInformation() {
</Typography>
</Box>
) : (
<>
<Box
sx={{
mx: { xs: 2, sm: 3, md: 4 },
py: 2,
display: 'flex',
flexDirection: 'column',
gap: 2,
bgcolor: 'background.paper',
}}
>
{isEditing && (
<ProfileImage
initials={initials}
uploadedImageUrl={uploadedImageUrl}
onImageChange={(file) => {
setUploadedImageFile(file);
const reader = new FileReader();
reader.onload = () =>
setUploadedImageUrl(reader.result as string);
reader.readAsDataURL(file);
}}
onRemoveImage={() => {
setUploadedImageFile(null);
setUploadedImageUrl(null);
}}
<Box
sx={{
mx: { xs: 2, sm: 3, md: 4 },
py: 2,
display: 'flex',
flexDirection: 'column',
gap: 2,
bgcolor: 'background.paper',
}}
>
{isEditing && (
<ProfileImage
initials={initials}
uploadedImageUrl={uploadedImageUrl}
onImageChange={(file) => {
setUploadedImageFile(file);
const reader = new FileReader();
reader.onload = () =>
setUploadedImageUrl(reader.result as string);
reader.readAsDataURL(file);
}}
onRemoveImage={() => {
setUploadedImageFile(null);
setUploadedImageUrl(null);
}}
/>
)}
{data &&
(isEditing ? (
<InfoRowEdit
ref={infoRowEditRef}
data={data}
setData={setData}
/>
)}
{data &&
(isEditing ? (
<InfoRowEdit data={data} setData={setData} />
) : (
<InfoRowDisplay
data={data}
uploadedImageUrl={uploadedImageUrl}
initials={initials}
/>
))}
</Box>
</>
) : (
<InfoRowDisplay
data={data}
uploadedImageUrl={uploadedImageUrl}
initials={initials}
/>
))}
</Box>
)}
</CardContainer>
</PageWrapper>