feat(frontend): message search and session export entry points
- SearchModal queries GET /messages/search and jumps to the matching session; opened from the sidebar button or Ctrl+K - session items in the sidebar gain a hover export button that downloads the markdown export via an authenticated fetch + blob (plain links cannot send the JWT)
This commit is contained in:
1 parent
9d040fde0b
commit
26d65dd6bb
4 files changed
+143
-7
No files matched your search
@@ -1,7 +1,8 @@
|
||||
import { useEffect } from 'react'
|
||||
import { useEffect, useState } from 'react'
|
||||
import { useParams } from 'react-router-dom'
|
||||
import { useChatStore } from '../../store/chatStore'
|
||||
import ChatContainer from '../../components/chat/ChatContainer'
|
||||
import SearchModal from '../../components/chat/SearchModal'
|
||||
import Sidebar from '../../components/layout/Sidebar'
|
||||
import { api } from '../../api/client'
|
||||
import type { Message } from '../../types/chat'
|
||||
@@ -9,6 +10,7 @@ import type { Message } from '../../types/chat'
|
||||
export default function ChatPage() {
|
||||
const { sessionId } = useParams()
|
||||
const { setSessionId, setMessages } = useChatStore()
|
||||
const [showSearch, setShowSearch] = useState(false)
|
||||
|
||||
useEffect(() => {
|
||||
if (!sessionId) return
|
||||
@@ -30,12 +32,26 @@ export default function ChatPage() {
|
||||
return () => { cancelled = true }
|
||||
}, [sessionId, setSessionId, setMessages])
|
||||
|
||||
// Ctrl+K opens message search
|
||||
useEffect(() => {
|
||||
const onKey = (e: KeyboardEvent) => {
|
||||
if ((e.ctrlKey || e.metaKey) && e.key === 'k') {
|
||||
e.preventDefault()
|
||||
setShowSearch(true)
|
||||
}
|
||||
}
|
||||
window.addEventListener('keydown', onKey)
|
||||
return () => window.removeEventListener('keydown', onKey)
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<div className="flex h-full">
|
||||
<Sidebar />
|
||||
<Sidebar onSearch={() => setShowSearch(true)} />
|
||||
<div className="flex-1 min-w-0">
|
||||
<ChatContainer />
|
||||
</div>
|
||||
{showSearch && <SearchModal onClose={() => setShowSearch(false)} />}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user