9be692974e
Pagina-editor, hoofdmenu, SEO en media onder Publieke Website → Pagina's (/website), los van het CMS in rikx-org: eigen tabellen in de beheerdatabase. Blokken (hero, tekstblok, testimonial, voordelenlijst, call-to-action) met Quill, NL/EN/DE met terugval op NL, en afbeeldingsupload naar MEDIA_DIR met een openbare /media-route (CSP-sandbox). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
37 lines
1.3 KiB
TypeScript
37 lines
1.3 KiB
TypeScript
"use client";
|
|
|
|
import { useEffect } from "react";
|
|
|
|
export function Modal({ title, onClose, children }: { title: string; onClose: () => void; children: React.ReactNode }) {
|
|
useEffect(() => {
|
|
const onKey = (e: KeyboardEvent) => e.key === "Escape" && onClose();
|
|
window.addEventListener("keydown", onKey);
|
|
return () => window.removeEventListener("keydown", onKey);
|
|
}, [onClose]);
|
|
|
|
return (
|
|
<div className="fixed inset-0 z-50 flex items-start justify-center overflow-y-auto bg-black/40 p-4 sm:p-10" onClick={onClose}>
|
|
<div
|
|
role="dialog"
|
|
aria-modal="true"
|
|
aria-label={title}
|
|
className="w-full max-w-2xl rounded-xl bg-white dark:bg-zinc-900 shadow-xl"
|
|
onClick={(e) => e.stopPropagation()}
|
|
>
|
|
<div className="flex items-center justify-between border-b border-zinc-200 dark:border-zinc-800 px-6 py-4">
|
|
<h2 className="text-base font-semibold text-zinc-900 dark:text-zinc-100">{title}</h2>
|
|
<button
|
|
type="button"
|
|
aria-label="Sluiten"
|
|
onClick={onClose}
|
|
className="text-2xl leading-none text-zinc-400 hover:text-zinc-700 dark:hover:text-zinc-200"
|
|
>
|
|
×
|
|
</button>
|
|
</div>
|
|
<div className="px-6 py-5">{children}</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|