TypeScript 97.5%
SQL 1.4%
Python 0.8%
1"use client";2import * as React from "react";3import { Trash2 } from "lucide-react";4import { authClient } from "@/lib/auth-client";5import { PasswordInput } from "@/components/auth/password-input";6import { Button } from "@/components/ui/button";7import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger } from "@/components/ui/dialog";8import { Field, Label } from "@/components/ui/label";9import { Alert } from "@/components/ui/alert";1011export function DeleteAccountDialog({ email }: { email: string }) {12 const [open, setOpen] = React.useState(false);13 const [password, setPassword] = React.useState("");14 const [error, setError] = React.useState<string | null>(null);15 const [requested, setRequested] = React.useState(false);16 const [loading, setLoading] = React.useState(false);1718 async function submit(e: React.FormEvent) {19 e.preventDefault();20 setError(null);21 setLoading(true);22 const { error } = await authClient.deleteUser({ password, callbackURL: "/goodbye" });23 setLoading(false);24 if (error) {25 setError(error.status === 400 || error.status === 401 ? "Incorrect password." : error.message ?? "Could not start account deletion. Try again.");26 return;27 }28 setRequested(true);29 }3031 return (32 <Dialog33 open={open}34 onOpenChange={(o) => {35 setOpen(o);36 if (!o) {37 setPassword("");38 setError(null);39 }40 }}41 >42 <DialogTrigger asChild>43 <Button variant="danger" size="sm">44 <Trash2 /> Delete account45 </Button>46 </DialogTrigger>47 <DialogContent size="sm">48 <DialogHeader>49 <DialogTitle>Delete your account</DialogTitle>50 <DialogDescription>51 This removes your login, organization, projects, API keys and request history. We send a confirmation link to <strong className="text-fg">{email}</strong>; nothing is deleted until you click it. After confirmation, data is purged 7 days later — email support@fetcha.co within that window if you change your mind.52 </DialogDescription>53 </DialogHeader>54 {requested ? (55 <>56 <Alert variant="success" title="Check your inbox">57 We emailed a confirmation link to {email}. Your account stays active until you confirm.58 </Alert>59 <DialogFooter>60 <Button onClick={() => setOpen(false)}>Close</Button>61 </DialogFooter>62 </>63 ) : (64 <form onSubmit={submit} className="grid gap-4" noValidate>65 {error ? <Alert variant="danger">{error}</Alert> : null}66 <Field>67 <Label htmlFor="delete-password">Confirm your password</Label>68 <PasswordInput id="delete-password" autoComplete="current-password" value={password} onChange={(e) => setPassword(e.target.value)} required autoFocus />69 </Field>70 <DialogFooter>71 <Button type="button" variant="outline" onClick={() => setOpen(false)} disabled={loading}>72 Cancel73 </Button>74 <Button type="submit" variant="danger" loading={loading} disabled={!password}>75 Send confirmation email76 </Button>77 </DialogFooter>78 </form>79 )}80 </DialogContent>81 </Dialog>82 );83}84