78 lines
2.4 KiB
TypeScript
78 lines
2.4 KiB
TypeScript
import config from "@payload-config";
|
|
import { headers as nextHeaders } from "next/headers";
|
|
import { redirect } from "next/navigation";
|
|
import { getPayload } from "payload";
|
|
import type { Ticket } from "@/payload-types";
|
|
import { TicketsView } from "@/components/frontend/helpdesk/TicketsView";
|
|
import { hasPermission } from "@/utils/access-control/hasPermission";
|
|
import { LifeBuoyIcon } from "lucide-react";
|
|
import { getTicketVoteSummaries } from "@/lib/tickets/voteState";
|
|
|
|
export const metadata = {
|
|
title: "Helpdesk: Polaris Task Force",
|
|
};
|
|
|
|
function HelpdeskDisabled() {
|
|
return (
|
|
<div className="mx-auto flex w-full max-w-2xl flex-col gap-4 p-5">
|
|
<div className="flex flex-col gap-1">
|
|
<div className="flex items-center gap-2">
|
|
<LifeBuoyIcon className="size-5 text-muted-foreground" />
|
|
<h1 className="text-lg font-semibold">Helpdesk</h1>
|
|
</div>
|
|
<p className="text-sm text-muted-foreground">
|
|
The Helpdesk is currently disabled by a unit admin.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export default async function HelpdeskPage() {
|
|
const headers = await nextHeaders();
|
|
const payload = await getPayload({ config });
|
|
const { user } = await payload.auth({
|
|
headers,
|
|
canSetHeaders: false,
|
|
});
|
|
|
|
if (!user) {
|
|
const pathname = headers.get("x-invoke-path") || "/helpdesk";
|
|
redirect(`/login?returnTo=${encodeURIComponent(pathname)}`);
|
|
}
|
|
|
|
const { helpdeskEnabled } = await payload.findGlobal({ slug: "game-rules" });
|
|
if (!helpdeskEnabled) {
|
|
return <HelpdeskDisabled />;
|
|
}
|
|
|
|
const ticketsRes = await payload.find({
|
|
collection: "tickets",
|
|
sort: "-updatedAt",
|
|
limit: 200,
|
|
depth: 2,
|
|
});
|
|
const tickets = ticketsRes.docs as unknown as Ticket[];
|
|
const [isStaff, voteSummaries] = await Promise.all([
|
|
hasPermission(payload, user, "tickets:staff"),
|
|
getTicketVoteSummaries(
|
|
payload,
|
|
user.id,
|
|
tickets.map((ticket) => ticket.id),
|
|
),
|
|
]);
|
|
|
|
return (
|
|
<div className="flex flex-col gap-6 p-5">
|
|
<div className="flex flex-col gap-1">
|
|
<div className="flex items-center gap-2">
|
|
<LifeBuoyIcon className="size-5 text-muted-foreground" />
|
|
<h1 className="text-lg font-semibold">Helpdesk</h1>
|
|
</div>
|
|
<p className="text-sm text-muted-foreground">Submit and track support requests.</p>
|
|
</div>
|
|
|
|
<TicketsView tickets={tickets} voteSummaries={voteSummaries} isStaff={isStaff} />
|
|
</div>
|
|
);
|
|
}
|