feat(web): pop-out modal forms for setup/subscriptions/roles
Add a reusable ui/Modal (Radix Dialog + terminal chrome) and move the add/edit forms in the Devices setup, Subscriptions and Roles screens into it, leaving each list in the page behind the modal. The Devices wizard's per- category device form is also fully translated (setup.* i18n keys). Claude-Session: https://claude.ai/code/session_01Xcm6ikLgGoCxxHrxtjkk5V
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
import * as Dialog from "@radix-ui/react-dialog";
|
||||
import type { ReactNode } from "react";
|
||||
|
||||
// Reusable modal shell — a thin wrapper over Radix Dialog matching the terminal
|
||||
// chrome (title bar + ✕, dark overlay, square panel). The same styling BoothPayModal
|
||||
// uses inline, factored out so every popped-out form looks identical. Radix handles
|
||||
// focus trap, Escape, and outside-click → onClose. `width` is a Tailwind max-width
|
||||
// class (the panel is responsive: w-full up to that cap).
|
||||
|
||||
export function Modal({
|
||||
open,
|
||||
onClose,
|
||||
title,
|
||||
children,
|
||||
width = "max-w-xl",
|
||||
}: {
|
||||
open: boolean;
|
||||
onClose: () => void;
|
||||
title: ReactNode;
|
||||
children: ReactNode;
|
||||
/** Tailwind max-width class for the panel (default max-w-xl). */
|
||||
width?: string;
|
||||
}) {
|
||||
return (
|
||||
<Dialog.Root open={open} onOpenChange={(o) => !o && onClose()}>
|
||||
<Dialog.Portal>
|
||||
<Dialog.Overlay className="fixed inset-0 z-40 bg-black/70" />
|
||||
<Dialog.Content
|
||||
className={`fixed left-1/2 top-1/2 z-50 max-h-[90vh] w-[95vw] ${width} -translate-x-1/2 -translate-y-1/2 overflow-y-auto rounded-term border border-term-border bg-term-panel font-mono text-term-text shadow-2xl`}
|
||||
aria-describedby={undefined}
|
||||
>
|
||||
<div className="sticky top-0 flex items-center justify-between border-b border-term-border bg-term-panel-2 px-4 py-2">
|
||||
<Dialog.Title className="m-0 text-[12px] font-semibold uppercase tracking-wider text-term-amber">
|
||||
{title}
|
||||
</Dialog.Title>
|
||||
<Dialog.Close className="text-term-muted hover:text-term-text" aria-label="Close">
|
||||
✕
|
||||
</Dialog.Close>
|
||||
</div>
|
||||
<div className="p-4">{children}</div>
|
||||
</Dialog.Content>
|
||||
</Dialog.Portal>
|
||||
</Dialog.Root>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user