import { useState } from "react"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { MessageCircle, X, Send, Loader2, MapPin, Play, ExternalLink, } from "lucide-react"; import { useMutation } from "@tanstack/react-query"; import { apiRequest } from "@/lib/queryClient"; import { useToast } from "@/hooks/use-toast"; import { useLanguage } from "@/hooks/use-language"; import { useLocation } from "wouter"; type Message = { type: "user" | "bot"; content: string; timestamp: Date; }; export function ChatBot() { const [location, navigate] = useLocation(); const [isOpen, setIsOpen] = useState(false); const [message, setMessage] = useState(""); const [chatHistory, setChatHistory] = useState([]); const { toast } = useToast(); const { language, t } = useLanguage(); const chatMutation = useMutation({ mutationFn: async (message: string) => { const res = await apiRequest("POST", "/api/chat", { message, language }); const data = await res.json(); if (data.error) { throw new Error(data.error); } return data.response; }, onSuccess: (data) => { console.log("Chat response:", data); setChatHistory((prev) => [ ...prev, { type: "bot", content: data.answer, timestamp: new Date(), }, ]); }, onError: (error: Error) => { toast({ title: t("Error", "خطأ"), description: error.message, variant: "destructive", }); }, }); const handleSend = () => { if (!message.trim()) return; setChatHistory((prev) => [ ...prev, { type: "user", content: message, timestamp: new Date() }, ]); chatMutation.mutate(message); setMessage(""); }; const handleKeyPress = (e: React.KeyboardEvent) => { if (e.key === "Enter" && !e.shiftKey) { e.preventDefault(); handleSend(); } }; const renderMessageContent = (content: string) => { const elements: JSX.Element[] = []; // Handle venue & stream buttons const buttonMatch = content.match(/data-url="([^"]+)"[^>]*>([^<]+)/); if (buttonMatch) { const [_, url, buttonText] = buttonMatch; elements.push( ); } // Convert markdown links `[Text](URL)` into full-width buttons const markdownLinkRegex = /\[(.*?)\]\((.*?)\)/g; let lastIndex = 0; let match; while ((match = markdownLinkRegex.exec(content)) !== null) { if (match.index > lastIndex) { elements.push( {content.slice(lastIndex, match.index)} ); } const [_, text, url] = match; elements.push( ); lastIndex = match.index + match[0].length; } if (lastIndex < content.length) { elements.push( {content.slice(lastIndex)} ); } return
{elements}
; }; return (
{isOpen ? (

{t("Summit Assistant", "مساعد القمة")}

{t( "👋 Hello! I'm your Summit Assistant. Ask me anything about the National Development Summit 2025.", "👋 مرحباً! أنا مساعد القمة. اسألني أي شيء عن قمة التنمية الوطنية 2025.", )}
{chatHistory.map((msg, idx) => (
{msg.type === "bot" ? renderMessageContent(msg.content) : msg.content}
))} {chatMutation.isPending && (
)}
setMessage(e.target.value)} onKeyPress={handleKeyPress} placeholder={t("Ask about the summit...", "اسأل عن القمة...")} className="flex-1" />
) : ( )}
); }