"use client"; import { useEffect, useState } from "react"; import { Users, Shield, Building2, Settings, LogOut, User, Key, KeyRound, Smartphone, Calendar, MapPin, Image as ImageIcon, Briefcase, Mail, ChevronLeft, ChevronRight } from "lucide-react"; import { useLanguage } from "@/components/language-provider"; import { useAuth } from "@/components/auth/auth-provider"; import { RouteGuard } from "@/components/auth/route-guard"; import { getAccessToken, apiFetch } from "@/lib/api"; import { Button } from "@/components/ui/button"; import { cn } from "@/lib/utils"; import { registerPasskey } from "@/lib/webauthn"; interface UserAccount { user_id: string; email: string; username?: string | null; full_name: string | null; given_name?: string | null; family_name?: string | null; trust_state?: string | null; trust_score?: number | null; skills?: string[]; birth_date?: string | null; province?: string | null; city?: string | null; gender?: string | null; avatar_url?: string | null; status: string; is_active: boolean; mfa_enabled: boolean; email_verified: boolean; phone_verified: boolean; phone: string | null; created_at: string; last_login_at: string | null; passkeys?: any[]; sessions?: any[]; } const SECTIONS = [ { key: "identity", labelFa: "هویت", labelEn: "Identity", icon: Users, descFa: "اطلاعات هویتی و پروفایل عمومی حساب", descEn: "Identity info and public profile", }, { key: "auth", labelFa: "احراز هویت", labelEn: "Authentication", icon: Shield, descFa: "اطلاعات ورود، دستگاه‌ها و امنیت حسابتان را مدیریت کنید", descEn: "Manage sign-in methods, devices and security", }, { key: "businesses", labelFa: "کسب‌وکارها", labelEn: "Businesses", icon: Building2, descFa: "سازمان‌ها و کسب‌وکارهای متصل به حساب شما", descEn: "Organizations connected to your account", }, { key: "bizManage", labelFa: "مدیریت کسب‌وکار", labelEn: "Business Management", icon: Settings, descFa: "ساخت، ویرایش و انتقال مالکیت کسب‌وکارها", descEn: "Create, edit and transfer businesses", }, ]; export default function AccountCenterPage() { const { lang } = useLanguage(); const t = (fa: string, en: string) => (lang === "fa" ? fa : en); const Chev = lang === "fa" ? ChevronLeft : ChevronRight; const { user: ctxUser, logout } = useAuth(); const [mounted, setMounted] = useState(false); const token = getAccessToken(); const [activeTab, setActiveTab] = useState("identity"); const [loading, setLoading] = useState(false); const [user, setUser] = useState(null); const [orgs, setOrgs] = useState([]); const [sessions, setSessions] = useState([]); const [products, setProducts] = useState([]); const [pkBusy, setPkBusy] = useState(false); const [pkError, setPkError] = useState(""); const [editing, setEditing] = useState(false); const [saving, setSaving] = useState(false); const [form, setForm] = useState>({}); const startEdit = () => { setForm({ full_name: user?.full_name || "", given_name: user?.given_name || "", family_name: user?.family_name || "", username: user?.username || "", province: user?.province || "", city: user?.city || "", gender: user?.gender || "", birth_date: user?.birth_date || "", skills: (user?.skills || []).join(", "), }); setEditing(true); }; const cancelEdit = () => setEditing(false); const saveEdit = async () => { setSaving(true); try { const payload: any = { ...form }; payload.skills = form.skills ? form.skills .split(",") .map((s: string) => s.trim()) .filter(Boolean) : []; const res = await apiFetch("/auth/me/", { method: "PATCH", body: JSON.stringify(payload), }); if (res.ok) { setUser(await res.json()); setEditing(false); } } finally { setSaving(false); } }; useEffect(() => { setMounted(true); }, []); // Keep the active tab in sync with the ?tab= query param so the URL reflects // the selected sidebar section and supports back/forward navigation. useEffect(() => { const valid = new Set(SECTIONS.map((s) => s.key)); const syncFromUrl = () => { const tab = new URLSearchParams(window.location.search).get("tab"); if (tab && valid.has(tab)) setActiveTab(tab); }; syncFromUrl(); window.addEventListener("popstate", syncFromUrl); return () => window.removeEventListener("popstate", syncFromUrl); }, []); useEffect(() => { if (ctxUser && !user) setUser(ctxUser as unknown as UserAccount); }, [ctxUser, user]); useEffect(() => { const fetchData = async () => { if (!token) return; setLoading(true); try { const userRes = await apiFetch("/auth/me/"); if (userRes.ok) setUser(await userRes.json()); const orgRes = await apiFetch("/organizations/"); if (orgRes.ok) { const d = await orgRes.json(); setOrgs((d as any).results || d || []); } const sessRes = await apiFetch("/sessions/"); if (sessRes.ok) { const d = await sessRes.json(); setSessions(Array.isArray(d) ? d : d.results || []); } const prodRes = await apiFetch("/products/"); if (prodRes.ok) { const d = await prodRes.json(); setProducts(Array.isArray(d) ? d : d.results || []); } } catch (e) { console.error(e); } finally { setLoading(false); } }; fetchData(); }, [token]); const handleLogout = async () => { await logout(); window.location.href = `/login?next=${encodeURIComponent(window.location.pathname)}`; }; const handleAddPasskey = async () => { if (!token) return; setPkBusy(true); setPkError(""); try { await registerPasskey(token, "My Passkey"); const userRes = await apiFetch("/auth/me/"); if (userRes.ok) setUser(await userRes.json()); } catch (e: any) { setPkError(e?.message || t("ثبت پاسکلی شکست خورد", "Passkey registration failed")); } finally { setPkBusy(false); } }; if (!mounted) return
; const current = SECTIONS.find((s) => s.key === activeTab); return (

{current ? t(current.labelFa, current.labelEn) : ""}

{current ? t(current.descFa, current.descEn) : ""}

{activeTab === "identity" && (
{/* Profile summary card */} {user?.avatar_url ? ( ) : ( )}
{user?.full_name || "-"}
{user?.email || ""}
{user?.status === "active" && ( {t("فعال", "Active")} )}
{typeof user?.mfa_enabled === "boolean" && ( {user.mfa_enabled ? t("احراز دومرحله‌ای فعال", "MFA enabled") : t("احراز دومرحله‌ای غیرفعال", "MFA disabled")} )} {user?.trust_state && ( {t("سطح اعتماد", "Trust")}: {user.trust_state} {typeof user.trust_score === "number" ? ` (${user.trust_score})` : ""} )}
{/* Personal info card */}

{t("اطلاعات شخصی", "Personal information")}

{editing ? (
) : ( )}
{loading ? ( ) : editing ? (
setForm({ ...form, full_name: v })} /> setForm({ ...form, given_name: v })} /> setForm({ ...form, family_name: v })} /> setForm({ ...form, username: v })} /> setForm({ ...form, province: v })} /> setForm({ ...form, city: v })} /> setForm({ ...form, gender: v })} select options={[ { value: "", label: t("انتخاب نشده", "Not set") }, { value: "male", label: t("مرد", "Male") }, { value: "female", label: t("زن", "Female") }, ]} /> setForm({ ...form, birth_date: v })} /> setForm({ ...form, skills: v })} full hint={t("با کاما جدا کنید", "Comma separated")} />
) : (
)}
)} {activeTab === "auth" && (
{pkError &&

{pkError}

}
{(sessions || []).slice(0, 5).map((s: any, i: number) => (
{s.device_name || t("دستگاه ناشناس", "Unknown device")}
{s.ip_address || "—"} ·{" "} {s.expires_at ? new Date(s.expires_at).toLocaleDateString(lang === "fa" ? "fa-IR" : "en-US") : "—"}
{s.status === "active" ? t("فعال", "Active") : (s.status || t("غیرفعال", "Inactive"))}
))} {(!sessions || sessions.length === 0) && !loading && (

{t("نشست فعالی یافت نشد", "No active sessions found")}

)}
)} {activeTab === "businesses" && ( {loading ? ( ) : orgs.length === 0 ? ( ) : (
{orgs.map((o: any, i: number) => (
{(o.name || "?").charAt(0)}
{o.name || o.slug}
{roleLabel(o.role, t)} {t("عضو", "Member")}
{o.joined_at ? new Date(o.joined_at).toLocaleDateString(lang === "fa" ? "fa-IR" : "en-US") : ""}
))}
)}
)} {activeTab === "bizManage" && (
{products.length === 0 ? (

{t("هنوز به محصولی دسترسی ندارید", "You don't have access to any product yet")}

) : ( products.map((p: any) => (
{(p.name || p.key || "?").charAt(0)}
{p.name || p.key}
{p.description || p.key}
)) )}
{t( "دسترسی به محصولات تابع سیاست دسترسی کلی است.", "Product access follows the global access policy." )}
)}
© {new Date().getFullYear()} UserManager · MyAccount Hamsoo
); } function Card({ children, className }: { children: React.ReactNode; className?: string }) { return (
{children}
); } function CardHead({ title, desc, action, classTop }: { title: string; desc?: string; action?: string; classTop?: string }) { return (

{title}

{desc &&

{desc}

}
{action && ( )}
); } function Field({ label, value, icon: Icon, full }: any) { return (
{label}
{Icon && } {value}
); } function EditField({ label, value, onChange, type, full, hint, select, options, }: any) { const base = "w-full rounded-xl border border-slate-200 bg-white px-3 py-2 text-sm text-slate-800 outline-none transition focus:border-[#6d5ef0]/50 focus:ring-2 focus:ring-[#6d5ef0]/15"; return (
{select ? ( ) : ( onChange(e.target.value)} /> )} {hint &&

{hint}

}
); } function Row({ icon: Icon, title, sub, verified, toggleOn, chev, button, onClick, busy }: any) { return (
{title}
{sub &&
{sub}
}
{verified !== undefined && ( {!verified && "! "} {verified ? "تأیید شده ✓" : "تأیید نشده"} )} {toggleOn !== undefined && ( )} {chev && } {button && ( )}
); } function ActionCard({ icon: Icon, title, desc, cta, primary }: any) { return (
{title}

{desc}

); } function Empty({ text, icon: Icon }: any) { return (

{text}

); } function Loading() { return (
{[...Array(4)].map((_, i) => (
))}
); } function genderLabel(g: string | null | undefined, t: (fa: string, en: string) => string) { if (!g) return "-"; if (g === "male") return t("مرد", "Male"); if (g === "female") return t("زن", "Female"); return g; } function roleLabel(r: string | undefined | null, t: (fa: string, en: string) => string) { const v = (r || "").toLowerCase(); if (v === "owner") return t("مالک", "Owner"); if (v === "admin") return t("مدیر", "Admin"); return t("عضو", "Member"); }