Full CRM rebuild with Next.js 15, TypeScript, Tailwind, Drizzle ORM, PostgreSQL, Redis, BullMQ, MinIO, and Socket.io. Includes 461 source files covering clients, berths, interests/pipeline, documents/EOI, expenses/invoices, email, notifications, dashboard, admin, and client portal. CI/CD via Gitea Actions with Docker builds. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
73 lines
2.1 KiB
TypeScript
73 lines
2.1 KiB
TypeScript
'use client';
|
|
|
|
import { type ReactNode } from 'react';
|
|
import {
|
|
AlertDialog,
|
|
AlertDialogAction,
|
|
AlertDialogCancel,
|
|
AlertDialogContent,
|
|
AlertDialogDescription,
|
|
AlertDialogFooter,
|
|
AlertDialogHeader,
|
|
AlertDialogTitle,
|
|
AlertDialogTrigger,
|
|
} from '@/components/ui/alert-dialog';
|
|
import { cn } from '@/lib/utils';
|
|
|
|
interface ConfirmationDialogProps {
|
|
/** The element that triggers the dialog to open */
|
|
trigger: ReactNode;
|
|
title: string;
|
|
description: string;
|
|
/** Label for the confirm action button (default: "Delete") */
|
|
confirmLabel?: string;
|
|
/** Label for the cancel button (default: "Cancel") */
|
|
cancelLabel?: string;
|
|
/** Whether the confirm action is destructive — renders in red (default: true) */
|
|
destructive?: boolean;
|
|
/** Called when the user confirms the action */
|
|
onConfirm: () => void | Promise<void>;
|
|
/** Whether the confirm button is in a loading state */
|
|
loading?: boolean;
|
|
}
|
|
|
|
/**
|
|
* Reusable confirmation dialog for destructive actions (delete, archive, etc.).
|
|
* Wraps shadcn AlertDialog so the trigger can be any element.
|
|
*/
|
|
export function ConfirmationDialog({
|
|
trigger,
|
|
title,
|
|
description,
|
|
confirmLabel = 'Delete',
|
|
cancelLabel = 'Cancel',
|
|
destructive = true,
|
|
onConfirm,
|
|
loading = false,
|
|
}: ConfirmationDialogProps) {
|
|
return (
|
|
<AlertDialog>
|
|
<AlertDialogTrigger asChild>{trigger}</AlertDialogTrigger>
|
|
<AlertDialogContent>
|
|
<AlertDialogHeader>
|
|
<AlertDialogTitle>{title}</AlertDialogTitle>
|
|
<AlertDialogDescription>{description}</AlertDialogDescription>
|
|
</AlertDialogHeader>
|
|
<AlertDialogFooter>
|
|
<AlertDialogCancel disabled={loading}>{cancelLabel}</AlertDialogCancel>
|
|
<AlertDialogAction
|
|
onClick={onConfirm}
|
|
disabled={loading}
|
|
className={cn(
|
|
destructive &&
|
|
'bg-destructive text-destructive-foreground hover:bg-destructive/90 focus:ring-destructive',
|
|
)}
|
|
>
|
|
{loading ? 'Please wait...' : confirmLabel}
|
|
</AlertDialogAction>
|
|
</AlertDialogFooter>
|
|
</AlertDialogContent>
|
|
</AlertDialog>
|
|
);
|
|
}
|