feat(housekeeping): cut over administration to ase

This commit is contained in:
Simo committed 2026-08-30 20:35:22 +02:00
1 parent c9e35cf602
commit 2b8f73a91d
457 files changed
+589 -55936

No files matched your search

File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
-77
View File
@@ -1,77 +0,0 @@
import { redirect } from "next/navigation";
import { getTranslations } from "next-intl/server";
import { StatusCard } from "@/components/admin/dashboard";
import { UnifiedTicketsTable } from "@/components/admin/unified-tickets-table";
import {
fetchUnifiedTicketInbox,
type TicketInboxTypeFilter,
} from "@/lib/admin/ticket-inbox";
import { fetchTicketQueueOpenCounts } from "@/lib/admin/ticket-queue-counts";
import { parseListParams } from "@/lib/admin-helpers";
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
export default async function AdminTicketInboxPage({
searchParams,
}: {
searchParams: Promise<Record<string, string>>;
}) {
const { session, permissions } = await getAdminContext();
if (!canAccess(permissions, PERMS.TICKETS_VIEW, session.user.rank)) {
redirect("/admin");
}
const t = await getTranslations("pages.admin.ticketInbox");
const raw = await searchParams;
const parsed = parseListParams(new URLSearchParams(raw));
const typeRaw = raw.filter_type || "all";
const type: TicketInboxTypeFilter =
typeRaw === "cms" || typeRaw === "help" ? typeRaw : "all";
const statusFilter = raw.filter_status || "open";
const openOnly = statusFilter !== "all";
const [inbox, queues] = await Promise.all([
fetchUnifiedTicketInbox({
page: parsed.page,
perPage: parsed.perPage,
search: parsed.search,
type,
openOnly,
base: "admin",
}),
fetchTicketQueueOpenCounts(),
]);
return (
<div className="space-y-6">
<p className="m-0 text-sm text-[var(--admin-text-muted)]">{t("hint")}</p>
<div className="grid grid-cols-[repeat(auto-fit,minmax(180px,1fr))] gap-3.5">
<StatusCard label={t("statCmsOpen")} value={queues.cmsOpen} icon="🎫" />
<StatusCard
label={t("statHelpOpen")}
value={queues.helpOpen}
state={queues.helpOpen > 0 ? "warn" : "neutral"}
icon="🛟"
/>
<StatusCard
label={t("statTotal")}
value={queues.cmsOpen + queues.helpOpen}
icon="📥"
/>
</div>
{inbox.total === 0 && !parsed.search ? (
<div className="admin-empty">{t("noTickets")}</div>
) : (
<UnifiedTicketsTable
data={{
rows: inbox.rows,
total: inbox.total,
page: inbox.page,
perPage: inbox.perPage,
lastPage: inbox.lastPage,
}}
/>
)}
</div>
);
}
-23
View File
@@ -1,23 +0,0 @@
import { asc } from "drizzle-orm";
import { redirect } from "next/navigation";
import { db, WebsiteTicketTemplate } from "@/lib/db";
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
import { TicketTemplatesManager } from "./templates-manager";
export default async function TicketTemplatesPage() {
const { session, permissions } = await getAdminContext();
if (!canAccess(permissions, PERMS.TICKETS_EDIT, session.user.rank)) {
redirect("/admin/tickets");
}
const templates = await db
.select()
.from(WebsiteTicketTemplate)
.orderBy(asc(WebsiteTicketTemplate.sortOrder));
return (
<div className="space-y-6">
<TicketTemplatesManager templates={templates} />
</div>
);
}
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff