181 lines
5.5 KiB
TypeScript
181 lines
5.5 KiB
TypeScript
import {
|
|
Box,
|
|
TextField,
|
|
FormControl,
|
|
InputLabel,
|
|
MenuItem,
|
|
Select,
|
|
Autocomplete,
|
|
FormHelperText,
|
|
} from '@mui/material';
|
|
import { useTranslation } from 'react-i18next';
|
|
import { countries } from '@/data/countries';
|
|
import { Gender } from '@/features/profile/types/settingsType';
|
|
import { type InfoRowEditProps } from '@/features/profile/types/settingsType';
|
|
import ReactCountryFlag from 'react-country-flag';
|
|
import { useState, forwardRef, useImperativeHandle } from 'react';
|
|
|
|
export const InfoRowEdit = forwardRef(
|
|
({ data, setData }: InfoRowEditProps, ref) => {
|
|
const { t } = useTranslation(['country', 'setting']);
|
|
const [touched, setTouched] = useState({
|
|
firstName: false,
|
|
lastName: false,
|
|
gender: false,
|
|
country: false,
|
|
});
|
|
|
|
const isValidName = (str: string) => /[A-Za-z\u0600-\u06FF]+/.test(str);
|
|
|
|
useImperativeHandle(ref, () => ({
|
|
validateFields: () => {
|
|
const newTouched = {
|
|
firstName: true,
|
|
lastName: true,
|
|
gender: true,
|
|
country: true,
|
|
};
|
|
setTouched(newTouched);
|
|
|
|
return (
|
|
data.firstName.trim() !== '' &&
|
|
isValidName(data.firstName) &&
|
|
data.lastName.trim() !== '' &&
|
|
isValidName(data.lastName) &&
|
|
data.gender !== Gender.None &&
|
|
data.country !== ''
|
|
);
|
|
},
|
|
}));
|
|
|
|
const countryOptions = countries.map((c) => ({
|
|
code: c.code,
|
|
label: t(c.label, { ns: 'country' }),
|
|
}));
|
|
const currentCountry =
|
|
countryOptions.find((c) => c.code === data.country) || null;
|
|
|
|
const fields = [
|
|
{
|
|
name: 'firstName' as const,
|
|
label: t('settingForm.name', { ns: 'setting' }),
|
|
value: data.firstName,
|
|
},
|
|
{
|
|
name: 'lastName' as const,
|
|
label: t('settingForm.familyName', { ns: 'setting' }),
|
|
value: data.lastName,
|
|
},
|
|
{
|
|
name: 'nationalCode' as const,
|
|
label: t('settingForm.optionalNationalCode', { ns: 'setting' }),
|
|
value: data.nationalCode,
|
|
},
|
|
];
|
|
|
|
return (
|
|
<Box sx={{ display: 'flex', gap: 2, flexWrap: 'wrap' }}>
|
|
{fields.map(({ name, label, value }) => (
|
|
<Box
|
|
key={name}
|
|
sx={{ width: { xs: '100%', sm: '48%', md: 'calc(50% - 8px)' } }}
|
|
>
|
|
<TextField
|
|
fullWidth
|
|
name={name}
|
|
value={value}
|
|
onChange={(e) =>
|
|
setData((prev) => ({ ...prev, [name]: e.target.value }))
|
|
}
|
|
label={label}
|
|
error={
|
|
name !== 'nationalCode' &&
|
|
touched[name] &&
|
|
(value.trim() === '' || !isValidName(value))
|
|
}
|
|
helperText={
|
|
name !== 'nationalCode' &&
|
|
touched[name] &&
|
|
(value.trim() === '' || !isValidName(value))
|
|
? t('settingForm.thisFieldIsRequired', { ns: 'setting' })
|
|
: undefined
|
|
}
|
|
/>
|
|
</Box>
|
|
))}
|
|
|
|
<Box sx={{ width: { xs: '100%', sm: '48%', md: 'calc(50% - 8px)' } }}>
|
|
<FormControl
|
|
fullWidth
|
|
error={touched.gender && data.gender === Gender.None}
|
|
>
|
|
<InputLabel>
|
|
{t('settingForm.genderPlaceholder', { ns: 'setting' })}
|
|
</InputLabel>
|
|
<Select
|
|
value={data.gender === Gender.None ? '' : data.gender}
|
|
label={t('settingForm.genderPlaceholder', { ns: 'setting' })}
|
|
onChange={(e) =>
|
|
setData((prev) => ({
|
|
...prev,
|
|
gender: e.target.value as Gender,
|
|
}))
|
|
}
|
|
>
|
|
<MenuItem value={Gender.Male}>
|
|
{t('settingForm.man', { ns: 'setting' })}
|
|
</MenuItem>
|
|
<MenuItem value={Gender.Female}>
|
|
{t('settingForm.woman', { ns: 'setting' })}
|
|
</MenuItem>
|
|
</Select>
|
|
<FormHelperText>
|
|
{touched.gender && data.gender === Gender.None
|
|
? t('settingForm.thisFieldIsRequired', { ns: 'setting' })
|
|
: ''}
|
|
</FormHelperText>
|
|
</FormControl>
|
|
</Box>
|
|
|
|
<Autocomplete
|
|
sx={{ width: { xs: '100%', sm: '48%', md: 'calc(50% - 8px)' } }}
|
|
options={countryOptions}
|
|
getOptionLabel={(option) => option.label}
|
|
value={currentCountry}
|
|
onChange={(_, newValue) =>
|
|
setData((prev) => ({ ...prev, country: newValue?.code || '' }))
|
|
}
|
|
renderOption={(props, option) => (
|
|
<Box
|
|
component="li"
|
|
{...props}
|
|
key={option.code}
|
|
sx={{ gap: 1, alignItems: 'center' }}
|
|
>
|
|
<ReactCountryFlag
|
|
countryCode={option.code}
|
|
svg
|
|
style={{ height: '1.5rem', width: '1.5rem' }}
|
|
/>
|
|
{option.label}
|
|
</Box>
|
|
)}
|
|
renderInput={(params) => (
|
|
<TextField
|
|
{...params}
|
|
label={t('settingForm.country', { ns: 'setting' })}
|
|
error={touched.country && data.country === ''}
|
|
helperText={
|
|
touched.country && data.country === ''
|
|
? t('settingForm.thisFieldIsRequired', { ns: 'setting' })
|
|
: ''
|
|
}
|
|
/>
|
|
)}
|
|
clearOnEscape
|
|
/>
|
|
</Box>
|
|
);
|
|
},
|
|
);
|