'use client' import { useState, useEffect, Suspense } from 'react' // CHANGED: add Suspense import { useSearchParams, useRouter } from 'next/navigation' import PageLayout from '../components/PageLayout' import Waves from '../components/background/waves' import { ToastProvider, useToast } from '../components/toast/toastComponent' function PasswordResetPageInner() { const searchParams = useSearchParams() const router = useRouter() const token = searchParams.get('token') // Email request state const [email, setEmail] = useState('') const [requestLoading, setRequestLoading] = useState(false) const [requestSuccess, setRequestSuccess] = useState(false) const [requestError, setRequestError] = useState('') // Reset-with-token state const [password, setPassword] = useState('') const [confirmPassword, setConfirmPassword] = useState('') const [showPassword, setShowPassword] = useState(false) const [resetLoading, setResetLoading] = useState(false) const [resetSuccess, setResetSuccess] = useState(false) const [resetError, setResetError] = useState('') const { showToast } = useToast() // Basic validators const validEmail = (val: string) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(val) const validPassword = (val: string) => /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[\W_]).{8,}$/.test(val) // Auto-redirect after successful password reset useEffect(() => { if (resetSuccess) { const t = setTimeout(() => router.push('/login'), 1800) return () => clearTimeout(t) } }, [resetSuccess, router]) const handleRequestSubmit = async (e: React.FormEvent) => { e.preventDefault() if (requestLoading) return if (!validEmail(email)) { const msg = 'Please enter a valid email address.' setRequestError(msg) showToast({ variant: 'error', title: 'Invalid email', message: msg, }) return } setRequestError('') setRequestLoading(true) try { // TODO: call API endpoint: POST /auth/password-reset/request await new Promise(r => setTimeout(r, 1100)) setRequestSuccess(true) showToast({ variant: 'success', title: 'Password reset email', message: 'If this email exists, a reset link has been sent.', }) } catch { const msg = 'Request failed. Please try again.' setRequestError(msg) showToast({ variant: 'error', title: 'Request failed', message: msg, }) } finally { setRequestLoading(false) } } const handleResetSubmit = async (e: React.FormEvent) => { e.preventDefault() if (resetLoading) return if (!validPassword(password)) { const msg = 'Password does not meet the requirements.' setResetError(msg) showToast({ variant: 'error', title: 'Invalid password', message: msg, }) return } if (password !== confirmPassword) { const msg = 'Passwords do not match.' setResetError(msg) showToast({ variant: 'error', title: 'Passwords do not match', message: msg, }) return } setResetError('') setResetLoading(true) try { // TODO: call API endpoint: POST /auth/password-reset/confirm { token, password } await new Promise(r => setTimeout(r, 1200)) setResetSuccess(true) showToast({ variant: 'success', title: 'Password updated', message: 'Your password has been changed. Redirecting to login...', }) } catch { const msg = 'Reset failed. Please try again.' setResetError(msg) showToast({ variant: 'error', title: 'Reset failed', message: msg, }) } finally { setResetLoading(false) } } const passwordHints = [ { label: 'At least 8 characters', pass: password.length >= 8 }, { label: 'Uppercase letter (A-Z)', pass: /[A-Z]/.test(password) }, { label: 'Lowercase letter (a-z)', pass: /[a-z]/.test(password) }, { label: 'Number (0-9)', pass: /\d/.test(password) }, { label: 'Special character (!@#$...)', pass: /[\W_]/.test(password) } ] return (
{/* push content a bit further down while still centering */}
{/* Widened container to match header */}
{/* Translucent form card (matching login glass style) */}

Reset password

{!token ? 'Request a link to reset your password.' : 'Set a new secure password.'}

{!token && (
{ setEmail(e.target.value); setRequestError(''); setRequestSuccess(false)}} className="w-full rounded-xl border border-white/40 bg-white/60 px-4 py-3 text-[#0F172A] placeholder-slate-600/80 shadow-sm focus:outline-none focus:ring-2 focus:ring-[#8D6B1D]/80 focus:border-[#8D6B1D] transition" placeholder="your.email@example.com" required />
{requestError && (
{requestError}
)} {requestSuccess && (
Email sent (if the address exists). Please check your inbox.
)}
Remember it now?{' '}
)} {token && (
{ setPassword(e.target.value); setResetError(''); setResetSuccess(false)}} className="w-full rounded-xl border border-white/40 bg-white/60 px-4 py-3 pr-12 text-[#0F172A] placeholder-slate-600/80 shadow-sm focus:outline-none focus:ring-2 focus:ring-[#8D6B1D]/80 focus:border-[#8D6B1D] transition" placeholder="Your new password" required />
{passwordHints.map(h => (
{h.label}
))}
{ setConfirmPassword(e.target.value); setResetError(''); setResetSuccess(false)}} className="w-full rounded-xl border border-white/40 bg-white/60 px-4 py-3 text-[#0F172A] placeholder-slate-600/80 shadow-sm focus:outline-none focus:ring-2 focus:ring-[#8D6B1D]/80 focus:border-[#8D6B1D] transition" placeholder="Confirm password" required /> {confirmPassword && password !== confirmPassword && (

Passwords do not match.

)}
{resetError && (
{resetError}
)} {resetSuccess && (
Password saved. Redirecting to login...
)}
Link expired?{' '}
)}
) } export default function PasswordResetPage() { return (

Loading...

} >
) }