266 lines
8.1 KiB
TypeScript
266 lines
8.1 KiB
TypeScript
import React, { useState } from 'react';
|
|
import {
|
|
TextField,
|
|
Box,
|
|
IconButton,
|
|
Switch,
|
|
FormGroup,
|
|
Typography,
|
|
InputAdornment,
|
|
} from '@mui/material';
|
|
import { useTranslation } from 'react-i18next';
|
|
import { TickCircle, Eye, EyeSlash, CloseCircle } from 'iconsax-react';
|
|
import { PasswordValidationItem } from './PasswordValidation';
|
|
import { Icon } from '@rkheftan/harmony-ui';
|
|
|
|
interface PasswordSectionProps {
|
|
showPasswordSection: boolean;
|
|
setShowPasswordSection: (checked: boolean) => void;
|
|
password: string;
|
|
setPassword: (password: string) => void;
|
|
confirmPassword: string;
|
|
setConfirmPassword: (confirmPassword: string) => void;
|
|
matchPassword: boolean;
|
|
hasNumber: boolean;
|
|
hasMinLength: boolean;
|
|
hasUpperAndLower: boolean;
|
|
hasSpecialChar: boolean;
|
|
validPassword: boolean;
|
|
showValidations: boolean;
|
|
}
|
|
|
|
export function PasswordSection({
|
|
showPasswordSection,
|
|
setShowPasswordSection,
|
|
password,
|
|
setPassword,
|
|
confirmPassword,
|
|
setConfirmPassword,
|
|
matchPassword,
|
|
hasNumber,
|
|
hasMinLength,
|
|
hasUpperAndLower,
|
|
hasSpecialChar,
|
|
validPassword,
|
|
showValidations,
|
|
}: PasswordSectionProps) {
|
|
const { t } = useTranslation('completionForm');
|
|
const [showPasswordText, setShowPasswordText] = useState(false);
|
|
const [showPasswordRepetitionText, setShowPasswordRepetitionText] =
|
|
useState(false);
|
|
|
|
const handleTogglePasswordSection = (
|
|
e: React.ChangeEvent<HTMLInputElement>,
|
|
) => {
|
|
setShowPasswordSection(e.target.checked);
|
|
};
|
|
|
|
const handleTogglePasswordEye = () => setShowPasswordText((prev) => !prev);
|
|
const handleTogglePasswordRepetitionEye = () =>
|
|
setShowPasswordRepetitionText((prev) => !prev);
|
|
|
|
return (
|
|
<>
|
|
<FormGroup>
|
|
<Box
|
|
sx={{
|
|
display: 'flex',
|
|
gap: 0.5,
|
|
px: { xs: 2, sm: -4 },
|
|
alignItems: 'center',
|
|
}}
|
|
>
|
|
<Switch
|
|
checked={showPasswordSection}
|
|
onChange={handleTogglePasswordSection}
|
|
/>
|
|
<Typography
|
|
sx={{
|
|
color: showPasswordSection ? 'primary.main' : 'text.primary',
|
|
}}
|
|
>
|
|
{t('completion.determinePassword')}
|
|
</Typography>
|
|
</Box>
|
|
</FormGroup>
|
|
|
|
{showPasswordSection && (
|
|
<Box
|
|
sx={{
|
|
display: 'flex',
|
|
flexDirection: 'column',
|
|
gap: 2,
|
|
px: { xs: 2, sm: 0 },
|
|
}}
|
|
>
|
|
<Box
|
|
sx={{
|
|
display: 'flex',
|
|
flexWrap: 'wrap',
|
|
gap: 2,
|
|
justifyContent: { xs: 'center', sm: 'flex-start' },
|
|
}}
|
|
>
|
|
<TextField
|
|
label={t('completion.password')}
|
|
value={password}
|
|
onChange={(e) => setPassword(e.target.value)}
|
|
variant="outlined"
|
|
type={showPasswordText ? 'text' : 'password'}
|
|
sx={{
|
|
flex: '1 1 260px',
|
|
'& .MuiInputBase-input': {
|
|
pr: 8, // Increased padding to accommodate both icons
|
|
},
|
|
}}
|
|
InputProps={{
|
|
endAdornment: (
|
|
<InputAdornment position="end">
|
|
<Box
|
|
sx={{
|
|
display: 'flex',
|
|
alignItems: 'center',
|
|
justifyContent: 'flex-end',
|
|
minWidth: '64px', // Adjusted to fit both icons
|
|
}}
|
|
>
|
|
<IconButton
|
|
onClick={handleTogglePasswordEye}
|
|
sx={{ p: 0.5 }}
|
|
>
|
|
{showPasswordText ? (
|
|
<Icon
|
|
Component={Eye}
|
|
color="primary.main"
|
|
size="medium"
|
|
/>
|
|
) : (
|
|
<Icon
|
|
Component={EyeSlash}
|
|
size="medium"
|
|
color="primary.main"
|
|
/>
|
|
)}
|
|
</IconButton>
|
|
{validPassword && (
|
|
<Icon
|
|
Component={TickCircle}
|
|
size="medium"
|
|
color="success.main"
|
|
variant="Bold"
|
|
/>
|
|
)}
|
|
</Box>
|
|
</InputAdornment>
|
|
),
|
|
}}
|
|
/>
|
|
|
|
<TextField
|
|
label={t('completion.passwordRepetition')}
|
|
variant="outlined"
|
|
value={confirmPassword}
|
|
onChange={(e) => setConfirmPassword(e.target.value)}
|
|
error={confirmPassword.length > 0 && !matchPassword}
|
|
helperText={
|
|
confirmPassword.length > 0 && !matchPassword
|
|
? t('completion.notCompatibility')
|
|
: ' '
|
|
}
|
|
type={showPasswordRepetitionText ? 'text' : 'password'}
|
|
sx={{
|
|
flex: '1 1 260px',
|
|
}}
|
|
InputProps={{
|
|
endAdornment: (
|
|
<InputAdornment position="end">
|
|
<Box
|
|
sx={{
|
|
display: 'flex',
|
|
alignItems: 'center',
|
|
justifyContent: 'flex-end',
|
|
minWidth: '64px',
|
|
}}
|
|
>
|
|
<IconButton
|
|
onClick={handleTogglePasswordRepetitionEye}
|
|
sx={{ p: 0.5 }}
|
|
>
|
|
{showPasswordRepetitionText ? (
|
|
<Icon
|
|
Component={Eye}
|
|
color="primary.main"
|
|
size="medium"
|
|
/>
|
|
) : (
|
|
<Icon
|
|
Component={EyeSlash}
|
|
size="medium"
|
|
color="primary.main"
|
|
/>
|
|
)}
|
|
</IconButton>
|
|
{confirmPassword.length > 0 && (
|
|
<Icon
|
|
Component={matchPassword ? TickCircle : CloseCircle}
|
|
size="medium"
|
|
color={matchPassword ? 'success.main' : 'error.main'}
|
|
variant="Bold"
|
|
/>
|
|
)}
|
|
</Box>
|
|
</InputAdornment>
|
|
),
|
|
}}
|
|
/>
|
|
</Box>
|
|
|
|
{password && showValidations && (
|
|
<Box
|
|
sx={{
|
|
display: 'flex',
|
|
flexWrap: 'wrap',
|
|
gap: 2,
|
|
justifyContent: { xs: 'center', sm: 'flex-start' },
|
|
}}
|
|
>
|
|
<Box
|
|
sx={{
|
|
flex: '1 1 260px',
|
|
display: 'flex',
|
|
flexDirection: 'column',
|
|
}}
|
|
>
|
|
<PasswordValidationItem
|
|
isValid={hasNumber}
|
|
label={t('completion.hasNumber')}
|
|
/>
|
|
<PasswordValidationItem
|
|
isValid={hasMinLength}
|
|
label={t('completion.hasMinLength')}
|
|
/>
|
|
</Box>
|
|
<Box
|
|
sx={{
|
|
flex: '1 1 260px',
|
|
display: 'flex',
|
|
flexDirection: 'column',
|
|
}}
|
|
>
|
|
<PasswordValidationItem
|
|
isValid={hasUpperAndLower}
|
|
label={t('completion.hasUpperAndLower')}
|
|
/>
|
|
<PasswordValidationItem
|
|
isValid={hasSpecialChar}
|
|
label={t('completion.hasSpecialChar')}
|
|
/>
|
|
</Box>
|
|
</Box>
|
|
)}
|
|
</Box>
|
|
)}
|
|
</>
|
|
);
|
|
}
|