feat(frontend): session list sidebar and persisted history loading
Cyrene CI / backend (push) Has been cancelled
Cyrene CI / frontend (push) Has been cancelled

- Sidebar lists sessions with title/relative time, click to switch,
  hover-to-delete; refreshes after each round so new titles appear
- ChatPage loads message history from GET /sessions/:id/messages when
  entering a session
- WS connect now passes user_id so persisted messages have an owner
This commit is contained in:
Aska committed 2026-08-20 20:34:08 +08:00
1 parent f8196c111c
commit 8190007865
5 files changed
+103 -13

No files matched your search

+29 -4
View File
@@ -2,15 +2,40 @@ import { useEffect } from 'react'
import { useParams } from 'react-router-dom'
import { useChatStore } from '../../store/chatStore'
import ChatContainer from '../../components/chat/ChatContainer'
import Sidebar from '../../components/layout/Sidebar'
import { api } from '../../api/client'
import type { Message } from '../../types/chat'
export default function ChatPage() {
const { sessionId } = useParams()
const { setSessionId } = useChatStore()
const { setSessionId, setMessages } = useChatStore()
useEffect(() => {
if (sessionId) setSessionId(sessionId)
}, [sessionId, setSessionId])
if (!sessionId) return
setSessionId(sessionId)
return <ChatContainer />
// Load persisted history for the session
let cancelled = false
api.sessions.messages(sessionId).then((data) => {
if (cancelled) return
const msgs: Message[] = (data.messages || []).map((m) => ({
id: `db-${m.id}`,
session_id: m.session_id,
role: m.role === 'user' ? 'user' : 'assistant',
content: m.content,
created_at: m.created_at,
}))
setMessages(msgs)
}).catch(() => { /* history unavailable */ })
return () => { cancelled = true }
}, [sessionId, setSessionId, setMessages])
return (
<div className="flex h-full">
<Sidebar />
<div className="flex-1 min-w-0">
<ChatContainer />
</div>
</div>
)
}