underrate's picture
Initial commit
34ed5b1 verified
Raw
History Blame Contribute Delete
4.62 kB
"use client"
import { useState, Suspense } from "react"
import { useRouter, useSearchParams } from "next/navigation"
import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
const API_URL = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:5000/api';
function ResetPasswordForm() {
const router = useRouter()
const searchParams = useSearchParams()
const token = searchParams.get("token")
const [password, setPassword] = useState("")
const [confirmPassword, setConfirmPassword] = useState("")
const [status, setStatus] = useState<"idle" | "loading" | "success" | "error">("idle")
const [errorMessage, setErrorMessage] = useState("")
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault()
if (password !== confirmPassword) {
setErrorMessage("Passwords do not match")
return
}
if (!token) {
setErrorMessage("Missing reset token")
return
}
setStatus("loading")
setErrorMessage("")
try {
const res = await fetch(`${API_URL}/auth/reset-password`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ token, password }),
})
const data = await res.json()
if (res.ok) {
setStatus("success")
setTimeout(() => {
router.push("/admin/login")
}, 2000)
} else {
setStatus("error")
setErrorMessage(data.error || "Failed to reset password")
}
} catch (error) {
setStatus("error")
setErrorMessage("An error occurred")
}
}
if (!token) {
return (
<div className="text-destructive">
Invalid link. Missing token.
</div>
)
}
return (
<form onSubmit={handleSubmit} className="space-y-4">
{status === "error" && (
<div className="bg-destructive/15 text-destructive p-3 rounded-md text-sm">
{errorMessage}
</div>
)}
{status === "success" && (
<div className="bg-green-100 text-green-700 p-3 rounded-md text-sm">
Password updated! Redirecting to login...
</div>
)}
<div className="space-y-2">
<Label htmlFor="password">New Password</Label>
<Input
id="password"
type="password"
required
value={password}
onChange={(e) => setPassword(e.target.value)}
disabled={status === "loading" || status === "success"}
/>
</div>
<div className="space-y-2">
<Label htmlFor="confirmPassword">Confirm Password</Label>
<Input
id="confirmPassword"
type="password"
required
value={confirmPassword}
onChange={(e) => setConfirmPassword(e.target.value)}
disabled={status === "loading" || status === "success"}
/>
</div>
<Button type="submit" className="w-full" disabled={status === "loading" || status === "success"}>
{status === "loading" ? "Resetting..." : "Reset Password"}
</Button>
</form>
)
}
export default function ResetPasswordPage() {
return (
<div className="flex min-h-screen items-center justify-center bg-muted/50 p-4">
<Card className="w-full max-w-md">
<CardHeader>
<CardTitle className="text-2xl font-bold">Reset Password</CardTitle>
<CardDescription>
Enter your new password below.
</CardDescription>
</CardHeader>
<CardContent>
<Suspense fallback={<div>Loading...</div>}>
<ResetPasswordForm />
</Suspense>
</CardContent>
</Card>
</div>
)
}