// PURPOSE: Standalone demo of @crema/knowledge-ui over MockKnowledgeTransport. // Drop into a consuming app's route (e.g. routes/knowledge-demo.tsx) to // exercise every surface with fixtures and no running service. // =========================================================================== import { useEffect, useState } from "react"; import { CollectionForm, CollectionList, ObjectList, ObjectViewer, MockKnowledgeTransport, type Collection, type CollectionInput, type CollectionPatch, type KnowledgeTransport, type ObjectOutline, type ObjectSummary, } from "../src/index"; const transport: KnowledgeTransport = new MockKnowledgeTransport(); type View = | { kind: "collections" } | { kind: "collection"; slug: string } | { kind: "object"; id: string }; export default function KnowledgeDemo() { const [view, setView] = useState({ kind: "collections" }); const [collections, setCollections] = useState([]); const [pending, setPending] = useState>({}); const [objects, setObjects] = useState([]); const [outline, setOutline] = useState(null); const [creating, setCreating] = useState(null); const [editing, setEditing] = useState(null); const [busy, setBusy] = useState(false); async function refresh() { const page = await transport.listCollections(); setCollections(page.collections); const queue = await transport.reviewQueue(); const counts: Record = {}; for (const c of queue) counts[c.collection] = (counts[c.collection] ?? 0) + 1; setPending(counts); } useEffect(() => { void refresh(); }, []); useEffect(() => { if (view.kind === "collection") void transport.listObjects(view.slug).then((p) => setObjects(p.objects)); if (view.kind === "object") void transport.outline(view.id).then(setOutline); }, [view]); async function onCreate(value: CollectionInput | CollectionPatch) { setBusy(true); await transport.createCollection(value as CollectionInput); setBusy(false); setCreating(null); void refresh(); } async function onEdit(value: CollectionInput | CollectionPatch) { if (!editing) return; setBusy(true); await transport.updateCollection(editing.slug, value as CollectionPatch); setBusy(false); setEditing(null); void refresh(); } return (
{view.kind === "collections" && ( <> {creating && (

New corpus

setCreating(null)} />
)} {editing && (

Corpus settings

setEditing(null)} />
)} setCreating(owner)} onOpen={(c) => setView({ kind: "collection", slug: c.slug })} /> )} {view.kind === "collection" && ( <>

{view.slug}

setView({ kind: "object", id: o.object_id })} /> )} {view.kind === "object" && outline && ( transport.readText(outline.object_id, sel)} resolveBlobUrl={() => transport.blobUrl(outline.object_id)} onOpenObject={(id) => setView({ kind: "object", id })} actions={{ onVerify: () => transport.updateObject(outline.object_id, { verified_at: new Date().toISOString() }), onDownload: () => transport.blobUrl(outline.object_id).then((u) => window.open(u)), }} /> )}
); }