From ff7b5ce4acba4481b63c12468f5313eea3796fb2 Mon Sep 17 00:00:00 2001 From: Koosha Lahouti Date: Sat, 19 Jul 2025 17:27:39 +0330 Subject: [PATCH] fix: styles --- src/App.tsx | 5 + src/components/CardContainer.tsx | 56 +++ src/components/CountDownTimer.tsx | 39 ++ .../components/PersonalInformation.tsx | 176 +++---- .../profile/components/PhoneNumber.tsx | 472 ++++++++---------- .../profile/components/SocialMedia.tsx | 423 ++++++++++------ 6 files changed, 658 insertions(+), 513 deletions(-) create mode 100644 src/components/CardContainer.tsx create mode 100644 src/components/CountDownTimer.tsx diff --git a/src/App.tsx b/src/App.tsx index 10a1234..76660a8 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -12,6 +12,7 @@ import { LanguageManager } from './components/LanguageManager'; <<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD ======= >>>>>>> f1620b6 (fix: issue in user profile) @@ -23,6 +24,9 @@ import { UserProfileForm } from './features/profile/components/UserProfileForm'; >>>>>>> f9815fb (fix: issue in user profile) ======= >>>>>>> 2a79376 (fix: merge conflict) +======= +import { UserForm } from './features/profile/components/UserForm'; +>>>>>>> 60c6dc1 (fix: styles) function App() { const { t } = useTranslation(); @@ -30,6 +34,7 @@ function App() { <> +
{t('helloWorld')} + + + + {title} + + + {subtitle} + + + {action} + + + {children} + + ); +} diff --git a/src/components/CountDownTimer.tsx b/src/components/CountDownTimer.tsx new file mode 100644 index 0000000..655fa9b --- /dev/null +++ b/src/components/CountDownTimer.tsx @@ -0,0 +1,39 @@ +import { useState, useEffect } from 'react'; + +interface CountdownTimerProps { + initialSeconds: number; + onComplete?: () => void; +} + +export function CountDownTimer({ + initialSeconds, + onComplete, +}: CountdownTimerProps) { + const [secondsLeft, setSecondsLeft] = useState(initialSeconds); + + useEffect(() => { + setSecondsLeft(initialSeconds); + }, [initialSeconds]); + + useEffect(() => { + if (secondsLeft <= 0) { + onComplete?.(); + return; + } + const timer = setInterval(() => { + setSecondsLeft((prev) => prev - 1); + }, 1000); + return () => clearInterval(timer); + }, [secondsLeft, onComplete]); + + const toPersianDigits = (str: string) => + str.replace(/\d/g, (d: string) => '۰۱۲۳۴۵۶۷۸۹'[parseInt(d)]); + + const formatTime = (totalSeconds: number) => { + const minutes = String(Math.floor(totalSeconds / 60)).padStart(2, '0'); + const seconds = String(totalSeconds % 60).padStart(2, '0'); + return toPersianDigits(`${minutes}:${seconds}`); + }; + + return {formatTime(secondsLeft)}; +} diff --git a/src/features/profile/components/PersonalInformation.tsx b/src/features/profile/components/PersonalInformation.tsx index 21967f1..9975735 100644 --- a/src/features/profile/components/PersonalInformation.tsx +++ b/src/features/profile/components/PersonalInformation.tsx @@ -3,13 +3,13 @@ import { Typography, Button, TextField, - Grid, FormControl, Select, MenuItem, type SelectChangeEvent, } from '@mui/material'; import { useState, type ChangeEvent } from 'react'; +import { CardContainer } from '@/components/CardContainer'; export function PersonalInformation() { const [isEditing, setIsEditing] = useState(false); @@ -51,58 +51,30 @@ export function PersonalInformation() { }; return ( -
- - - - - اطلاعات شخصی من - - - این اطلاعات شما صرفا برای احراز هویت شما است و نزد هارمونی باقی - می‌ماند - - - + {isEditing && ( - - - - + } + > + + {isEditing ? ( ) : ( - - + + نام - + {displayValue(data.firstName)} )} - + - + {isEditing ? ( ) : ( - - + + نام خانوادگی - + {displayValue(data.lastName)} )} - + - + {isEditing ? ( ) : ( - - + + جنسیت - + {displayValue(data.gender)} )} - + - + {isEditing ? ( ) : ( - - + + کد ملی - + {displayValue(data.nationalCode)} )} - - - -
+ + + + ); } diff --git a/src/features/profile/components/PhoneNumber.tsx b/src/features/profile/components/PhoneNumber.tsx index ccaff35..8e08d09 100644 --- a/src/features/profile/components/PhoneNumber.tsx +++ b/src/features/profile/components/PhoneNumber.tsx @@ -2,305 +2,253 @@ import { Box, Typography, Button, - Dialog, - DialogTitle, - DialogContent, - IconButton, TextField, + IconButton, + GlobalStyles, } from '@mui/material'; -import { Edit, CloseSquare } from 'iconsax-react'; -import { useState, useEffect } from 'react'; +import { Edit, Refresh, TickCircle } from 'iconsax-react'; +import { useState, useEffect, type ChangeEvent } from 'react'; +import { CardContainer } from '@/components/CardContainer'; +import { CountDownTimer } from '@/components/CountDownTimer'; export function PhoneNumber() { - const [open, setOpen] = useState(false); - const [dialogStep, setDialogStep] = useState<'enterPhone' | 'verifyCode'>( - 'enterPhone', + const [isEditing, setIsEditing] = useState(false); + const [phoneNumber, setPhoneNumber] = useState(''); + const [verificationCode, setVerificationCode] = useState(''); + const [buttonState, setButtonState] = useState<'default' | 'counting'>( + 'default', ); - const [buttonState, setButtonState] = useState('default'); // default | counting | sent - const [countdown, setCountdown] = useState(120); + const [isVerifying, setIsVerifying] = useState(false); + const [isVerified, setIsVerified] = useState(false); - const handleChangePhoneNumber = () => { - setOpen(true); - }; - const handleClose = () => { - setOpen(false); - setDialogStep('enterPhone'); - }; const handleSendCode = () => { - setDialogStep('verifyCode'); - setButtonState('sent'); + setButtonState('counting'); + setIsVerified(false); + }; + + const handleVerifyCode = () => { + setIsVerifying(true); setTimeout(() => { - setButtonState('counting'); - setCountdown(120); - }, 1000); - }; - const handleResendCode = () => { - setButtonState('sent'); - setTimeout(() => { - setButtonState('counting'); - setCountdown(120); - }, 1000); + setIsVerifying(false); + setIsVerified(true); + }, 1500); }; - useEffect(() => { - if (buttonState === 'counting' && countdown > 0) { - const timer = setInterval(() => { - setCountdown((prev) => prev - 1); - }, 1000); - return () => clearInterval(timer); - } - if (countdown === 0 && buttonState === 'counting') { - setButtonState('default'); - } - }, [buttonState, countdown]); - - const toPersianDigits = (str: string) => - str.replace(/\d/g, (d: string) => '۰۱۲۳۴۵۶۷۸۹'[parseInt(d)]); - - const getButtonLabel = () => { - if (buttonState === 'sent') return 'ارسال شد!'; - if (buttonState === 'counting') { - const minutes = String(Math.floor(countdown / 60)).padStart(2, '0'); - const seconds = String(countdown % 60).padStart(2, '0'); - const time = `${minutes}:${seconds}`; - return toPersianDigits(time); - } - return 'ارسال دوباره کد'; + const toggleEdit = () => { + setIsEditing((prev) => !prev); + setButtonState('default'); + setIsVerified(false); + setVerificationCode(''); }; - const handleEdit = () => { - setDialogStep('enterPhone'); + const handlePhoneNumberChange = (e: ChangeEvent) => { + const value = e.target.value.replace(/\D/g, ''); + setPhoneNumber(value); + }; + + const handleVerificationCodeChange = (e: ChangeEvent) => { + const value = e.target.value.replace(/\D/g, ''); + setVerificationCode(value); }; return ( -
+ <> + - - - شماره تماس من - - این اطلاعات شما صرفا برای احراز هویت شما است و نزد هارمونی باقی - می‌ماند - - - - - - - - - 09909366045 - - - ۱ ماه پیش - - - - {/* */} - - - - - - ویرایش شماره تماس - - - - - - - {dialogStep === 'enterPhone' ? ( - <> - - شماره تماس جدید - - - شماره تماس جدید جایگزین شماره تماس قبلی شما خواهد شد - - + + {isEditing && ( - - ) : ( - <> - - - - اعتبار سنجی - - - کد تایید 4 رقمی به شماره موبایل شما ارسال شد. لطفا آن را - وارد کنید - - - - + )} + + + } + > + {isEditing ? ( + + + + تغییر شماره تماس + + + شماره تماس جدید شما جایگزین شماره تماس قبلی(+989123456789) + خواهد شد. + + + + setButtonState('default')} + > + + + ) : null, }} /> - + + {isVerified ? ( + + + تایید شد + + ) : ( + )} + + {buttonState === 'counting' && !isVerified && ( + + - - )} - - - -
+ )} + + ) : ( + + + 09909366045 + + + ۱ ماه پیش + + + )} + + + ); } diff --git a/src/features/profile/components/SocialMedia.tsx b/src/features/profile/components/SocialMedia.tsx index 8e84bf9..cd543b5 100644 --- a/src/features/profile/components/SocialMedia.tsx +++ b/src/features/profile/components/SocialMedia.tsx @@ -1,4 +1,12 @@ -import { Google, Apple, Sms, Trash, CloseSquare } from 'iconsax-react'; +import { + Google, + Apple, + Sms, + Trash, + CloseSquare, + Message, + ArrowDown3, +} from 'iconsax-react'; import { Box, Button, @@ -8,13 +16,33 @@ import { DialogContent, IconButton, TextField, + Menu, + MenuItem, + ListItemIcon, + ListItemText, } from '@mui/material'; -import { useState } from 'react'; +import React, { useState } from 'react'; +import { CardContainer } from '@/components/CardContainer'; export function SocialMedia() { - const [open, setOpen] = useState(false); - const handleOpen = () => setOpen(true); - const handleClose = () => setOpen(false); + const [openDialog, setOpenDialog] = useState(false); + const [emailInput, setEmailInput] = useState(''); + const [emailError, setEmailError] = useState(false); + const [anchor, setAnchor] = useState(null); + const openMenu = Boolean(anchor); + + const handleOpenDialog = () => setOpenDialog(true); + const handleCloseDialog = () => setOpenDialog(false); + + const handleClickMenu = (e: React.MouseEvent) => { + setAnchor(e.currentTarget); + }; + const handleCloseMenu = () => setAnchor(null); + const handleEmailChange = (e: React.ChangeEvent) => { + const value = e.target.value; + setEmailInput(value); + setEmailError(!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value)); + }; const emailList = [ { email: 'emailtemp@email.com', provider: 'email' }, @@ -22,189 +50,256 @@ export function SocialMedia() { ]; return ( -
- + + + { + handleCloseMenu(); + handleOpenDialog(); + }} + > + + + + ایمیل + + { + handleCloseMenu(); + handleOpenDialog(); + }} + > + + + + گوگل + + { + handleCloseMenu(); + handleOpenDialog(); + }} + > + + + + اپل + + + + } > - - ایمیل و شبکه‌های اجتماعی من - - این اطلاعات شما صرفاً برای احراز هویت شما است و نزد هارمونی باقی - می‌ماند - - - - - - {emailList.map((item, index) => ( - - - {item.provider === 'google' && ( - - )} - {item.provider === 'apple' && ( - - )} - {item.provider === 'email' && ( - - )} - - - - {item.email} - - ۱ ماه پیش - - - - - - - - ))} - - - - - افزودن ایمیل / سوشال - - - - - - - ( + - - - - - - یا - - + + {item.provider === 'google' && ( + + )} + {item.provider === 'apple' && ( + + )} + {item.provider === 'email' && ( + + )} + + + {item.email} + + + ۱ ماه پیش + + + + + + + ))} + - - + /> + + + + + یا + + + + + + + + - - - -
+ + + + ); }