import { useEffect, useState } from 'react'; import { Box, Typography } from '@mui/material'; import { useTranslation } from 'react-i18next'; import Logo from '@/components/Logo'; import { PersonalInfoFields } from '../components/UserCompletionForm/PersonalInfoFields'; import { PasswordSection } from '../components/UserCompletionForm/PasswordSection'; import { EmailSection } from '../components/UserCompletionForm/EmailSection'; import { SubmitSection } from '../components/UserCompletionForm/SubmitSection'; import { useToast } from '@rkheftan/harmony-ui'; import { toLocaleDigits } from '../../../utils/persianDigit'; import i18n from '@/config/i18n'; import { Gender } from '../types/settingForm'; import { useApi } from '@/hooks/useApi'; import { sendEmailOtpApi, confirmEmailOtpApi, completeUserInformationApi, } from '../api/userCompletion'; import { containsSymbol } from '@/utils/regexes/containsSymbol'; import { least8Chars } from '@/utils/regexes/least8Chars'; import { containsNumber } from '@/utils/regexes/containsNumber'; import { hasUpperAndLowerLetter } from '@/utils/regexes/hasUpperAndLowerLetter'; import { isEmail } from '@/utils/regexes/isEmail'; import { useNavigate, useSearchParams } from 'react-router-dom'; export function UserCompletionPage() { const [params] = useSearchParams(); const { t } = useTranslation('completionForm'); const showToast = useToast(); const navigate = useNavigate(); const [firstName, setFirstName] = useState(''); const [lastName, setLastName] = useState(''); const [nationalId, setNationalId] = useState(''); const [birthDate, setBirthDate] = useState(null); const [sex, setSex] = useState(Gender.Female); const [country, setCountry] = useState(''); const [showPasswordSection, setShowPasswordSection] = useState(false); const [password, setPassword] = useState(''); const [confirmPassword, setConfirmPassword] = useState(''); const [showEmail, setShowEmail] = useState(false); const [email, setEmail] = useState(''); const [verificationCode, setVerificationCode] = useState(''); const [codeSent, setCodeSent] = useState(false); const [buttonState, setButtonState] = useState<'default' | 'counting'>( 'default', ); const [countdown, setCountdown] = useState(0); const [emailVerified, setEmailVerified] = useState(false); const [showPasswordValidations, setShowPasswordValidations] = useState(false); const hasNumber = containsNumber(password); const hasMinLength = least8Chars(password); const hasUpperAndLower = hasUpperAndLowerLetter(password); const hasSpecialChar = containsSymbol(password); const validPassword = hasNumber && hasMinLength && hasUpperAndLower && hasSpecialChar; const matchPassword = password === confirmPassword; const correctEmail = isEmail(email); const { execute: sendCode, data: sendCodeData } = useApi(sendEmailOtpApi); const { execute: verifyCode, data: verifyCodeData, loading: isVerifyingCode, } = useApi(confirmEmailOtpApi); const { execute: submitForm, data: submitData, loading: isSubmitting, error: submitError, } = useApi(completeUserInformationApi); const getErrorMessage = (error: unknown): string | null => { if (!error) return null; if (error instanceof Error) return error.message; return String(error); }; useEffect(() => { if (sendCodeData) { if (sendCodeData.data.success) { showToast({ message: sendCodeData.data.message || t('completion.successfullCodeSent'), severity: 'success', }); setCodeSent(true); setButtonState('counting'); setCountdown(120); } else { showToast({ message: sendCodeData.data.message || t('completion.problem'), severity: 'error', }); } } }, [sendCodeData, showToast, t]); useEffect(() => { if (verifyCodeData) { if (verifyCodeData.data.success) { setEmailVerified(true); showToast({ message: verifyCodeData.data.message || t('completion.codeVerified'), severity: 'success', }); } else { showToast({ message: verifyCodeData.data.message || t('completion.invalidCode'), severity: 'error', }); setEmailVerified(false); } } }, [verifyCodeData, showToast, t]); useEffect(() => { if (submitData) { showToast({ message: submitData.data.message || t( submitData.data.success ? 'completion.submitSuccess' : 'completion.submitError', ), severity: submitData.data.success ? 'success' : 'error', }); if (submitData.data.success) { const returnUrl = params.get('returnUrl'); navigate( returnUrl ? `/account-created?returnUrl=${returnUrl}` : '`/account-created', ); } } else if (submitError) { showToast({ message: getErrorMessage(submitError) || t('completion.problem'), severity: 'error', }); } }, [submitData, submitError, showToast, t, navigate, params]); useEffect(() => { setShowPasswordValidations(password ? !validPassword : false); }, [password, validPassword]); useEffect(() => { let timer: NodeJS.Timeout; if (buttonState === 'counting' && countdown > 0) { timer = setInterval(() => { setCountdown((prev) => { if (prev <= 1) { setButtonState('default'); clearInterval(timer); return 0; } return prev - 1; }); }, 1000); } return () => clearInterval(timer); }, [buttonState, countdown]); const handleSendCode = () => { sendCode({ email }); }; const handleVerifyCode = () => { if (!verificationCode.trim()) { showToast({ message: 'Please enter the verification code', severity: 'warning', }); return; } verifyCode({ email, otpCode: verificationCode }); }; const handleSubmit = () => { submitForm({ firstName, lastName, gender: sex, nationalId, savePassword: showPasswordSection, password: showPasswordSection ? password : undefined, saveEmail: showEmail, email: showEmail ? email : undefined, birthDate, country, }); }; const getButtonLabel = () => { if (buttonState === 'counting') { const m = String(Math.floor(countdown / 60)).padStart(2, '0'); const s = String(countdown % 60).padStart(2, '0'); return toLocaleDigits(`${m}:${s}`, i18n.language); } return t('completion.vericationCodeButton'); }; const handleEditEmail = () => { setButtonState('default'); setCodeSent(false); setEmailVerified(false); setVerificationCode(''); }; return ( {t('completion.title')} {t('completion.description')} ); }