feat: add chat components from jarvis frontend
- Migrated Chat.tsx with message handling and UI structure - Migrated ChatInput.tsx with character limits and keyboard shortcuts - Migrated MessageList.tsx with thinking/reasoning display - Migrated ConversationSidebar.tsx (simplified placeholder) - Migrated BackendStatusBanner.tsx (simplified placeholder) - Created components/chat/index.ts barrel export - Created app/chat/page.tsx placeholder route These components are adapted from jarvis-fe but not yet fully functional: - API calls placeholder (need to wire up /api/brain/query) - Auth hooks stubbed (need useAuth implementation) - Project/conversation hooks stubbed (need implementation) - Imports changed from @jarvis/* to @mosaic/* Next steps: - Implement missing hooks (useAuth, useProjects, useConversations, useApi) - Wire up backend API endpoints - Add proper TypeScript types - Implement full conversation management
This commit is contained in:
99
apps/web/src/app/chat/page.tsx
Normal file
99
apps/web/src/app/chat/page.tsx
Normal file
@@ -0,0 +1,99 @@
|
||||
"use client";
|
||||
|
||||
import { useRef, useState } from "react";
|
||||
import { Chat, type ChatRef, ConversationSidebar, type ConversationSidebarRef } from "@/components/chat";
|
||||
|
||||
/**
|
||||
* Chat Page
|
||||
*
|
||||
* Placeholder route for the chat interface migrated from jarvis-fe.
|
||||
*
|
||||
* TODO:
|
||||
* - Integrate with authentication
|
||||
* - Connect to brain API endpoints (/api/brain/query)
|
||||
* - Implement conversation persistence
|
||||
* - Add project/workspace integration
|
||||
* - Wire up actual hooks (useAuth, useProjects, useConversations, useApi)
|
||||
*/
|
||||
export default function ChatPage() {
|
||||
const chatRef = useRef<ChatRef>(null);
|
||||
const sidebarRef = useRef<ConversationSidebarRef>(null);
|
||||
const [sidebarOpen, setSidebarOpen] = useState(false);
|
||||
const [currentConversationId, setCurrentConversationId] = useState<string | null>(null);
|
||||
|
||||
const handleConversationChange = (conversationId: string | null) => {
|
||||
setCurrentConversationId(conversationId);
|
||||
// TODO: Update sidebar when conversation changes
|
||||
};
|
||||
|
||||
const handleSelectConversation = (conversationId: string | null) => {
|
||||
// TODO: Load conversation from backend
|
||||
console.log("Select conversation:", conversationId);
|
||||
setCurrentConversationId(conversationId);
|
||||
};
|
||||
|
||||
const handleNewConversation = (projectId?: string | null) => {
|
||||
chatRef.current?.startNewConversation(projectId);
|
||||
setCurrentConversationId(null);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="flex h-screen overflow-hidden" style={{ backgroundColor: "rgb(var(--color-background))" }}>
|
||||
{/* Conversation Sidebar */}
|
||||
<ConversationSidebar
|
||||
ref={sidebarRef}
|
||||
isOpen={sidebarOpen}
|
||||
onClose={() => setSidebarOpen(!sidebarOpen)}
|
||||
currentConversationId={currentConversationId}
|
||||
onSelectConversation={handleSelectConversation}
|
||||
onNewConversation={handleNewConversation}
|
||||
/>
|
||||
|
||||
{/* Main Chat Area */}
|
||||
<div className="flex flex-1 flex-col overflow-hidden">
|
||||
{/* Header */}
|
||||
<header
|
||||
className="border-b px-4 py-3 flex items-center gap-3"
|
||||
style={{
|
||||
backgroundColor: "rgb(var(--surface-0))",
|
||||
borderColor: "rgb(var(--border-default))",
|
||||
}}
|
||||
>
|
||||
{/* Toggle Sidebar Button */}
|
||||
<button
|
||||
onClick={() => setSidebarOpen(!sidebarOpen)}
|
||||
className="p-2 rounded-lg transition-colors hover:bg-[rgb(var(--surface-1))]"
|
||||
aria-label="Toggle sidebar"
|
||||
title="Toggle conversation history"
|
||||
>
|
||||
<svg
|
||||
className="h-5 w-5"
|
||||
style={{ color: "rgb(var(--text-muted))" }}
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
strokeWidth={1.5}
|
||||
>
|
||||
<path d="M3.75 6.75h16.5M3.75 12h16.5m-16.5 5.25h16.5" />
|
||||
</svg>
|
||||
</button>
|
||||
|
||||
<div className="flex-1">
|
||||
<h1 className="text-lg font-semibold" style={{ color: "rgb(var(--text-primary))" }}>
|
||||
AI Chat
|
||||
</h1>
|
||||
<p className="text-xs" style={{ color: "rgb(var(--text-muted))" }}>
|
||||
Migrated from Jarvis - Connect to brain API for full functionality
|
||||
</p>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
{/* Chat Component */}
|
||||
<Chat
|
||||
ref={chatRef}
|
||||
onConversationChange={handleConversationChange}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user