"use client"; import React, { useState, useRef, useEffect } from 'react'; import { motion, AnimatePresence } from 'framer-motion'; import { MessageCircle, X, Send, MinusSquare, Maximize2, Minimize2, Loader2, Bot } from 'lucide-react'; import { cn } from '@/lib/utils'; import { useStore } from '@/lib/store'; interface Message { role: 'user' | 'assistant'; content: string; } 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 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 { // Retrieve history for context (optional, limiting to last 10 messages) const history = messages.slice(-10).map(m => ({ role: m.role, content: m.content })); // Get cookies from store const { settings } = useStore.getState(); const grokCookies = settings.grokCookies; // Parse cookies string to object if retrieved from text area (simple key=value parsing) let cookieObj: Record = {}; if (grokCookies) { // Basic parsing for "name=value; name2=value2" or JSON try { // Try JSON first const parsed = JSON.parse(grokCookies); if (Array.isArray(parsed)) { // Handle standard cookie export format (list of objects) parsed.forEach((c: any) => { if (c.name && c.value) { cookieObj[c.name] = c.value; } }); } else if (typeof parsed === 'object' && parsed !== null) { // Handle direct key-value object // Cast to ensure type compatibility if needed, though 'parsed' is anyish here cookieObj = parsed as Record; } } catch { // Try semicolon separated grokCookies.split(';').forEach((c: string) => { const parts = c.trim().split('='); if (parts.length >= 2) { const key = parts[0].trim(); const val = parts.slice(1).join('=').trim(); if (key && val) cookieObj[key] = val; } }); } } const res = await fetch('/api/grok-debug', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ message: userMsg, history: history, cookies: cookieObj, userAgent: navigator.userAgent }) }); const data = await res.json(); if (data.error || data.detail) { // Handle both simple error string and FastAPI detail array 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('Grok Chat Error:', error); setMessages(prev => [...prev, { role: 'assistant', content: `Error: ${error.message || 'Failed to connect to Grok.'}` }]); } finally { setIsLoading(false); } }; const handleKeyDown = (e: React.KeyboardEvent) => { if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); handleSend(); } }; 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 */}
setIsMinimized(!isMinimized)}>
Grok AI
{/* Messages Area */} {!isMinimized && ( <>
{messages.length === 0 && (

Ask Grok anything...

)} {messages.map((msg, idx) => (
{msg.content}
))} {isLoading && (
Computing...
)}
{/* Input Area */}
setInput(e.target.value)} onKeyDown={handleKeyDown} placeholder="Type a message..." className="flex-1 bg-black/50 border border-white/10 rounded-xl px-4 py-2.5 text-sm text-white focus:outline-none focus:border-purple-500/50 focus:ring-1 focus:ring-purple-500/20 transition-all placeholder:text-white/20" disabled={isLoading} />
)} )}
); }