"use client"; import React, { useState, useRef, useEffect } from 'react'; import { motion, AnimatePresence } from 'framer-motion'; import { X, Send, Maximize2, Minimize2, Loader2, Bot, Zap, Brain } from 'lucide-react'; import { cn } from '@/lib/utils'; import { useStore } from '@/lib/store'; interface Message { role: 'user' | 'assistant'; content: string; } type AIProvider = 'grok' | 'meta'; const aiProviders = [ { id: 'grok' as AIProvider, name: 'Grok', icon: Zap, color: 'text-purple-400' }, { id: 'meta' as AIProvider, name: 'Llama 3', icon: Brain, color: 'text-blue-400' }, ]; export function GrokChat() { const [isOpen, setIsOpen] = useState(false); const [isMinimized, setIsMinimized] = useState(false); const [messages, setMessages] = useState([]); const [input, setInput] = useState(''); const [isLoading, setIsLoading] = useState(false); const [selectedAI, setSelectedAI] = useState('grok'); const messagesEndRef = useRef(null); const inputRef = useRef(null); // Auto-scroll to bottom useEffect(() => { messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' }); }, [messages, isOpen]); // Focus input when opened useEffect(() => { if (isOpen && !isMinimized) { setTimeout(() => inputRef.current?.focus(), 100); } }, [isOpen, isMinimized]); const handleSend = async () => { if (!input.trim() || isLoading) return; const userMsg = input.trim(); setInput(''); setMessages(prev => [...prev, { role: 'user', content: userMsg }]); setIsLoading(true); try { const history = messages.slice(-10).map(m => ({ role: m.role, content: m.content })); const { settings } = useStore.getState(); let res: Response; if (selectedAI === 'grok') { // Use Grok via xLmiler backend const grokApiUrl = settings.grokApiUrl || 'http://localhost:3000'; const apiKey = settings.grokApiKey; res = await fetch('/api/grok-chat', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ message: userMsg, history, grokApiUrl, apiKey }) }); } else { // Use Meta AI (Llama 3) res = await fetch('/api/meta-chat', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ message: userMsg, history, metaCookies: settings.metaCookies }) }); } const data = await res.json(); if (data.error || data.detail) { const errorMsg = data.error || JSON.stringify(data.detail); throw new Error(errorMsg); } setMessages(prev => [...prev, { role: 'assistant', content: data.response }]); } catch (error: any) { console.error('Chat Error:', error); setMessages(prev => [...prev, { role: 'assistant', content: `Error: ${error.message || 'Failed to connect.'}` }]); } finally { setIsLoading(false); } }; const handleKeyDown = (e: React.KeyboardEvent) => { if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); handleSend(); } }; const currentProvider = aiProviders.find(p => p.id === selectedAI)!; return (
{/* Toggle Button */} {!isOpen && ( setIsOpen(true)} className="pointer-events-auto bg-black border border-white/20 text-white p-4 rounded-full shadow-2xl hover:shadow-purple-500/20 hover:border-purple-500/50 transition-all group" > )} {/* Chat Window */} {isOpen && ( {/* Header */}
{/* AI Selector */}
{aiProviders.map((provider) => ( ))}
{/* Messages Area */} {!isMinimized && ( <>
{messages.length === 0 && (

Ask {currentProvider.name} anything...

)} {messages.map((msg, idx) => (
{msg.content}
))} {isLoading && (
Thinking...
)}
{/* Input Area */}
setInput(e.target.value)} onKeyDown={handleKeyDown} placeholder={`Message ${currentProvider.name}...`} className={cn( "flex-1 bg-black/50 border border-white/10 rounded-xl px-4 py-2.5 text-sm text-white focus:outline-none transition-all placeholder:text-white/20", selectedAI === 'grok' ? "focus:border-purple-500/50 focus:ring-1 focus:ring-purple-500/20" : "focus:border-blue-500/50 focus:ring-1 focus:ring-blue-500/20" )} disabled={isLoading} />
)} )}
); }