Translate admin panel to all 6 languages
This commit is contained in:
1 parent
f381aa987f
commit
befa4ec282
63 files changed
+9353
-1443
No files matched your search
@@ -1,4 +1,5 @@
|
||||
import Link from "next/link";
|
||||
import { getTranslations } from "next-intl/server";
|
||||
import { deletePermission, upsertPermission } from "@/actions/admin-housekeeping";
|
||||
import { StatusCard } from "@/components/admin/dashboard";
|
||||
import { prisma } from "@/lib/prisma";
|
||||
@@ -10,6 +11,8 @@ export default async function AdminHousekeeping({
|
||||
}: {
|
||||
searchParams: Promise<{ q?: string; mode?: "manage" | "import" }>;
|
||||
}) {
|
||||
const t = await getTranslations("pages.admin.housekeeping");
|
||||
|
||||
const sp = await searchParams;
|
||||
const q = (sp.q ?? "").trim();
|
||||
const mode = sp.mode === "import" ? "import" : "manage";
|
||||
@@ -49,50 +52,48 @@ export default async function AdminHousekeeping({
|
||||
<span className="text-lg">🔑</span>
|
||||
</div>
|
||||
<div>
|
||||
<h1 className="m-0 text-xl font-extrabold text-[var(--color-text)]">Housekeeping Permissions</h1>
|
||||
<p className="m-0 text-xs text-[var(--color-text-muted)] mt-0.5">
|
||||
Minimum rank required to access each housekeeping permission key.
|
||||
</p>
|
||||
<h1 className="m-0 text-xl font-extrabold text-[var(--color-text)]">{t("title")}</h1>
|
||||
<p className="m-0 text-xs text-[var(--color-text-muted)] mt-0.5">{t("subtitle")}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="admin-stat-row">
|
||||
<span className="admin-stat-chip">{permissions.length} permissions</span>
|
||||
<span className="admin-stat-chip">Highest min rank: {maxRank}</span>
|
||||
<span className="admin-stat-chip">Total min rank: {totalMin}</span>
|
||||
<span className="admin-stat-chip">{t("permissionsCount", { count: permissions.length })}</span>
|
||||
<span className="admin-stat-chip">{t("highestMinRank", { rank: maxRank })}</span>
|
||||
<span className="admin-stat-chip">{t("totalMinRank", { total: totalMin })}</span>
|
||||
</div>
|
||||
|
||||
<div className="admin-filter-bar">
|
||||
<form className="flex gap-2 flex-1">
|
||||
<input name="q" defaultValue={q} placeholder="Search permission key..." className="flex-1 min-w-[200px]" />
|
||||
<button type="submit" className="btn btn-primary">Search</button>
|
||||
<input name="q" defaultValue={q} placeholder={t("searchPermission")} className="flex-1 min-w-[200px]" />
|
||||
<button type="submit" className="btn btn-primary">{t("search")}</button>
|
||||
</form>
|
||||
<Link href="/admin/housekeeping?mode=manage" className="btn btn-outline">Manage</Link>
|
||||
<Link href="/admin/housekeeping?mode=import&form=selected_ids" className="btn btn-outline">Import selection</Link>
|
||||
<Link href="/admin/housekeeping?mode=manage" className="btn btn-outline">{t("manage")}</Link>
|
||||
<Link href="/admin/housekeeping?mode=import&form=selected_ids" className="btn btn-outline">{t("importSelection")}</Link>
|
||||
</div>
|
||||
|
||||
{mode === "manage" ? (
|
||||
<section>
|
||||
<h2 className="admin-section-title">Add / overwrite permission</h2>
|
||||
<h2 className="admin-section-title">{t("addPermission")}</h2>
|
||||
<form action={upsertPermission} className="admin-card">
|
||||
<div className="flex gap-2 flex-wrap">
|
||||
<input name="permission" placeholder="permission key" required className="min-w-[200px]" />
|
||||
<input name="minRank" type="number" min={0} placeholder="Min rank" required className="w-[110px]" />
|
||||
<input name="description" placeholder="description" className="flex-1 min-w-[160px]" />
|
||||
<button type="submit" className="btn btn-primary">Save</button>
|
||||
<input name="permission" placeholder={t("permissionKey")} required className="min-w-[200px]" />
|
||||
<input name="minRank" type="number" min={0} placeholder={t("minRank")} required className="w-[110px]" />
|
||||
<input name="description" placeholder={t("description")} className="flex-1 min-w-[160px]" />
|
||||
<button type="submit" className="btn btn-primary">{t("save")}</button>
|
||||
</div>
|
||||
</form>
|
||||
</section>
|
||||
) : (
|
||||
<section>
|
||||
<h2 className="admin-section-title">Import Permissions</h2>
|
||||
<h2 className="admin-section-title">{t("importPermissions")}</h2>
|
||||
<p className="text-xs text-[var(--color-text-muted)] -mt-2 mb-3">
|
||||
Paste comma-separated permission IDs to import them as a selection.
|
||||
{t("importHint")}
|
||||
</p>
|
||||
<form action={upsertPermission} className="admin-card">
|
||||
<div className="flex gap-2 flex-wrap">
|
||||
<input name="q" placeholder="Permission IDs (comma-separated)" required className="flex-1 min-w-[200px]" />
|
||||
<button type="submit" className="btn btn-primary">Import</button>
|
||||
<input name="q" placeholder={t("importPlaceholder")} required className="flex-1 min-w-[200px]" />
|
||||
<button type="submit" className="btn btn-primary">{t("import")}</button>
|
||||
</div>
|
||||
</form>
|
||||
</section>
|
||||
@@ -100,19 +101,19 @@ export default async function AdminHousekeeping({
|
||||
|
||||
<section>
|
||||
<h2 className="admin-section-title">
|
||||
Permissions <span className="inline-block text-[0.72rem] font-bold px-2 py-0.5 rounded-full bg-[var(--color-primary)]/18 text-[var(--color-text)]">{filtered.length}</span>
|
||||
{t("permissions")} <span className="inline-block text-[0.72rem] font-bold px-2 py-0.5 rounded-full bg-[var(--color-primary)]/18 text-[var(--color-text)]">{filtered.length}</span>
|
||||
</h2>
|
||||
{filtered.length === 0 ? (
|
||||
<div className="admin-empty">No housekeeping permissions match this search.</div>
|
||||
<div className="admin-empty">{t("noPermissions")}</div>
|
||||
) : (
|
||||
<div className="overflow-x-auto">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th className="w-[40px]">#</th>
|
||||
<th>Permission</th>
|
||||
<th>Description</th>
|
||||
<th className="w-[200px]">Min rank</th>
|
||||
<th>{t("colPermission")}</th>
|
||||
<th>{t("colDescription")}</th>
|
||||
<th className="w-[200px]">{t("colMinRank")}</th>
|
||||
<th className="w-[80px]" />
|
||||
</tr>
|
||||
</thead>
|
||||
@@ -136,7 +137,7 @@ export default async function AdminHousekeeping({
|
||||
style={{ width: 90 }}
|
||||
/>
|
||||
<button type="submit" className="btn btn-outline">
|
||||
Save
|
||||
{t("save")}
|
||||
</button>
|
||||
</form>
|
||||
</td>
|
||||
|
||||
Reference in new issue
Block a user