import { LoadingButton } from '@mui/lab'; import { Box, IconButton, InputLabel, TextField, Typography, } from '@mui/material'; import { useFormik } from 'formik'; import * as Yup from 'yup'; import { useStyles } from './resetPasswordStyles'; import { useRef, useState } from 'react'; import PasswordValidation from '../Login/component/PasswordValidation'; import { VisibilityOffOutlined, VisibilityOutlined } from '@mui/icons-material'; import useQuery from '../../hooks/useQuery'; import { passwordLengthRegex, passwordLetterRegex, passwordNumberRegex, passwordSpacesRegex, } from '../../utils/regex'; import { pushNotification } from '../../utils/notification'; import { NOTIFICATION } from '../../constants'; import { resetPassword } from '../../services/auth.services'; const validationSchema = Yup.object().shape({ password: Yup.string() .matches(passwordLengthRegex, 'Password must be at least 8 characters') .matches(passwordLetterRegex, 'Password must contain at least one letter') .matches(passwordNumberRegex, 'Password must contain at least one number') .matches(passwordSpacesRegex, 'Password must not start or end with a space') .required('Password is required'), confirmPassword: Yup.string() .oneOf([Yup.ref('password'), null], 'Passwords must match') .required('Passwords must match'), }); function ResetPasswordForm({ onSubmit }) { const query = useQuery(); const classes = useStyles(); const [showPassword, setShowPassword] = useState(false); const [showConfirmPassword, setShowConfirmPassword] = useState(false); const fieldRefs = { password: useRef(null), confirmPassword: useRef(null), }; const formik = useFormik({ initialValues: { password: '', confirmPassword: '' }, validationSchema, onSubmit: (values) => handleSubmit(values, formik), }); const handleSubmit = async (values, formik) => { try { values.token = query.get('token'); const requestBody = { token: values.token, password: values.password, }; const response = await resetPassword(requestBody); if (response.status === 200) { pushNotification(response?.data?.message, NOTIFICATION.SUCCESS); } onSubmit(); } catch (error) { return; } finally { formik.setSubmitting(false); formik.resetForm(); } }; const handleTogglePasswordVisibility = (field) => { if (field === 'password') { setShowPassword((prevShowPassword) => !prevShowPassword); } else if (field === 'confirmPassword') { setShowConfirmPassword( (prevShowConfirmPassword) => !prevShowConfirmPassword ); } }; const handleSubmitClick = async (e) => { e.preventDefault(); const formikErrors = await formik.validateForm(); const errors = Object.keys(formikErrors); if (errors.length) { // Find the first invalid field and focus it const firstErrorField = errors[0]; const firstErrorRef = fieldRefs[firstErrorField]?.current; if (firstErrorRef) { // Scroll to the first invalid field smoothly if (typeof firstErrorRef?.scrollIntoView === 'function') { firstErrorRef?.scrollIntoView({ behavior: 'smooth', block: 'center', }); } // Focus the field after a slight delay (to ensure scrolling completes first) setTimeout(() => firstErrorRef.focus(), 300); } // Show error notification if (formik?.touched[firstErrorField]) pushNotification(formikErrors[firstErrorField], NOTIFICATION.ERROR); } formik.handleSubmit(); }; return (
Note: Password must be at least 8 characters, contain 1 letter and 1 number, with no spaces at the beginning/end. Enter New Password handleTogglePasswordVisibility('password')} edge="end" > {!showPassword ? ( ) : ( )} ), }} /> {/* Password validation display */} {!formik.isValid && ( <> Note: Password must be )} Confirm New Password handleTogglePasswordVisibility('confirmPassword') } edge="end" > {!showConfirmPassword ? ( ) : ( )} ), }} /> Save New Password
); } export default ResetPasswordForm;