Files
pragativeer-v2/src/app/dashboard/settings/password/page.tsx

116 lines
4.6 KiB
TypeScript

"use client";
import { fetchWithAuth } from "@/lib/apiClient";
import { useState } from "react";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { Lock } from "lucide-react";
export default function PasswordPage() {
const [currentPassword, setCurrentPassword] = useState("");
const [newPassword, setNewPassword] = useState("");
const [confirmPassword, setConfirmPassword] = useState("");
const [passwordSaving, setPasswordSaving] = useState(false);
const handleChangePassword = async () => {
if (newPassword !== confirmPassword) {
alert("New passwords do not match.");
return;
}
setPasswordSaving(true);
try {
const res = await fetchWithAuth("/api/auth/change-password", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
current_password: currentPassword,
new_password: newPassword,
}),
});
const data = await res.json();
if (res.ok) {
alert(data.message || "Password updated successfully!");
setCurrentPassword("");
setNewPassword("");
setConfirmPassword("");
} else {
alert("Failed to change password: " + (data.detail || "Unknown error"));
}
} catch (err) {
console.error(err);
alert("Network error. Could not change password.");
} finally {
setPasswordSaving(false);
}
};
return (
<div className="p-8 space-y-8 max-w-3xl mx-auto">
<div className="flex flex-col md:flex-row md:items-end justify-between gap-4">
<div>
<h1 className="text-3xl md:text-4xl font-black tracking-tight flex items-center gap-3 mb-1">
<span className="p-2.5 rounded-xl bg-purple-50 dark:bg-[var(--cyan-ai-10)] border border-purple-300/60 dark:border-[var(--cyan-ai-20)]">
<Lock className="text-purple-600 dark:text-[var(--cyan-ai)]" size={28} />
</span>
Change Password
</h1>
<p className="text-muted-foreground text-base font-medium max-w-2xl pl-1">
Update your account password securely.
</p>
</div>
</div>
<Card className="border-border bg-background shadow-sm">
<CardHeader>
<CardTitle>Change Password</CardTitle>
<CardDescription>Update your account password</CardDescription>
</CardHeader>
<CardContent className="space-y-6">
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
<div className="space-y-2">
<label className="text-sm font-bold">Current Password</label>
<input
type="password"
value={currentPassword}
onChange={(e) => setCurrentPassword(e.target.value)}
className="w-full bg-secondary/50 border border-border rounded-lg px-4 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-[var(--cyan-ai)]"
placeholder="Enter current password"
/>
</div>
<div className="hidden md:block"></div>
<div className="space-y-2">
<label className="text-sm font-bold">New Password</label>
<input
type="password"
value={newPassword}
onChange={(e) => setNewPassword(e.target.value)}
className="w-full bg-secondary/50 border border-border rounded-lg px-4 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-[var(--cyan-ai)]"
placeholder="Enter new password"
/>
</div>
<div className="space-y-2">
<label className="text-sm font-bold">Confirm New Password</label>
<input
type="password"
value={confirmPassword}
onChange={(e) => setConfirmPassword(e.target.value)}
className="w-full bg-secondary/50 border border-border rounded-lg px-4 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-[var(--cyan-ai)]"
placeholder="Confirm new password"
/>
</div>
</div>
<div className="flex pt-2 border-t border-border mt-6">
<Button
className="bg-foreground text-background hover:bg-foreground/90 font-bold px-6 rounded-xl"
onClick={handleChangePassword}
disabled={passwordSaving || !currentPassword || !newPassword || !confirmPassword}
>
{passwordSaving ? "Updating..." : "Update Password"}
</Button>
</div>
</CardContent>
</Card>
</div>
);
}