Initial commit: Port Nimara CRM (Layers 0-4)
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>
This commit is contained in:
72
src/components/shared/confirmation-dialog.tsx
Normal file
72
src/components/shared/confirmation-dialog.tsx
Normal file
@@ -0,0 +1,72 @@
|
||||
'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>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user