137 lines
4.8 KiB
TypeScript
137 lines
4.8 KiB
TypeScript
"use client"
|
||
|
||
import { useState } from "react"
|
||
import { useRouter } from "next/navigation"
|
||
import Link from "next/link"
|
||
import { ChevronLeft, Phone, Hash } from "lucide-react"
|
||
|
||
export default function ForgotPasswordPage() {
|
||
const router = useRouter()
|
||
const [phone, setPhone] = useState("")
|
||
const [newPassword, setNewPassword] = useState("")
|
||
const [confirmPassword, setConfirmPassword] = useState("")
|
||
const [error, setError] = useState("")
|
||
const [success, setSuccess] = useState(false)
|
||
const [loading, setLoading] = useState(false)
|
||
|
||
const handleSubmit = async (e: React.FormEvent) => {
|
||
e.preventDefault()
|
||
setError("")
|
||
setLoading(true)
|
||
|
||
try {
|
||
if (!phone.trim()) {
|
||
setError("请输入手机号")
|
||
return
|
||
}
|
||
if (!newPassword.trim()) {
|
||
setError("请输入新密码")
|
||
return
|
||
}
|
||
if (newPassword.trim().length < 6) {
|
||
setError("密码至少 6 位")
|
||
return
|
||
}
|
||
if (newPassword !== confirmPassword) {
|
||
setError("两次输入的密码不一致")
|
||
return
|
||
}
|
||
|
||
const res = await fetch("/api/auth/reset-password", {
|
||
method: "POST",
|
||
headers: { "Content-Type": "application/json" },
|
||
body: JSON.stringify({ phone: phone.trim(), newPassword: newPassword.trim() }),
|
||
})
|
||
const data = await res.json()
|
||
|
||
if (data.success) {
|
||
setSuccess(true)
|
||
setTimeout(() => router.push("/view/login"), 2000)
|
||
} else {
|
||
setError(data.error || "重置失败")
|
||
}
|
||
} finally {
|
||
setLoading(false)
|
||
}
|
||
}
|
||
|
||
if (success) {
|
||
return (
|
||
<div className="min-h-screen bg-black text-white flex flex-col items-center justify-center px-6">
|
||
<p className="text-[#30d158] text-lg mb-4">密码已重置</p>
|
||
<p className="text-gray-500 text-sm">请使用新密码登录,正在跳转...</p>
|
||
</div>
|
||
)
|
||
}
|
||
|
||
return (
|
||
<div className="min-h-screen bg-black text-white flex flex-col">
|
||
<header className="flex items-center px-4 py-3">
|
||
<Link
|
||
href="/view/login"
|
||
className="w-9 h-9 rounded-full bg-[#1c1c1e] flex items-center justify-center"
|
||
>
|
||
<ChevronLeft className="w-5 h-5 text-gray-400" />
|
||
</Link>
|
||
<h1 className="flex-1 text-center text-lg font-semibold">找回密码</h1>
|
||
<div className="w-9" />
|
||
</header>
|
||
|
||
<main className="flex-1 px-6 pt-8">
|
||
<p className="text-gray-500 text-sm mb-6">
|
||
请输入注册时使用的手机号和新密码,重置后请使用新密码登录。
|
||
</p>
|
||
|
||
<form onSubmit={handleSubmit} className="space-y-4">
|
||
<div className="relative">
|
||
<Phone className="absolute left-4 top-1/2 -translate-y-1/2 w-5 h-5 text-gray-500" />
|
||
<input
|
||
type="tel"
|
||
value={phone}
|
||
onChange={(e) => setPhone(e.target.value)}
|
||
placeholder="手机号"
|
||
className="w-full pl-12 pr-4 py-3.5 bg-[#1c1c1e] rounded-xl text-white placeholder-gray-500 focus:outline-none focus:ring-2 focus:ring-[#30d158]/50"
|
||
/>
|
||
</div>
|
||
|
||
<div className="relative">
|
||
<Hash className="absolute left-4 top-1/2 -translate-y-1/2 w-5 h-5 text-gray-500" />
|
||
<input
|
||
type="password"
|
||
value={newPassword}
|
||
onChange={(e) => setNewPassword(e.target.value)}
|
||
placeholder="新密码(至少 6 位)"
|
||
className="w-full pl-12 pr-4 py-3.5 bg-[#1c1c1e] rounded-xl text-white placeholder-gray-500 focus:outline-none focus:ring-2 focus:ring-[#30d158]/50"
|
||
/>
|
||
</div>
|
||
|
||
<div className="relative">
|
||
<Hash className="absolute left-4 top-1/2 -translate-y-1/2 w-5 h-5 text-gray-500" />
|
||
<input
|
||
type="password"
|
||
value={confirmPassword}
|
||
onChange={(e) => setConfirmPassword(e.target.value)}
|
||
placeholder="再次输入新密码"
|
||
className="w-full pl-12 pr-4 py-3.5 bg-[#1c1c1e] rounded-xl text-white placeholder-gray-500 focus:outline-none focus:ring-2 focus:ring-[#30d158]/50"
|
||
/>
|
||
</div>
|
||
|
||
{error && <p className="text-red-500 text-sm">{error}</p>}
|
||
|
||
<button
|
||
type="submit"
|
||
disabled={loading || !phone || !newPassword || !confirmPassword}
|
||
className="w-full py-3.5 bg-[#30d158] text-white font-medium rounded-xl active:scale-[0.98] transition-transform disabled:opacity-50"
|
||
>
|
||
{loading ? "提交中..." : "重置密码"}
|
||
</button>
|
||
</form>
|
||
|
||
<p className="text-gray-500 text-xs mt-6 text-center">
|
||
若该手机号未注册,将提示「该手机号未注册」;重置后请使用新密码在登录页登录。
|
||
</p>
|
||
</main>
|
||
</div>
|
||
)
|
||
}
|