From a0fdf2486eb70ee0837d8288102fde5bb6d35508 Mon Sep 17 00:00:00 2001 From: Logan Date: Sun, 21 Jun 2026 14:55:34 -0400 Subject: [PATCH] chat fixes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Focus: textarea gets refocused via inputRef after the AI response (or error) lands Persistence: chat history saved to localStorage keyed by trip ID, loaded on mount — survives refreshes --- drb-frontend/app/trips/[id]/page.tsx | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/drb-frontend/app/trips/[id]/page.tsx b/drb-frontend/app/trips/[id]/page.tsx index fc754f5..d2f8505 100644 --- a/drb-frontend/app/trips/[id]/page.tsx +++ b/drb-frontend/app/trips/[id]/page.tsx @@ -497,6 +497,8 @@ interface SuggestionCard { added?: boolean; } +const CHAT_STORAGE_KEY = (tripId: string) => `drb-trip-chat-${tripId}`; + function AssistantPanel({ trip, onAddEvent, @@ -504,15 +506,26 @@ function AssistantPanel({ trip: TripRecord & { events: TripEvent[] }; onAddEvent: (event: TripEvent) => void; }) { - const [messages, setMessages] = useState([]); + const storageKey = CHAT_STORAGE_KEY(trip.trip_id); + const [messages, setMessages] = useState(() => { + try { + const saved = localStorage.getItem(storageKey); + return saved ? JSON.parse(saved) : []; + } catch { return []; } + }); const [input, setInput] = useState(""); const [loading, setLoading] = useState(false); - const bottomRef = useRef(null); + const bottomRef = useRef(null); + const inputRef = useRef(null); useEffect(() => { bottomRef.current?.scrollIntoView({ behavior: "smooth" }); }, [messages]); + useEffect(() => { + try { localStorage.setItem(storageKey, JSON.stringify(messages)); } catch { /* quota */ } + }, [messages, storageKey]); + async function send() { const text = input.trim(); if (!text || loading) return; @@ -540,6 +553,7 @@ function AssistantPanel({ ]); } finally { setLoading(false); + inputRef.current?.focus(); } } @@ -703,6 +717,7 @@ function AssistantPanel({