'use client'; import { AnimatePresence, motion } from 'framer-motion'; import { useState, useCallback, useEffect } from 'react'; import { useWindowSize } from 'usehooks-ts'; import Sidebar from './Sidebar'; interface ChatBlockProps { isVisible: boolean; onClose: () => void; initialMessage?: string; } export interface Message { id: string; content: string; role: 'user' | 'assistant'; timestamp: Date; } export default function ChatBlock({ isVisible, onClose, initialMessage, }: ChatBlockProps) { const [messages, setMessages] = useState([]); const [input, setInput] = useState(''); const [isSidebarOpen, setIsSidebarOpen] = useState(true); const { width: windowWidth } = useWindowSize(); const isMobile = windowWidth ? windowWidth < 768 : false; const [currentUrl] = useState(''); // Spring configuration for smoother animations const springConfig = { type: 'spring', stiffness: 350, damping: 30, }; // Animation variants for the main container const containerVariants = { hidden: { opacity: 0, scale: 0.8 }, visible: { opacity: 1, scale: 1, transition: springConfig, }, exit: { opacity: 0, scale: 0.8, transition: { duration: 0.2 }, }, }; const handleSubmit = useCallback( (e: React.FormEvent) => { e.preventDefault(); if (!input.trim()) return; const newMessage: Message = { id: Date.now().toString(), content: input, role: 'user', timestamp: new Date(), }; setMessages((prev) => [...prev, newMessage]); setInput(''); }, [input], ); useEffect(() => { if (isVisible && initialMessage && messages.length === 0) { const newMessage: Message = { id: Date.now().toString(), content: initialMessage, role: 'user', timestamp: new Date(), }; setMessages([newMessage]); } }, [isVisible, initialMessage, messages.length]); useEffect(() => { const handleKeyDown = (e: KeyboardEvent) => { if (!isVisible) return; // Only handle shortcuts when chat is visible // Handle ESC to close if (e.key === 'Escape') { e.preventDefault(); onClose(); } // Handle CMD+Enter or CTRL+Enter to submit if ((e.metaKey || e.ctrlKey) && e.key === 'Enter' && input.trim()) { e.preventDefault(); handleSubmit(e as unknown as React.FormEvent); } // Handle CMD+K or CTRL+K to toggle sidebar if ((e.metaKey || e.ctrlKey) && e.key === 'k') { e.preventDefault(); setIsSidebarOpen(!isSidebarOpen); } }; window.addEventListener('keydown', handleKeyDown); return () => window.removeEventListener('keydown', handleKeyDown); }, [ onClose, handleSubmit, input, isVisible, isSidebarOpen, setIsSidebarOpen, ]); return ( {isVisible && ( {!isMobile && ( setIsSidebarOpen(!isSidebarOpen)} /> )}
{!isMobile && ( setIsSidebarOpen(!isSidebarOpen)} className="p-2 hover:bg-gray-100 text-gray-600 hover:text-gray-900 transition-colors " whileHover={{ scale: 1.05 }} whileTap={{ scale: 0.95 }} > {isSidebarOpen ? '←' : '→'} )}

Browser

Close
{/* Browser Chrome */}
{/* Window Controls */}
{/* Navigation Bar */}
{currentUrl || 'about:blank'}
{/* Browser Content */}