Files
Account/src/features/profile/components/PersonalInformation.tsx

331 lines
9.9 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import {
Box,
Typography,
Button,
TextField,
FormControl,
Select,
MenuItem,
Avatar,
Autocomplete,
type SelectChangeEvent,
} from '@mui/material';
import { useState, type ChangeEvent } from 'react';
import { CardContainer } from '@/components/CardContainer';
import { CountryFlag, countryCodeMap } from '@/components/CountryFlag';
import { useTranslation } from 'react-i18next';
import { Camera } from 'iconsax-react';
export function PersonalInformation() {
const { t } = useTranslation('profileSetting');
const [isEditing, setIsEditing] = useState(false);
const [gender, setGender] = useState('');
const initialData = {
firstName: 'محمد حسین',
lastName: 'برزه‌گر',
country: 'قطر',
gender: 'مرد',
nationalCode: '',
};
const [data, setData] = useState(initialData);
const [uploadedImageUrl, setUploadedImageUrl] = useState<string | null>(null);
const handleChange = (e: ChangeEvent<HTMLInputElement>) => {
const { name, value } = e.target;
setData((prev) => ({
...prev,
[name]: value,
}));
};
const toggleEdit = () => {
setIsEditing((prev) => !prev);
if (isEditing) {
setData((prev) => ({
...prev,
gender: gender === 'male' ? 'مرد' : gender === 'female' ? 'زن' : '',
}));
} else {
setGender(
data.gender === 'مرد' ? 'male' : data.gender === 'زن' ? 'female' : '',
);
}
};
const handleChangeGender = (e: SelectChangeEvent) => {
setGender(e.target.value);
};
const displayValue = (value: string | null | undefined) => {
return value && value.trim() !== '' ? value : 'تعیین نشده';
};
const handleImageChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const file = e.target.files?.[0];
if (file) {
const reader = new FileReader();
reader.onload = () => {
setUploadedImageUrl(reader.result as string);
};
reader.readAsDataURL(file);
}
};
const initials = `${data.firstName?.trim()[0] || ''}${data.lastName?.trim()[0] || ''}`;
return (
<Box
sx={{ display: 'flex', justifyContent: 'center', alignItems: 'center' }}
>
<CardContainer
title={t('settingForm.titlePersonalInfo')}
subtitle={t('settingForm.descriptionPersonalInfo')}
highlighted={isEditing}
action={
<Box sx={{ display: 'flex', gap: 1 }}>
{isEditing && (
<Button
variant="text"
onClick={() => setIsEditing(false)}
size="large"
sx={{
color: 'primary.main',
width: '43px',
textTransform: 'none',
}}
>
{t('settingForm.rejectButton')}
</Button>
)}
<Button
onClick={toggleEdit}
size="large"
variant="outlined"
sx={{
textTransform: 'none',
border: '1px solid',
borderColor: 'primary.main',
borderRadius: '4px',
backgroundColor: isEditing
? 'primary.main'
: 'background.paper',
color: isEditing ? 'primary.contrastText' : 'primary.main',
px: '22px',
py: '8px',
width: isEditing ? '85px' : '93px',
}}
>
{isEditing
? t('settingForm.saveButton')
: t('settingForm.editButton')}
</Button>
</Box>
}
>
<Box
sx={{
px: { xs: 2, sm: 3, md: 4 },
py: 2,
display: 'flex',
flexDirection: 'column',
gap: 2,
}}
>
{isEditing && (
<Box
sx={{
display: 'flex',
alignItems: 'center',
gap: 2,
flexWrap: 'wrap',
}}
>
<Avatar
sx={{
bgcolor: 'secondary.main',
width: 88,
height: 88,
fontSize: '20px',
}}
src={uploadedImageUrl || undefined}
>
{initials}
</Avatar>
<Box>
<Typography variant="body1">
{t('settingForm.profilePicture')}
</Typography>
<Typography variant="body2" color="text.secondary">
{t('settingForm.allowedFormat')}
</Typography>
<Box mt={1}>
<Button
variant="contained"
component="label"
sx={{
borderRadius: 2,
textTransform: 'none',
height: '30px',
fontSize: '13px',
}}
startIcon={<Camera size={18} color="white" />}
>
{t('settingForm.uploadPicture')}
<input
hidden
accept="image/png, image/jpeg, image/gif"
type="file"
onChange={handleImageChange}
/>
</Button>
</Box>
</Box>
</Box>
)}
<Box sx={{ display: 'flex', flexWrap: 'wrap', gap: 2 }}>
{[
{
name: 'firstName',
label: t('settingForm.name'),
value: data.firstName,
},
{
name: 'lastName',
label: t('settingForm.familyName'),
value: data.lastName,
},
{
name: 'nationalCode',
label: t('settingForm.nationalCode'),
value: data.nationalCode,
},
].map((field, index) => (
<Box
key={index}
sx={{
width: {
xs: '100%',
sm: '48%',
md: 'calc(50% - 8px)',
},
}}
>
{isEditing ? (
<TextField
fullWidth
name={field.name}
value={field.value}
onChange={handleChange}
label={field.label}
/>
) : (
<Box sx={{ px: 2 }}>
<Typography variant="caption" color="text.secondary">
{field.label}
</Typography>
<Typography variant="body1" color="text.primary">
{displayValue(field.value)}
</Typography>
</Box>
)}
</Box>
))}
<Box
sx={{
width: {
xs: '100%',
sm: '48%',
md: 'calc(50% - 8px)',
},
}}
>
{isEditing ? (
<FormControl fullWidth>
<Select
value={gender}
onChange={handleChangeGender}
displayEmpty
renderValue={(selected) => {
if (!selected) {
return (
<span style={{ color: '#aaa' }}>
{t('settingForm.genderPlaceholder')}
</span>
);
}
return selected === 'male'
? t('settingForm.man')
: t('settingForm.woman');
}}
>
<MenuItem value="male">{t('settingForm.man')}</MenuItem>
<MenuItem value="female">{t('settingForm.woman')}</MenuItem>
</Select>
</FormControl>
) : (
<Box sx={{ px: 2 }}>
<Typography variant="caption" color="text.secondary">
{t('settingForm.gender')}
</Typography>
<Typography variant="body1" color="text.primary">
{displayValue(data.gender)}
</Typography>
</Box>
)}
</Box>
{isEditing && (
<Autocomplete
sx={{
width: {
xs: '100%',
sm: '48%',
md: 'calc(50% - 8px)',
},
}}
options={Object.keys(countryCodeMap)}
value={data.country}
onChange={(_, newValue) =>
setData((prev) => ({
...prev,
country: newValue || '',
}))
}
renderOption={(props, option) => (
<Box component="li" {...props}>
<CountryFlag country={option} />
</Box>
)}
renderInput={(params) => (
<TextField {...params} label={t('settingForm.country')} />
)}
/>
)}
{!isEditing && (
<Box
sx={{
px: 2,
width: {
xs: '100%',
sm: '48%',
md: 'calc(50% - 8px)',
},
}}
>
<Typography variant="caption" color="text.secondary">
{t('settingForm.country')}
</Typography>
<CountryFlag country={data.country} />
</Box>
)}
</Box>
</Box>
</CardContainer>
</Box>
);
}