Add kanban board to page

This commit is contained in:
2026-02-01 16:20:35 +01:00
parent aa95635e3e
commit 940e934237
2 changed files with 124 additions and 1 deletions

View File

@ -0,0 +1,122 @@
import { Badge } from "@/components/ui/badge";
import { prisma } from "@/lib/prisma";
const statusStyles: Record<string, string> = {
ACCEPTED: "bg-sky-500/15 text-sky-300 border-sky-500/30",
INPROGRESS: "bg-amber-500/15 text-amber-300 border-amber-500/30",
COMPLETED: "bg-emerald-500/15 text-emerald-300 border-emerald-500/30",
};
const statusLabels: Record<string, string> = {
ACCEPTED: "Accepted",
INPROGRESS: "In progress",
COMPLETED: "Completed",
};
export default async function CommissionStatusPage() {
const [queueItems, doneItems] = await Promise.all([
prisma.commissionRequest.findMany({
where: { status: { in: ["ACCEPTED", "INPROGRESS"] } },
include: { type: true, option: true, extras: true, customCard: true },
orderBy: { createdAt: "desc" },
}),
prisma.commissionRequest.findMany({
where: { status: "COMPLETED" },
include: { type: true, option: true, extras: true, customCard: true },
orderBy: { createdAt: "desc" },
}),
]);
return (
<div className="mx-auto w-full max-w-6xl px-4 py-8 flex flex-col gap-8">
<div className="flex flex-col gap-2">
<h1 className="text-3xl font-bold">Commission Status</h1>
</div>
<div className="grid grid-cols-1 gap-6 md:grid-cols-2">
<section className="rounded-2xl border border-border/60 bg-muted/20 p-4 sm:p-6">
<div className="mb-4">
<h2 className="text-xl font-semibold">Commissions Queue</h2>
<p className="text-sm text-muted-foreground">Accepted and in progress</p>
</div>
<div className="flex flex-col gap-3">
{queueItems.length > 0 ? (
queueItems.map((item) => (
<div
key={item.id}
className="rounded-xl border border-border/60 bg-background p-4 shadow-sm"
>
<div className="font-semibold text-lg">{item.customerName}</div>
<div className="mt-2 flex flex-wrap gap-2">
<Badge variant="outline">
{item.customCard?.name ?? item.type?.name ?? "Custom"}
</Badge>
<Badge variant="outline">
{item.option?.name ?? "Base option"}
</Badge>
{item.extras.map((extra) => (
<Badge key={extra.id} variant="secondary">
{extra.name}
</Badge>
))}
{item.extras.length === 0 ? (
<Badge variant="secondary">No extras</Badge>
) : null}
<Badge className={statusStyles[item.status] ?? ""}>
{statusLabels[item.status] ?? item.status}
</Badge>
</div>
</div>
))
) : (
<div className="rounded-xl border border-dashed border-border/60 bg-background p-4 text-sm text-muted-foreground">
No public items yet.
</div>
)}
</div>
</section>
<section className="rounded-2xl border border-border/60 bg-muted/20 p-4 sm:p-6">
<div className="mb-4">
<h2 className="text-xl font-semibold">Done</h2>
</div>
<div className="flex flex-col gap-3">
{doneItems.length > 0 ? (
doneItems.map((item) => (
<div
key={item.id}
className="rounded-xl border border-border/60 bg-background p-4 shadow-sm"
>
<div className="font-semibold text-lg">{item.customerName}</div>
<div className="mt-2 flex flex-wrap gap-2">
<Badge variant="outline">
{item.customCard?.name ?? item.type?.name ?? "Custom"}
</Badge>
<Badge variant="outline">
{item.option?.name ?? "Base option"}
</Badge>
{item.extras.map((extra) => (
<Badge key={extra.id} variant="secondary">
{extra.name}
</Badge>
))}
{item.extras.length === 0 ? (
<Badge variant="secondary">No extras</Badge>
) : null}
<Badge className={statusStyles[item.status] ?? ""}>
{statusLabels[item.status] ?? item.status}
</Badge>
</div>
</div>
))
) : (
<div className="rounded-xl border border-dashed border-border/60 bg-background p-4 text-sm text-muted-foreground">
No completed items yet.
</div>
)}
</div>
</section>
</div>
</div>
);
}

View File

@ -12,6 +12,7 @@ const links = [
{ href: "/artworks", label: "Portfolio" },
{ href: "/artworks/animalstudies", label: "Animal Studies" },
{ href: "/commissions", label: "Commissions" },
{ href: "/commissions/status", label: "Commission Status" },
{ href: "/tos", label: "Terms of Service" },
// { href: "/portfolio/artfight", label: "Artfight" },
// { href: "/portfolio/minis", label: "Miniatures" },