diff --git a/ui/src/components/ConfirmDialog.tsx b/ui/src/components/ConfirmDialog.tsx new file mode 100644 index 0000000..57391e2 --- /dev/null +++ b/ui/src/components/ConfirmDialog.tsx @@ -0,0 +1,106 @@ +import { ExclamationTriangleIcon, CheckCircleIcon, InformationCircleIcon } from "@heroicons/react/24/outline"; +import { cx } from "@/cva.config"; +import { Button } from "@/components/Button"; +import Modal from "@/components/Modal"; + +type Variant = "danger" | "success" | "warning" | "info"; + +interface ConfirmDialogProps { + open: boolean; + onClose: () => void; + title: string; + description: string; + variant?: Variant; + confirmText?: string; + cancelText?: string | null; + onConfirm: () => void; + isConfirming?: boolean; +} + +const variantConfig = { + danger: { + icon: ExclamationTriangleIcon, + iconClass: "text-red-600", + iconBgClass: "bg-red-100", + buttonTheme: "danger", + }, + success: { + icon: CheckCircleIcon, + iconClass: "text-green-600", + iconBgClass: "bg-green-100", + buttonTheme: "primary", + }, + warning: { + icon: ExclamationTriangleIcon, + iconClass: "text-yellow-600", + iconBgClass: "bg-yellow-100", + buttonTheme: "lightDanger", + }, + info: { + icon: InformationCircleIcon, + iconClass: "text-blue-600", + iconBgClass: "bg-blue-100", + buttonTheme: "primary", + }, +} as Record; + +export function ConfirmDialog({ + open, + onClose, + title, + description, + variant = "info", + confirmText = "Confirm", + cancelText = "Cancel", + onConfirm, + isConfirming = false, +}: ConfirmDialogProps) { + const { icon: Icon, iconClass, iconBgClass, buttonTheme } = variantConfig[variant]; + + return ( + +
+
+
+
+
+
+
+

+ {title} +

+
+ {description} +
+
+
+ +
+ {cancelText && ( +
+
+
+
+
+ ); +} \ No newline at end of file diff --git a/ui/src/components/MacroForm.tsx b/ui/src/components/MacroForm.tsx index b85a0f9..44c819d 100644 --- a/ui/src/components/MacroForm.tsx +++ b/ui/src/components/MacroForm.tsx @@ -1,15 +1,15 @@ import { useState } from "react"; -import { LuPlus, LuInfo } from "react-icons/lu"; +import { LuPlus } from "react-icons/lu"; import { KeySequence } from "@/hooks/stores"; import { Button } from "@/components/Button"; import { InputFieldWithLabel, FieldError } from "@/components/InputField"; import Fieldset from "@/components/Fieldset"; import { MacroStepCard } from "@/components/MacroStepCard"; -import Modal from "@/components/Modal"; import { DEFAULT_DELAY, MAX_STEPS_PER_MACRO, MAX_KEYS_PER_STEP } from "@/constants/macros"; import FieldLabel from "@/components/FieldLabel"; +import { ConfirmDialog } from "@/components/ConfirmDialog"; interface ValidationErrors { name?: string; @@ -312,44 +312,19 @@ export function MacroForm({ - setShowDeleteConfirm(false)} - > -
-
-
-
-

- Delete Macro -

-
- Are you sure you want to delete this macro? This action cannot be undone. -
-
- -
-
-
-
-
-
+ title="Delete Macro" + description="Are you sure you want to delete this macro? This action cannot be undone." + variant="danger" + confirmText={isDeleting ? "Deleting" : "Delete"} + onConfirm={() => { + onDelete?.(); + setShowDeleteConfirm(false); + }} + isConfirming={isDeleting} + /> ); } \ No newline at end of file diff --git a/ui/src/components/MacroStepCard.tsx b/ui/src/components/MacroStepCard.tsx index 60a5ab1..6d1dd5c 100644 --- a/ui/src/components/MacroStepCard.tsx +++ b/ui/src/components/MacroStepCard.tsx @@ -1,4 +1,4 @@ -import { LuArrowUp, LuArrowDown, LuX, LuInfo } from "react-icons/lu"; +import { LuArrowUp, LuArrowDown, LuX } from "react-icons/lu"; import { Button } from "@/components/Button"; import { Combobox } from "@/components/Combobox";