Files
no-copy-frontend/src/app/ui/forms/confirm-mail-modal-window.tsx
T

139 lines
3.4 KiB
TypeScript
Raw Normal View History

2026-01-23 18:06:08 +07:00
import styles from '@/app/styles/module/login.module.scss';
import { useTranslations } from 'next-intl';
2026-02-27 14:18:14 +07:00
import { ChangeEvent, MouseEvent, useState, useEffect } from 'react';
2026-01-23 18:06:08 +07:00
import { resendConfirmEmail, confirmEmail } from '@/app/actions/auth';
2026-01-26 13:04:13 +07:00
import { IconRefresh } from '@/app/ui/icons/icons';
2026-02-27 14:18:14 +07:00
export default function ConfirmMailModalWindow({ userId, email, onClose }: { userId: number | undefined, email: string | undefined, onClose?: () => void }) {
const [error, setError] = useState<string | null>(null);
const [isPending, setIsPending] = useState(false);
2026-01-26 13:04:13 +07:00
const [confirmCodeValue, setConfirmCodeValue] = useState('');
const [isInputDisabled, setIsInputDisabled] = useState(true);
const [timer, setTimer] = useState(30);
const t = useTranslations('Login-register-form');
2026-01-23 18:06:08 +07:00
2026-02-27 14:18:14 +07:00
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);
}
}
2026-01-23 18:06:08 +07:00
async function reSendEmailConfirmCode(e: MouseEvent) {
e.preventDefault();
if (userId) {
2026-02-27 14:18:14 +07:00
setIsInputDisabled(true);
2026-01-23 18:06:08 +07:00
await resendConfirmEmail(userId);
2026-02-27 14:18:14 +07:00
setTimer(30);
2026-01-23 18:06:08 +07:00
}
}
2026-01-26 13:04:13 +07:00
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]);
2026-01-23 18:06:08 +07:00
return (
<div
className="modal-window"
onClick={(e) => e.stopPropagation()}
>
<div className={`${styles['form-group']} ${styles['form-group-confrim-window']}`}>
2026-02-27 14:18:14 +07:00
<form onSubmit={handleConfirmEmail}>
2026-01-23 18:06:08 +07:00
<div className={`${styles['form-group']}`}>
2026-01-26 13:04:13 +07:00
<h4>
{t('enter-confirmation-code')}
<br />
</h4>
2026-02-27 14:18:14 +07:00
<p className="mb-6">
2026-01-26 13:04:13 +07:00
{email}
</p>
2026-01-23 18:06:08 +07:00
<input
type="text"
id="emailConfirm"
name="emailConfirm"
className={`${styles['form-input']}`}
2026-01-26 13:04:13 +07:00
placeholder={t('confirmation-code')}
value={confirmCodeValue}
2026-02-27 14:18:14 +07:00
onChange={onChangeHandler}
disabled={isPending}
2026-01-23 18:06:08 +07:00
/>
2026-02-27 14:18:14 +07:00
{error && (
<p className="text-sm text-red-500">
{error}
2026-01-26 13:04:13 +07:00
</p>
)}
2026-01-23 18:06:08 +07:00
</div>
2026-02-27 14:18:14 +07:00
<div className={`${styles['form-group-confrim-window-button-group']}`}>
2026-01-26 13:04:13 +07:00
<button
type="submit"
className={`${styles['btn']}`}
2026-02-27 14:18:14 +07:00
disabled={confirmCodeValue.length !== 6 || isPending}
2026-01-26 13:04:13 +07:00
>
2026-02-27 14:18:14 +07:00
{isPending ? t('confirming') : t('confirm')}
2026-01-23 18:06:08 +07:00
</button>
2026-02-27 14:18:14 +07:00
2026-01-23 18:06:08 +07:00
<button
2026-02-27 14:18:14 +07:00
className={`${styles['btn'] + ' ' + styles['refresh']}`}
disabled={isInputDisabled || isPending}
onClick={reSendEmailConfirmCode}
2026-01-26 13:04:13 +07:00
title={t('resend-code')}
2026-02-27 14:18:14 +07:00
type="button"
2026-01-23 18:06:08 +07:00
>
2026-01-26 13:04:13 +07:00
<IconRefresh />
2026-02-27 14:18:14 +07:00
<div>
{t('resend-code')}
</div>
2026-01-26 13:04:13 +07:00
{timer !== 0 ? timer : ''}
2026-01-23 18:06:08 +07:00
</button>
</div>
</form>
</div>
</div>
2026-02-27 14:18:14 +07:00
);
2026-01-23 18:06:08 +07:00
}