"use client"; import { useState } from "react"; import { User2, LogOut, Download, Shield, Calendar, Pill, Activity, FileText, Printer, ClipboardList, Trash2, AlertTriangle, } from "lucide-react"; import { t, type SupportedLanguage } from "@/lib/i18n"; import type { User } from "@/lib/hooks/useAuth"; interface ProfileViewProps { user: User; onLogout: () => void; onExport: () => void; onOpenEHR: () => void; /** * Self-service account deletion. Wired to useAuth.deleteMe which * calls DELETE /api/auth/me with the user's current password + * email confirmation. On success the parent navigates away (the * session is already invalidated server-side and the auth state * cleared locally). On failure the API's error message is shown * inline — typically "Password is incorrect" or "Too many * deletion attempts. Try again later." (3/hour rate limit). */ onDeleteAccount: ( password: string, confirmEmail: string, ) => Promise<{ ok: boolean; error?: string; message?: string }>; medicationCount: number; appointmentCount: number; vitalCount: number; recordCount: number; language: SupportedLanguage; } export function ProfileView({ user, onLogout, onExport, onOpenEHR, onDeleteAccount, medicationCount, appointmentCount, vitalCount, recordCount, language, }: ProfileViewProps) { const handlePrint = () => { window.print(); }; return (

{user.displayName || user.email}

{user.email}

{user.emailVerified ? ( Email verified ) : ( Email not verified )}
{/* Health summary cards */}
{/* Actions */}
{/* Privacy note */}

Your data is yours

Health data is stored locally in your browser and synced to your private account on our server. No third parties. No ads. You can export or delete everything at any time.

{/* Logout */}

Member since{" "} {user.createdAt ? new Date(user.createdAt).toLocaleDateString() : "recently"}

{/* * Danger zone — self-service account deletion (GDPR Art. 17). * * Intentionally placed below the privacy note + logout, behind * an extra click, and rendered in muted danger styling rather * than a primary CTA. The submit step requires the user to * RE-TYPE both their email and current password — these are * also enforced server-side; the client copy is just to make * accidental clicks harder. * * Admins cannot self-delete from this UI: the backend returns * 403 for is_admin users, and we hide the trigger button up * front so admins don't get an "error" experience for a * deliberate restriction. */} {!user.isAdmin && ( )}
); } function DangerZone({ email, onDeleteAccount, }: { email: string; onDeleteAccount: ProfileViewProps["onDeleteAccount"]; }) { const [open, setOpen] = useState(false); const [confirmEmail, setConfirmEmail] = useState(""); const [password, setPassword] = useState(""); const [busy, setBusy] = useState(false); const [error, setError] = useState(""); const reset = () => { setConfirmEmail(""); setPassword(""); setError(""); }; const handleCancel = () => { setOpen(false); reset(); }; const handleSubmit = async () => { if (!confirmEmail.trim() || !password) { setError("Type your email and current password to continue."); return; } setBusy(true); setError(""); const res = await onDeleteAccount(password, confirmEmail.trim()); setBusy(false); if (!res.ok) { setError(res.error || "Deletion failed"); return; } // On success the auth hook has already wiped local state and the // parent (MedOSApp) navigates away — no further action needed here. }; return (

Danger zone

Permanently delete your account and all associated health data (medications, appointments, vitals, records, chat history, settings). This action cannot be undone.

{!open && ( )} {open && (

Are you sure? This is permanent.

{error && (

{error}

)}
)}
); } function StatCard({ icon: Icon, label, value, }: { icon: any; label: string; value: number; }) { return (
{value}
{label}
); }