import { AnimatePresence, motion } from "framer-motion"; import { Maximize2, MessageCircle, Minimize2, Send, X } from "lucide-react"; import { useEffect, useRef, useState } from "react"; import { createLogger } from "../../shared/lib/logger.js"; import { cn } from "../../shared/lib/utils"; const logger = createLogger("mascot-chat"); export interface ChatMessage { id: string; role: "user" | "mascot"; content: string; timestamp: number; avatar?: string; } interface MascotChatbotProps { onClose?: () => void; isOpen?: boolean; onSendMessage?: (message: string) => Promise; mascotName?: string; mascotAvatar?: string; className?: string; } export function MascotChatbot({ onClose, isOpen = false, onSendMessage, mascotName = "Mascot", mascotAvatar = "https://raw.githubusercontent.com/IMPHNEN/imphnen-frontend-service/develop/apps/dimentorin/public/image/mascot-1.png", className, }: MascotChatbotProps) { const [messages, setMessages] = useState([ { id: "init-1", role: "mascot", content: "Halo! 👋 Saya mascot mu. Ada yang bisa aku bantu tentang conversation atau analytics?", timestamp: Date.now(), }, ]); const [input, setInput] = useState(""); const [loading, setLoading] = useState(false); const [isMinimized, setIsMinimized] = useState(false); const messagesEndRef = useRef(null); const scrollToBottom = () => { messagesEndRef.current?.scrollIntoView({ behavior: "smooth" }); }; useEffect(() => { scrollToBottom(); }, [messages]); const handleSendMessage = async (e: { preventDefault: () => void }) => { e.preventDefault(); if (!input.trim() || loading) return; const userMessage: ChatMessage = { id: `user-${Date.now()}`, role: "user", content: input.trim(), timestamp: Date.now(), }; setMessages((prev) => [...prev, userMessage]); setInput(""); setLoading(true); try { let response = "Aku sedang memproses pertanyaanmu..."; if (onSendMessage) { response = await onSendMessage(input.trim()); } else { // Default mascot responses response = generateMascotResponse(input.trim(), messages); } const mascotMessage: ChatMessage = { id: `mascot-${Date.now()}`, role: "mascot", content: response, timestamp: Date.now(), }; setMessages((prev) => [...prev, mascotMessage]); } catch (error) { logger.error("Error sending message", { error: error instanceof Error ? error.message : String(error), }); const errorMessage: ChatMessage = { id: `mascot-error-${Date.now()}`, role: "mascot", content: "Maaf, ada error saat aku memproses. Coba lagi ya! 😅", timestamp: Date.now(), }; setMessages((prev) => [...prev, errorMessage]); } finally { setLoading(false); } }; if (!isOpen) return null; return ( {/* Header */}

{mascotName}

{loading ? "Mengetik..." : "Online"}

setIsMinimized(!isMinimized)} className="p-1.5 hover:bg-white/20 rounded-lg transition-colors" title={isMinimized ? "Maximize" : "Minimize"} > {isMinimized ? ( ) : ( )} { onClose?.(); }} className="p-1.5 hover:bg-white/20 rounded-lg transition-colors" title="Close" >
{/* Messages */} {!isMinimized && ( <>
{messages.map((message) => ( {message.role === "mascot" && ( {mascotName} )}
{message.content}
))} {loading && ( {mascotName}
)}
{/* Input */}
setInput(e.target.value)} placeholder="Tanya mascot..." disabled={loading} className="flex-1 px-3 py-2 rounded-lg border border-input bg-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring text-sm disabled:opacity-50" />
)} ); } // Default mascot responses based on keywords function generateMascotResponse( input: string, messages: ChatMessage[], ): string { const lowerInput = input.toLowerCase(); const responseMap: Record = { halo: "Halo juga! 👋 Senang ketemu kamu. Ada yang bisa aku bantu?", terima: "Sama-sama! 😊", apa: "Aku adalah mascot virtual yang membantu kamu memahami conversation dan analytics. Tanya aku apa saja!", siapa: "Aku mascot mu yang baik hati! Siap membantu dengan insights tentang chat dan analytics.", chat: "Setiap chat yang terjadi di sini aku analisis untuk memberikan insights yang berguna. Keren kan? 😎", pesan: "Aku bisa memberikan ringkasan tentang pesan-pesan yang dikirim, siapa yang paling aktif, dan topik populer!", analitik: "Analytics menunjukkan pola conversation, waktu aktif, partisipan utama, dan banyak hal menarik lainnya! 📊", berapa: "Tanya aku 'berapa pesan hari ini' atau 'berapa orang yang chat' dan aku akan jawab dengan data real-time!", }; for (const [keyword, response] of Object.entries(responseMap)) { if (lowerInput.includes(keyword)) { return response; } } // Default response if (messages.length < 5) { return "Bagus! Aku akan belajar tentang apa yang kamu tanya. Coba tanya aku tentang chat, analytics, atau partisipan! 🎯"; } return `Menarik! "${input}" - itu hal yang perlu diperhatikan. Ada yang lain ingin kamu ketahui? 🤔`; }