fix: apply bugfix agent improvements to src/app/dashboard/settings/page.tsx

This commit is contained in:
cupadev-admin 2026-03-09 12:48:36 +00:00
parent 1a0508bba5
commit 90482f2c99
1 changed files with 207 additions and 0 deletions

View File

@ -0,0 +1,207 @@
"use client";
import { useState } from "react";
import { useForm } from "react-hook-form";
import { useAuthStore } from "@/store/authStore";
import toast from "react-hot-toast";
import { User, Lock, Save } from "lucide-react";
interface ProfileForm {
name: string;
email: string;
}
interface PasswordForm {
currentPassword: string;
newPassword: string;
confirmPassword: string;
}
export default function SettingsPage() {
const { user, updateUser } = useAuthStore();
const [activeTab, setActiveTab] = useState<"profile" | "password">("profile");
const profileForm = useForm<ProfileForm>({
defaultValues: {
name: user?.name ?? "",
email: user?.email ?? "",
},
});
const passwordForm = useForm<PasswordForm>();
const onProfileSubmit = (data: ProfileForm) => {
try {
updateUser(data);
toast.success("Profile updated successfully!");
} catch {
toast.error("Failed to update profile.");
}
};
const onPasswordSubmit = (data: PasswordForm) => {
if (data.newPassword !== data.confirmPassword) {
toast.error("Passwords do not match.");
return;
}
if (data.newPassword.length < 6) {
toast.error("Password must be at least 6 characters.");
return;
}
try {
updateUser({ password: data.newPassword });
toast.success("Password updated successfully!");
passwordForm.reset();
} catch {
toast.error("Failed to update password.");
}
};
return (
<div className="space-y-6 max-w-2xl">
<div>
<h1 className="text-2xl font-bold text-gray-900">Settings</h1>
<p className="text-gray-500 mt-1">Manage your account settings.</p>
</div>
<div className="bg-white rounded-xl shadow-sm border border-gray-200">
<div className="border-b border-gray-200">
<nav className="flex gap-0" aria-label="Tabs">
{[
{ key: "profile", label: "Profile", icon: User },
{ key: "password", label: "Password", icon: Lock },
].map(({ key, label, icon: Icon }) => (
<button
key={key}
onClick={() => setActiveTab(key as "profile" | "password")}
className={`flex items-center gap-2 px-6 py-4 text-sm font-medium border-b-2 transition-colors ${
activeTab === key
? "border-primary-500 text-primary-600"
: "border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300"
}`}
>
<Icon size={16} />
{label}
</button>
))}
</nav>
</div>
<div className="p-6">
{activeTab === "profile" && (
<form
onSubmit={profileForm.handleSubmit(onProfileSubmit)}
className="space-y-4"
>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
Name
</label>
<input
{...profileForm.register("name", {
required: "Name is required",
})}
className="w-full px-3 py-2 border border-gray-300 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-primary-500 focus:border-transparent"
/>
{profileForm.formState.errors.name && (
<p className="text-red-500 text-xs mt-1">
{profileForm.formState.errors.name.message}
</p>
)}
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
Email
</label>
<input
type="email"
{...profileForm.register("email", {
required: "Email is required",
})}
className="w-full px-3 py-2 border border-gray-300 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-primary-500 focus:border-transparent"
/>
{profileForm.formState.errors.email && (
<p className="text-red-500 text-xs mt-1">
{profileForm.formState.errors.email.message}
</p>
)}
</div>
<button
type="submit"
className="inline-flex items-center gap-2 px-4 py-2 bg-primary-600 text-white rounded-lg hover:bg-primary-700 text-sm font-medium"
>
<Save size={16} />
Save Changes
</button>
</form>
)}
{activeTab === "password" && (
<form
onSubmit={passwordForm.handleSubmit(onPasswordSubmit)}
className="space-y-4"
>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
Current Password
</label>
<input
type="password"
{...passwordForm.register("currentPassword", {
required: "Current password is required",
})}
className="w-full px-3 py-2 border border-gray-300 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-primary-500 focus:border-transparent"
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
New Password
</label>
<input
type="password"
{...passwordForm.register("newPassword", {
required: "New password is required",
minLength: {
value: 6,
message: "Password must be at least 6 characters",
},
})}
className="w-full px-3 py-2 border border-gray-300 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-primary-500 focus:border-transparent"
/>
{passwordForm.formState.errors.newPassword && (
<p className="text-red-500 text-xs mt-1">
{passwordForm.formState.errors.newPassword.message}
</p>
)}
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
Confirm New Password
</label>
<input
type="password"
{...passwordForm.register("confirmPassword", {
required: "Please confirm your password",
})}
className="w-full px-3 py-2 border border-gray-300 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-primary-500 focus:border-transparent"
/>
</div>
<button
type="submit"
className="inline-flex items-center gap-2 px-4 py-2 bg-primary-600 text-white rounded-lg hover:bg-primary-700 text-sm font-medium"
>
<Save size={16} />
Update Password
</button>
</form>
)}
</div>
</div>
</div>
);
}