144 lines
5.1 KiB
JavaScript
144 lines
5.1 KiB
JavaScript
(function () {
|
||
var cfg = window.EB_CONCIERGE || {};
|
||
var botId = cfg.botId;
|
||
var apiBase = (cfg.apiBase || '').replace(/\/$/, '');
|
||
if (!botId || !apiBase) {
|
||
// eslint-disable-next-line no-console
|
||
console.error('[EventBuzz Concierge] Missing window.EB_CONCIERGE.botId or apiBase');
|
||
return;
|
||
}
|
||
|
||
var storageKey = 'ebc_session_' + botId;
|
||
var sessionId = null;
|
||
try { sessionId = localStorage.getItem(storageKey); } catch {}
|
||
|
||
function el(tag, attrs, children) {
|
||
var n = document.createElement(tag);
|
||
if (attrs) for (var k in attrs) n.setAttribute(k, attrs[k]);
|
||
if (children) children.forEach(function (c) { n.appendChild(typeof c === 'string' ? document.createTextNode(c) : c); });
|
||
return n;
|
||
}
|
||
|
||
function addCssOnce() {
|
||
if (document.getElementById('ebc-css')) return;
|
||
var link = el('link', { id: 'ebc-css', rel: 'stylesheet', href: apiBase.replace(/\/api$/, '') + '/embed/concierge-widget.css' });
|
||
document.head.appendChild(link);
|
||
}
|
||
|
||
addCssOnce();
|
||
|
||
var launcher = el('button', { class: 'ebc-launcher', type: 'button', 'aria-label': 'Chat with event concierge' }, ['Chat']);
|
||
var panel = el('div', { class: 'ebc-panel', role: 'dialog', 'aria-label': 'Event concierge chat' });
|
||
var header = el('div', { class: 'ebc-header' });
|
||
var title = el('div', { class: 'ebc-title' }, ['Event Concierge']);
|
||
var closeBtn = el('button', { class: 'ebc-close', type: 'button', 'aria-label': 'Close' }, ['×']);
|
||
header.appendChild(title);
|
||
header.appendChild(closeBtn);
|
||
|
||
var messages = el('div', { class: 'ebc-messages' });
|
||
var error = el('div', { class: 'ebc-error' }, ['']);
|
||
var inputBar = el('div', { class: 'ebc-inputbar' });
|
||
var input = el('input', { class: 'ebc-input', placeholder: 'Ask a question…', maxlength: '800' });
|
||
var sendBtn = el('button', { class: 'ebc-send', type: 'button' }, ['Send']);
|
||
inputBar.appendChild(input);
|
||
inputBar.appendChild(sendBtn);
|
||
|
||
panel.appendChild(header);
|
||
panel.appendChild(messages);
|
||
panel.appendChild(error);
|
||
panel.appendChild(inputBar);
|
||
document.body.appendChild(launcher);
|
||
document.body.appendChild(panel);
|
||
|
||
function setError(msg) {
|
||
if (!msg) {
|
||
error.style.display = 'none';
|
||
error.textContent = '';
|
||
return;
|
||
}
|
||
error.style.display = 'block';
|
||
error.textContent = msg;
|
||
}
|
||
|
||
function addMessage(role, text) {
|
||
var bubble = el('div', { class: 'ebc-msg' + (role === 'user' ? ' ebc-user' : '') });
|
||
bubble.textContent = text;
|
||
messages.appendChild(bubble);
|
||
messages.scrollTop = messages.scrollHeight;
|
||
}
|
||
|
||
function openPanel() {
|
||
panel.classList.add('ebc-open');
|
||
input.focus();
|
||
}
|
||
function closePanel() {
|
||
panel.classList.remove('ebc-open');
|
||
}
|
||
|
||
launcher.addEventListener('click', function () {
|
||
if (panel.classList.contains('ebc-open')) closePanel();
|
||
else openPanel();
|
||
});
|
||
closeBtn.addEventListener('click', closePanel);
|
||
|
||
function http(path, body) {
|
||
return fetch(apiBase + path, {
|
||
method: body ? 'POST' : 'GET',
|
||
headers: { 'Content-Type': 'application/json' },
|
||
body: body ? JSON.stringify(body) : undefined,
|
||
credentials: 'omit'
|
||
}).then(function (r) {
|
||
return r.json().then(function (j) { return { status: r.status, json: j }; });
|
||
});
|
||
}
|
||
|
||
// Load config
|
||
http('/public/concierge/' + encodeURIComponent(botId) + '/config').then(function (res) {
|
||
if (res.json && res.json.success && res.json.data) {
|
||
title.textContent = res.json.data.eventName ? ('Concierge · ' + res.json.data.eventName) : 'Event Concierge';
|
||
var greet = res.json.data.greeting;
|
||
if (greet) addMessage('assistant', greet.replace(/\{eventName\}/g, res.json.data.eventName || 'the event'));
|
||
if (res.json.data.maxMessageLength) input.setAttribute('maxlength', String(res.json.data.maxMessageLength));
|
||
}
|
||
});
|
||
|
||
function send() {
|
||
var text = String(input.value || '').trim();
|
||
if (!text) return;
|
||
setError(null);
|
||
input.value = '';
|
||
addMessage('user', text);
|
||
sendBtn.disabled = true;
|
||
|
||
http('/public/concierge/' + encodeURIComponent(botId) + '/chat', {
|
||
sessionId: sessionId || undefined,
|
||
message: text
|
||
}).then(function (res) {
|
||
sendBtn.disabled = false;
|
||
if (!res.json || !res.json.success) {
|
||
setError((res.json && res.json.error && res.json.error.message) ? res.json.error.message : 'Request failed');
|
||
return;
|
||
}
|
||
if (res.json.data && res.json.data.sessionId) {
|
||
sessionId = res.json.data.sessionId;
|
||
try { localStorage.setItem(storageKey, sessionId); } catch {}
|
||
}
|
||
addMessage('assistant', (res.json.data && res.json.data.reply) ? res.json.data.reply : '…');
|
||
// Log detected intent to browser console when backend returns it
|
||
if (res.json.data && res.json.data.intent) {
|
||
// eslint-disable-next-line no-console
|
||
console.info('[EventBuzz Concierge] detected intent:', res.json.data.intent);
|
||
}
|
||
}).catch(function (e) {
|
||
sendBtn.disabled = false;
|
||
setError(e && e.message ? e.message : 'Network error');
|
||
});
|
||
}
|
||
|
||
sendBtn.addEventListener('click', send);
|
||
input.addEventListener('keydown', function (e) {
|
||
if (e.key === 'Enter') send();
|
||
});
|
||
})();
|
||
|