chore: optimization of code
This commit is contained in:
@@ -0,0 +1,208 @@
|
||||
import { Box, Typography, TextField, IconButton, Button } from '@mui/material';
|
||||
import { Edit, Refresh, TickCircle } from 'iconsax-react';
|
||||
import { CountDownTimer } from '@/components/CountDownTimer';
|
||||
import { Toast } from '@/components/Toast';
|
||||
import { CountryCodeSelector } from '../../CountryCodeSelector';
|
||||
|
||||
export default function PhoneEditForm({
|
||||
phoneNumber,
|
||||
setPhoneNumber,
|
||||
countryCode,
|
||||
setCountryCode,
|
||||
verificationCode,
|
||||
setVerificationCode,
|
||||
isVerified,
|
||||
isVerifying,
|
||||
buttonState,
|
||||
setButtonState,
|
||||
handleSendCode,
|
||||
handleVerifyClick,
|
||||
error,
|
||||
inputError,
|
||||
handleBlur,
|
||||
textFieldRef,
|
||||
inputRef,
|
||||
phones,
|
||||
showToast,
|
||||
setShowToast,
|
||||
t,
|
||||
}: {
|
||||
phoneNumber: string;
|
||||
setPhoneNumber: (v: string) => void;
|
||||
countryCode: string;
|
||||
setCountryCode: (v: string) => void;
|
||||
verificationCode: string;
|
||||
setVerificationCode: (v: string) => void;
|
||||
isVerified: boolean;
|
||||
isVerifying: boolean;
|
||||
buttonState: 'default' | 'counting';
|
||||
setButtonState: (v: 'default' | 'counting') => void;
|
||||
handleSendCode: () => void;
|
||||
handleVerifyClick: () => void;
|
||||
error?: string;
|
||||
inputError: boolean;
|
||||
handleBlur: () => void;
|
||||
textFieldRef: React.RefObject<HTMLDivElement>;
|
||||
inputRef: React.RefObject<HTMLInputElement>;
|
||||
phones: { phone: string; time: string; withCode: string }[];
|
||||
showToast: boolean;
|
||||
setShowToast: (v: boolean) => void;
|
||||
t: (key: string) => string;
|
||||
}) {
|
||||
return (
|
||||
<Box sx={{ px: { xs: 2, sm: 4 }, bgcolor: 'background.paper' }}>
|
||||
<Box sx={{ mb: 2 }}>
|
||||
<Typography variant="h6">{t('settingForm.editPhoneNumber')}</Typography>
|
||||
<Typography variant="body2" color="text.secondary">
|
||||
{t('settingForm.phoneNumberText')}({phones.map((p) => p.withCode)})
|
||||
{t('settingForm.verb')}
|
||||
</Typography>
|
||||
</Box>
|
||||
|
||||
<Box
|
||||
sx={{ display: 'flex', flexWrap: 'wrap', gap: 2, alignItems: 'center' }}
|
||||
>
|
||||
<TextField
|
||||
name="phoneNumber"
|
||||
label={t('settingForm.newPhoneNumber')}
|
||||
type="tel"
|
||||
value={phoneNumber}
|
||||
ref={textFieldRef}
|
||||
inputRef={inputRef}
|
||||
onBlur={handleBlur}
|
||||
error={inputError}
|
||||
helperText={inputError ? error : ''}
|
||||
onChange={(e) => setPhoneNumber(e.target.value)}
|
||||
sx={{ flex: '1 1 240px', minWidth: 0 }}
|
||||
placeholder="09123456789"
|
||||
inputProps={{ dir: 'rtl', style: { textAlign: 'right' } }}
|
||||
InputProps={{
|
||||
endAdornment:
|
||||
buttonState === 'counting' ? (
|
||||
<IconButton
|
||||
size="small"
|
||||
onClick={() => {
|
||||
setButtonState('default');
|
||||
setPhoneNumber('');
|
||||
}}
|
||||
sx={{ mr: 1 }}
|
||||
>
|
||||
<Edit size="24" color="#64B5F6" />
|
||||
</IconButton>
|
||||
) : null,
|
||||
}}
|
||||
slotProps={{
|
||||
htmlInput: {
|
||||
dir: 'auto',
|
||||
sx: { lineHeight: 1.5, paddingX: 0 },
|
||||
},
|
||||
input: {
|
||||
endAdornment: (
|
||||
<CountryCodeSelector
|
||||
value={countryCode}
|
||||
onChange={setCountryCode}
|
||||
show={true}
|
||||
menuAnchor={textFieldRef.current}
|
||||
onCloseFocusRef={inputRef}
|
||||
/>
|
||||
),
|
||||
},
|
||||
}}
|
||||
/>
|
||||
|
||||
{isVerified ? (
|
||||
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
|
||||
<TickCircle size="24" style={{ color: '#43A047' }} variant="Bold" />
|
||||
<Typography sx={{ color: 'success.main' }}>
|
||||
{t('settingForm.successButton')}
|
||||
</Typography>
|
||||
</Box>
|
||||
) : (
|
||||
<Button
|
||||
variant="text"
|
||||
onClick={handleSendCode}
|
||||
disabled={buttonState === 'counting' || phoneNumber.length === 0}
|
||||
sx={{
|
||||
textTransform: 'none',
|
||||
minWidth: { xs: '100%', sm: 170 },
|
||||
color: 'primary.main',
|
||||
height: 56,
|
||||
}}
|
||||
>
|
||||
{buttonState === 'counting' ? (
|
||||
<CountDownTimer
|
||||
initialSeconds={60}
|
||||
onComplete={() => setButtonState('default')}
|
||||
/>
|
||||
) : (
|
||||
t('settingForm.verificationCodeButton')
|
||||
)}
|
||||
</Button>
|
||||
)}
|
||||
</Box>
|
||||
|
||||
{buttonState === 'counting' && !isVerified && (
|
||||
<Box
|
||||
sx={{
|
||||
display: 'flex',
|
||||
flexWrap: 'wrap',
|
||||
gap: 2,
|
||||
mt: 2,
|
||||
alignItems: 'center',
|
||||
}}
|
||||
>
|
||||
<TextField
|
||||
name="verificationCode"
|
||||
label={t('settingForm.verificationCode')}
|
||||
type="tel"
|
||||
value={verificationCode}
|
||||
onChange={(e) =>
|
||||
setVerificationCode(e.target.value.replace(/\D/g, ''))
|
||||
}
|
||||
sx={{ flex: '1 1 240px', minWidth: 0 }}
|
||||
placeholder={t('settingForm.verificationCode')}
|
||||
inputProps={{ dir: 'rtl', style: { textAlign: 'right' } }}
|
||||
/>
|
||||
|
||||
<Button
|
||||
variant="contained"
|
||||
onClick={handleVerifyClick}
|
||||
disabled={isVerifying || verificationCode.length === 0}
|
||||
sx={{
|
||||
textTransform: 'none',
|
||||
minWidth: { xs: '100%', sm: 170 },
|
||||
bgcolor: 'primary.main',
|
||||
height: 56,
|
||||
}}
|
||||
>
|
||||
{isVerifying ? (
|
||||
<Box
|
||||
component="span"
|
||||
sx={{
|
||||
display: 'flex',
|
||||
animation: 'spin 1s linear infinite',
|
||||
'@keyframes spin': {
|
||||
'0%': { transform: 'rotate(0deg)' },
|
||||
'100%': { transform: 'rotate(360deg)' },
|
||||
},
|
||||
}}
|
||||
>
|
||||
<Refresh size="20" color="white" />
|
||||
</Box>
|
||||
) : (
|
||||
t('settingForm.checkCode')
|
||||
)}
|
||||
</Button>
|
||||
</Box>
|
||||
)}
|
||||
|
||||
<Toast
|
||||
color="success"
|
||||
open={showToast}
|
||||
onClose={() => setShowToast(false)}
|
||||
>
|
||||
{t('settingForm.successfulChangePhone')}
|
||||
</Toast>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user