{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "auth-account-delete",
  "title": "Auth Account Delete",
  "description": "Delete account with password confirmation and data loss acknowledgment.",
  "registryDependencies": [
    "alert-dialog",
    "button",
    "card",
    "checkbox",
    "field",
    "input-group",
    "label"
  ],
  "files": [
    {
      "path": "registry/new-york/blocks/auth/auth-account-delete.tsx",
      "content": "\"use client\";\n\nimport { AlertTriangle, Loader2, Trash2 } from \"lucide-react\";\nimport { useCallback, useState } from \"react\";\nimport { cn } from \"@/lib/utils\";\nimport {\n  AlertDialog,\n  AlertDialogAction,\n  AlertDialogCancel,\n  AlertDialogContent,\n  AlertDialogDescription,\n  AlertDialogFooter,\n  AlertDialogHeader,\n  AlertDialogTitle,\n  AlertDialogTrigger,\n} from \"@/registry/new-york/ui/alert-dialog\";\nimport { Button } from \"@/registry/new-york/ui/button\";\nimport {\n  Card,\n  CardContent,\n  CardDescription,\n  CardHeader,\n  CardTitle,\n} from \"@/registry/new-york/ui/card\";\nimport { Checkbox } from \"@/registry/new-york/ui/checkbox\";\nimport {\n  Field,\n  FieldContent,\n  FieldError,\n  FieldLabel,\n} from \"@/registry/new-york/ui/field\";\nimport {\n  InputGroup,\n  InputGroupInput,\n} from \"@/registry/new-york/ui/input-group\";\nimport { Label } from \"../../ui/label\";\n\nexport interface AuthAccountDeleteProps {\n  onDelete?: (data: { confirmText: string }) => void;\n  className?: string;\n  isLoading?: boolean;\n  errors?: {\n    confirmText?: string;\n    general?: string;\n  };\n  confirmText?: string;\n  dataSummary?: {\n    projects?: number;\n    files?: number;\n    storage?: string;\n  };\n}\n\ninterface WarningBannerProps {\n  className?: string;\n}\n\nfunction WarningBanner({ className }: WarningBannerProps) {\n  return (\n    <div\n      className={cn(\n        \"flex items-start gap-3 rounded-lg border border-destructive/50 bg-destructive/5 p-4\",\n        className\n      )}\n    >\n      <AlertTriangle\n        aria-hidden=\"true\"\n        className=\"size-5 shrink-0 text-destructive\"\n      />\n      <div className=\"flex flex-1 flex-col gap-2\">\n        <p className=\"font-medium text-destructive text-sm\">\n          This action cannot be undone\n        </p>\n        <p className=\"text-muted-foreground text-xs\">\n          This will permanently delete your account and remove all of your data\n          from our servers. This action is irreversible.\n        </p>\n      </div>\n    </div>\n  );\n}\n\ninterface DataSummaryProps {\n  dataSummary: {\n    projects?: number;\n    files?: number;\n    storage?: string;\n  };\n}\n\nfunction DataSummary({ dataSummary }: DataSummaryProps) {\n  return (\n    <div className=\"flex flex-col gap-2 rounded-lg border bg-muted/50 p-4\">\n      <h3 className=\"font-medium text-sm\">Data that will be deleted:</h3>\n      <ul className=\"flex flex-col gap-1 text-muted-foreground text-xs\">\n        {dataSummary.projects !== undefined && (\n          <li>\n            •{\" \"}\n            <span className=\"tabular-nums\">\n              {dataSummary.projects} project\n              {dataSummary.projects !== 1 ? \"s\" : \"\"}\n            </span>\n          </li>\n        )}\n        {dataSummary.files !== undefined && (\n          <li>\n            •{\" \"}\n            <span className=\"tabular-nums\">\n              {dataSummary.files} file{dataSummary.files !== 1 ? \"s\" : \"\"}\n            </span>\n          </li>\n        )}\n        {dataSummary.storage && <li>• {dataSummary.storage} of storage</li>}\n        <li>• All account settings and preferences</li>\n        <li>• All personal information</li>\n      </ul>\n    </div>\n  );\n}\n\ninterface ConfirmTextFieldProps {\n  id: string;\n  value: string;\n  error?: string;\n  confirmText: string;\n  onChange: (value: string) => void;\n}\n\nfunction ConfirmTextField({\n  id,\n  value,\n  error,\n  confirmText,\n  onChange,\n}: ConfirmTextFieldProps) {\n  return (\n    <Field data-invalid={!!error}>\n      <FieldLabel htmlFor={id}>\n        Type <span className=\"font-mono\">{confirmText}</span> to confirm\n        <span aria-label=\"required\" className=\"text-destructive\">\n          {\" \"}\n          *\n        </span>\n      </FieldLabel>\n      <FieldContent>\n        <InputGroup aria-invalid={!!error}>\n          <InputGroupInput\n            aria-describedby={error ? `${id}-error` : undefined}\n            aria-invalid={!!error}\n            id={id}\n            name=\"confirmText\"\n            onChange={(e) => onChange(e.target.value)}\n            placeholder={`${confirmText}…`}\n            required\n            style={{ fontSize: \"16px\" }}\n            type=\"text\"\n            value={value}\n          />\n        </InputGroup>\n        {error && (\n          <FieldError id={`${id}-error`} role=\"alert\">\n            {error}\n          </FieldError>\n        )}\n      </FieldContent>\n    </Field>\n  );\n}\n\ninterface AcknowledgmentCheckboxProps {\n  id: string;\n  checked: boolean;\n  label: string;\n  onCheckedChange: (checked: boolean) => void;\n}\n\nfunction AcknowledgmentCheckbox({\n  id,\n  checked,\n  label,\n  onCheckedChange,\n}: AcknowledgmentCheckboxProps) {\n  return (\n    <div className=\"flex items-center gap-2\">\n      <Checkbox\n        checked={checked}\n        id={id}\n        onCheckedChange={(checked) => onCheckedChange(checked === true)}\n      />\n      <Label\n        className=\"cursor-pointer text-sm leading-relaxed peer-disabled:cursor-not-allowed peer-disabled:opacity-70\"\n        htmlFor={id}\n      >\n        {label}\n      </Label>\n    </div>\n  );\n}\n\ninterface DeleteConfirmationDialogProps {\n  onOpenChange: (open: boolean) => void;\n  typedConfirm: string;\n  acknowledgeDataLoss: boolean;\n  acknowledgeIrreversible: boolean;\n  confirmText: string;\n  isLoading: boolean;\n  isFormValid: boolean;\n  confirmTextError?: string;\n  onTypedConfirmChange: (value: string) => void;\n  onAcknowledgeDataLossChange: (checked: boolean) => void;\n  onAcknowledgeIrreversibleChange: (checked: boolean) => void;\n  onDelete: () => void;\n  onReset: () => void;\n}\n\nfunction DeleteConfirmationDialog({\n  onOpenChange,\n  typedConfirm,\n  acknowledgeDataLoss,\n  acknowledgeIrreversible,\n  confirmText,\n  isLoading,\n  isFormValid,\n  confirmTextError,\n  onTypedConfirmChange,\n  onAcknowledgeDataLossChange,\n  onAcknowledgeIrreversibleChange,\n  onDelete,\n  onReset,\n}: DeleteConfirmationDialogProps) {\n  const handleKeyDown = useCallback(\n    (e: React.KeyboardEvent) => {\n      if (e.key === \"Enter\" && isFormValid && !isLoading) {\n        e.preventDefault();\n        onDelete();\n      }\n      if (e.key === \"Escape\" && !isLoading) {\n        onOpenChange(false);\n        onReset();\n      }\n    },\n    [isFormValid, isLoading, onDelete, onOpenChange, onReset]\n  );\n\n  const completedSteps = [\n    typedConfirm === confirmText,\n    acknowledgeDataLoss,\n    acknowledgeIrreversible,\n  ].filter(Boolean).length;\n\n  return (\n    <AlertDialogContent\n      className=\"max-w-md\"\n      onKeyDown={handleKeyDown}\n      style={{ overscrollBehavior: \"contain\" }}\n    >\n      <AlertDialogHeader>\n        <AlertDialogTitle className=\"flex items-center gap-2\">\n          <AlertTriangle\n            aria-hidden=\"true\"\n            className=\"size-5 text-destructive\"\n          />\n          Confirm account deletion\n        </AlertDialogTitle>\n        <AlertDialogDescription>\n          This action is permanent and cannot be undone. Please confirm by\n          typing <span className=\"font-mono font-semibold\">{confirmText}</span>{\" \"}\n          below.\n        </AlertDialogDescription>\n      </AlertDialogHeader>\n\n      <div className=\"flex flex-col gap-4 py-4\">\n        <ConfirmTextField\n          confirmText={confirmText}\n          error={confirmTextError}\n          id=\"delete-account-confirm\"\n          onChange={onTypedConfirmChange}\n          value={typedConfirm}\n        />\n\n        <div className=\"flex flex-col gap-3\">\n          <AcknowledgmentCheckbox\n            checked={acknowledgeDataLoss}\n            id=\"acknowledge-data-loss\"\n            label=\"I understand that all my data will be permanently deleted and cannot be recovered\"\n            onCheckedChange={onAcknowledgeDataLossChange}\n          />\n\n          <AcknowledgmentCheckbox\n            checked={acknowledgeIrreversible}\n            id=\"acknowledge-irreversible\"\n            label=\"I understand this action is irreversible\"\n            onCheckedChange={onAcknowledgeIrreversibleChange}\n          />\n        </div>\n      </div>\n\n      <AlertDialogFooter>\n        <AlertDialogCancel\n          className=\"min-h-[32px] min-w-[32px] touch-manipulation\"\n          onClick={onReset}\n        >\n          Cancel\n        </AlertDialogCancel>\n        <AlertDialogAction\n          aria-busy={isLoading}\n          className=\"min-h-[32px] min-w-[32px] touch-manipulation bg-destructive text-destructive-foreground hover:bg-destructive/90\"\n          data-loading={isLoading}\n          disabled={!isFormValid || isLoading}\n          onClick={onDelete}\n        >\n          {isLoading ? (\n            <>\n              <Loader2 aria-hidden=\"true\" className=\"size-4 animate-spin\" />\n              Deleting…\n            </>\n          ) : (\n            <>\n              <Trash2 aria-hidden=\"true\" className=\"size-4\" />\n              Delete account permanently\n            </>\n          )}\n        </AlertDialogAction>\n      </AlertDialogFooter>\n    </AlertDialogContent>\n  );\n}\n\nexport default function AuthAccountDelete({\n  onDelete,\n  className,\n  isLoading = false,\n  errors,\n  confirmText = \"DELETE\",\n  dataSummary,\n}: AuthAccountDeleteProps) {\n  const [typedConfirm, setTypedConfirm] = useState(\"\");\n  const [acknowledgeDataLoss, setAcknowledgeDataLoss] = useState(false);\n  const [acknowledgeIrreversible, setAcknowledgeIrreversible] = useState(false);\n  const [isDialogOpen, setIsDialogOpen] = useState(false);\n\n  const isFormValid =\n    typedConfirm === confirmText &&\n    acknowledgeDataLoss &&\n    acknowledgeIrreversible;\n\n  const handleDelete = useCallback(() => {\n    if (!isFormValid) {\n      return;\n    }\n    onDelete?.({\n      confirmText: typedConfirm,\n    });\n  }, [isFormValid, typedConfirm, onDelete]);\n\n  const handleReset = useCallback(() => {\n    setTypedConfirm(\"\");\n    setAcknowledgeDataLoss(false);\n    setAcknowledgeIrreversible(false);\n  }, []);\n\n  const handleDialogOpenChange = useCallback(\n    (open: boolean) => {\n      setIsDialogOpen(open);\n      if (!open) {\n        handleReset();\n      }\n    },\n    [handleReset]\n  );\n\n  const confirmTextError = errors?.confirmText;\n  const generalError = errors?.general;\n\n  return (\n    <Card\n      className={cn(\n        \"w-full max-w-sm border-destructive/50 shadow-xs\",\n        className\n      )}\n    >\n      <CardHeader>\n        <CardTitle className=\"flex items-center gap-2 text-destructive\">\n          Delete account\n        </CardTitle>\n        <CardDescription>\n          Permanently delete your account and all associated data\n        </CardDescription>\n      </CardHeader>\n      <CardContent>\n        <div className=\"flex flex-col gap-6\">\n          {generalError && (\n            <div\n              aria-live=\"polite\"\n              className=\"rounded-lg border border-destructive/50 bg-destructive/10 p-3 text-destructive text-sm\"\n              role=\"alert\"\n            >\n              {generalError}\n            </div>\n          )}\n\n          <WarningBanner />\n\n          {dataSummary && <DataSummary dataSummary={dataSummary} />}\n\n          <AlertDialog\n            onOpenChange={handleDialogOpenChange}\n            open={isDialogOpen}\n          >\n            <AlertDialogTrigger asChild>\n              <Button\n                className=\"min-h-[32px] w-full touch-manipulation\"\n                type=\"button\"\n                variant=\"destructive\"\n              >\n                <Trash2 aria-hidden=\"true\" className=\"size-4\" />\n                Delete my account\n              </Button>\n            </AlertDialogTrigger>\n            <DeleteConfirmationDialog\n              acknowledgeDataLoss={acknowledgeDataLoss}\n              acknowledgeIrreversible={acknowledgeIrreversible}\n              confirmText={confirmText}\n              confirmTextError={confirmTextError}\n              isFormValid={isFormValid}\n              isLoading={isLoading}\n              onAcknowledgeDataLossChange={setAcknowledgeDataLoss}\n              onAcknowledgeIrreversibleChange={setAcknowledgeIrreversible}\n              onDelete={handleDelete}\n              onOpenChange={handleDialogOpenChange}\n              onReset={handleReset}\n              onTypedConfirmChange={setTypedConfirm}\n              typedConfirm={typedConfirm}\n            />\n          </AlertDialog>\n        </div>\n      </CardContent>\n    </Card>\n  );\n}\n",
      "type": "registry:ui"
    }
  ],
  "categories": [
    "block",
    "auth"
  ],
  "type": "registry:ui"
}