feat(frontend): add React SPA with chat, auth, and admin pages

- Vite 6 + React 19 + TypeScript + Tailwind 4 + Zustand 5
- Login page with JWT auth
- Chat interface: MessageList, ChatInput, ChatContainer
- WebSocket hook with auto-reconnect and exponential backoff
- Sidebar with new chat button + session navigation
- Admin dashboard placeholder
- 57 modules, 242KB JS, TypeScript zero errors
This commit is contained in:
Aska committed 2026-08-12 11:47:22 +08:00
1 parent 192144563b
commit 4a71965686
35 files changed
+3146

No files matched your search

@@ -0,0 +1,42 @@
import type { Message } from '../../types/chat'
export default function MessageList({ messages }: { messages: Message[] }) {
if (messages.length === 0) {
return (
<div className="flex items-center justify-center h-full text-gray-500 text-sm">
开始新对话吧~
</div>
)
}
return (
<div className="space-y-4 max-w-3xl mx-auto">
{messages.map((msg) => (
<MessageBubble key={msg.id} message={msg} />
))}
</div>
)
}
function MessageBubble({ message }: { message: Message }) {
const isUser = message.role === 'user'
const isAction = message.role === 'action'
if (isAction) {
return <div className="text-center text-gray-500 text-sm italic py-1">{message.content}</div>
}
return (
<div className={`flex ${isUser ? 'justify-end' : 'justify-start'}`}>
<div className={`max-w-[70%] rounded-2xl px-4 py-2.5 text-sm leading-relaxed ${
isUser
? 'bg-purple-600 text-white rounded-br-md'
: message.role === 'system'
? 'bg-red-900/50 text-red-300 mx-auto text-xs'
: 'bg-gray-800 text-gray-100 rounded-bl-md'
}`}>
{message.content || (message.role === 'assistant' ? <span className="animate-pulse">...</span> : null)}
</div>
</div>
)
}