129 lines · 5.1 KB
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 (
    <PageContainer className="max-w-7xl space-y-4">
      <header className="flex flex-wrap items-center gap-3">