feat(admin): extend housekeeping permissions page with groups, presets, audit, test, import/export, rank overview and dependency tracking
- Add group_name, depends_on and updated_by columns to website_housekeeping_permissions - Add migration 0016 for new columns - Rewrite housekeeping page with 7 tabs: Overview, Manage, Import/Export, Rank overview, Presets, Test, Audit log - Add permission groups/categories with filtering - Add bulk JSON import/export - Add rank overview grouped by permission category - Add permission presets for Moderator (rank 5), Admin (rank 7), Super Admin (rank 8) - Add audit logging for all permission changes via AdminAuditLog - Add test mode to check permissions by rank - Add dependency tracking with warnings for missing dependencies - Add overview dashboard with statistics - Add Dutch and English translations for all new features
This commit is contained in:
1 parent
49d204e85c
commit
98d4b715df
7 files changed
+1636
-220
No files matched your search
@@ -0,0 +1,53 @@
|
||||
"use client";
|
||||
|
||||
import { useTranslations } from "next-intl";
|
||||
import { useCallback, useState } from "react";
|
||||
|
||||
export function HousekeepingClient() {
|
||||
const t = useTranslations("pages.admin.housekeeping");
|
||||
const [exportData, setExportData] = useState<string | null>(null);
|
||||
const [copying, setCopying] = useState(false);
|
||||
|
||||
const handleExport = useCallback(async () => {
|
||||
const { exportPermissions } = await import("@/actions/admin-housekeeping");
|
||||
const data = await exportPermissions();
|
||||
setExportData(data);
|
||||
}, []);
|
||||
|
||||
const handleCopy = useCallback(async () => {
|
||||
if (!exportData) return;
|
||||
setCopying(true);
|
||||
try {
|
||||
await navigator.clipboard.writeText(exportData);
|
||||
} catch {
|
||||
// fallback
|
||||
}
|
||||
setTimeout(() => setCopying(false), 1500);
|
||||
}, [exportData]);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<button
|
||||
type="button"
|
||||
onClick={handleExport}
|
||||
className="btn btn-outline mb-3"
|
||||
>
|
||||
{t("export")}
|
||||
</button>
|
||||
{exportData && (
|
||||
<div className="relative">
|
||||
<pre className="admin-card font-mono text-xs overflow-auto max-h-[300px] p-3">
|
||||
{exportData}
|
||||
</pre>
|
||||
<button
|
||||
type="button"
|
||||
onClick={handleCopy}
|
||||
className="btn btn-outline btn-sm absolute top-2 right-2"
|
||||
>
|
||||
{copying ? t("copied") : t("copy")}
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in new issue
Block a user