pelagia-portal/App/app/(portal)/profile/change-password-form.tsx
Hardik bff9696b7b fix(profile): allow empty current password when setting password for first time
SSO users have no passwordHash and should be able to set a local password
without providing a current one. Users with an existing password still
must verify it. Removes the client-side required attribute and updates
the server-side logic accordingly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-29 00:14:46 +05:30

95 lines
2.9 KiB
TypeScript

"use client";
import { useState } from "react";
import { changePassword } from "./actions";
export function ChangePasswordForm() {
const [success, setSuccess] = useState(false);
const [error, setError] = useState("");
const [pending, setPending] = useState(false);
async function handleSubmit(e: React.FormEvent<HTMLFormElement>) {
e.preventDefault();
const form = e.currentTarget;
const fd = new FormData(form);
const newPw = fd.get("newPassword") as string;
const confirmPw = fd.get("confirmPassword") as string;
if (newPw !== confirmPw) {
setError("New passwords do not match");
return;
}
setPending(true);
setSuccess(false);
setError("");
const result = await changePassword(fd);
setPending(false);
if ("error" in result) {
setError(result.error);
} else {
setSuccess(true);
form.reset();
}
}
return (
<form onSubmit={handleSubmit} className="space-y-4">
<div>
<label className="block text-sm font-medium text-neutral-700 mb-1.5">
Current password
</label>
<input
type="password"
name="currentPassword"
autoComplete="current-password"
className="w-full rounded-lg border border-neutral-300 px-3 py-2.5 text-sm focus:border-primary-500 focus:outline-none focus:ring-2 focus:ring-primary-500/20"
/>
</div>
<div>
<label className="block text-sm font-medium text-neutral-700 mb-1.5">
New password
</label>
<input
type="password"
name="newPassword"
required
minLength={8}
autoComplete="new-password"
className="w-full rounded-lg border border-neutral-300 px-3 py-2.5 text-sm focus:border-primary-500 focus:outline-none focus:ring-2 focus:ring-primary-500/20"
/>
</div>
<div>
<label className="block text-sm font-medium text-neutral-700 mb-1.5">
Confirm new password
</label>
<input
type="password"
name="confirmPassword"
required
minLength={8}
autoComplete="new-password"
className="w-full rounded-lg border border-neutral-300 px-3 py-2.5 text-sm focus:border-primary-500 focus:outline-none focus:ring-2 focus:ring-primary-500/20"
/>
</div>
{error && (
<p className="text-sm text-danger-700 bg-danger-50 rounded-lg px-3 py-2">{error}</p>
)}
{success && (
<p className="text-sm text-success-700 bg-success-50 rounded-lg px-3 py-2">
Password changed successfully.
</p>
)}
<button
type="submit"
disabled={pending}
className="rounded-lg bg-primary-600 px-4 py-2.5 text-sm font-semibold text-white hover:bg-primary-700 disabled:opacity-60 transition-colors"
>
{pending ? "Saving…" : "Change Password"}
</button>
</form>
);
}