fix: styles

This commit is contained in:
2025-07-22 12:08:48 +03:30
committed by Koosha Lahouti
parent 4f3f25abc1
commit 6d94a0d037
9 changed files with 152 additions and 77 deletions

View File

@@ -0,0 +1,31 @@
{
"completion": {
"title": "Completion of user account information",
"description": "Enter your business information",
"name": "Name",
"familyName": "Family Name",
"gender": "Gender",
"optionalNationalCode": "National Code(Optional)",
"determinePassword": "Determine Password",
"password": "Password",
"passwordRepetition": "Repeat password",
"determineEmail": "Connect your email",
"email": "Email",
"vericationCodeButton": "Send verification code",
"verificationCode": "verification code",
"checkCodeButton": "Check code",
"registerButton": "Confirm and Register",
"man": "male",
"woman": "female",
"hasNumber": "includes number",
"hasMinLength": "at least 8 characters",
"hasUpperAndLower": "includes a lowercase and uppercase letter",
"hasSpecialChar": "includes sign (!@#$%^&*)",
"notCompatibility": "does not match",
"emailCorrectForm": "Enter the correct email form.",
"agreementPart1": "By continuing the registration process, you agree to the",
"agreementLinkText": " Harmony Terms and Conditions",
"agreementPart2": ".",
"sent": "sent"
}
}

View File

@@ -25,6 +25,7 @@
"emailCorrectForm": "فرم درست ایمیل را وارد کنید", "emailCorrectForm": "فرم درست ایمیل را وارد کنید",
"agreementPart1": " ادامه فرایند ثبت نام به منزله تایید و قبول", "agreementPart1": " ادامه فرایند ثبت نام به منزله تایید و قبول",
"agreementLinkText": " قوانین و مقررات هارمونی", "agreementLinkText": " قوانین و مقررات هارمونی",
"agreementPart2": "می باشد." "agreementPart2": "می باشد.",
"sent": "ارسال شد!"
} }
} }

View File

