diff --git a/components/settings/SettingsDeleteAccountCard.tsx b/components/settings/SettingsDeleteAccountCard.tsx new file mode 100644 index 0000000..7eed30a --- /dev/null +++ b/components/settings/SettingsDeleteAccountCard.tsx @@ -0,0 +1,137 @@ +/** + * @file components/settings/SettingsDeleteAccountCard.tsx + * @description Card component for handling account deletion with dynamic button inline confirmation and guest protection. + */ + +"use client"; + +import { useState } from "react"; +import { useUser } from "@/lib/context/UserContext"; +import { Trash2, AlertTriangle, ChevronDown } from "lucide-react"; +import { ActionButton } from "@/components/ui/ActionButton"; +import { signOut } from "next-auth/react"; + +interface SettingsDeleteAccountCardProps { + defaultOpen?: boolean; +} + +export function SettingsDeleteAccountCard({ + defaultOpen = false, +}: SettingsDeleteAccountCardProps) { + const [isOpen, setIsOpen] = useState(defaultOpen); + const [isDeleting, setIsDeleting] = useState(false); + const [isConfirmingDelete, setIsConfirmingDelete] = useState(false); + const [error, setError] = useState(null); + + const { currentUser } = useUser(); + + if (!currentUser) return null; + + const guestEmail = process.env.NEXT_PUBLIC_GUEST_EMAIL; + const isGuest = Boolean( + guestEmail && currentUser.email?.toLowerCase() === guestEmail.toLowerCase(), + ); + + /** Handles the two-step delete trigger and API request. */ + const handleDelete = async () => { + if (!isConfirmingDelete) { + setIsConfirmingDelete(true); + return; + } + + if (isDeleting) return; + + try { + setIsDeleting(true); + setError(null); + + const res = await fetch("/api/users/profile", { + method: "DELETE", + }); + + if (!res.ok) { + const data = await res.json(); + throw new Error(data.error || "Failed to delete account"); + } + + await signOut({ callbackUrl: "/login" }); + } catch (err) { + setError(err instanceof Error ? err.message : "An error occurred"); + setIsDeleting(false); + setIsConfirmingDelete(false); + } + }; + + return ( +
+ {/* Header / Toggle Button */} + + + {/* Collapsible Body */} + {isOpen && ( +
+ {isGuest ? ( +
+ + Guest accounts cannot be deleted. +
+ ) : ( +
+

+ Once you delete your account, there is no going back. Please be + certain. +

+ + {error &&

{error}

} + +
+ + {isConfirmingDelete ? "Sure?" : "Delete Account"} + + + {isConfirmingDelete && ( + setIsConfirmingDelete(false)} + disabled={isDeleting} + > + Cancel + + )} +
+
+ )} +
+ )} +
+ ); +} diff --git a/components/settings/SettingsView.tsx b/components/settings/SettingsView.tsx index 56e9a30..035b9bb 100644 --- a/components/settings/SettingsView.tsx +++ b/components/settings/SettingsView.tsx @@ -7,6 +7,7 @@ import { useUser } from "@/lib/context/UserContext"; import { SettingsProfileCard } from "./SettingsProfileCard"; +import { SettingsDeleteAccountCard } from "./SettingsDeleteAccountCard"; /** Renders the settings view layout for managing user profile settings. */ export function SettingsView() { @@ -25,8 +26,9 @@ export function SettingsView() { if (!currentUser) return null; return ( -
+
+
); }