"use client";
import { useState } from "react";
import {
Trash2,
AlertTriangle,
Download,
Shield,
Loader2,
Check,
X,
} from "lucide-react";
import { Button } from "@/components/ui/button";
import {
Dialog,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle,
DialogTrigger,
} from "@/components/ui/dialog";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Checkbox } from "@/components/ui/checkbox";
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
import { Separator } from "@/components/ui/separator";
import { cn } from "@/lib/utils";
const deletionReasons = [
{ value: "not-using", label: "I'm not using the service anymore" },
{ value: "too-expensive", label: "It's too expensive" },
{ value: "missing-features", label: "Missing features I need" },
{ value: "switching", label: "Switching to another service" },
{ value: "privacy", label: "Privacy concerns" },
{ value: "other", label: "Other reason" },
];
const CONFIRMATION_PHRASE = "delete my account";
export const title = "React Dialog Block Delete Account";
export default function DialogDeleteAccount() {
const [open, setOpen] = useState(false);
const [step, setStep] = useState(1);
const [reason, setReason] = useState("");
const [dataExported, setDataExported] = useState(false);
const [password, setPassword] = useState("");
const [confirmPhrase, setConfirmPhrase] = useState("");
const [understood, setUnderstood] = useState(false);
const [isDeleting, setIsDeleting] = useState(false);
const [isExporting, setIsExporting] = useState(false);
const isConfirmPhraseValid =
confirmPhrase.toLowerCase() === CONFIRMATION_PHRASE;
const handleExportData = async () => {
setIsExporting(true);
await new Promise((resolve) => setTimeout(resolve, 2000));
setIsExporting(false);
setDataExported(true);
};
const handleDelete = async () => {
if (!isConfirmPhraseValid || !understood || !password) return;
setIsDeleting(true);
await new Promise((resolve) => setTimeout(resolve, 2000));
setIsDeleting(false);
setOpen(false);
// In real app: redirect to goodbye page, clear session
};
const handleClose = () => {
setOpen(false);
setTimeout(() => {
setStep(1);
setReason("");
setDataExported(false);
setPassword("");
setConfirmPhrase("");
setUnderstood(false);
}, 200);
};
return (
<Dialog open={open} onOpenChange={setOpen}>
<div className="flex min-h-[350px] items-center justify-center">
<DialogTrigger asChild>
<Button variant="destructive">
<Trash2 className="mr-2 h-4 w-4" />
Delete Account
</Button>
</DialogTrigger>
</div>
<DialogContent className="sm:max-w-md">
<DialogHeader>
<DialogTitle className="flex items-center gap-2 text-destructive">
<Trash2 className="h-5 w-5" />
Delete Account
</DialogTitle>
<DialogDescription>
{step === 1 && "This action is permanent and cannot be undone."}
{step === 2 && "Please verify your identity to continue."}
{step === 3 && "Final confirmation required."}
</DialogDescription>
</DialogHeader>
<div className="py-4">
{/* Step 1: Warning and Data Export */}
{step === 1 && (
<div className="space-y-4">
<Alert variant="destructive">
<AlertTriangle className="h-4 w-4" />
<AlertTitle>Warning</AlertTitle>
<AlertDescription>
Deleting your account will permanently remove all your data,
including projects, files, and settings.
</AlertDescription>
</Alert>
{/* Data Export */}
<div className="rounded-lg border p-4 space-y-3">
<div className="flex items-center gap-2">
<Download className="h-4 w-4" />
<span className="font-medium">Export Your Data</span>
</div>
<p className="text-sm text-muted-foreground">
Before deleting, you can download a copy of all your data.
</p>
<Button
variant="outline"
className="w-full"
onClick={handleExportData}
disabled={isExporting || dataExported}
>
{isExporting ? (
<>
<Loader2 className="mr-2 h-4 w-4 animate-spin" />
Preparing export...
</>
) : dataExported ? (
<>
<Check className="mr-2 h-4 w-4" />
Data exported
</>
) : (
<>
<Download className="mr-2 h-4 w-4" />
Export all data
</>
)}
</Button>
</div>
{/* Reason Selection */}
<div className="space-y-2">
<Label>Why are you leaving? (optional)</Label>
<Select value={reason} onValueChange={setReason}>
<SelectTrigger>
<SelectValue placeholder="Select a reason" />
</SelectTrigger>
<SelectContent>
{deletionReasons.map((r) => (
<SelectItem key={r.value} value={r.value}>
{r.label}
</SelectItem>
))}
</SelectContent>
</Select>
</div>
</div>
)}
{/* Step 2: Password Verification */}
{step === 2 && (
<div className="space-y-4">
<div className="flex items-center gap-2 text-sm text-muted-foreground">
<Shield className="h-4 w-4" />
<span>For your security, please verify your password.</span>
</div>
<div className="space-y-2">
<Label htmlFor="delete-password">Password</Label>
<Input
id="delete-password"
type="password"
placeholder="Enter your password"
value={password}
onChange={(e) => setPassword(e.target.value)}
/>
</div>
<p className="text-xs text-muted-foreground">
This helps us verify that you're the account owner.
</p>
</div>
)}
{/* Step 3: Final Confirmation */}
{step === 3 && (
<div className="space-y-4">
<Alert variant="destructive">
<AlertTriangle className="h-4 w-4" />
<AlertDescription>
This is your last chance to cancel. Once deleted, your account
and all associated data will be permanently removed.
</AlertDescription>
</Alert>
<div className="space-y-2">
<Label htmlFor="confirm-phrase">
Type{" "}
<span className="font-mono font-bold">
{CONFIRMATION_PHRASE}
</span>{" "}
to confirm
</Label>
<Input
id="confirm-phrase"
placeholder={CONFIRMATION_PHRASE}
value={confirmPhrase}
onChange={(e) => setConfirmPhrase(e.target.value)}
className={cn(
isConfirmPhraseValid && "border-destructive focus-visible:ring-destructive"
)}
/>
</div>
<div className="flex items-start gap-2 rounded-lg border border-destructive/50 p-3">
<Checkbox
id="understood"
checked={understood}
onCheckedChange={(checked) => setUnderstood(checked === true)}
className="mt-0.5"
/>
<Label
htmlFor="understood"
className="text-sm font-normal cursor-pointer"
>
I understand that this action is irreversible and all my data
will be permanently deleted.
</Label>
</div>
</div>
)}
{/* Progress Indicator */}
<div className="flex justify-center gap-1.5 mt-6">
{[1, 2, 3].map((s) => (
<div
key={s}
className={cn(
"h-2 w-2 rounded-full transition-colors",
s === step
? "bg-destructive"
: s < step
? "bg-destructive/50"
: "bg-muted"
)}
/>
))}
</div>
</div>
<DialogFooter className="flex-col sm:flex-row gap-2">
{step > 1 && (
<Button
variant="ghost"
onClick={() => setStep(step - 1)}
disabled={isDeleting}
className="sm:mr-auto"
>
Back
</Button>
)}
<Button variant="outline" onClick={handleClose} disabled={isDeleting}>
Cancel
</Button>
{step < 3 ? (
<Button
variant="destructive"
onClick={() => setStep(step + 1)}
disabled={step === 2 && !password}
>
Continue
</Button>
) : (
<Button
variant="destructive"
onClick={handleDelete}
disabled={!isConfirmPhraseValid || !understood || isDeleting}
>
{isDeleting ? (
<>
<Loader2 className="mr-2 h-4 w-4 animate-spin" />
Deleting...
</>
) : (
<>
<Trash2 className="mr-2 h-4 w-4" />
Delete Forever
</>
)}
</Button>
)}
</DialogFooter>
</DialogContent>
</Dialog>
);
}