"use client"; import Link from "next/link"; import { useEffect, useState } from "react"; import { useParams } from "next/navigation"; import { AppShell } from "@/components/AppShell"; import { NoteEditor } from "@/components/NoteEditor"; import { MetadataPanel } from "@/components/MetadataPanel"; import { LinkedNotesPanel } from "@/components/LinkedNotesPanel"; import { TaskReviewPanel } from "@/components/TaskReviewPanel"; import { ArtifactPanel } from "@/components/ArtifactPanel"; import { AgentTimeline } from "@/components/AgentTimeline"; import { LinkNoteModal } from "@/components/LinkNoteModal"; import { archiveNote, createNoteArtifact, createNoteTask, getNoteDetail, restoreNote, summarizeNote, updateNoteDetail } from "@/lib/notes-client"; import type { NoteDetail } from "@/lib/types"; export default function NoteDetailPage() { const params = useParams<{ noteId: string }>(); const noteId = params.noteId; const [note, setNote] = useState(null); const [isSaving, setIsSaving] = useState(false); const [isCreatingTask, setIsCreatingTask] = useState(false); const [isCreatingArtifact, setIsCreatingArtifact] = useState(false); const [error, setError] = useState(null); const [showLinkNote, setShowLinkNote] = useState(false); useEffect(() => { void (async () => { try { setNote(await getNoteDetail(noteId)); } catch (err) { setError(err instanceof Error ? err.message : "Unable to load note"); } })(); }, [noteId]); async function handleSave(updates: { title: string; body: string }) { if (!note) { return; } setIsSaving(true); try { await updateNoteDetail(note.id, note.workspaceId, updates); const refreshed = await getNoteDetail(note.id); setNote(refreshed); setError(null); } catch (err) { setError(err instanceof Error ? err.message : "Unable to save note"); } finally { setIsSaving(false); } } async function handleCreateArtifact(input: { title: string; artifactType: "file" | "summary" | "extraction" | "citation" | "export"; description?: string; blobPath?: string; }) { if (!note) { return; } setIsCreatingArtifact(true); try { await createNoteArtifact({ id: crypto.randomUUID(), workspaceId: note.workspaceId, noteId: note.id, artifactType: input.artifactType, title: input.title, description: input.description, blobPath: input.blobPath, }); const refreshed = await getNoteDetail(note.id); setNote(refreshed); setError(null); } catch (err) { setError(err instanceof Error ? err.message : "Unable to create artifact"); } finally { setIsCreatingArtifact(false); } } async function handleCreateTask(input: { title: string; description?: string }) { if (!note) { return; } setIsCreatingTask(true); try { await createNoteTask({ id: crypto.randomUUID(), workspaceId: note.workspaceId, noteId: note.id, title: input.title, description: input.description, source: "manual", }); const refreshed = await getNoteDetail(note.id); setNote(refreshed); setError(null); } catch (err) { setError(err instanceof Error ? err.message : "Unable to create task"); } finally { setIsCreatingTask(false); } } async function handleSummarize() { if (!note) return; try { await summarizeNote(note.id, note.workspaceId); setNote(await getNoteDetail(note.id, note.workspaceId)); } catch (err) { setError(err instanceof Error ? err.message : "Unable to summarize note"); } } async function handleArchive() { if (!note) return; try { await archiveNote(note.id, note.workspaceId); setNote(await getNoteDetail(note.id, note.workspaceId)); } catch (err) { setError(err instanceof Error ? err.message : "Unable to archive note"); } } async function handleRestore() { if (!note) return; try { await restoreNote(note.id, note.workspaceId); setNote(await getNoteDetail(note.id, note.workspaceId)); } catch (err) { setError(err instanceof Error ? err.message : "Unable to restore note"); } } if (!note) { return ( Loading} >
{error ?? "Loading note…"}
); } return ( {isSaving ? (
Saving
) : ( {`Review: ${note.metadata.reviewState}`} )} {note.status === "archived" ? ( ) : ( )} } >
{showLinkNote && ( ln.id)} onLinked={() => { setShowLinkNote(false); void getNoteDetail(note.id, note.workspaceId).then(setNote); }} onClose={() => setShowLinkNote(false)} /> )}
); }