fix/ styles and seperate the main file to different components
This commit is contained in:
@@ -1,56 +1,53 @@
|
||||
import {
|
||||
TextField,
|
||||
FormControl,
|
||||
InputLabel,
|
||||
MenuItem,
|
||||
Select,
|
||||
Box,
|
||||
type SelectChangeEvent,
|
||||
Switch,
|
||||
FormGroup,
|
||||
Button,
|
||||
Typography,
|
||||
Link,
|
||||
} from '@mui/material';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { Box, Typography } from '@mui/material';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { PersonalInfoFields } from './PersonalInfoFields';
|
||||
import { PasswordSection } from './PasswordSection';
|
||||
import { EmailSection } from './EmailSection';
|
||||
import { SubmitSection } from './SubmitSection';
|
||||
|
||||
export function UserCompletionForm() {
|
||||
const { t } = useTranslation('completionForm');
|
||||
const [sex, setSex] = useState('');
|
||||
const [showPassword, setShowPassword] = useState(false);
|
||||
const [showEmail, setShowEmail] = useState(false);
|
||||
const [showPasswordSection, setShowPasswordSection] = useState(false);
|
||||
const [password, setPassword] = useState('');
|
||||
const [email, setEmail] = useState('');
|
||||
const [confirmPassword, setConfirmPassword] = useState('');
|
||||
const [showEmail, setShowEmail] = useState(false);
|
||||
const [email, setEmail] = useState('');
|
||||
const [codeSent, setCodeSent] = useState(false);
|
||||
const [verificationCode, setVerificationCode] = useState('');
|
||||
const [buttonState, setButtonState] = useState('default'); // default | counting | sent
|
||||
const [buttonState, setButtonState] = useState<
|
||||
'default' | 'counting' | 'sent'
|
||||
>('default'); // default | counting | sent
|
||||
const [countdown, setCountdown] = useState(60);
|
||||
const [emailVerified, setEmailVerified] = useState(false);
|
||||
const [isVerifyingCode, setIsVerifyingCode] = useState(false);
|
||||
|
||||
const matchPassword = password === confirmPassword;
|
||||
const hasNumber = /\d/.test(password);
|
||||
const hasMinLength = password.length >= 8;
|
||||
const hasUpperAndLower = /[A-Z]/.test(password) && /[a-z]/.test(password);
|
||||
const hasSpecialChar = /[!@#$%^&*]/.test(password);
|
||||
const validPassword =
|
||||
hasNumber && hasMinLength && hasUpperAndLower && hasSpecialChar;
|
||||
const [showPasswordValidations, setShowPasswordValidations] = useState(false);
|
||||
|
||||
const correctEmail = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
|
||||
|
||||
const handleTogglePassword = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setShowPassword(e.target.checked);
|
||||
};
|
||||
const handleToggleEmail = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setShowEmail(e.target.checked);
|
||||
};
|
||||
|
||||
const handleChange = (e: SelectChangeEvent) => {
|
||||
setSex(e.target.value);
|
||||
};
|
||||
|
||||
const onClickCodeSent = () => {
|
||||
setCodeSent(true);
|
||||
setButtonState('sent');
|
||||
setTimeout(() => {
|
||||
setButtonState('counting');
|
||||
setCountdown(60);
|
||||
}, 1000);
|
||||
};
|
||||
useEffect(() => {
|
||||
if (password) {
|
||||
if (!validPassword) {
|
||||
setShowPasswordValidations(true);
|
||||
} else {
|
||||
const timer = setTimeout(() => {
|
||||
setShowPasswordValidations(false);
|
||||
}, 1000);
|
||||
return () => clearTimeout(timer);
|
||||
}
|
||||
} else {
|
||||
setShowPasswordValidations(false);
|
||||
}
|
||||
}, [password, validPassword]);
|
||||
|
||||
useEffect(() => {
|
||||
let timer: ReturnType<typeof setInterval>;
|
||||
@@ -76,282 +73,112 @@ export function UserCompletionForm() {
|
||||
const time = `${minutes}:${seconds}`;
|
||||
return toPersianDigits(time);
|
||||
}
|
||||
return 'ارسال کد تایید';
|
||||
return t('completion.vericationCodeButton');
|
||||
};
|
||||
|
||||
const handleSendCode = () => {
|
||||
setCodeSent(true);
|
||||
setButtonState('sent');
|
||||
setTimeout(() => {
|
||||
setButtonState('counting');
|
||||
setCountdown(60);
|
||||
}, 1000);
|
||||
};
|
||||
|
||||
const handleVerifyCode = () => {
|
||||
setIsVerifyingCode(true);
|
||||
setTimeout(() => {
|
||||
setIsVerifyingCode(false);
|
||||
setEmailVerified(true);
|
||||
}, 1000);
|
||||
};
|
||||
|
||||
const handleEditEmail = () => {
|
||||
setButtonState('default');
|
||||
setCodeSent(false);
|
||||
setEmailVerified(false);
|
||||
};
|
||||
|
||||
return (
|
||||
<div
|
||||
dir="rtl"
|
||||
style={{
|
||||
<Box
|
||||
sx={{
|
||||
backgroundColor: '#F5F5F5',
|
||||
minHeight: '100vh',
|
||||
display: 'flex',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
p: 2,
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
width: '500px',
|
||||
width: '730px',
|
||||
backgroundColor: 'white',
|
||||
border: '1px solid #ccc',
|
||||
borderRadius: 2,
|
||||
padding: 5,
|
||||
margin: '40px auto',
|
||||
boxShadow: 2,
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
gap: 2,
|
||||
}}
|
||||
>
|
||||
<Box sx={{ flexDirection: 'column', mb: 2 }}>
|
||||
<Typography variant="h5" sx={{ mb: 0.5 }}>
|
||||
تکمیل اطلاعات حساب کاربری
|
||||
</Typography>
|
||||
<Typography sx={{ color: 'gray', fontSize: '14px' }}>
|
||||
اطلاعات کسب و کار خود را وارد کنید
|
||||
</Typography>
|
||||
</Box>
|
||||
<Box
|
||||
sx={{
|
||||
display: 'flex',
|
||||
gap: 2,
|
||||
flexDirection: 'column',
|
||||
px: 4,
|
||||
width: '100%',
|
||||
maxWidth: '666px',
|
||||
height: '92px',
|
||||
mt: '32px',
|
||||
}}
|
||||
>
|
||||
<TextField
|
||||
label="نام"
|
||||
placeholder="نام"
|
||||
variant="outlined"
|
||||
sx={{
|
||||
width: '330px',
|
||||
'& .MuiOutlinedInput-root': {
|
||||
height: 45,
|
||||
},
|
||||
}}
|
||||
/>
|
||||
<TextField
|
||||
label="نام خانوادگی"
|
||||
placeholder="نام خانوادگی"
|
||||
variant="outlined"
|
||||
sx={{
|
||||
width: '330px',
|
||||
'& .MuiOutlinedInput-root': {
|
||||
height: 45,
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
<Box sx={{ display: 'flex', gap: 2 }}>
|
||||
<FormControl sx={{ width: '330px' }}>
|
||||
<InputLabel id="sex-label">جنسیت</InputLabel>
|
||||
<Select
|
||||
labelId="sex-label"
|
||||
id="sex"
|
||||
value={sex}
|
||||
label="جنسیت"
|
||||
onChange={handleChange}
|
||||
sx={{
|
||||
height: '45px',
|
||||
'& .MuiSelect-select': {
|
||||
paddingY: '10px',
|
||||
},
|
||||
}}
|
||||
>
|
||||
<MenuItem value="female">زن</MenuItem>
|
||||
<MenuItem value="male">مرد</MenuItem>
|
||||
</Select>
|
||||
</FormControl>
|
||||
|
||||
<TextField
|
||||
label="کدملی(اختیاری)"
|
||||
placeholder="کدملی(اختیاری)"
|
||||
variant="outlined"
|
||||
sx={{
|
||||
width: '330px',
|
||||
'& .MuiOutlinedInput-root': {
|
||||
height: 45,
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
<FormGroup>
|
||||
<Box sx={{ display: 'flex', gap: 0.5, alignItems: 'center' }}>
|
||||
<Switch
|
||||
checked={showPassword}
|
||||
onChange={handleTogglePassword}
|
||||
sx={{
|
||||
color: '#2979FF',
|
||||
transform: 'scaleX(-1)',
|
||||
'& .MuiSwitch-thumb': {
|
||||
transform: 'scaleX(-1)',
|
||||
},
|
||||
}}
|
||||
/>
|
||||
<Typography> تعیین رمز عبور</Typography>
|
||||
</Box>
|
||||
</FormGroup>
|
||||
{showPassword && (
|
||||
<Box sx={{ display: 'flex', gap: 2 }}>
|
||||
<Box
|
||||
sx={{ display: 'flex', flexDirection: 'column', width: '330px' }}
|
||||
>
|
||||
<TextField
|
||||
label="رمز عبور"
|
||||
value={password}
|
||||
onChange={(e) => setPassword(e.target.value)}
|
||||
variant="outlined"
|
||||
sx={{
|
||||
'& .MuiOutlinedInput-root': {
|
||||
height: 45,
|
||||
},
|
||||
}}
|
||||
/>
|
||||
{password && (
|
||||
<Box sx={{ mt: 1 }}>
|
||||
<Typography
|
||||
variant="caption"
|
||||
sx={{ color: hasNumber ? 'green' : 'red' }}
|
||||
>
|
||||
شامل عدد
|
||||
</Typography>
|
||||
<br />
|
||||
<Typography
|
||||
variant="caption"
|
||||
sx={{ color: hasMinLength ? 'green' : 'red' }}
|
||||
>
|
||||
حداقل 8 کاراکتر
|
||||
</Typography>
|
||||
<br />
|
||||
<Typography
|
||||
variant="caption"
|
||||
sx={{ color: hasUpperAndLower ? 'green' : 'red' }}
|
||||
>
|
||||
شامل یک حرف بزرگ و کوچک
|
||||
</Typography>
|
||||
<br />
|
||||
<Typography
|
||||
variant="caption"
|
||||
sx={{ color: hasSpecialChar ? 'green' : 'red' }}
|
||||
>
|
||||
شامل علامت(!@#$%^&*)
|
||||
</Typography>
|
||||
</Box>
|
||||
)}
|
||||
</Box>
|
||||
{showPassword && (
|
||||
<TextField
|
||||
label="تکرار رمز عبور"
|
||||
variant="outlined"
|
||||
onChange={(e) => setConfirmPassword(e.target.value)}
|
||||
error={confirmPassword.length > 0 && !matchPassword}
|
||||
helperText={
|
||||
confirmPassword.length > 0 && !matchPassword
|
||||
? 'مطابقت ندارد'
|
||||
: ' '
|
||||
}
|
||||
sx={{
|
||||
width: '330px',
|
||||
'& .MuiOutlinedInput-root': {
|
||||
height: 45,
|
||||
},
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</Box>
|
||||
)}
|
||||
|
||||
<FormGroup>
|
||||
<Box sx={{ display: 'flex', gap: 0.5, alignItems: 'center' }}>
|
||||
<Switch
|
||||
checked={showEmail}
|
||||
onChange={handleToggleEmail}
|
||||
sx={{
|
||||
transform: 'scaleX(-1)',
|
||||
'& .MuiSwitch-thumb': {
|
||||
transform: 'scaleX(-1)',
|
||||
},
|
||||
}}
|
||||
/>
|
||||
<Typography> اتصال ایمیل خود</Typography>
|
||||
</Box>
|
||||
</FormGroup>
|
||||
{showEmail && (
|
||||
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 2 }}>
|
||||
<Box sx={{ display: 'flex', gap: 2 }}>
|
||||
<Box sx={{ display: 'flex', flexDirection: 'column' }}>
|
||||
<TextField
|
||||
label="ایمیل"
|
||||
variant="outlined"
|
||||
value={email}
|
||||
onChange={(e) => setEmail(e.target.value)}
|
||||
sx={{
|
||||
width: '330px',
|
||||
'& .MuiOutlinedInput-root': {
|
||||
height: 45,
|
||||
},
|
||||
}}
|
||||
/>
|
||||
{email && (
|
||||
<Typography sx={{ color: correctEmail ? 'green' : 'red' }}>
|
||||
فرم درست ایمیل وارد کنید
|
||||
</Typography>
|
||||
)}
|
||||
</Box>
|
||||
<Button
|
||||
variant="text"
|
||||
onClick={onClickCodeSent}
|
||||
sx={{ width: '200px', color: '#2979FF' }}
|
||||
disabled={buttonState === 'sent' || buttonState === 'counting'}
|
||||
>
|
||||
{getButtonLabel()}
|
||||
</Button>
|
||||
</Box>
|
||||
{codeSent && (
|
||||
<Box sx={{ display: 'flex', gap: 2 }}>
|
||||
<TextField
|
||||
label="کد تایید"
|
||||
variant="outlined"
|
||||
value={verificationCode}
|
||||
onChange={(e) => setVerificationCode(e.target.value)}
|
||||
sx={{
|
||||
width: '330px',
|
||||
'& .MuiOutlinedInput-root': {
|
||||
height: 45,
|
||||
},
|
||||
}}
|
||||
/>
|
||||
<Button
|
||||
variant="contained"
|
||||
sx={{
|
||||
width: '150px',
|
||||
backgroundColor: 'white',
|
||||
border: 0.5,
|
||||
borderColor: '#1976d2',
|
||||
color: '#1976d2',
|
||||
}}
|
||||
>
|
||||
بررسی کد
|
||||
</Button>
|
||||
</Box>
|
||||
)}
|
||||
</Box>
|
||||
)}
|
||||
<Box sx={{ display: 'flex', gap: 2 }}>
|
||||
<Typography variant="body2" sx={{ flex: 1 }}>
|
||||
ادامه فرایند ثبت نام به منزله تایید و قبول{' '}
|
||||
<Link href="" target="_blank" rel="">
|
||||
قوانین و مقررات هارمونی
|
||||
</Link>{' '}
|
||||
می باشد.
|
||||
</Typography>
|
||||
<Button
|
||||
variant="contained"
|
||||
sx={{ width: '250px', height: '40px', backgroundColor: '#2979FF' }}
|
||||
<Typography
|
||||
variant="h5"
|
||||
color="text.primary"
|
||||
sx={{ mt: '16px', px: 2 }}
|
||||
>
|
||||
تایید و ثبت نام
|
||||
</Button>
|
||||
{t('completion.title')}
|
||||
</Typography>
|
||||
<Typography variant="body2" color="text.secondary" sx={{ px: 2 }}>
|
||||
{t('completion.description')}
|
||||
</Typography>
|
||||
</Box>
|
||||
|
||||
<PersonalInfoFields sex={sex} setSex={setSex} />
|
||||
|
||||
<PasswordSection
|
||||
showPasswordSection={showPasswordSection}
|
||||
setShowPasswordSection={setShowPasswordSection}
|
||||
password={password}
|
||||
setPassword={setPassword}
|
||||
confirmPassword={confirmPassword}
|
||||
setConfirmPassword={setConfirmPassword}
|
||||
matchPassword={matchPassword}
|
||||
hasNumber={hasNumber}
|
||||
hasMinLength={hasMinLength}
|
||||
hasUpperAndLower={hasUpperAndLower}
|
||||
hasSpecialChar={hasSpecialChar}
|
||||
validPassword={validPassword}
|
||||
showValidations={showPasswordValidations}
|
||||
/>
|
||||
|
||||
<EmailSection
|
||||
showEmail={showEmail}
|
||||
setShowEmail={setShowEmail}
|
||||
email={email}
|
||||
setEmail={setEmail}
|
||||
correctEmail={correctEmail}
|
||||
codeSent={codeSent}
|
||||
verificationCode={verificationCode}
|
||||
setVerificationCode={setVerificationCode}
|
||||
buttonState={buttonState}
|
||||
getButtonLabel={getButtonLabel}
|
||||
handleSendCode={handleSendCode}
|
||||
handleVerifyCode={handleVerifyCode}
|
||||
emailVerified={emailVerified}
|
||||
isVerifyingCode={isVerifyingCode}
|
||||
handleEditEmail={handleEditEmail}
|
||||
/>
|
||||
|
||||
<SubmitSection />
|
||||
</Box>
|
||||
</div>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user