update confirm email code window

This commit is contained in:
smanylov
2026-01-26 13:04:13 +07:00
parent 4166cb1d80
commit bf9926f004
7 changed files with 101 additions and 26 deletions
+2 -2
View File
@@ -331,8 +331,8 @@ export async function tokenLifeExtension() {
} }
export async function confirmEmail( export async function confirmEmail(
state: any | undefined, state: {error: string} | undefined,
formData: any formData: FormData
) { ) {
console.log('confirmEmail'); console.log('confirmEmail');
const emailConfirm = formData.get('emailConfirm') as string || ''; const emailConfirm = formData.get('emailConfirm') as string || '';
+16
View File
@@ -140,6 +140,22 @@
transition: all 0.3s; transition: all 0.3s;
margin-bottom: 18px; margin-bottom: 18px;
margin: 20px 0 0 0; margin: 20px 0 0 0;
&:hover {
transform: translateY(-2px);
}
&:disabled {
background: linear-gradient(135deg, #414291, #4b3975);
&:hover {
transform: none;
}
}
&.refresh {
width: fit-content;
}
} }
.form-group-confrim-window { .form-group-confrim-window {
+68 -21
View File
@@ -1,23 +1,57 @@
import styles from '@/app/styles/module/login.module.scss'; import styles from '@/app/styles/module/login.module.scss';
import { useTranslations } from 'next-intl'; import { useTranslations } from 'next-intl';
import { MouseEvent, useActionState } from 'react'; import { ChangeEvent, MouseEvent, useActionState, useState, useEffect } from 'react';
import { resendConfirmEmail, confirmEmail } from '@/app/actions/auth'; import { resendConfirmEmail, confirmEmail } from '@/app/actions/auth';
export default function ConfirmMailModalWindow({ userId }: any) { import { IconRefresh } from '@/app/ui/icons/icons';
const t = useTranslations('Login-register-form'); export default function ConfirmMailModalWindow({ userId, email }: { userId: number | undefined, email: string | undefined }) {
const [stateEmailConfrim, formActionEmailConfrim, isPendingEmailConfrim] = useActionState( const [stateEmailConfrim, formActionEmailConfrim, isPendingEmailConfrim] = useActionState(
confirmEmail, confirmEmail,
undefined, undefined,
); );
const [confirmCodeValue, setConfirmCodeValue] = useState('');
const [isInputDisabled, setIsInputDisabled] = useState(true);
const [timer, setTimer] = useState(30);
const t = useTranslations('Login-register-form');
async function reSendEmailConfirmCode(e: MouseEvent) { async function reSendEmailConfirmCode(e: MouseEvent) {
e.preventDefault(); e.preventDefault();
console.log(userId ? userId : '');
if (userId) { if (userId) {
await resendConfirmEmail(userId); await resendConfirmEmail(userId);
} }
} }
function onChangeHandler(e: ChangeEvent<HTMLInputElement>) {
const newValue = e.target.value.replace(/([^0-9])/g, '');
if (newValue.length <= 6) {
setConfirmCodeValue(newValue);
}
}
useEffect(() => {
let interval: NodeJS.Timeout;
if (timer > 0 && isInputDisabled) {
interval = setInterval(() => {
setTimer(prev => {
if (prev <= 1) {
setIsInputDisabled(false);
return 0;
}
return prev - 1;
});
}, 1000);
}
return () => {
if (interval) clearInterval(interval);
};
}, [timer, isInputDisabled]);
/* const resetTimer = () => {
setIsInputDisabled(true);
setTimer(30);
}; */
return ( return (
<div <div
className="modal-window" className="modal-window"
@@ -28,24 +62,24 @@ export default function ConfirmMailModalWindow({ userId }: any) {
formActionEmailConfrim(e); formActionEmailConfrim(e);
}}> }}>
<div className={`${styles['form-group']}`}> <div className={`${styles['form-group']}`}>
<h4 <h4>
{t('enter-confirmation-code')}
<br />
</h4>
<p
className="mb-6" className="mb-6"
> >
{t('enter-confirmation-code')} {email}
</h4> </p>
<label
className={`${styles['form-label']}`}
>
{t('confirmation-code')}
</label>
<input <input
type="text" type="text"
id="emailConfirm" id="emailConfirm"
name="emailConfirm" name="emailConfirm"
className={`${styles['form-input']}`} className={`${styles['form-input']}`}
placeholder="mail-code" placeholder={t('confirmation-code')}
defaultValue="" value={confirmCodeValue}
onChange={(e) => { onChange={(e: ChangeEvent<HTMLInputElement>) => {
onChangeHandler(e)
}} }}
/> />
<input <input
@@ -55,24 +89,37 @@ export default function ConfirmMailModalWindow({ userId }: any) {
style={{ display: 'none' }} style={{ display: 'none' }}
defaultValue={userId ? userId : ''} defaultValue={userId ? userId : ''}
/> />
{!stateEmailConfrim?.error && (
<p
className="text-sm text-red-500"
>
{t('entered-code-is-incorrect')}
</p>
)}
</div> </div>
<div> <div>
{stateEmailConfrim?.error} {stateEmailConfrim?.error}
</div> </div>
<div className="flex gap-2"> <div className="flex gap-2">
<button type="submit" className={`${styles['btn']}`}> <button
Проверить type="submit"
className={`${styles['btn']}`}
disabled={confirmCodeValue.length !== 6}
>
{t('confirm')}
</button> </button>
<button <button
className={`${styles['btn']}`} className={`${styles['btn'] + ' ' + styles['refresh']} flex`}
disabled={isInputDisabled}
onClick={(e) => { onClick={(e) => {
reSendEmailConfirmCode(e); reSendEmailConfirmCode(e);
}} }}
title={t('resend-code')}
> >
test <IconRefresh />
{timer !== 0 ? timer : ''}
</button> </button>
</div> </div>
</form> </form>
</div> </div>
</div> </div>
+1 -1
View File
@@ -125,7 +125,7 @@ export default function RegisterForm() {
setShowMailConfirmWindow(false); setShowMailConfirmWindow(false);
}} }}
> >
<ConfirmMailModalWindow userId={state?.userId}/> <ConfirmMailModalWindow userId={state?.userId} email={formState?.previousState?.email} />
</div> </div>
)} )}
<form action={(e) => { <form action={(e) => {
+6
View File
@@ -145,4 +145,10 @@ export function IconBurgerMenu() {
return ( return (
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" className="icon"><path fill="currentColor" d="M4 6a1 1 0 0 1 1-1h14a1 1 0 1 1 0 2H5a1 1 0 0 1-1-1m0 6a1 1 0 0 1 1-1h14a1 1 0 1 1 0 2H5a1 1 0 0 1-1-1m1 5a1 1 0 1 0 0 2h14a1 1 0 1 0 0-2z" /></svg> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" className="icon"><path fill="currentColor" d="M4 6a1 1 0 0 1 1-1h14a1 1 0 1 1 0 2H5a1 1 0 0 1-1-1m0 6a1 1 0 0 1 1-1h14a1 1 0 1 1 0 2H5a1 1 0 0 1-1-1m1 5a1 1 0 1 0 0 2h14a1 1 0 1 0 0-2z" /></svg>
) )
}
export function IconRefresh() {
return (
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="currentColor" d="M12 20q-3.35 0-5.675-2.325T4 12t2.325-5.675T12 4q1.725 0 3.3.712T18 6.75V4h2v7h-7V9h4.2q-.8-1.4-2.187-2.2T12 6Q9.5 6 7.75 7.75T6 12t1.75 4.25T12 18q1.925 0 3.475-1.1T17.65 14h2.1q-.7 2.65-2.85 4.325T12 20" /></svg>
)
} }
+4 -1
View File
@@ -263,6 +263,9 @@
"register-error-phone-not-allowed-symbols": "", "register-error-phone-not-allowed-symbols": "",
"register-error-password-not-allowed-symbols": "Password contains invalid characters.", "register-error-password-not-allowed-symbols": "Password contains invalid characters.",
"confirmation-code": "Confirmation code", "confirmation-code": "Confirmation code",
"enter-confirmation-code": "Enter the confirmation code" "enter-confirmation-code": "Enter the confirmation code sent to your email:",
"confirm": "Confirm",
"entered-code-is-incorrect": "The code you entered is incorrect.",
"resend-code": "Resend code"
} }
} }
+4 -1
View File
@@ -263,6 +263,9 @@
"register-error-phone-not-allowed-symbols": "", "register-error-phone-not-allowed-symbols": "",
"register-error-password-not-allowed-symbols": "Пароль содержит недопустимые символы.", "register-error-password-not-allowed-symbols": "Пароль содержит недопустимые символы.",
"confirmation-code": "Код подтверждения", "confirmation-code": "Код подтверждения",
"enter-confirmation-code": "Введите код подтверждения" "enter-confirmation-code": "Введите код подтверждения высланный на почту:",
"confirm": "Подтвердить",
"entered-code-is-incorrect": "Введенный код не верен.",
"resend-code": "Выслать код заново"
} }
} }