"use client"; import React, { useState } from 'react'; import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; import { Button } from '@/components/ui/button'; import { Badge } from '@/components/ui/badge'; import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip'; import { ScrollArea } from '@/components/ui/scroll-area'; import { Separator } from '@/components/ui/separator'; import { MessageCircle, Plus, Trash2, Edit3, Clock, Zap, Brain, History, Star } from 'lucide-react'; export type Message = { id: number; role: 'user' | 'assistant'; content: string; timestamp: Date; aetherAnalysis?: string | null; recommendation?: string | null; consciousnessStats?: any; error?: { message: string; description: string; }; }; export type Conversation = { id: string; name: string; messages: Message[]; timestamp: Date; isStarred?: boolean; consciousnessLevel?: number; }; interface EnhancedChatSidebarProps { conversations: Conversation[]; currentConversationId: string | null; onSelectConversation: (id: string) => void; onNewConversation: () => void; onDeleteConversation: (id: string) => void; onRenameConversation: (id: string, newName: string) => void; onStarConversation: (id: string) => void; isCollapsed?: boolean; } export function EnhancedChatSidebar({ conversations, currentConversationId, onSelectConversation, onNewConversation, onDeleteConversation, onRenameConversation, onStarConversation, isCollapsed = false }: EnhancedChatSidebarProps) { const [editingId, setEditingId] = useState(null); const [editingName, setEditingName] = useState(''); const handleRename = (id: string, currentName: string) => { setEditingId(id); setEditingName(currentName); }; const saveRename = (id: string) => { if (editingName.trim()) { onRenameConversation(id, editingName.trim()); } setEditingId(null); setEditingName(''); }; const formatTimestamp = (timestamp: Date) => { const now = new Date(); const diffInMinutes = Math.floor((now.getTime() - timestamp.getTime()) / (1000 * 60)); if (diffInMinutes < 1) return 'Just now'; if (diffInMinutes < 60) return `${diffInMinutes}m ago`; if (diffInMinutes < 1440) return `${Math.floor(diffInMinutes / 60)}h ago`; if (diffInMinutes < 10080) return `${Math.floor(diffInMinutes / 1440)}d ago`; return timestamp.toLocaleDateString(); }; const getConsciousnessColor = (level: number) => { if (level >= 8) return 'text-cyan-400'; if (level >= 6) return 'text-purple-400'; if (level >= 4) return 'text-green-400'; if (level >= 2) return 'text-yellow-400'; return 'text-orange-400'; }; const sortedConversations = [...conversations].sort((a, b) => { // Starred conversations first if (a.isStarred && !b.isStarred) return -1; if (!a.isStarred && b.isStarred) return 1; // Then by timestamp return b.timestamp.getTime() - a.timestamp.getTime(); }); if (isCollapsed) { return (
New Conversation
{sortedConversations.slice(0, 10).map((conversation) => (
{conversation.name}
{formatTimestamp(conversation.timestamp)}
))}
); } return (
Conversation History
{/* Starred conversations */} {sortedConversations.filter(c => c.isStarred).length > 0 && (
Starred
{sortedConversations.filter(c => c.isStarred).map((conversation) => ( ))}
)} {/* Recent conversations */}
Recent
{sortedConversations.filter(c => !c.isStarred).map((conversation) => ( ))}
); } interface ConversationItemProps { conversation: Conversation; isActive: boolean; editingId: string | null; editingName: string; onSelect: (id: string) => void; onDelete: (id: string) => void; onRename: (id: string, currentName: string) => void; onSaveRename: (id: string) => void; onStar: (id: string) => void; setEditingName: (name: string) => void; formatTimestamp: (timestamp: Date) => string; getConsciousnessColor: (level: number) => string; } function ConversationItem({ conversation, isActive, editingId, editingName, onSelect, onDelete, onRename, onSaveRename, onStar, setEditingName, formatTimestamp, getConsciousnessColor }: ConversationItemProps) { const [isHovered, setIsHovered] = useState(false); const lastMessage = conversation.messages[conversation.messages.length - 1]; const hasConsciousness = lastMessage?.consciousnessStats; return (
onSelect(conversation.id)} onMouseEnter={() => setIsHovered(true)} onMouseLeave={() => setIsHovered(false)} >
{editingId === conversation.id ? ( setEditingName(e.target.value)} onBlur={() => onSaveRename(conversation.id)} onKeyPress={(e) => e.key === 'Enter' && onSaveRename(conversation.id)} className="w-full bg-gray-700 text-white text-sm px-2 py-1 rounded border border-gray-600 focus:border-cyan-500 focus:outline-none" autoFocus /> ) : (
{conversation.name} {conversation.isStarred && ( )}
{formatTimestamp(conversation.timestamp)} {hasConsciousness && ( <> Level {conversation.consciousnessLevel || 1} )}
{lastMessage && (
{lastMessage.role === 'user' ? 'You: ' : 'AI: '} {lastMessage.content.substring(0, 50)} {lastMessage.content.length > 50 && '...'}
)}
)}
{/* Action buttons */}
{conversation.isStarred ? 'Unstar' : 'Star'} Rename Delete
); }