fix: styles and add a country textfield in personal field

This commit is contained in:
2025-07-23 17:28:25 +03:30
parent 3b3db1be41
commit 9c9e148426
7 changed files with 381 additions and 327 deletions

View File

@@ -6,18 +6,21 @@ import {
FormControl,
Select,
MenuItem,
Avatar,
Autocomplete,
type SelectChangeEvent,
} from '@mui/material';
import { useState, type ChangeEvent } from 'react';
import { CardContainer } from '@/components/CardContainer';
import { CountryFlag } from '@/components/CountryFlag';
import { CountryFlag, countryCodeMap } from '@/components/CountryFlag';
import { useTranslation } from 'react-i18next';
import { Profile } from 'iconsax-react';
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: 'برزه‌گر',
@@ -26,6 +29,8 @@ export function PersonalInformation() {
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) => ({
@@ -56,16 +61,22 @@ export function PersonalInformation() {
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',
backgroundColor: '#F5F5F5',
justifyContent: 'center',
alignItems: 'center',
p: 2,
overflow: 'hidden',
}}
sx={{ display: 'flex', justifyContent: 'center', alignItems: 'center' }}
>
<CardContainer
title={t('settingForm.titlePersonalInfo')}
@@ -78,10 +89,7 @@ export function PersonalInformation() {
variant="text"
onClick={() => setIsEditing(false)}
size="large"
sx={{
color: '#2979FF',
width: '43px',
}}
sx={{ color: '#2979FF', width: '43px' }}
>
{t('settingForm.rejectButton')}
</Button>
@@ -109,142 +117,178 @@ export function PersonalInformation() {
>
<Box
sx={{
px: 4,
py: 2,
display: 'flex',
flexWrap: 'wrap',
gap: 4,
p: 2,
flexDirection: 'column',
gap: 2,
}}
>
<Box sx={{ width: 'calc(50% - 16px)' }}>
{isEditing ? (
<TextField
fullWidth
name="firstName"
value={data.firstName}
onChange={handleChange}
label={t('settingForm.name')}
/>
) : (
<Box
{isEditing && (
<Box sx={{ display: 'flex', alignItems: 'center', gap: 2 }}>
<Avatar
sx={{
height: 'auto',
display: 'flex',
flexDirection: 'column',
justifyContent: 'center',
alignItems: 'flex-start',
gap: 0.5,
px: 4,
bgcolor: '#00C3B7',
width: 88,
height: 88,
fontSize: '20px',
}}
src={uploadedImageUrl || undefined}
>
<Typography variant="caption" color="text.secondary">
{`${t('settingForm.name')} و ${t('settingForm.familyName')}`}
{initials}
</Avatar>
<Box>
<Typography variant="body1">
{t('settingForm.profilePicture')}
</Typography>
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
<Profile size="20" color="gray" />
<Typography variant="body1" color="text.primary">
{displayValue(data.firstName + ' ' + data.lastName)}
</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>
)}
<Box sx={{ width: 'calc(50% - 16px)' }}>
{isEditing ? (
<TextField
fullWidth
name="lastName"
value={data.lastName}
onChange={handleChange}
label={t('settingForm.familyName')}
<Box sx={{ display: 'flex', flexWrap: 'wrap', gap: 2 }}>
<Box sx={{ width: 'calc(50% - 8px)' }}>
{isEditing ? (
<TextField
fullWidth
name="firstName"
value={data.firstName}
onChange={handleChange}
label={t('settingForm.name')}
/>
) : (
<Box sx={{ px: 4 }}>
<Typography variant="caption" color="text.secondary">
{`${t('settingForm.name')} و ${t('settingForm.familyName')}`}
</Typography>
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
<Avatar>{initials}</Avatar>
<Typography variant="body1" color="text.primary">
{displayValue(data.firstName + ' ' + data.lastName)}
</Typography>
</Box>
</Box>
)}
</Box>
<Box sx={{ width: 'calc(50% - 8px)' }}>
{isEditing ? (
<TextField
fullWidth
name="lastName"
value={data.lastName}
onChange={handleChange}
label={t('settingForm.familyName')}
/>
) : (
<Box sx={{ px: 4 }}>
<Typography variant="caption" color="text.secondary">
{t('settingForm.country')}
</Typography>
<CountryFlag country={data.country} />
</Box>
)}
</Box>
<Box sx={{ width: '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: 4 }}>
<Typography variant="caption" color="text.secondary">
{t('settingForm.gender')}
</Typography>
<Typography variant="body1" color="text.primary">
{displayValue(data.gender)}
</Typography>
</Box>
)}
</Box>
<Box sx={{ width: 'calc(50% - 8px)' }}>
{isEditing ? (
<TextField
fullWidth
name="nationalCode"
value={data.nationalCode}
onChange={handleChange}
label={t('settingForm.nationalCode')}
/>
) : (
<Box sx={{ px: 4 }}>
<Typography variant="caption" color="text.secondary">
{t('settingForm.nationalCode')}
</Typography>
<Typography variant="body1" color="text.primary">
{displayValue(data.nationalCode)}
</Typography>
</Box>
)}
</Box>
{isEditing && (
<Autocomplete
sx={{ width: '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')} />
)}
/>
) : (
<Box
sx={{
height: '48px',
display: 'flex',
flexDirection: 'column',
justifyContent: 'center',
}}
>
<Typography variant="caption" color="text.secondary">
{t('settingForm.country')}
</Typography>
<CountryFlag country={data.country} />
</Box>
)}
</Box>
<Box sx={{ width: 'calc(50% - 16px)' }}>
{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={{
height: '48px',
display: 'flex',
flexDirection: 'column',
justifyContent: 'center',
px: 4,
}}
>
<Typography variant="caption" color="text.secondary">
{t('settingForm.gender')}
</Typography>
<Typography variant="body1" color="text.primary">
{displayValue(data.gender)}
</Typography>
</Box>
)}
</Box>
<Box sx={{ width: 'calc(50% - 16px)' }}>
{isEditing ? (
<TextField
fullWidth
name="nationalCode"
value={data.nationalCode}
onChange={handleChange}
label={t('settingForm.nationalCode')}
/>
) : (
<Box
sx={{
height: '48px',
display: 'flex',
flexDirection: 'column',
justifyContent: 'center',
}}
>
<Typography variant="caption" color="text.secondary">
{t('settingForm.nationalCode')}{' '}
</Typography>
<Typography variant="body1" color="text.primary">
{displayValue(data.nationalCode)}
</Typography>
</Box>
)}
</Box>
</Box>