"use client";
import { useEffect, useState, useCallback, useMemo, useRef } from "react";
import { useEditor, EditorContent } from "@tiptap/react";
import StarterKit from "@tiptap/starter-kit";
import Placeholder from "@tiptap/extension-placeholder";
import type { NoteDetail } from "@/lib/types";
import { useDebounce } from "@/lib/use-debounce";
import { copilotTransform, type CopilotAction, type CopilotTone } from "@/lib/copilot-client";
import { toast } from "@/lib/toast";
const TOOLBAR_BTN: React.CSSProperties = {
border: "none",
borderRadius: "var(--nl-radius-sm)",
padding: "4px 8px",
background: "transparent",
color: "var(--nl-text-secondary)",
fontSize: "var(--nl-fs-sm)",
cursor: "pointer",
};
const TOOLBAR_BTN_ACTIVE: React.CSSProperties = {
...TOOLBAR_BTN,
background: "rgba(90,140,255,0.18)",
color: "var(--nl-text-primary)",
};
function ToolbarButton({ active, onClick, label }: { active: boolean; onClick: () => void; label: string }) {
return (
);
}
export function NoteEditor({
note,
onSave,
isSaving = false,
autoSave = true,
autoSaveDelayMs = 1500,
copilotNoteId,
copilotWorkspaceId,
}: {
note: NoteDetail;
onSave: (updates: { title: string; body: string }, options?: { quiet?: boolean }) => Promise
"); editor.chain().focus().insertContent(`
${escaped}
`).run(); toast.success("Continuation inserted — review and save"); } catch (e) { toast.error(e instanceof Error ? e.message : "Continue failed"); } finally { setCopilotBusy(false); } return; } // "explain" shows result in a tooltip, doesn't replace text if (action === "explain") { if (!selected) { toast.error("Select text to explain"); return; } setCopilotBusy(true); try { const out = await copilotTransform(copilotNoteId, copilotWorkspaceId, action, selected); setExplainResult(out); } catch (e) { toast.error(e instanceof Error ? e.message : "Explain failed"); } finally { setCopilotBusy(false); } return; } if (!selected) { toast.error("Select text in the editor first"); return; } setCopilotBusy(true); try { const out = await copilotTransform(copilotNoteId, copilotWorkspaceId, action, selected, tone); const escaped = out .split("\n") .map((line) => line.replace(//g, ">")) .join(""); editor.chain().focus().deleteSelection().insertContent(`
${escaped}
`).run(); toast.success("Copilot insert applied — review and save"); } catch (e) { toast.error(e instanceof Error ? e.message : "Copilot failed"); } finally { setCopilotBusy(false); } }, [editor, copilotNoteId, copilotWorkspaceId], ); return (