import { createFileRoute, Link, useNavigate } from "@tanstack/react-router"; import { useState } from "react"; import { z } from "zod"; import { createProject, listProjects } from "~/fns/projects"; import { useAction } from "~/hooks/use-action"; import { Badge } from "~/ui/Badge"; import { EmptyState } from "~/ui/EmptyState"; import { PageContainer } from "~/ui/PageContainer"; import { Panel } from "~/ui/Panel"; import { RelativeTime } from "~/ui/RelativeTime"; import { Button, buttonClass } from "~/ui/Button"; import { SelectField, TextAreaField, TextField } from "~/ui/Field"; import { ErrorBanner } from "~/ui/Callout"; import { cn } from "~/utils/cn"; import { Heading } from "~/ui/Heading"; export const Route = createFileRoute("/projects/$owner/")({ validateSearch: z.object({ closed: z.boolean().optional() }), loaderDeps: ({ search }) => search, loader: ({ params, deps }) => listProjects({ data: { owner: params.owner, closed: deps.closed ?? false } }), head: ({ params }) => ({ meta: [{ title: `Projects · ${params.owner}` }] }), component: ProjectsPage, }); const VISIBILITY = [ { value: "private", label: "Private — members only" }, { value: "public", label: "Public" }, ] as const; function NewProject({ owner }: { owner: string }) { const navigate = useNavigate(); const [open, setOpen] = useState(false); const create = useAction(createProject, { invalidate: false }); if (!open) return ( ); return (
{ event.preventDefault(); const form = new FormData(event.currentTarget); const result = await create.run({ data: { owner, title: String(form.get("title") ?? ""), description: String(form.get("description") ?? ""), visibility: form.get("visibility") === "public" ? "public" : "private", }, }); if (result) await navigate({ to: "/projects/$owner/$number", params: { owner, number: String(result.number) } }); }} >
); } function ProjectsPage() { const data = Route.useLoaderData(); const search = Route.useSearch(); const closed = search.closed ?? false; return (
{data.owner} {" "} / projects Open Closed
{data.canCreate && }
{data.projects.length === 0 ? ( Projects track issues and pull requests across repositories. ) : ( )}
); }