Add shared ConfirmDialog; upgrade wordfilter with client actions and toasts.
Local Build and Deploy / deploy (push) Successful in 1m6s

Co-authored-by: Cursor <[email protected]>
This commit is contained in:
SimoandCursor committed 2026-07-17 20:28:43 +02:00
1 parent 1039044e48
commit a2ca9b3c23
9 files changed
+366 -149

No files matched your search

+15 -59
View File
@@ -13,6 +13,7 @@ import {
exportPermissions,
upsertPermission,
} from "@/actions/admin-housekeeping";
import { ConfirmDialog } from "@/components/admin/confirm-dialog";
const PAGE_SIZE = 25;
@@ -32,59 +33,6 @@ interface SharedProps {
permSet: Set<string>;
}
/* ────────── Confirm Modal ────────── */
interface ConfirmModalProps {
open: boolean;
title: string;
message: string;
confirmLabel?: string;
cancelLabel?: string;
variant?: "danger" | "primary";
onConfirm: () => void;
onCancel: () => void;
}
function ConfirmModal({
open,
title,
message,
confirmLabel,
cancelLabel,
variant = "danger",
onConfirm,
onCancel,
}: ConfirmModalProps) {
const t = useTranslations("pages.admin.housekeeping");
if (!open) return null;
return (
<div
className="fixed inset-0 z-50 flex items-center justify-center bg-black/40"
onClick={onCancel}
>
<div
className="admin-card max-w-sm w-full mx-4 p-5 shadow-xl"
onClick={(e) => e.stopPropagation()}
>
<h3 className="font-bold text-lg mb-2">{title}</h3>
<p className="text-sm opacity-70 mb-5">{message}</p>
<div className="flex gap-2 justify-end">
<button type="button" onClick={onCancel} className="btn btn-outline">
{cancelLabel ?? t("cancel")}
</button>
<button
type="button"
onClick={onConfirm}
className={variant === "danger" ? "btn btn-danger" : "btn btn-primary"}
>
{confirmLabel ?? t("confirm")}
</button>
</div>
</div>
</div>
);
}
/* ────────── Manage Section ────────── */
export function ManageSection(props: SharedProps) {
@@ -293,20 +241,24 @@ export function ManageSection(props: SharedProps) {
return (
<div>
<ConfirmModal
<ConfirmDialog
open={confirmDel !== null}
onOpenChange={(open) => {
if (!open) setConfirmDel(null);
}}
title={t("confirmDelete")}
message={
description={
confirmDel === "__bulk__"
? t("confirmBulkDelete", { count: selected.size })
: t("confirmDeletePermission")
}
confirmLabel={t("confirm")}
cancelLabel={t("cancel")}
onConfirm={() =>
confirmDel === "__bulk__"
? handleBulkDelete()
: handleDelete(confirmDel!)
}
onCancel={() => setConfirmDel(null)}
/>
<div className="admin-filter-bar">
@@ -663,12 +615,16 @@ export function PresetsSection() {
return (
<section>
<ConfirmModal
<ConfirmDialog
open={confirmClear}
onOpenChange={(open) => {
if (!open) setConfirmClear(false);
}}
title={t("confirmClearAll")}
message={t("confirmClearAllDesc")}
description={t("confirmClearAllDesc")}
confirmLabel={t("confirm")}
cancelLabel={t("cancel")}
onConfirm={handleClearAll}
onCancel={() => setConfirmClear(false)}
/>
<h2 className="admin-section-title">{t("presets")}</h2>