diff --git a/frontend/src/components/workspace/settings/account-settings-page.tsx b/frontend/src/components/workspace/settings/account-settings-page.tsx new file mode 100644 index 000000000..6382b8859 --- /dev/null +++ b/frontend/src/components/workspace/settings/account-settings-page.tsx @@ -0,0 +1,132 @@ +"use client"; + +import { LogOutIcon } from "lucide-react"; +import { useState } from "react"; + +import { Button } from "@/components/ui/button"; +import { Input } from "@/components/ui/input"; +import { fetchWithAuth, getCsrfHeaders } from "@/core/api/fetcher"; +import { useAuth } from "@/core/auth/AuthProvider"; +import { parseAuthError } from "@/core/auth/types"; + +import { SettingsSection } from "./settings-section"; + +export function AccountSettingsPage() { + const { user, logout } = useAuth(); + const [currentPassword, setCurrentPassword] = useState(""); + const [newPassword, setNewPassword] = useState(""); + const [confirmPassword, setConfirmPassword] = useState(""); + const [message, setMessage] = useState(""); + const [error, setError] = useState(""); + const [loading, setLoading] = useState(false); + + const handleChangePassword = async (e: React.FormEvent) => { + e.preventDefault(); + setError(""); + setMessage(""); + + if (newPassword !== confirmPassword) { + setError("New passwords do not match"); + return; + } + if (newPassword.length < 8) { + setError("Password must be at least 8 characters"); + return; + } + + setLoading(true); + try { + const res = await fetchWithAuth("/api/v1/auth/change-password", { + method: "POST", + headers: { + "Content-Type": "application/json", + ...getCsrfHeaders(), + }, + body: JSON.stringify({ + current_password: currentPassword, + new_password: newPassword, + }), + }); + + if (!res.ok) { + const data = await res.json(); + const authError = parseAuthError(data); + setError(authError.message); + return; + } + + setMessage("Password changed successfully"); + setCurrentPassword(""); + setNewPassword(""); + setConfirmPassword(""); + } catch { + setError("Network error. Please try again."); + } finally { + setLoading(false); + } + }; + + return ( +