8e69ac185e
- ChatPanel: add 'chat-message ${role}' CSS classes to message wrappers
so .chat-message.user and .chat-message.assistant rules apply correctly
- LoginPage: rename className 'login-error' -> 'error' to match the
.login-card .error selector in globals.css
- MCPAppRenderer: verify event.source matches iframe contentWindow before
processing postMessage to close cross-window injection vector
- App: remove redundant await refresh() after createNew() since
createNew() already calls refresh() internally
- useArtifacts: wrap listArtifacts call in try/catch with console.error,
matching the error-handling pattern already used in useSessions
49 lines
1.3 KiB
TypeScript
49 lines
1.3 KiB
TypeScript
import { useAuth } from './hooks/useAuth'
|
|
import { useSessions } from './hooks/useSessions'
|
|
import { useChat } from './hooks/useChat'
|
|
import { LoginPage } from './components/LoginPage'
|
|
import { SessionSidebar } from './components/SessionSidebar'
|
|
import { ChatPanel } from './components/ChatPanel'
|
|
import { RightPanel } from './components/RightPanel'
|
|
|
|
function App() {
|
|
const { user, loading: authLoading, login, logout } = useAuth()
|
|
const { sessions, activeSessionId, createNew, switchTo, refresh } = useSessions()
|
|
const { messages, isStreaming, sendMessage } = useChat(activeSessionId)
|
|
|
|
if (authLoading) {
|
|
return (
|
|
<div className='login-page'>
|
|
<div style={{ color: '#8888aa' }}>Loading...</div>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
if (!user) {
|
|
return <LoginPage onLogin={login} />
|
|
}
|
|
|
|
return (
|
|
<div className='app-layout'>
|
|
<SessionSidebar
|
|
sessions={sessions}
|
|
activeSessionId={activeSessionId}
|
|
onSelect={(id) => switchTo(id)}
|
|
onCreate={async () => {
|
|
await createNew()
|
|
}}
|
|
onLogout={logout}
|
|
/>
|
|
<ChatPanel
|
|
messages={messages}
|
|
isStreaming={isStreaming}
|
|
onSend={sendMessage}
|
|
sessionId={activeSessionId}
|
|
/>
|
|
<RightPanel sessionId={activeSessionId} />
|
|
</div>
|
|
)
|
|
}
|
|
|
|
export default App
|