fix: apply bugfix agent improvements to src/app/dashboard/settings/page.tsx
This commit is contained in:
parent
1a0508bba5
commit
90482f2c99
|
|
@ -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>
|
||||
);
|
||||
}
|
||||
Loading…
Reference in New Issue