import { createFileRoute, Link, useNavigate } from "@tanstack/react-router"; import { InlineSelect } from "~/ui/Field"; import { z } from "zod"; import { deleteProject, getProject, updateProject } from "~/fns/projects"; import { useAction } from "~/hooks/use-action"; import { useProjectLive } from "~/hooks/use-project-live"; import { ProjectBoard } from "~/components/project/ProjectBoard"; import { ProjectTable } from "~/components/project/ProjectTable"; import { ProjectToolbar } from "~/components/project/ProjectToolbar"; import { Avatar } from "~/ui/Avatar"; import { Badge } from "~/ui/Badge"; import { PageContainer } from "~/ui/PageContainer"; import { Panel } from "~/ui/Panel"; import { Button, buttonClass } from "~/ui/Button"; import { cn } from "~/utils/cn"; import { Heading } from "~/ui/Heading"; export const Route = createFileRoute("/projects/$owner/$number")({ validateSearch: z.object({ view: z.enum(["table", "board"]).optional(), group: z.string().optional() }), loader: ({ params }) => getProject({ data: { owner: params.owner, number: Number(params.number) } }), head: ({ loaderData }) => ({ meta: [{ title: loaderData ? `${loaderData.project.title} · Project` : "Project" }] }), component: ProjectPage, }); function ProjectPage() { const data = Route.useLoaderData(); const params = Route.useParams(); const search = Route.useSearch(); const navigate = useNavigate(); const live = useProjectLive(data.project.owner, data.project.number); const update = useAction(updateProject); const remove = useAction(deleteProject, { invalidate: false }); const view = search.view ?? "table"; const selects = data.fields.filter((field) => field.kind === "single_select"); const group = selects.find((field) => field.id === search.group) ?? selects[0]; const { project } = data; return (
{project.owner} / {project.title} {project.visibility} {project.closed && Closed}
{live.viewers.slice(0, 5).map((name) => ( ))}
{project.description &&

{project.description}

}
{(["table", "board"] as const).map((item) => ( {item} ))} {view === "board" && selects.length > 1 && ( navigate({ to: "/projects/$owner/$number", params, search: { ...search, group: value } }) } options={selects.map((field) => ({ value: field.id, label: `Group by ${field.name}` }))} /> )} {data.canWrite && (
)}
{data.canWrite && } {view === "board" ? : }
); }