import { CampaignDocuments } from "@/components/campaign/CampaignDocuments"; import { DocumentPreview } from "@/components/documents/DocumentPreview"; import { Tab, TabbedLayout } from "@/components/layout/TabbedLayout"; import { Loader } from "@/components/Loader"; import { DocumentLoader } from "@/context/document/DocumentLoader"; import { useDocument } from "@/context/document/hooks"; import { pb } from "@/lib/pocketbase"; import type { Campaign, DocumentId } from "@/lib/types"; import { createFileRoute, Link } from "@tanstack/react-router"; import { useEffect, useState } from "react"; import { z } from "zod"; const CampaignTabs = { sessions: { label: "Sessions", docType: "session" }, secrets: { label: "Secrets", docType: "secret" }, npcs: { label: "NPCs", docType: "npc" }, locations: { label: "Locations", docType: "location" }, threads: { label: "Threads", docType: "thread" }, fronts: { label: "Fronts", docType: "front" }, } as const; const campaignSearchSchema = z.object({ tab: z .enum(Object.keys(CampaignTabs) as (keyof typeof CampaignTabs)[]) .default("sessions"), docId: z.optional(z.string().transform((s) => s as DocumentId)), }); export const Route = createFileRoute( "/_app/_authenticated/campaigns/$campaignId", )({ component: RouteComponent, pendingComponent: Loader, validateSearch: (s) => campaignSearchSchema.parse(s), }); function RouteComponent() { const params = Route.useParams(); const { tab, docId } = Route.useSearch(); const [loading, setLoading] = useState(true); const [campaign, setCampaign] = useState(null); useEffect(() => { async function fetchData() { setLoading(true); const campaign = await pb .collection("campaigns") .getOne(params.campaignId); setCampaign(campaign as Campaign); setLoading(false); } fetchData(); }, [setCampaign, setLoading]); if (loading || campaign === null) { return ; } return ( {campaign.name} } navigation={ ← Back to campaigns } tabs={Object.entries(CampaignTabs).map(([key, { label }]) => ( ))} content={ } flyout={docId && } /> ); } function Flyout({ docId }: { docId: DocumentId }) { const { docResult } = useDocument(docId); if (docResult?.type !== "ready") { return ( ); } const doc = docResult.value.doc; return ; }