fix mail confirm work

This commit is contained in:
smanylov
2026-02-27 14:18:14 +07:00
parent 55acfe7efe
commit 10c3a2326b
6 changed files with 101 additions and 58 deletions
+15 -10
View File
@@ -409,14 +409,8 @@ export async function tokenLifeExtension() {
} }
} }
export async function confirmEmail( export async function confirmEmail(userId: number, verifyToken: string) {
state: { error: string } | undefined,
formData: FormData
) {
console.log('confirmEmail'); console.log('confirmEmail');
const emailConfirm = formData.get('emailConfirm') as string || '';
console.log(emailConfirm);
const userId = formData.get('userId') as string || '';
try { try {
const response = await fetch(`${API_BASE_URL}/api/v1/data`, { const response = await fetch(`${API_BASE_URL}/api/v1/data`, {
@@ -431,7 +425,7 @@ export async function confirmEmail(
message_body: { message_body: {
resend: 0, resend: 0,
user_id: userId, user_id: userId,
verify_token: emailConfirm verify_token: verifyToken
} }
}), }),
}); });
@@ -442,12 +436,23 @@ export async function confirmEmail(
if (parsed.message_code === 0) { if (parsed.message_code === 0) {
await createSession(parsed.message_body.token, parsed.message_body.email as string); await createSession(parsed.message_body.token, parsed.message_body.email as string);
} else {
return {
success: false,
error: 'entered-code-is-incorrect'
};
} }
} else {
return {
success: false,
error: 'server-error'
};
} }
} catch (error) { } catch (error) {
return { return {
error: 'error' success: false,
} error: 'network-error'
};
} }
redirect('/pages/dashboard'); redirect('/pages/dashboard');
+21 -1
View File
@@ -186,11 +186,31 @@
} }
&.refresh { &.refresh {
width: fit-content; width: 100%;
display: flex;
justify-content: center;
gap: 3px;
} }
} }
.form-group-confrim-window { .form-group-confrim-window {
min-width: 500px;
&-button-group {
display: flex;
justify-content: center;
gap: 10px;
}
@media (max-width: 550px) {
min-width: auto;
&-button-group {
flex-direction: column;
gap: 10px;
}
}
.btn { .btn {
margin: 0; margin: 0;
} }
+56 -44
View File
@@ -1,22 +1,51 @@
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 { ChangeEvent, MouseEvent, useActionState, useState, useEffect } from 'react'; import { ChangeEvent, MouseEvent, useState, useEffect } from 'react';
import { resendConfirmEmail, confirmEmail } from '@/app/actions/auth'; import { resendConfirmEmail, confirmEmail } from '@/app/actions/auth';
import { IconRefresh } from '@/app/ui/icons/icons'; import { IconRefresh } from '@/app/ui/icons/icons';
export default function ConfirmMailModalWindow({ userId, email }: { userId: number | undefined, email: string | undefined }) {
const [stateEmailConfrim, formActionEmailConfrim, isPendingEmailConfrim] = useActionState( export default function ConfirmMailModalWindow({ userId, email, onClose }: { userId: number | undefined, email: string | undefined, onClose?: () => void }) {
confirmEmail, const [error, setError] = useState<string | null>(null);
undefined, const [isPending, setIsPending] = useState(false);
);
const [confirmCodeValue, setConfirmCodeValue] = useState(''); const [confirmCodeValue, setConfirmCodeValue] = useState('');
const [isInputDisabled, setIsInputDisabled] = useState(true); const [isInputDisabled, setIsInputDisabled] = useState(true);
const [timer, setTimer] = useState(30); const [timer, setTimer] = useState(30);
const t = useTranslations('Login-register-form'); const t = useTranslations('Login-register-form');
async function handleConfirmEmail(e: React.FormEvent) {
e.preventDefault();
if (!userId || confirmCodeValue.length !== 6) {
return;
}
setIsPending(true);
setError(null);
try {
const result = await confirmEmail(userId, confirmCodeValue);
if (result.error) {
setError(t(result.error));
} else {
if (onClose) {
setTimeout(() => onClose(), 1500);
}
}
} catch (err) {
setError(t('entered-code-is-incorrect'));
} finally {
setIsPending(false);
}
}
async function reSendEmailConfirmCode(e: MouseEvent) { async function reSendEmailConfirmCode(e: MouseEvent) {
e.preventDefault(); e.preventDefault();
if (userId) { if (userId) {
setIsInputDisabled(true);
await resendConfirmEmail(userId); await resendConfirmEmail(userId);
setTimer(30);
} }
} }
@@ -47,28 +76,19 @@ export default function ConfirmMailModalWindow({ userId, email }: { userId: numb
}; };
}, [timer, isInputDisabled]); }, [timer, isInputDisabled]);
/* const resetTimer = () => {
setIsInputDisabled(true);
setTimer(30);
}; */
return ( return (
<div <div
className="modal-window" className="modal-window"
onClick={(e) => e.stopPropagation()} onClick={(e) => e.stopPropagation()}
> >
<div className={`${styles['form-group']} ${styles['form-group-confrim-window']}`}> <div className={`${styles['form-group']} ${styles['form-group-confrim-window']}`}>
<form action={(e) => { <form onSubmit={handleConfirmEmail}>
formActionEmailConfrim(e);
}}>
<div className={`${styles['form-group']}`}> <div className={`${styles['form-group']}`}>
<h4> <h4>
{t('enter-confirmation-code')} {t('enter-confirmation-code')}
<br /> <br />
</h4> </h4>
<p <p className="mb-6">
className="mb-6"
>
{email} {email}
</p> </p>
<input <input
@@ -78,50 +98,42 @@ export default function ConfirmMailModalWindow({ userId, email }: { userId: numb
className={`${styles['form-input']}`} className={`${styles['form-input']}`}
placeholder={t('confirmation-code')} placeholder={t('confirmation-code')}
value={confirmCodeValue} value={confirmCodeValue}
onChange={(e: ChangeEvent<HTMLInputElement>) => { onChange={onChangeHandler}
onChangeHandler(e) disabled={isPending}
}}
/> />
<input
type="hiden" {error && (
id="userId" <p className="text-sm text-red-500">
name="userId" {error}
style={{ display: 'none' }}
defaultValue={userId ? userId : ''}
/>
{stateEmailConfrim?.error && (
<p
className="text-sm text-red-500"
>
{t('entered-code-is-incorrect')}
</p> </p>
)} )}
</div> </div>
<div>
{stateEmailConfrim?.error} <div className={`${styles['form-group-confrim-window-button-group']}`}>
</div>
<div className="flex gap-2">
<button <button
type="submit" type="submit"
className={`${styles['btn']}`} className={`${styles['btn']}`}
disabled={confirmCodeValue.length !== 6} disabled={confirmCodeValue.length !== 6 || isPending}
> >
{t('confirm')} {isPending ? t('confirming') : t('confirm')}
</button> </button>
<button <button
className={`${styles['btn'] + ' ' + styles['refresh']} flex`} className={`${styles['btn'] + ' ' + styles['refresh']}`}
disabled={isInputDisabled} disabled={isInputDisabled || isPending}
onClick={(e) => { onClick={reSendEmailConfirmCode}
reSendEmailConfirmCode(e);
}}
title={t('resend-code')} title={t('resend-code')}
type="button"
> >
<IconRefresh /> <IconRefresh />
<div>
{t('resend-code')}
</div>
{timer !== 0 ? timer : ''} {timer !== 0 ? timer : ''}
</button> </button>
</div> </div>
</form> </form>
</div> </div>
</div> </div>
) );
} }
+1 -1
View File
@@ -253,7 +253,7 @@ export default function RegisterForm() {
setShowMailConfirmWindow(false); setShowMailConfirmWindow(false);
}} }}
> >
<ConfirmMailModalWindow userId={state?.userId} email={formState?.previousState?.email} /> <ConfirmMailModalWindow userId={state?.userId} email={formState?.previousState?.email} onClose={() => { setShowMailConfirmWindow(false) }} />
</div> </div>
)} )}
<form action={(e) => { <form action={(e) => {
+4 -1
View File
@@ -375,6 +375,9 @@
"INN": "INN", "INN": "INN",
"fullName-required": "Please fill in the field correctly.", "fullName-required": "Please fill in the field correctly.",
"fullName-too-short": "Name must be at least 2 characters long.", "fullName-too-short": "Name must be at least 2 characters long.",
"company-already-registered": "The company is already registered." "company-already-registered": "The company is already registered.",
"confirming" : "Confirming",
"server-error": "Server error",
"network-error": "Network error"
} }
} }
+4 -1
View File
@@ -375,6 +375,9 @@
"INN": "ИНН", "INN": "ИНН",
"fullName-required": "Заполните поле корректно.", "fullName-required": "Заполните поле корректно.",
"fullName-too-short": "Имя должно содержать не менее 2 символов.", "fullName-too-short": "Имя должно содержать не менее 2 символов.",
"company-already-registered": "Компания уже зарегистрирована." "company-already-registered": "Компания уже зарегистрирована.",
"confirming": "Подтверждение",
"server-error": "Ошибка сервера",
"network-error": "Сетевая ошибка"
} }
} }