From ccdf0b68ea2606b0439f66cb294dda00497d9400 Mon Sep 17 00:00:00 2001 From: BOHA Date: Sun, 7 Jun 2026 08:43:25 +0200 Subject: [PATCH] refactor(mui): remove dead legacy FormModal and ConfirmModal Both components have zero importers after the phase-25 migrations (verified: no `./FormModal` or `./ConfirmModal` imports remain; build passes). Their MUI kit replacements are ui/Modal and ui/ConfirmDialog. Co-Authored-By: Claude Opus 4.8 (1M context) --- src/admin/components/ConfirmModal.tsx | 171 ---------------------- src/admin/components/FormModal.tsx | 201 -------------------------- 2 files changed, 372 deletions(-) delete mode 100644 src/admin/components/ConfirmModal.tsx delete mode 100644 src/admin/components/FormModal.tsx diff --git a/src/admin/components/ConfirmModal.tsx b/src/admin/components/ConfirmModal.tsx deleted file mode 100644 index 166e62a..0000000 --- a/src/admin/components/ConfirmModal.tsx +++ /dev/null @@ -1,171 +0,0 @@ -import { useEffect, type ReactNode } from "react"; -import { motion, AnimatePresence } from "framer-motion"; -import useReducedMotion from "../hooks/useReducedMotion"; -import useModalLock from "../hooks/useModalLock"; - -interface ConfirmModalProps { - isOpen: boolean; - onClose: () => void; - onConfirm: () => void; - title: string; - message: ReactNode; - confirmText?: string; - cancelText?: string; - type?: "danger" | "warning" | "default" | "info"; - confirmVariant?: "danger" | "primary"; - loading?: boolean; -} - -function ConfirmIcon({ type }: { type: string }) { - switch (type) { - case "danger": - return ( - - - - - - ); - case "info": - return ( - - - - - - ); - case "warning": - return ( - - - - - - ); - default: - return ( - - - - - - ); - } -} - -export default function ConfirmModal({ - isOpen, - onClose, - onConfirm, - title, - message, - confirmText = "Potvrdit", - cancelText = "Zrušit", - type = "default", - confirmVariant, - loading, -}: ConfirmModalProps) { - const reducedMotion = useReducedMotion(); - // Lock body scroll while open (ref-counted, nesting-safe) — matches FormModal. - useModalLock(isOpen); - useEffect(() => { - if (!isOpen) return; - - function handleKeyDown(e: KeyboardEvent) { - if (e.key === "Escape" && !loading) { - onClose(); - } - } - - window.addEventListener("keydown", handleKeyDown); - return () => window.removeEventListener("keydown", handleKeyDown); - }, [isOpen, loading, onClose]); - - const duration = reducedMotion ? 0 : 0.22; - const ease = [0.16, 1, 0.3, 1] as const; - - return ( - - {isOpen && ( - -
!loading && onClose()} - /> - -
-
- -
-

- {title} -

-

{message}

-
-
- - -
-
- - )} - - ); -} diff --git a/src/admin/components/FormModal.tsx b/src/admin/components/FormModal.tsx deleted file mode 100644 index 4c0d8df..0000000 --- a/src/admin/components/FormModal.tsx +++ /dev/null @@ -1,201 +0,0 @@ -import { - useEffect, - type ReactNode, - type FormEvent, - Children, - isValidElement, - cloneElement, -} from "react"; -import { motion, AnimatePresence } from "framer-motion"; -import useModalLock from "../hooks/useModalLock"; -import useReducedMotion from "../hooks/useReducedMotion"; - -export interface FormModalProps { - isOpen: boolean; - onClose: () => void; - onSubmit?: () => void; // called when user clicks primary button (only if provided) - title: string; - /** Optional muted line shown under the title in the header. */ - subtitle?: ReactNode; - children: ReactNode; // modal body (form fields) - submitLabel?: string; // primary button text - cancelLabel?: string; // cancel button text - loading?: boolean; - /** Disable the primary (submit) button — e.g. until the form is valid. - * Keeps the button visibly greyed out instead of clickable-but-inert. */ - submitDisabled?: boolean; - hideFooter?: boolean; // for "view-only" modals - size?: "sm" | "md" | "lg"; // optional - closeOnBackdrop?: boolean; // default true - closeOnEsc?: boolean; // default true - /** Slot for footer-left actions (e.g. delete). Rendered to the LEFT of - * the standard cancel/submit group in the modal footer. */ - footerLeft?: ReactNode; - /** Hide the close × in the header. Default false. */ - hideCloseButton?: boolean; -} - -export default function FormModal({ - isOpen, - onClose, - onSubmit, - title, - subtitle, - children, - submitLabel = "Uložit", - cancelLabel = "Zrušit", - loading = false, - submitDisabled = false, - hideFooter = false, - size = "md", - closeOnBackdrop = true, - closeOnEsc = true, - footerLeft, - hideCloseButton = false, -}: FormModalProps) { - useModalLock(isOpen); - const reducedMotion = useReducedMotion(); - - useEffect(() => { - if (!isOpen || !closeOnEsc) return; - - function handleKeyDown(e: KeyboardEvent) { - if (e.key === "Escape" && !loading) { - onClose(); - } - } - - window.addEventListener("keydown", handleKeyDown); - return () => window.removeEventListener("keydown", handleKeyDown); - }, [isOpen, closeOnEsc, loading, onClose]); - - const handleBackdropClick = () => { - if (closeOnBackdrop && !loading) onClose(); - }; - - const handlePrimaryClick = (e: FormEvent) => { - e.preventDefault(); - if (onSubmit) onSubmit(); - }; - - const titleId = "form-modal-title"; - const modalClassName = - size === "lg" ? "admin-modal admin-modal-lg" : "admin-modal"; - - // Snappier ease curve for modal entry — matches the "industrial/refined" - // tone. Roughly equivalent to the cubic-bezier(0.16, 1, 0.3, 1) used by - // a lot of design systems for "expo out" feel. - const ease = [0.16, 1, 0.3, 1] as const; - const duration = reducedMotion ? 0 : 0.22; - // Stagger the body children slightly for a "drawing-in" reveal. We cap - // the cascade so long forms don't drag on forever. - const childrenArray = Children.toArray(children).filter(isValidElement); - const stagger = reducedMotion ? 0 : Math.min(childrenArray.length, 5) * 0.03; - - return ( - - {isOpen && ( - -
- -
-
-

- {title} -

- {subtitle &&

{subtitle}

} -
- {!hideCloseButton && ( - - )} -
- -
- {reducedMotion || stagger === 0 - ? children - : Children.map(children, (child, i) => { - if (!isValidElement(child)) return child; - return ( - - {cloneElement(child)} - - ); - })} -
- - {!hideFooter && ( -
-
{footerLeft}
-
- - {onSubmit && ( - - )} -
-
- )} -
- - )} - - ); -}