"use client"; import { useState, useCallback } from "react"; interface Message { role: "user" | "assistant"; content: string; } export function useClaudeChat(campaignId: string) { const [messages, setMessages] = useState([]); const [isStreaming, setIsStreaming] = useState(false); const [sessionId, setSessionId] = useState(null); const sendMessage = useCallback( async (content: string) => { const userMessage: Message = { role: "user", content }; setMessages((prev) => [...prev, userMessage]); setIsStreaming(true); const assistantMessage: Message = { role: "assistant", content: "" }; setMessages((prev) => [...prev, assistantMessage]); try { const res = await fetch("/api/claude", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ message: content, sessionId, campaignId, }), }); if (!res.ok || !res.body) { setMessages((prev) => { const updated = [...prev]; updated[updated.length - 1] = { role: "assistant", content: "Failed to get response from Claude.", }; return updated; }); setIsStreaming(false); return; } const reader = res.body.getReader(); const decoder = new TextDecoder(); let buffer = ""; while (true) { const { done, value } = await reader.read(); if (done) break; buffer += decoder.decode(value, { stream: true }); const lines = buffer.split("\n"); buffer = lines.pop() || ""; for (const line of lines) { if (!line.startsWith("data: ")) continue; try { const data = JSON.parse(line.slice(6)); if (data.done) continue; if (data.text) { setMessages((prev) => { const updated = [...prev]; const last = updated[updated.length - 1]; updated[updated.length - 1] = { ...last, content: last.content + data.text, }; return updated; }); } if (data.sessionId) { setSessionId(data.sessionId); } } catch { // skip malformed lines } } } } catch { setMessages((prev) => { const updated = [...prev]; updated[updated.length - 1] = { role: "assistant", content: "Connection error. Please try again.", }; return updated; }); } setIsStreaming(false); }, [campaignId, sessionId] ); return { messages, sendMessage, isStreaming }; }