import React, { useEffect, useState } from "react"; import { apiUrl, getAuthHeaders, clearSessionToken } from "../../utils/api.js"; // Account settings — the GitPilot account (your email/password identity). // This is intentionally separate from the GitHub connection, which only grants // access to repositories. Here you manage who you are; GitHub manages what you // can touch. export default function AccountTab({ onLogout }) { const [account, setAccount] = useState(null); const [loading, setLoading] = useState(true); const [loadError, setLoadError] = useState(""); // Profile const [name, setName] = useState(""); const [savingProfile, setSavingProfile] = useState(false); const [profileMsg, setProfileMsg] = useState(""); // Password const [curPw, setCurPw] = useState(""); const [newPw, setNewPw] = useState(""); const [confirmPw, setConfirmPw] = useState(""); const [savingPw, setSavingPw] = useState(false); const [pwMsg, setPwMsg] = useState(null); // {kind, text} // Delete (danger zone) const [confirmDelete, setConfirmDelete] = useState(false); const [delPw, setDelPw] = useState(""); const [deleting, setDeleting] = useState(false); const [delErr, setDelErr] = useState(""); const jsonHeaders = () => ({ "Content-Type": "application/json", ...getAuthHeaders() }); const loadAccount = async () => { setLoading(true); setLoadError(""); try { const res = await fetch(apiUrl("/api/account/me"), { credentials: "include", headers: getAuthHeaders(), }); if (res.status === 401) { setAccount(null); return; } const data = await res.json(); if (!res.ok) throw new Error(data.detail || "Could not load your account."); setAccount(data); setName(data.name || ""); } catch (e) { setLoadError(e.message || "Could not load your account."); } finally { setLoading(false); } }; useEffect(() => { loadAccount(); }, []); const isPasswordAccount = account?.provider === "password"; const saveProfile = async () => { setSavingProfile(true); setProfileMsg(""); try { const res = await fetch(apiUrl("/api/account/profile"), { method: "PATCH", credentials: "include", headers: jsonHeaders(), body: JSON.stringify({ name: name.trim() || null }), }); const data = await res.json(); if (!res.ok) throw new Error(data.detail || "Could not save your profile."); setAccount(data); setProfileMsg("Saved."); setTimeout(() => setProfileMsg(""), 3000); } catch (e) { setProfileMsg(e.message || "Could not save your profile."); } finally { setSavingProfile(false); } }; const changePassword = async () => { setPwMsg(null); if (newPw.length < 8) { setPwMsg({ kind: "err", text: "New password must be at least 8 characters." }); return; } if (newPw !== confirmPw) { setPwMsg({ kind: "err", text: "New password and confirmation don't match." }); return; } setSavingPw(true); try { const res = await fetch(apiUrl("/api/account/password/change"), { method: "POST", credentials: "include", headers: jsonHeaders(), body: JSON.stringify({ current_password: curPw, new_password: newPw }), }); const data = await res.json(); if (!res.ok) throw new Error(data.detail || "Could not change your password."); setPwMsg({ kind: "ok", text: "Password changed successfully." }); setCurPw(""); setNewPw(""); setConfirmPw(""); } catch (e) { setPwMsg({ kind: "err", text: e.message || "Could not change your password." }); } finally { setSavingPw(false); } }; const deleteAccount = async () => { setDeleting(true); setDelErr(""); try { const res = await fetch(apiUrl("/api/account/delete"), { method: "POST", credentials: "include", headers: jsonHeaders(), body: JSON.stringify({ password: delPw || null }), }); const data = await res.json().catch(() => ({})); if (!res.ok) throw new Error(data.detail || "Could not delete your account."); // Gone for good — clear local session and return to a signed-out state. clearSessionToken(); if (typeof onLogout === "function") onLogout(); window.location.href = "/"; } catch (e) { setDelErr(e.message || "Could not delete your account."); setDeleting(false); } }; if (loading) { return (
Loading your account…
This is your GitPilot account — your email/password identity, separate from the GitHub connection that grants repository access.
Your GitPilot account — your identity and sign-in. This is separate from the GitHub connection, which only grants repository access.
{/* Profile */}