//? intent: Recover access — request a reset link, then set a new password with it.
import { useEffect, useRef, useState } from 'react';
import { Link, useSearchParams } from 'react-router-dom';
import { loginPageUrl } from 'config';
import { i18nNotify as notify, useTranslator } from '@luckystack/core/client';
import { apiRequest } from 'src/_sockets/apiRequest';
export const template = 'plain';
export default function ResetPasswordPage() {
const [params, setParams] = useSearchParams();
//? Read the reset token once, then drop it from the address bar: a live
//? reset link is an account-takeover credential, and while it sits in the
//? URL it reaches browser history, the Referer header and error-tracker
//? pageload/navigation/replay data. The link stays valid until used, so
//? reopening it from the email still works after a reload.
const [token] = useState(() => params.get('token') ?? '');
useEffect(() => {
if (!params.has('token')) return;
setParams((previous) => {
const next = new URLSearchParams(previous);
next.delete('token');
return next;
}, { replace: true });
}, [params, setParams]);
return (
);
}
function RequestForm() {
const translate = useTranslator();
const [loading, setLoading] = useState(false);
const [submitted, setSubmitted] = useState(false);
const inputRef = useRef(null);
const handleSubmit = async (event: React.SyntheticEvent) => {
event.preventDefault();
if (loading) return;
const email = inputRef.current?.value.trim() ?? '';
if (!email) return;
setLoading(true);
const response = await apiRequest({
name: 'reset-password/sendReset',
version: 'v1',
data: { email },
});
setLoading(false);
if (response.status === 'success') {
setSubmitted(true);
notify.success({ key: 'login.resetEmailSent' });
} else {
notify.error({ key: response.errorCode });
}
};
return (
);
}
function ConfirmForm({ token }: { token: string }) {
const translate = useTranslator();
const [loading, setLoading] = useState(false);
const [done, setDone] = useState(false);
const passwordRef = useRef(null);
const confirmRef = useRef(null);
const inputClass = 'rounded-md w-full h-9 border border-container1-border bg-container1 px-3 text-sm focus:outline-none focus:border-primary focus:ring-2 focus:ring-primary/30 transition-colors';
const handleSubmit = async (event: React.SyntheticEvent) => {
event.preventDefault();
if (loading) return;
const password = passwordRef.current?.value ?? '';
const confirmPassword = confirmRef.current?.value ?? '';
if (password !== confirmPassword) {
notify.error({ key: 'login.passwordNotMatch' });
return;
}
setLoading(true);
const response = await apiRequest({
name: 'reset-password/confirmReset',
version: 'v1',
data: { token, password, confirmPassword },
});
setLoading(false);
if (response.status === 'success') {
setDone(true);
notify.success({ key: 'login.resetPasswordUpdated' });
} else {
notify.error({ key: response.errorCode });
}
};
return (
);
}