const { useState, useEffect, useRef, useCallback } = React; function Hj93ChatBubbleApp() { const C = window.HJ93_CHATBOT || {}; const i18n = C.i18n || {}; const [open, setOpen] = useState(false); const [input, setInput] = useState(''); const [messages, setMessages] = useState([]); const [typing, setTyping] = useState(false); const [started, setStarted] = useState(false); const streamRef = useRef(null); const cssVars = { '--hj93-primary-from': C.primaryFrom || '#0078D4', '--hj93-primary-to': C.primaryTo || '#00BCF2', '--hj93-chat-bg': C.chatBg || '#1e1e2e', '--hj93-bot-msg-bg': C.botMsgBg || '#2a2a3e', '--hj93-border': C.borderColor || '#3a3a4e', '--hj93-accent': C.accentColor || '#00BCF2', }; useEffect(() => { if (open && streamRef.current) { streamRef.current.scrollTop = streamRef.current.scrollHeight; } }, [open, messages, typing, started]); const sendMessage = useCallback(async () => { const text = (input || '').trim(); if (!text || typing) return; setStarted(true); setInput(''); setMessages((m) => [...m, { role: 'user', text }]); setTyping(true); try { const hdr = { 'Content-Type': 'application/json', 'X-HJ93-Nonce': C.nonce || '', 'X-WP-Nonce': C.nonceRest || C.nonce || '', }; const res = await fetch(C.restUrl, { method: 'POST', credentials: 'same-origin', headers: hdr, body: JSON.stringify({ message: text, conversationId: null }), }); const data = await res.json().catch(() => ({})); let replyText = ''; if (data != null && typeof data.reply !== 'undefined' && data.reply !== null && data.reply !== '') { replyText = String(data.reply); } else if (data != null && data.data && typeof data.data.reply !== 'undefined' && data.data.reply !== '') { replyText = String(data.data.reply); } if (!res.ok) { const errMsg = (data && data.message && String(data.message)) || (data && data.code && String(data.code)) || i18n.error || 'Error'; setMessages(function (m) { return m.concat({ role: 'bot', text: errMsg }); }); return; } if (replyText !== '') { setMessages(function (m) { return m.concat({ role: 'bot', text: replyText }); }); } else { setMessages(function (m) { return m.concat({ role: 'bot', text: i18n.error || 'Error' }); }); } } catch (e) { setMessages((m) => [...m, { role: 'bot', text: i18n.error || 'Error' }]); } finally { setTyping(false); } }, [C.restUrl, C.nonce, input, typing, i18n.error]); const onKeyDown = (e) => { if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); sendMessage(); } }; const title = C.botTitle || 'Chat'; return (
{open && (

{title}

{!started && (

{C.welcomeTitle || ''}

{C.welcomeText || ''}

)} {messages.map((msg, idx) => (
{(msg.role === 'user' ? i18n.you : 'A').charAt(0)}
{msg.role === 'user' ? i18n.you || 'Tú' : title}
{msg.text}
))} {typing && (
A
{i18n.typing || '…'}
)}