"use client"; import { useIsMutating } from "@tanstack/react-query"; import React, { useEffect, useState } from "react"; import { createPortal } from "react-dom"; import { z } from "zod"; const ConfirmationModalPropsSchema = z.object({ isOpen: z.boolean(), title: z.string().min(1, "Title is required"), message: z.string().min(1, "Message is required"), confirmText: z.string().optional().default("Confirm"), cancelText: z.string().optional().default("Cancel"), onConfirm: z.function(), onCancel: z.function(), variant: z .enum(["default", "danger", "warning"]) .optional() .default("default"), size: z.enum(["sm", "md", "lg"]).optional().default("md"), }); export type ConfirmationModalProps = z.infer< typeof ConfirmationModalPropsSchema >; const ConfirmationModal: React.FC = (props) => { const isMutating = useIsMutating(); const validatedProps = ConfirmationModalPropsSchema.parse(props); const { isOpen, title, message, confirmText, cancelText, onConfirm, onCancel, variant, size, } = validatedProps; const [mounted, setMounted] = useState(false); useEffect(() => { setMounted(true); return () => setMounted(false); }, []); useEffect(() => { const handleEscape = (event: KeyboardEvent) => { if (event.key === "Escape" && isOpen) { onCancel(); } }; if (isOpen) { document?.addEventListener("keydown", handleEscape); document.body.style.overflow = "hidden"; } return () => { document.removeEventListener("keydown", handleEscape); document.body.style.overflow = "unset"; }; }, [isOpen, onCancel]); if (!mounted || !isOpen) return null; const variantStyles = { default: { confirmBtn: "bg-primary hover:bg-primary/90 focus:ring-primary", icon: "🔔", iconBg: "bg-blue-100", }, danger: { confirmBtn: "bg-red-light hover:bg-red-light/90 focus:ring-red-light", icon: "⚠️", iconBg: "bg-red-light/20", }, warning: { confirmBtn: "bg-yellow-dark hover:bg-yellow-dark/90 focus:ring-yellow-dark", icon: "⚠️", iconBg: "bg-yellow-light/20", }, }; const sizeStyles = { sm: "max-w-sm", md: "max-w-md", lg: "max-w-lg", }; const currentVariant = variantStyles[variant]; const currentSize = sizeStyles[size]; return createPortal(
{currentVariant.icon}

{message}

, document.body, ); }; export default ConfirmationModal;