Files
openclaw/integrations/paradiz-web/wordpress-plugin/paradiz-web-chat/chat.js

150 lines
5.4 KiB
JavaScript

(function(){
function init(){
const fab = document.getElementById('paradiz-web-chat-fab');
const modal = document.getElementById('paradiz-web-chat-modal');
const closeBtn = document.getElementById('paradiz-web-chat-close');
const sendBtn = document.getElementById('paradiz-web-chat-send');
const input = document.getElementById('paradiz-web-chat-input');
const log = document.getElementById('paradiz-web-chat-log');
if(!fab || !modal || !closeBtn || !sendBtn || !input || !log) return;
const STORAGE_KEY = 'paradiz_web_chat_history_v1';
const CLIENT_ID_KEY = 'paradiz_web_chat_client_id_v1';
const MAX_MESSAGES = 80;
const getClientId = () => {
try {
let id = localStorage.getItem(CLIENT_ID_KEY);
if(!id){
id = 'c_' + Date.now().toString(36) + '_' + Math.random().toString(36).slice(2, 10);
localStorage.setItem(CLIENT_ID_KEY, id);
}
return id;
} catch(_) {
return 'c_fallback';
}
};
const saveHistory = () => {
try {
const items = Array.from(log.querySelectorAll('.paradiz-msg')).map((el) => ({
text: el.textContent || '',
type: el.classList.contains('paradiz-user') ? 'user' : 'bot'
}));
const trimmed = items.slice(-MAX_MESSAGES);
localStorage.setItem(STORAGE_KEY, JSON.stringify(trimmed));
} catch(_) {}
};
const restoreHistory = () => {
try {
const raw = localStorage.getItem(STORAGE_KEY);
if(!raw) return false;
const arr = JSON.parse(raw);
if(!Array.isArray(arr) || !arr.length) return false;
log.innerHTML = '';
for(const item of arr){
const p = document.createElement('p');
p.className = 'paradiz-msg ' + (item.type === 'user' ? 'paradiz-user' : 'paradiz-bot');
p.textContent = String(item.text || '');
log.appendChild(p);
}
log.scrollTop = log.scrollHeight;
return true;
} catch(_) {
return false;
}
};
const addMsg = (text, type) => {
const p = document.createElement('p');
p.className = 'paradiz-msg ' + (type === 'user' ? 'paradiz-user' : 'paradiz-bot');
p.textContent = text;
log.appendChild(p);
log.scrollTop = log.scrollHeight;
saveHistory();
};
restoreHistory();
fab.addEventListener('click', () => {
modal.style.display = (modal.style.display === 'block') ? 'none' : 'block';
if(modal.style.display === 'block') input.focus();
});
closeBtn.addEventListener('click', () => {
modal.style.display = 'none';
});
const sendQuestion = async () => {
const q = input.value.trim();
if(!q){
addMsg('Введите вопрос.', 'bot');
return;
}
addMsg('Вы: ' + q, 'user');
input.value = '';
const typingEl = document.createElement('p');
typingEl.className = 'paradiz-msg paradiz-bot';
typingEl.textContent = 'Печатают…';
log.appendChild(typingEl);
log.scrollTop = log.scrollHeight;
try {
const body = new URLSearchParams();
body.set('action', 'paradiz_web_chat');
body.set('nonce', (window.ParadizWebChatCfg && ParadizWebChatCfg.nonce) ? ParadizWebChatCfg.nonce : '');
body.set('question', q);
body.set('client_id', getClientId());
const resp = await fetch((window.ParadizWebChatCfg && ParadizWebChatCfg.ajaxUrl) ? ParadizWebChatCfg.ajaxUrl : '/wp-admin/admin-ajax.php', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8' },
body: body.toString(),
credentials: 'same-origin'
});
const data = await resp.json();
if(typingEl && typingEl.parentNode) typingEl.parentNode.removeChild(typingEl);
if(data && data.success){
addMsg((data.data && data.data.answer) ? data.data.answer : 'Нет ответа', 'bot');
const b64 = data?.data?.booking_doc_base64 || '';
const name = data?.data?.booking_doc_name || 'booking.docx';
if(b64){
addMsg('Лист предварительной брони сформирован. Скачайте файл ниже 👇', 'bot');
const a = document.createElement('a');
a.href = 'data:application/vnd.openxmlformats-officedocument.wordprocessingml.document;base64,' + b64;
a.download = name;
a.textContent = '📄 Скачать лист предварительной брони';
a.style.display = 'block';
a.style.marginBottom = '8px';
log.appendChild(a);
saveHistory();
}
} else {
addMsg((data && data.data && data.data.message) ? data.data.message : 'Ошибка', 'bot');
}
} catch (e) {
if(typingEl && typingEl.parentNode) typingEl.parentNode.removeChild(typingEl);
addMsg('Сетевая ошибка: ' + (e && e.message ? e.message : 'unknown'), 'bot');
}
};
sendBtn.addEventListener('click', sendQuestion);
input.addEventListener('keydown', (e) => {
if(e.key === 'Enter' && !e.shiftKey){
e.preventDefault();
sendQuestion();
}
});
}
if(document.readyState === 'loading'){
document.addEventListener('DOMContentLoaded', init);
} else {
init();
}
})();