diff --git a/src/app/components/delete/deleteConfirmationModal.tsx b/src/app/components/delete/deleteConfirmationModal.tsx index 09155e1..12bc257 100644 --- a/src/app/components/delete/deleteConfirmationModal.tsx +++ b/src/app/components/delete/deleteConfirmationModal.tsx @@ -1,4 +1,5 @@ import React from "react"; +import ConfirmActionModal from "../modals/ConfirmActionModal"; type DeleteConfirmationModalProps = { open: boolean; @@ -23,44 +24,18 @@ export default function DeleteConfirmationModal({ onCancel, children, }: DeleteConfirmationModalProps) { - if (!open) return null; return ( -
-
-
-
-
-
-
- - - -
-

{title}

-
-

{description}

- {children} -
- - -
-
-
-
-
+ ); } diff --git a/src/app/components/modals/ConfirmActionModal.tsx b/src/app/components/modals/ConfirmActionModal.tsx new file mode 100644 index 0000000..3523775 --- /dev/null +++ b/src/app/components/modals/ConfirmActionModal.tsx @@ -0,0 +1,132 @@ +'use client' + +import React from 'react' +import { Fragment } from 'react' +import { Dialog, Transition } from '@headlessui/react' +import { ExclamationTriangleIcon } from '@heroicons/react/24/outline' + +type ConfirmIntent = 'default' | 'danger' + +interface ConfirmActionModalProps { + open: boolean + title: string + description: string + confirmText?: string + cancelText?: string + pending?: boolean + intent?: ConfirmIntent + onClose: () => void + onConfirm: () => Promise | void + extraContent?: React.ReactNode +} + +export default function ConfirmActionModal({ + open, + title, + description, + confirmText = 'Confirm', + cancelText = 'Cancel', + pending = false, + intent = 'default', + onClose, + onConfirm, + extraContent, +}: ConfirmActionModalProps) { + const [displayData, setDisplayData] = React.useState({ + title, + description, + confirmText, + cancelText, + intent, + extraContent: extraContent ?? null, + }) + + React.useEffect(() => { + if (!open) return + setDisplayData({ + title, + description, + confirmText, + cancelText, + intent, + extraContent: extraContent ?? null, + }) + }, [open, title, description, confirmText, cancelText, intent, extraContent]) + + const activeIntent = displayData.intent + + const confirmButtonClass = + activeIntent === 'danger' + ? 'inline-flex items-center rounded-md border border-red-300 bg-red-600 px-3 py-2 text-sm text-white hover:bg-red-700 disabled:opacity-60' + : 'inline-flex items-center rounded-md border border-[#8D6B1D] bg-[#8D6B1D] px-3 py-2 text-sm text-white hover:bg-[#7A5E1A] disabled:opacity-60' + + const iconColorClass = activeIntent === 'danger' ? 'text-red-600' : 'text-amber-600' + + return ( + + {} : onClose} className="relative z-[1100]"> + +
+ + +
+
+ + +
+
+ +
+
+ + {displayData.title} + +
+

{displayData.description}

+ {displayData.extraContent ?
{displayData.extraContent}
: null} +
+
+
+ +
+ + +
+
+
+
+
+
+
+ ) +}