From 1c26daa82806c3e27cccc5c14dce87eb02be5919 Mon Sep 17 00:00:00 2001 From: Drew Haven Date: Sat, 9 Aug 2025 15:49:36 -0700 Subject: [PATCH] Adding UI for threads --- src/components/documents/DocumentEditForm.tsx | 11 +++ src/components/documents/DocumentPreview.tsx | 12 +++ src/components/documents/DocumentRow.tsx | 12 +++ src/components/documents/GenericEditForm.tsx | 87 +++++++++++++++++++ .../documents/NewCampaignDocumentForm.tsx | 2 + 5 files changed, 124 insertions(+) create mode 100644 src/components/documents/GenericEditForm.tsx diff --git a/src/components/documents/DocumentEditForm.tsx b/src/components/documents/DocumentEditForm.tsx index e19d9d5..b5eba63 100644 --- a/src/components/documents/DocumentEditForm.tsx +++ b/src/components/documents/DocumentEditForm.tsx @@ -6,6 +6,7 @@ import { SceneEditForm } from "./scene/SceneEditForm"; import { SecretEditForm } from "./secret/SecretEditForm"; import { SessionEditForm } from "./session/SessionEditForm"; import { TreasureEditForm } from "./treasure/TreasureEditForm"; +import { GenericEditForm } from "./GenericEditForm"; /** * Renders a form for any document type depending on the relationship. @@ -26,5 +27,15 @@ export const DocumentEditForm = ({ document }: { document: AnyDocument }) => { return ; case "treasure": return ; + case "thread": + return ( + + ); } }; diff --git a/src/components/documents/DocumentPreview.tsx b/src/components/documents/DocumentPreview.tsx index 070006e..86d6d4e 100644 --- a/src/components/documents/DocumentPreview.tsx +++ b/src/components/documents/DocumentPreview.tsx @@ -32,6 +32,15 @@ export const DocumentPreview = ({ doc }: { doc: AnyDocument }) => { const ShowDocument = ({ doc }: { doc: AnyDocument }) => { switch (doc.type) { + case "front": + return ( + + ); + case "location": return ( { case "scene": return ; + case "thread": + return ; + case "treasure": return ; } diff --git a/src/components/documents/DocumentRow.tsx b/src/components/documents/DocumentRow.tsx index 5268633..f024e01 100644 --- a/src/components/documents/DocumentRow.tsx +++ b/src/components/documents/DocumentRow.tsx @@ -17,6 +17,15 @@ export const DocumentRow = ({ root?: AnyDocument; }) => { switch (document.type) { + case "front": + return ( + + ); + case "location": return ( ; + case "thread": + return ; + case "treasure": return ; } diff --git a/src/components/documents/GenericEditForm.tsx b/src/components/documents/GenericEditForm.tsx new file mode 100644 index 0000000..637e1cd --- /dev/null +++ b/src/components/documents/GenericEditForm.tsx @@ -0,0 +1,87 @@ +import { AutoSaveTextarea } from "@/components/AutoSaveTextarea"; +import { pb } from "@/lib/pocketbase"; +import type { AnyDocument, Location } from "@/lib/types"; +import { useDocumentCache } from "@/context/document/hooks"; + +export type GenericFieldType = "multiline" | "singleline" | "checkbox"; + +export type Props = { + doc: T; + fields: { [K in keyof T["data"]]: GenericFieldType }; +}; + +export const GenericEditForm = ({ + doc, + fields, +}: Props) => { + return ( +
+ { + // The type checker seems to lose the types when using Object.entries here. + Object.entries(fields).map( + ([fieldName, fieldType]: [string, unknown]) => ( + + ), + ) + } +
+ ); +}; + +const GenericEditFormField = ({ + doc, + fieldName, + fieldType, +}: { + doc: T; + fieldName: keyof T["data"]; + fieldType: GenericFieldType; +}) => { + const { dispatch } = useDocumentCache(); + + // The type checker really doesn't like indexing into this type implicitly, so we'll store it in a temporary to give it the right hints. + const data = doc.data as T["data"]; + + async function saveField(value: string) { + const updated: T = await pb.collection("documents").update(doc.id, { + data: { + ...doc.data, + [fieldName]: value, + }, + }); + dispatch({ type: "setDocument", doc: updated }); + } + + switch (fieldType) { + case "multiline": + return ( + + ); + case "singleline": + return ( + + ); + case "checkbox": + return ( + saveField(e.target.value)} + className="accent-emerald-500 w-5 h-5" + /> + ); + } +}; diff --git a/src/components/documents/NewCampaignDocumentForm.tsx b/src/components/documents/NewCampaignDocumentForm.tsx index 40154ef..5b09628 100644 --- a/src/components/documents/NewCampaignDocumentForm.tsx +++ b/src/components/documents/NewCampaignDocumentForm.tsx @@ -20,6 +20,8 @@ export const NewCampaignDocumentForm = ({ switch (docType) { case "session": return ; + case "thread": + return ; default: throw new Error( `Rendered NewCampaignDocumentForm with unsupported docType: ${docType}`,