"use client"; import { useState, useCallback, useRef, useEffect } from "react"; import { IngestResultSchema } from "@/lib/schemas/blueprint"; import type { IngestResult } from "@/lib/schemas/blueprint"; import type { LogEntry, PipelineStage } from "@/lib/types"; type PromptBarProps = { stage: PipelineStage; onLog: (entry: Omit) => void; onBlueprint: (result: IngestResult, sourceText: string) => void; onStageChange: (stage: PipelineStage) => void; onDeliveryChange?: (text: string) => void; }; export function PromptBar({ stage, onLog, onBlueprint, onStageChange, onDeliveryChange }: PromptBarProps) { const [prompt, setPrompt] = useState(""); const [running, setRunning] = useState(false); const [showDelivery, setShowDelivery] = useState(false); const [deliveryText, setDeliveryText] = useState(""); const textareaRef = useRef(null); // Load persisted delivery instructions client-side only (avoids SSR hydration mismatch) useEffect(() => { const saved = localStorage.getItem("nexus_delivery_instructions"); if (saved) { setDeliveryText(saved); onDeliveryChange?.(saved); } // eslint-disable-next-line react-hooks/exhaustive-deps }, []); const isIdle = stage === "idle" || stage === "done" || stage === "error"; const canSubmit = isIdle && !running && prompt.trim().length > 0; const handleRun = useCallback(async () => { const text = prompt.trim(); if (!text || !isIdle || running) return; setRunning(true); onStageChange("ingesting"); onLog({ level: "info", message: "Prompt dispatched to Analyst…" }); onLog({ level: "stream", message: text.length > 100 ? text.slice(0, 100) + "…" : text, }); try { const res = await fetch("/api/ingest", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ sourceText: text, locale: "en" }), }); if (!res.ok) { const err = await res.json().catch(() => ({ error: "Unknown error" })); throw new Error((err as { error?: string }).error ?? `HTTP ${res.status}`); } const raw: unknown = await res.json(); const result = IngestResultSchema.parse(raw); onBlueprint(result, text); // Stage management handed to the pipeline orchestrator in page.tsx setPrompt(""); } catch (err) { const msg = err instanceof Error ? err.message : "Pipeline error"; onLog({ level: "error", message: msg }); onStageChange("error"); } finally { setRunning(false); } }, [prompt, isIdle, running, onLog, onBlueprint, onStageChange]); const handleKeyDown = (e: React.KeyboardEvent) => { if (e.key === "Enter" && (e.metaKey || e.ctrlKey)) { e.preventDefault(); void handleRun(); } }; return (