Files
membership-fe/src/components/ConfirmationDialog.js

112 lines
3.8 KiB
JavaScript

import React from 'react';
import {
AlertDialog,
AlertDialogAction,
AlertDialogCancel,
AlertDialogContent,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogTitle,
} from './ui/alert-dialog';
import { AlertTriangle, Info, CheckCircle } from 'lucide-react';
/**
* Reusable confirmation dialog component following the design system
*
* @param {boolean} open - Controls dialog visibility
* @param {function} onOpenChange - Callback when dialog open state changes
* @param {function} onConfirm - Callback when user confirms
* @param {string} title - Dialog title
* @param {string} description - Dialog description/message
* @param {string} confirmText - Confirm button text (default: "Confirm")
* @param {string} cancelText - Cancel button text (default: "Cancel")
* @param {string} variant - Visual variant: 'warning', 'danger', 'info', 'success' (default: 'warning')
* @param {boolean} loading - Show loading state on confirm button
*/
const ConfirmationDialog = ({
open,
onOpenChange,
onConfirm,
title,
description,
confirmText = 'Confirm',
cancelText = 'Cancel',
variant = 'warning',
loading = false,
}) => {
const variants = {
warning: {
icon: AlertTriangle,
iconColor: 'text-[var(--orange-light)]',
confirmButtonClass: 'bg-[var(--orange-light)] text-white hover:bg-[var(--orange-sand)] rounded-full px-6',
},
danger: {
icon: AlertTriangle,
iconColor: 'text-red-600',
confirmButtonClass: 'bg-red-600 text-white hover:bg-red-700 rounded-full px-6',
},
info: {
icon: Info,
iconColor: 'text-brand-purple ',
confirmButtonClass: 'bg-brand-purple text-white hover:bg-[var(--purple-plum)] rounded-full px-6',
},
success: {
icon: CheckCircle,
iconColor: 'text-[var(--green-light)]',
confirmButtonClass: 'bg-[var(--green-light)] text-white hover:bg-[var(--green-pastel)] rounded-full px-6',
},
};
const config = variants[variant] || variants.warning;
const Icon = config.icon;
return (
<AlertDialog open={open} onOpenChange={onOpenChange}>
<AlertDialogContent className="bg-background rounded-2xl border border-[var(--neutral-800)] p-0 overflow-hidden max-w-md">
<AlertDialogHeader className="p-6 pb-4">
<div className="flex items-start gap-4">
<div className={`p-3 rounded-full bg-[var(--lavender-500)] ${config.iconColor}`}>
<Icon className="h-6 w-6" />
</div>
<div className="flex-1">
<AlertDialogTitle
className="text-xl font-semibold text-[var(--purple-ink)] mb-2"
style={{ fontFamily: "'Inter', sans-serif" }}
>
{title}
</AlertDialogTitle>
<AlertDialogDescription
className="text-brand-purple text-sm leading-relaxed"
style={{ fontFamily: "'Nunito Sans', sans-serif" }}
>
{description}
</AlertDialogDescription>
</div>
</div>
</AlertDialogHeader>
<AlertDialogFooter className="p-6 pt-4 bg-[var(--lavender-500)] flex-row gap-3 justify-end">
<AlertDialogCancel
className="border-2 border-[var(--neutral-800)] text-brand-purple hover:bg-background rounded-full px-6"
disabled={loading}
>
{cancelText}
</AlertDialogCancel>
<AlertDialogAction
onClick={(e) => {
e.preventDefault();
onConfirm();
}}
className={config.confirmButtonClass}
disabled={loading}
>
{loading ? 'Processing...' : confirmText}
</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
);
};
export default ConfirmationDialog;