62 lines
1.9 KiB
TypeScript
62 lines
1.9 KiB
TypeScript
"use client";
|
|
|
|
import { AlertTriangle } from "lucide-react";
|
|
import { Button } from "@/components/ui/button";
|
|
import { cn } from "@/lib/utils";
|
|
|
|
type Props = {
|
|
open: boolean;
|
|
title: string;
|
|
message: string;
|
|
confirmLabel?: string;
|
|
variant?: "danger" | "default";
|
|
loading?: boolean;
|
|
onConfirm: () => void;
|
|
onCancel: () => void;
|
|
};
|
|
|
|
export function ConfirmDialog({
|
|
open,
|
|
title,
|
|
message,
|
|
confirmLabel = "Bestätigen",
|
|
variant = "danger",
|
|
loading = false,
|
|
onConfirm,
|
|
onCancel
|
|
}: Props) {
|
|
if (!open) return null;
|
|
|
|
return (
|
|
<div className="fixed inset-0 z-50 flex items-center justify-center p-4 animate-in fade-in duration-150">
|
|
<div className="absolute inset-0 bg-slate-950/50" onClick={onCancel} />
|
|
<div className={cn(
|
|
"relative rounded-2xl border bg-white p-6 shadow-2xl max-w-sm w-full animate-in zoom-in-95 fade-in duration-150",
|
|
variant === "danger" && "border-red-200"
|
|
)}>
|
|
<div className={cn(
|
|
"mb-4 inline-flex h-12 w-12 items-center justify-center rounded-full",
|
|
variant === "danger" ? "bg-red-100" : "bg-amber-100"
|
|
)}>
|
|
<AlertTriangle className={cn("h-6 w-6", variant === "danger" ? "text-red-600" : "text-amber-600")} />
|
|
</div>
|
|
<h3 className="text-base font-black text-slate-900 mb-1">{title}</h3>
|
|
<p className="text-sm text-slate-500 mb-6">{message}</p>
|
|
<div className="flex justify-end gap-2">
|
|
<Button type="button" variant="secondary" onClick={onCancel} disabled={loading}>
|
|
Abbrechen
|
|
</Button>
|
|
<Button
|
|
type="button"
|
|
variant={variant === "danger" ? "destructive" : "default"}
|
|
onClick={onConfirm}
|
|
disabled={loading}
|
|
>
|
|
{loading ? "Bitte warten..." : confirmLabel}
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|