From dca77a891b0f49c7e8aaf26fc2f145a2288bd5a9 Mon Sep 17 00:00:00 2001 From: remco Date: Wed, 1 Jul 2026 18:45:01 +0200 Subject: [PATCH] feat: enhance housekeeping page with search, import mode and inline form editing --- src/app/admin/housekeeping/page.tsx | 115 +++++++++++++++++++++++----- 1 file changed, 97 insertions(+), 18 deletions(-) diff --git a/src/app/admin/housekeeping/page.tsx b/src/app/admin/housekeeping/page.tsx index 2996f9f4..2dac2483 100644 --- a/src/app/admin/housekeeping/page.tsx +++ b/src/app/admin/housekeeping/page.tsx @@ -4,20 +4,42 @@ import { prisma } from "@/lib/prisma"; export const dynamic = "force-dynamic"; -export default async function AdminHousekeeping() { +export default async function AdminHousekeeping({ + searchParams, +}: { + searchParams: Promise<{ q?: string; mode?: "manage" | "import" }>; +}) { + const sp = await searchParams; + const q = (sp.q ?? "").trim(); + const mode = sp.mode === "import" ? "import" : "manage"; + let permissions: Awaited< ReturnType > = []; try { permissions = await prisma.websiteHousekeepingPermissions.findMany({ - orderBy: [{ minRank: "asc" }, { permission: "asc" }], + orderBy: [{ permission: "asc" }], }); } catch { permissions = []; } + const filtered = q + ? permissions.filter((p) => p.permission.toLowerCase().includes(q.toLowerCase())) + : permissions; + const ranks = permissions.map((p) => p.minRank); const maxRank = ranks.length ? Math.max(...ranks) : 0; + const totalMin = ranks.reduce((sum, r) => sum + r, 0); + + const selectedIds = new Set(); + if (mode === "import") { + const importRaw = String(sp.q ?? ""); + if (importRaw) { + const importIds = importRaw.split(",").map((i) => Number(i.trim())).filter((i) => !isNaN(i)); + importIds.forEach((id) => selectedIds.add(id)); + } + } return (
@@ -30,33 +52,89 @@ export default async function AdminHousekeeping() {
+
-
-

Add / overwrite permission

-
-
- - - - + +
+ + +
- -
+ + + + {mode === "manage" ? ( +
+

Add / overwrite permission

+
+
+ + + + +
+
+
+ ) : ( +
+

Import Permissions

+

+ Paste comma-separated permission IDs to import them as a selection. +

+
+
+ + +
+
+
+ )}

- Permissions {permissions.length} + Permissions {filtered.length}

- {permissions.length === 0 ? ( -

No housekeeping permissions defined yet.

+ {filtered.length === 0 ? ( +

No housekeeping permissions match this search.

) : (
+ @@ -64,8 +142,9 @@ export default async function AdminHousekeeping() { - {permissions.map((p) => ( - + {filtered.map((p, i) => ( + +
# Permission Description Min rank
{i + 1} {p.permission}