import { createSignal, createEffect, onCleanup, Show } from "solid-js"; import { A, useNavigate } from "@solidjs/router"; import { Title, Meta } from "@solidjs/meta"; import CountdownCircleTimer from "~/components/CountdownCircleTimer"; import { isValidEmail } from "~/lib/validation"; import { getClientCookie } from "~/lib/cookies.client"; export default function RequestPasswordResetPage() { const navigate = useNavigate(); // State management const [loading, setLoading] = createSignal(false); const [countDown, setCountDown] = createSignal(0); const [showSuccessMessage, setShowSuccessMessage] = createSignal(false); const [error, setError] = createSignal(""); // Form refs let emailRef: HTMLInputElement | undefined; let timerInterval: number | undefined; // Calculate remaining time from cookie const calcRemainder = (timer: string) => { const expires = new Date(timer); const remaining = expires.getTime() - Date.now(); const remainingInSeconds = remaining / 1000; if (remainingInSeconds <= 0) { setCountDown(0); if (timerInterval) { clearInterval(timerInterval); } } else { setCountDown(remainingInSeconds); } }; // Check for existing timer on mount createEffect(() => { const timer = getClientCookie("passwordResetRequested"); if (timer) { timerInterval = setInterval( () => calcRemainder(timer), 1000 ) as unknown as number; } onCleanup(() => { if (timerInterval) { clearInterval(timerInterval); } }); }); // Form submission handler const requestPasswordResetTrigger = async (e: Event) => { e.preventDefault(); setError(""); setShowSuccessMessage(false); if (!emailRef) { setError("Please enter an email address"); return; } const email = emailRef.value; // Validate email if (!isValidEmail(email)) { setError("Invalid email address"); return; } setLoading(true); try { const response = await fetch("/api/trpc/auth.requestPasswordReset", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ email }) }); const result = await response.json(); if (response.ok && result.result?.data) { setShowSuccessMessage(true); setError(""); // Start countdown timer const timer = getClientCookie("passwordResetRequested"); if (timer) { if (timerInterval) { clearInterval(timerInterval); } timerInterval = setInterval(() => { calcRemainder(timer); }, 1000) as unknown as number; } } else { const errorMsg = result.error?.message || "Failed to send reset email"; if (errorMsg.includes("countdown not expired")) { setError("Please wait before requesting another reset email"); } else { setError(errorMsg); } } } catch (err) { console.error("Password reset request error:", err); setError("An error occurred. Please try again."); } finally { setLoading(false); } }; const renderTime = () => { return (
{countDown().toFixed(0)}
); }; return ( <> Request Password Reset | Michael Freno
Password Reset Request
requestPasswordResetTrigger(e)} class="mt-4 flex w-full justify-center" >
{/* Email Input */}
{/* Countdown Timer or Submit Button */} 0} fallback={ } >
false} > {renderTime}
{/* Success Message */}
If email exists, you will receive an email shortly!
{/* Error Message */}
{error()}
{/* Back to Login Link */}
Back to Login
); }