Files
vfxreview/app/(dashboard)/projects/[id]/kanban/page.tsx
T
twotalesanimation 0fbe856dce Initial commit
2026-05-19 22:20:29 +02:00

107 lines
3.0 KiB
TypeScript

import { notFound, redirect } from "next/navigation";
import Link from "next/link";
import { db } from "@/lib/db";
import { auth } from "@/auth";
import { KanbanBoard } from "@/components/tasks/KanbanBoard";
import { ArrowLeft, LayoutDashboard } from "lucide-react";
export async function generateMetadata({
params,
}: {
params: Promise<{ id: string }>;
}) {
const { id } = await params;
const project = await db.project.findUnique({
where: { id },
select: { name: true },
});
return { title: project ? `${project.name} — Kanban` : "Kanban" };
}
export default async function KanbanPage({
params,
}: {
params: Promise<{ id: string }>;
}) {
const { id } = await params;
const session = await auth();
if (!session?.user) redirect("/login");
// Clients cannot access kanban
if (session.user.role === "CLIENT") redirect(`/projects/${id}`);
const project = await db.project.findUnique({
where: { id },
select: { id: true, name: true, code: true },
});
if (!project) notFound();
const [tasks, artists] = await Promise.all([
db.task.findMany({
where: { projectId: id },
orderBy: [{ status: "asc" }, { sortOrder: "asc" }],
include: {
shot: { select: { id: true, shotCode: true } },
asset: { select: { id: true, assetCode: true, name: true } },
assignedArtist: {
select: { id: true, name: true, email: true, image: true },
},
_count: { select: { versions: true } },
versions: {
take: 1,
orderBy: { versionNumber: "desc" },
select: {
id: true,
versionNumber: true,
approvalStatus: true,
createdAt: true,
},
},
},
}),
db.user.findMany({
where: { isActive: true },
select: { id: true, name: true, email: true },
orderBy: { name: "asc" },
}),
]);
return (
<div className="p-6 space-y-6 max-w-[1800px] mx-auto">
{/* Breadcrumb */}
<div className="flex items-center gap-2 text-sm text-muted-foreground">
<Link href="/projects" className="hover:text-foreground transition-colors">
Projects
</Link>
<span>/</span>
<Link
href={`/projects/${id}`}
className="hover:text-foreground transition-colors"
>
{project.name}
</Link>
<span>/</span>
<span className="text-foreground">Kanban</span>
</div>
{/* Header */}
<div className="flex items-center gap-3">
<Link
href={`/projects/${id}`}
className="text-zinc-400 hover:text-white transition-colors"
>
<ArrowLeft className="h-5 w-5" />
</Link>
<LayoutDashboard className="h-5 w-5 text-amber-400" />
<div>
<h1 className="text-xl font-bold">{project.name}</h1>
<p className="text-sm text-muted-foreground">Kanban Board {tasks.length} tasks</p>
</div>
</div>
{/* Board */}
<KanbanBoard tasks={tasks} projectId={id} artists={artists} />
</div>
);
}