From 0e2f724f14ddb797817adfb6f8aabc1c719f839b Mon Sep 17 00:00:00 2001 From: Koosha Lahouti Date: Sat, 26 Jul 2025 16:49:17 +0330 Subject: [PATCH] fix: styles and make it responsive --- public/locales/fa/completionForm.json | 3 +- src/components/CustomAlert.tsx | 97 ++++++++ .../authentication/components/DateOfBirth.tsx | 8 +- .../components/EmailSection.tsx | 178 +++++++++----- .../components/PasswordSection.tsx | 46 +++- .../components/PersonalInfoFields.tsx | 221 ++++++++++-------- .../components/SubmitSection.tsx | 122 +++++++--- 7 files changed, 478 insertions(+), 197 deletions(-) create mode 100644 src/components/CustomAlert.tsx diff --git a/public/locales/fa/completionForm.json b/public/locales/fa/completionForm.json index f30e60c..f4f4f4f 100644 --- a/public/locales/fa/completionForm.json +++ b/public/locales/fa/completionForm.json @@ -29,6 +29,7 @@ "sent": "ارسال شد!", "country": "کشور", "dateOfBirth": "تاریخ تولد(اختیاری)", - "invalidCountry": "کشور انتخاب شده صحیح نیست" + "invalidCountry": "کشور انتخاب شده صحیح نیست", + "rules": "قوانین و مقررات" } } diff --git a/src/components/CustomAlert.tsx b/src/components/CustomAlert.tsx new file mode 100644 index 0000000..32c413a --- /dev/null +++ b/src/components/CustomAlert.tsx @@ -0,0 +1,97 @@ +import React, { useState, useEffect } from 'react'; +import { Box, Alert, IconButton, type AlertColor } from '@mui/material'; +import { + TickCircle, + CloseSquare, + Warning2, + InfoCircle, + CloseCircle, +} from 'iconsax-react'; + +type AlertType = AlertColor; + +interface CustomAlertProps { + message: string; + onClose: () => void; + severity?: AlertType; + open: boolean; + duration?: number; + delayOnClose?: number; + rtl?: boolean; + icon?: React.ReactNode; +} + +const defaultIcons: Record = { + success: , + error: , + warning: , + info: , +}; + +export const CustomAlert: React.FC = ({ + message, + severity, + open, + onClose, + duration = 4000, + delayOnClose = 2000, + rtl = false, + icon, +}) => { + const [visible, setVisible] = useState(open); + + useEffect(() => { + setVisible(open); + }, [open]); + + useEffect(() => { + if (visible && duration > 0) { + const timer = setTimeout(() => { + setVisible(false); + onClose(); + }, duration); + return () => clearTimeout(timer); + } + }, [visible, duration, onClose]); + + const handleClose = () => { + setTimeout(() => { + setVisible(false); + onClose(); + }, delayOnClose); + }; + + if (!visible) return null; + + return ( + + + + + } + sx={{ + width: '396px', + flexDirection: 'row-reverse', + justifyContent: 'space-between', + alignItems: 'center', + textAlign: rtl ? 'right' : 'left', + direction: rtl ? 'rtl' : 'ltr', + }} + > + {message} + + + ); +}; diff --git a/src/features/authentication/components/DateOfBirth.tsx b/src/features/authentication/components/DateOfBirth.tsx index 4edc9f3..11e0b64 100644 --- a/src/features/authentication/components/DateOfBirth.tsx +++ b/src/features/authentication/components/DateOfBirth.tsx @@ -24,11 +24,9 @@ export function DateOfBirth() { textField: { fullWidth: true, sx: { - width: { - xs: '100%', - sm: '70%', - md: '309px', - }, + flex: '1 1 260px', + maxWidth: '309px', + width: '100%', }, }, }} diff --git a/src/features/authentication/components/EmailSection.tsx b/src/features/authentication/components/EmailSection.tsx index 46ac855..2e29cad 100644 --- a/src/features/authentication/components/EmailSection.tsx +++ b/src/features/authentication/components/EmailSection.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useEffect, useState } from 'react'; import { TextField, Box, @@ -11,6 +11,7 @@ import { } from '@mui/material'; import { useTranslation } from 'react-i18next'; import { TickCircle, Edit, Refresh } from 'iconsax-react'; +import { CustomAlert } from '@/components/CustomAlert'; interface EmailSectionProps { showEmail: boolean; @@ -48,11 +49,33 @@ export function EmailSection({ handleEditEmail, }: EmailSectionProps) { const { t } = useTranslation('completionForm'); + const [showSuccessAlert, setShowSuccessAlert] = useState(false); + const [showEmailErrorAlert, setShowEmailErrorAlert] = useState(false); + const onSendCodeClick = () => { + if (!correctEmail) { + setShowEmailErrorAlert(true); + return; + } + setShowEmailErrorAlert(false); + handleSendCode(); + }; const handleToggleEmail = (e: React.ChangeEvent) => { setShowEmail(e.target.checked); }; + useEffect(() => { + if (emailVerified) { + setShowSuccessAlert(true); + } + }, [emailVerified]); + + const fieldSx = { + flex: '1 1 260px', + maxWidth: emailVerified ? '634px' : '462px', + width: '100%', + }; + return ( <> @@ -61,7 +84,7 @@ export function EmailSection({ display: 'flex', alignItems: 'center', gap: 1, - px: { xs: 2, sm: 6 }, + px: { xs: 2, sm: 0 }, }} > @@ -79,68 +102,68 @@ export function EmailSection({ display: 'flex', flexDirection: 'column', gap: 2, - px: { xs: 2, sm: 6 }, + px: { xs: 2, sm: 0 }, }} > - - - setEmail(e.target.value)} - error={email.length > 0 && !correctEmail} - sx={{ maxWidth: '462px' }} - InputProps={{ - startAdornment: - !isVerifyingCode && emailVerified ? ( - - + setEmail(e.target.value)} + error={email.length > 0 && !correctEmail} + sx={fieldSx} + InputProps={{ + startAdornment: + !isVerifyingCode && emailVerified ? ( + + + + ) : null, + endAdornment: + buttonState === 'counting' ? ( + + + - - ) : null, - endAdornment: - buttonState === 'counting' ? ( - - - - - - ) : null, - }} - inputProps={{ - style: { - paddingLeft: buttonState === 'counting' ? '0px' : undefined, - }, - }} - /> - {email && ( - - {correctEmail ? '' : t('completion.emailCorrectForm')} - - )} - + + + ) : null, + }} + inputProps={{ + style: { + paddingLeft: buttonState === 'counting' ? '0px' : undefined, + }, + }} + /> {!isVerifyingCode && !emailVerified && ( - + + {t('completion.agreementPart1')}{' '} + + {t('completion.agreementLinkText')} + {' '} + {t('completion.agreementPart2')} + + + + + + + + {t('completion.rules') || t('completion.rules')} + + + + {agreementText} + + + ); }