import { createFileRoute } from "@tanstack/react-router"; import { pb } from "@/lib/pocketbase"; import { AutoSaveTextarea } from "@/components/AutoSaveTextarea"; import { useState } from "react"; import { RelationshipType, type Secret } from "@/lib/types"; import { DocumentList } from "@/components/DocumentList"; export const Route = createFileRoute("/_authenticated/document/$documentId")({ loader: async ({ params }) => { const doc = await pb.collection("documents").getOne(params.documentId); // Fetch the unique relationship where this document is the primary and type is "plannedSecrets" const relationships = await pb.collection("relationships").getList(1, 1, { filter: `primary = "${params.documentId}" && type = "${RelationshipType.Secrets}"`, }); // Get all related secret document IDs from the secondary field const secretIds = relationships.items.length > 0 ? relationships.items[0].secondary : []; // Fetch all related secret documents let secrets: any[] = []; if (Array.isArray(secretIds) && secretIds.length > 0) { secrets = await pb.collection("documents").getFullList({ filter: secretIds.map((id) => `id = "${id}"`).join(" || "), }); } return { document: doc, secrets }; }, component: RouteComponent, }); function RouteComponent() { const { document: session, secrets } = Route.useLoaderData(); const strongStart = session?.data?.session?.strongStart || ""; const [newSecret, setNewSecret] = useState(""); const [adding, setAdding] = useState(false); const [secretList, setSecretList] = useState(secrets); const [error, setError] = useState(null); async function handleSaveStrongStart(newValue: string) { await pb.collection("documents").update(session.id, { data: { ...session.data, session: { ...session.data.session, strongStart: newValue, }, }, }); } async function handleAddSecret() { if (!newSecret.trim()) return; setAdding(true); setError(null); try { // 1. Create the secret document const secretDoc = await pb.collection("documents").create({ campaign: session.campaign, // assuming campaign is an id or object data: { secret: { text: newSecret, discoveredOn: null, }, }, }); // 2. Check for existing relationship const existing = await pb.collection("relationships").getFullList({ filter: `primary = "${session.id}" && type = "${RelationshipType.Secrets}"`, }); if (existing.length > 0) { // Update existing relationship to add new secret to secondary array await pb.collection("relationships").update(existing[0].id, { "+secondary": secretDoc.id, }); } else { // Create new relationship await pb.collection("relationships").create({ primary: session.id, secondary: [secretDoc.id], type: RelationshipType.Secrets, }); } setSecretList([...secretList, secretDoc]); setNewSecret(""); } catch (e: any) { setError(e?.message || "Failed to add secret."); } finally { setAdding(false); } } async function handleToggleDiscovered(secret: Secret, checked: boolean) { // 1. Update the discovered field in the secret document const updatedSecret: Secret = await pb .collection("documents") .update(secret.id, { data: { ...secret.data, secret: { text: secret.data.secret.text, discovered: checked, }, }, }); // 2. Remove any existing discoveredIn relationship const rels = await pb.collection("relationships").getList(1, 1, { filter: `primary = "${secret.id}" && type = "discoveredIn"`, }); if (rels.items.length > 0) { await pb.collection("relationships").delete(rels.items[0].id); } // 3. If marking as discovered, add a new discoveredIn relationship if (checked) { await pb.collection("relationships").create({ primary: secret.id, secondary: [session.id], type: "discoveredIn", }); } // 4. Update local state setSecretList( secretList.map((s: any) => (s.id === secret.id ? updatedSecret : s)), ); } return (

Session Strong Start

{secretList && ( (
{ e.preventDefault(); handleAddSecret(); onSubmit(); }} > setNewSecret(e.target.value)} disabled={adding} /> {error && (
{error}
)}
)} renderRow={(secret) => (
  • handleToggleDiscovered(secret, e.target.checked) } className="accent-emerald-500 w-5 h-5" aria-label="Discovered" /> {secret.data?.secret?.text || ( (No secret text) )}
  • )} /> )}
    ); }