'use client' import { useState, useEffect, useCallback } from 'react' import { useRouter } from 'next/navigation' import { ShieldCheck, AlertCircle, CheckCircle2, ArrowLeft, Mail, Lock, KeyRound } from 'lucide-react' import Link from 'next/link' import { api } from '@/lib/api' import { USE_MOCK } from '@/contexts/AuthContext' type Step = 'email' | 'code' | 'done' export default function ForgotPasswordPage() { const router = useRouter() const [step, setStep] = useState('email') const [email, setEmail] = useState('') const [emailCode, setEmailCode] = useState('') const [newPassword, setNewPassword] = useState('') const [confirmPassword, setConfirmPassword] = useState('') const [error, setError] = useState('') const [isLoading, setIsLoading] = useState(false) const [codeSending, setCodeSending] = useState(false) const [countdown, setCountdown] = useState(0) useEffect(() => { if (countdown <= 0) return const timer = setTimeout(() => setCountdown(countdown - 1), 1000) return () => clearTimeout(timer) }, [countdown]) const handleSendCode = useCallback(async () => { if (!email) { setError('请输入邮箱') return } if (countdown > 0) return setError('') setCodeSending(true) try { if (USE_MOCK) { await new Promise((resolve) => setTimeout(resolve, 500)) setCountdown(60) setStep('code') return } await api.sendEmailCode({ email, purpose: 'reset_password' }) setCountdown(60) setStep('code') } catch (err) { const msg = err instanceof Error ? err.message : '发送验证码失败' setError(msg) } finally { setCodeSending(false) } }, [email, countdown]) const handleResetPassword = async (e: React.FormEvent) => { e.preventDefault() setError('') if (!emailCode) { setError('请输入验证码') return } if (newPassword.length < 6) { setError('密码至少 6 位') return } if (newPassword !== confirmPassword) { setError('两次密码不一致') return } setIsLoading(true) try { if (USE_MOCK) { await new Promise((resolve) => setTimeout(resolve, 500)) setStep('done') return } await api.resetPassword({ email, email_code: emailCode, new_password: newPassword }) setStep('done') } catch (err) { const msg = err instanceof Error ? err.message : '重置密码失败' setError(msg) } finally { setIsLoading(false) } } // 成功页 if (step === 'done') { return (

密码已重置

请使用新密码登录

) } return (
{/* 返回 */} 返回登录 {/* 标题 */}
重置密码

{step === 'email' ? '输入邮箱获取验证码' : '设置新密码'}

{/* 步骤指示 */}
{ e.preventDefault(); handleSendCode() } : handleResetPassword} className="space-y-5"> {error && (
{error}
)} {step === 'email' ? ( <> {/* 邮箱 */}
setEmail(e.target.value)} className="w-full pl-12 pr-4 py-3.5 bg-bg-elevated border border-border-subtle rounded-xl text-text-primary placeholder-text-tertiary focus:outline-none focus:ring-2 focus:ring-accent-indigo focus:border-transparent transition-all" required />
) : ( <> {/* 验证码 */}
setEmailCode(e.target.value.replace(/\D/g, '').slice(0, 6))} maxLength={6} className="w-full pl-12 pr-4 py-3.5 bg-bg-elevated border border-border-subtle rounded-xl text-text-primary placeholder-text-tertiary focus:outline-none focus:ring-2 focus:ring-accent-indigo focus:border-transparent transition-all" required />
{/* 新密码 */}
setNewPassword(e.target.value)} className="w-full pl-12 pr-4 py-3.5 bg-bg-elevated border border-border-subtle rounded-xl text-text-primary placeholder-text-tertiary focus:outline-none focus:ring-2 focus:ring-accent-indigo focus:border-transparent transition-all" required />
{/* 确认密码 */}
setConfirmPassword(e.target.value)} className="w-full pl-12 pr-4 py-3.5 bg-bg-elevated border border-border-subtle rounded-xl text-text-primary placeholder-text-tertiary focus:outline-none focus:ring-2 focus:ring-accent-indigo focus:border-transparent transition-all" required />
)}
) }