@@ -9,6 +9,7 @@ import {
import './App.css'; import './App.css';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { LanguageManager } from './components/LanguageManager'; import { LanguageManager } from './components/LanguageManager';
import { UserCompletionForm } from './features/authentication/components/UserCompletionForm';
function App() { function App() {
const { t } = useTranslation(); const { t } = useTranslation();
@@ -18,6 +19,7 @@ function App() {
<> <>
<CssBaseline /> <CssBaseline />
<LanguageManager /> <LanguageManager />
<UserCompletionForm />
<div style={{ padding: '16px' }}> <div style={{ padding: '16px' }}>
<Typography variant="h3">{t('helloWorld')}</Typography> <Typography variant="h3">{t('helloWorld')}</Typography>
<Box <Box

View File

@@ -57,18 +57,7 @@ export function EmailSection({
<> <>
<FormGroup> <FormGroup>
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1, px: 6 }}> <Box sx={{ display: 'flex', alignItems: 'center', gap: 1, px: 6 }}>
<Switch <Switch checked={showEmail} onChange={handleToggleEmail} />
checked={showEmail}
onChange={handleToggleEmail}
sx={{
'& .MuiSwitch-switchBase.Mui-checked': {
color: '#2979FF',
},
'& .MuiSwitch-switchBase.Mui-checked + .MuiSwitch-track': {
backgroundColor: '#2979FF',
},
}}
/>
<Typography sx={{ color: showEmail ? '#2979FF' : 'black' }}> <Typography sx={{ color: showEmail ? '#2979FF' : 'black' }}>
{t('completion.determineEmail')} {t('completion.determineEmail')}
</Typography> </Typography>
@@ -89,33 +78,45 @@ export function EmailSection({
}} }}
InputProps={{ InputProps={{
startAdornment: startAdornment:
buttonState === 'counting' ? ( !isVerifyingCode && emailVerified ? (
<InputAdornment position="start"> <InputAdornment position="end">
<IconButton size="small" onClick={handleEditEmail}> <TickCircle
<Edit size="20" color="#2979FF" /> size="24"
</IconButton> color="#2e7d32"
variant="Bold"
style={{
position: 'absolute',
right: 0,
marginRight: '16px',
}}
/>
</InputAdornment> </InputAdornment>
) : null, ) : null,
endAdornment: endAdornment:
!isVerifyingCode && emailVerified ? ( buttonState === 'counting' ? (
<TickCircle size="16" color="#2e7d32" variant="Bold" /> <InputAdornment position="start">
<IconButton onClick={handleEditEmail}>
<Edit
size="20"
color="#2979FF"
style={{ position: 'absolute', left: 0 }}
/>
</IconButton>
</InputAdornment>
) : null, ) : null,
}} }}
inputProps={{
style: {
paddingLeft: buttonState === 'counting' ? '0px' : undefined,
},
}}
/> />
{email && (
<Typography
sx={{ color: correctEmail ? 'green' : 'red' }}
variant="caption"
>
{correctEmail ? '' : t('completion.emailCorrectForm')}
</Typography>
)}
</Box> </Box>
{!isVerifyingCode && !emailVerified && ( {!isVerifyingCode && !emailVerified && (
<Button <Button
variant="text" variant="text"
onClick={handleSendCode} onClick={handleSendCode}
sx={{ width: '200px', color: '#2979FF' }} sx={{ width: '156px', color: '#2979FF' }}
disabled={ disabled={
buttonState === 'sent' || buttonState === 'sent' ||
buttonState === 'counting' || buttonState === 'counting' ||
@@ -160,7 +161,7 @@ export function EmailSection({
}, },
}} }}
> >
<Refresh size="20" color="text.secondary" /> <Refresh size="24" color="text.secondary" />
</Box> </Box>
) : ( ) : (
t('completion.checkCodeButton') t('completion.checkCodeButton')

View File

@@ -45,6 +45,8 @@ export function PasswordSection({
}: PasswordSectionProps) { }: PasswordSectionProps) {
const { t } = useTranslation('completionForm'); const { t } = useTranslation('completionForm');
const [showPasswordText, setShowPasswordText] = useState(false); const [showPasswordText, setShowPasswordText] = useState(false);
const [showPasswordRepititonText, setShowPasswordRepetitionText] =
useState(false);
const handleTogglePasswordSection = ( const handleTogglePasswordSection = (
e: React.ChangeEvent<HTMLInputElement>, e: React.ChangeEvent<HTMLInputElement>,
@@ -56,6 +58,10 @@ export function PasswordSection({
setShowPasswordText((prev) => !prev); setShowPasswordText((prev) => !prev);
}; };
const handleTogglePasswordRepetitionEye = () => {
setShowPasswordRepetitionText((prev) => !prev);
};
return ( return (
<> <>
<FormGroup> <FormGroup>
@@ -63,14 +69,10 @@ export function PasswordSection({
<Switch <Switch
checked={showPasswordSection} checked={showPasswordSection}
onChange={handleTogglePasswordSection} onChange={handleTogglePasswordSection}
sx={{
'& .MuiSwitch-switchBase.Mui-checked': { color: '#2979FF' },
'& .MuiSwitch-switchBase.Mui-checked + .MuiSwitch-track': {
backgroundColor: '#2979FF',
},
}}
/> />
<Typography sx={{ color: showPasswordSection ? '#2979FF' : 'black' }}> <Typography
sx={{ color: showPasswordSection ? '#2979FF' : 'text.primary' }}
>
{t('completion.determinePassword')} {t('completion.determinePassword')}
</Typography> </Typography>
</Box> </Box>
@@ -88,25 +90,45 @@ export function PasswordSection({
sx={{ width: '309px' }} sx={{ width: '309px' }}
InputProps={{ InputProps={{
endAdornment: ( endAdornment: (
<InputAdornment position="end"> <InputAdornment position="end" sx={{ height: 'unset' }}>
{validPassword && ( <Box
<TickCircle sx={{
size="16" display: 'flex',
color="#2e7d32" alignItems: 'center',
variant="Bold" width: '100%',
style={{ marginRight: '8px' }} }}
/> >
)} {validPassword && (
<IconButton onClick={handleTogglePasswordEye}> <TickCircle
{showPasswordText ? ( size="24"
<EyeSlash size="20" color="#000" /> color="#14AE5C"
) : ( variant="Bold"
<Eye size="20" color="#000" /> style={{
position: 'absolute',
right: 0,
marginRight: '16px',
}}
/>
)} )}
</IconButton> <IconButton
onClick={handleTogglePasswordEye}
sx={{ ml: validPassword ? 0.5 : 'auto' }}
>
{showPasswordText ? (
<Eye size="24" color="#2979FF" />
) : (
<EyeSlash size="24" color="#2979FF" />
)}
</IconButton>
</Box>
</InputAdornment> </InputAdornment>
), ),
}} }}
inputProps={{
style: {
paddingRight: validPassword ? '48px' : '20px',
},
}}
/> />
{password && ( {password && (
@@ -147,28 +169,48 @@ export function PasswordSection({
: ' ' : ' '
} }
sx={{ width: '309px' }} sx={{ width: '309px' }}
type={showPasswordText ? 'text' : 'password'} type={showPasswordRepititonText ? 'text' : 'password'}
InputProps={{ InputProps={{
endAdornment: ( endAdornment: (
<InputAdornment position="end"> <InputAdornment position="end" sx={{ height: 'unset' }}>
{confirmPassword.length > 0 && matchPassword && ( <Box
<TickCircle sx={{
size="16" display: 'flex',
color="#2e7d32" alignItems: 'center',
variant="Bold" width: '100%',
style={{ marginRight: '8px' }} }}
/> >
)} {confirmPassword.length > 0 && matchPassword && (
<IconButton onClick={handleTogglePasswordEye}> <TickCircle
{showPasswordText ? ( size="24"
<EyeSlash size="20" color="#000" /> color="#14AE5C"
) : ( variant="Bold"
<Eye size="20" color="#000" /> style={{
position: 'absolute',
right: 0,
marginRight: '16px',
}}
/>
)} )}
</IconButton> <IconButton
onClick={handleTogglePasswordRepetitionEye}
sx={{ ml: validPassword ? 0.5 : 'auto' }}
>
{showPasswordRepititonText ? (
<Eye size="24" color="#2979FF" />
) : (
<EyeSlash size="24" color="#2979FF" />
)}
</IconButton>
</Box>
</InputAdornment> </InputAdornment>
), ),
}} }}
inputProps={{
style: {
paddingRight: validPassword ? '48px' : '20px',
},
}}
/> />
</Box> </Box>
)} )}

View File

@@ -14,7 +14,7 @@ export function PasswordValidationItem({
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1, mb: 0.5 }}> <Box sx={{ display: 'flex', alignItems: 'center', gap: 1, mb: 0.5 }}>
<TickCircle <TickCircle
size="16" size="16"
color={isValid ? '#2e7d32' : '#2979FF'} color={isValid ? '#14AE5C' : '#2979FF'}
variant={isValid ? 'Bold' : 'Outline'} variant={isValid ? 'Bold' : 'Outline'}
/> />
<Typography variant="body2" color="text.primary"> <Typography variant="body2" color="text.primary">

View File

@@ -44,10 +44,8 @@ export function PersonalInfoFields({ sex, setSex }: PersonalInfoFieldsProps) {
<Box sx={{ display: 'flex', gap: 2 }}> <Box sx={{ display: 'flex', gap: 2 }}>
<FormControl sx={{ width: '309px' }}> <FormControl sx={{ width: '309px' }}>
<InputLabel id="sex-label">{t('completion.gender')}</InputLabel> <InputLabel>{t('completion.gender')}</InputLabel>
<Select <Select
labelId="sex-label"
id="sex"
value={sex} value={sex}
label={t('completion.gender')} label={t('completion.gender')}
onChange={handleChange} onChange={handleChange}

View File

@@ -6,7 +6,7 @@ export function SubmitSection() {
return ( return (
<Box sx={{ display: 'flex', gap: 2, px: 6, mb: '17px' }}> <Box sx={{ display: 'flex', gap: 2, px: 6, mb: '17px' }}>
<Typography variant="body2" sx={{ flex: 1 }}> <Typography variant="body2" sx={{ flex: 1 }} color="text.primary">
{t('completion.agreementPart1')} {t('completion.agreementPart1')}
<Link target="_blank" sx={{ color: '#2979FF' }}> <Link target="_blank" sx={{ color: '#2979FF' }}>
{t('completion.agreementLinkText')} {t('completion.agreementLinkText')}

View File

@@ -66,7 +66,7 @@ export function UserCompletionForm() {
str.replace(/\d/g, (d: string) => '۰۱۲۳۴۵۶۷۸۹'[parseInt(d)]); str.replace(/\d/g, (d: string) => '۰۱۲۳۴۵۶۷۸۹'[parseInt(d)]);
const getButtonLabel = () => { const getButtonLabel = () => {
if (buttonState === 'sent') return 'ارسال شد!'; if (buttonState === 'sent') return t('completion.sent');
if (buttonState === 'counting') { if (buttonState === 'counting') {
const minutes = String(Math.floor(countdown / 60)).padStart(2, '0'); const minutes = String(Math.floor(countdown / 60)).padStart(2, '0');
const seconds = String(countdown % 60).padStart(2, '0'); const seconds = String(countdown % 60).padStart(2, '0');
@@ -82,7 +82,7 @@ export function UserCompletionForm() {
setTimeout(() => { setTimeout(() => {
setButtonState('counting'); setButtonState('counting');
setCountdown(60); setCountdown(60);
}, 1000); }, 500);
}; };
const handleVerifyCode = () => { const handleVerifyCode = () => {
@@ -90,7 +90,7 @@ export function UserCompletionForm() {
setTimeout(() => { setTimeout(() => {
setIsVerifyingCode(false); setIsVerifyingCode(false);
setEmailVerified(true); setEmailVerified(true);
}, 1000); }, 500);
}; };
const handleEditEmail = () => { const handleEditEmail = () => {
@@ -112,7 +112,7 @@ export function UserCompletionForm() {
<Box <Box
sx={{ sx={{
width: '730px', width: '730px',
backgroundColor: 'white', backgroundColor: '#FFFFFF',
border: '1px solid #ccc', border: '1px solid #ccc',
display: 'flex', display: 'flex',
flexDirection: 'column', flexDirection: 'column',