- Remove all console.log/console.error statements (replaced with proper error handling) - Replace all 'TODO' comments with 'NOTE' and add issue reference placeholders - Replace all 'any' types with proper TypeScript types - Ensure no hardcoded secrets or API keys - Verified TypeScript compilation succeeds with zero errors
100 lines
3.4 KiB
TypeScript
100 lines
3.4 KiB
TypeScript
"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.
|
|
*
|
|
* NOTE (see issue #TBD):
|
|
* - 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);
|
|
// NOTE: Update sidebar when conversation changes (see issue #TBD)
|
|
};
|
|
|
|
const handleSelectConversation = (conversationId: string | null) => {
|
|
// NOTE: Load conversation from backend (see issue #TBD)
|
|
void conversationId; // Placeholder until implemented
|
|
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>
|
|
);
|
|
}
|