<!-- Chatbot button -->
<div id="chatbot-button" class="chatbot-button">
<i class="far fa-comment-dots"></i>
</div>
<!-- Chatbot popup -->
<div id="chatbot-popup" class="chatbot-popup">
<div class="chatbot-header">
<div class="chatbot-header-title">
<i class="fas fa-circle-info"></i>
</div>
<div class="chatbot-header-title">
<span>{{ 'chatbot.title'|trans({}, 'chatbot')|default('Assistència') }}</span>
</div>
<div class="chatbot-header-actions">
<button class="chatbot-clear-button" title="{{ 'chatbot.clear_conversation'|trans({}, 'chatbot')|default('Borrar conversación') }}">
<i class="fas fa-trash-alt"></i>
</button>
<div class="chatbot-header-close">
<i class="fas fa-times"></i>
</div>
</div>
</div>
<div class="chatbot-content">
<div class="chatbot-messages">
{% if conversation is defined and conversation|length > 0 %}
{# Mostrar conversación previa desde la sesión #}
{% for message in conversation %}
<div class="chatbot-message chatbot-message-{{ message.type }}">
<div class="chatbot-message-icon">
<i class="fas {% if message.type == 'user' %}fa-user{% else %}fa-circle-info{% endif %}"></i>
</div>
<div class="chatbot-message-content">
<p>{{ message.message }}</p>
</div>
</div>
{% endfor %}
{% else %}
{# Mensaje de bienvenida y temas de ayuda si no hay conversación previa #}
<div class="chatbot-message chatbot-message-bot">
<div class="chatbot-message-icon">
<i class="fas fa-circle-info"></i>
</div>
<div class="chatbot-message-content">
<p>{{ 'chatbot.welcome'|trans({}, 'chatbot')|default('Hola! En què puc ajudar-te avui?') }}</p>
</div>
</div>
{# <div class="chatbot-help-topics">#}
{# <div class="chatbot-help-topic" data-query="Com puc trobar un curs?">#}
{# <div class="chatbot-help-topic-icon">#}
{# <i class="fas fa-circle-question"></i>#}
{# </div>#}
{# <div class="chatbot-help-topic-content">#}
{# <p>{{ 'chatbot.help.find_course'|trans({}, 'chatbot')|default('Com puc trobar un curs?') }}</p>#}
{# </div>#}
{# </div>#}
{# <div class="chatbot-help-topic" data-query="Informació sobre inscripcions">#}
{# <div class="chatbot-help-topic-icon">#}
{# <i class="fas fa-circle-info"></i>#}
{# </div>#}
{# <div class="chatbot-help-topic-content">#}
{# <p>{{ 'chatbot.help.inscriptions'|trans({}, 'chatbot')|default('Informació sobre inscripcions') }}</p>#}
{# </div>#}
{# </div>#}
{# <div class="chatbot-help-topic" data-query="Com contactar amb un punt d'orientació?">#}
{# <div class="chatbot-help-topic-icon">#}
{# <i class="fas fa-comments"></i>#}
{# </div>#}
{# <div class="chatbot-help-topic-content">#}
{# <p>{{ 'chatbot.help.orientation'|trans({}, 'chatbot')|default('Com contactar amb un punt d\'orientació?') }}</p>#}
{# </div>#}
{# </div>#}
{# </div>#}
{% endif %}
</div>
<div class="chatbot-input">
<input type="text" placeholder="{{ 'chatbot.input_placeholder'|trans({}, 'chatbot')|default('Escriu la teva pregunta...') }}">
<button type="button">
<i class="fas fa-paper-plane"></i>
</button>
</div>
</div>
</div>
<script type="text/javascript">
document.addEventListener('DOMContentLoaded', function() {
// Debug: Check if we have cookies
console.log('Cookies available:', document.cookie);
// Manual check for conversation cookie and display
function getCookieValue(cookieName) {
const name = cookieName + "=";
const decodedCookie = decodeURIComponent(document.cookie);
const cookieArray = decodedCookie.split(';');
for (let i = 0; i < cookieArray.length; i++) {
let cookie = cookieArray[i].trim();
if (cookie.indexOf(name) === 0) {
return cookie.substring(name.length, cookie.length);
}
}
return "";
}
const chatbotCookie = getCookieValue('chatbot_conversation');
console.log('Chatbot cookie found:', chatbotCookie ? 'Yes' : 'No');
if (chatbotCookie) {
try {
// Try to decode the cookie value
const decodedValue = atob(chatbotCookie);
const conversation = JSON.parse(decodedValue);
console.log('Parsed conversation:', conversation);
// If the server didn't render the conversation, let's do it manually
const chatbotMessages = document.querySelector('.chatbot-messages');
const helpTopics = document.querySelector('.chatbot-help-topics');
if (conversation && conversation.length > 0 && helpTopics) {
console.log('Rendering conversation from cookie...');
// Clear existing welcome message
chatbotMessages.innerHTML = '';
// Add messages from conversation
conversation.forEach(message => {
const messageDiv = document.createElement('div');
messageDiv.className = `chatbot-message chatbot-message-${message.type}`;
const iconDiv = document.createElement('div');
iconDiv.className = 'chatbot-message-icon';
const icon = document.createElement('i');
if (message.type === 'user') {
icon.className = 'fas fa-user';
} else {
icon.className = 'fas fa-circle-info';
}
iconDiv.appendChild(icon);
const contentDiv = document.createElement('div');
contentDiv.className = 'chatbot-message-content';
const paragraph = document.createElement('p');
// For bot messages, process Markdown-like formatting and preserve line breaks
if (message.type === 'bot') {
// Convert ** text ** to <strong>text</strong>
const formattedMessage = message.message
.replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>')
.replace(/\n/g, '<br>');
paragraph.innerHTML = formattedMessage;
} else {
// For user messages, keep using textContent for security
paragraph.textContent = message.message;
}
contentDiv.appendChild(paragraph);
messageDiv.appendChild(iconDiv);
messageDiv.appendChild(contentDiv);
chatbotMessages.appendChild(messageDiv);
});
// Hide help topics since we have a conversation
helpTopics.style.display = 'none';
}
} catch (error) {
console.error('Error parsing conversation cookie:', error);
}
}
const chatbotButton = document.getElementById('chatbot-button');
const chatbotPopup = document.getElementById('chatbot-popup');
const chatbotClose = document.querySelector('.chatbot-header-close');
const chatbotClear = document.querySelector('.chatbot-clear-button');
const chatbotMessages = document.querySelector('.chatbot-messages');
const chatbotInput = document.querySelector('.chatbot-input input');
const chatbotSendButton = document.querySelector('.chatbot-input button');
const chatbotHelpTopics = document.querySelectorAll('.chatbot-help-topic');
// Toggle chatbot popup
chatbotButton.addEventListener('click', function() {
chatbotPopup.classList.toggle('open');
if (chatbotPopup.classList.contains('open')) {
chatbotInput.focus();
}
});
// Close chatbot popup
chatbotClose.addEventListener('click', function() {
chatbotPopup.classList.remove('open');
});
// Clear conversation
chatbotClear.addEventListener('click', function() {
// Send request to clear the conversation
fetch('{{ path("chatbot_clear") }}', {
method: 'POST',
})
.then(response => response.json())
.then(data => {
if (data.success) {
// Clear all messages in the UI
chatbotMessages.innerHTML = '';
// Add welcome message back
const welcomeMessage = document.createElement('div');
welcomeMessage.className = 'chatbot-message chatbot-message-bot';
welcomeMessage.innerHTML = `
<div class="chatbot-message-icon">
<i class="fas fa-circle-info"></i>
</div>
<div class="chatbot-message-content">
<p>{{ 'chatbot.welcome'|trans({}, 'chatbot')|default('Hola! En què puc ajudar-te avui?') }}</p>
</div>
`;
chatbotMessages.appendChild(welcomeMessage);
// Add help topics back
const helpTopics = document.createElement('div');
helpTopics.className = 'chatbot-help-topics';
helpTopics.innerHTML = ``;
{#helpTopics.innerHTML = `#}
{# <div class="chatbot-help-topic" data-query="Com puc trobar un curs?">#}
{# <div class="chatbot-help-topic-icon">#}
{# <i class="fas fa-circle-question"></i>#}
{# </div>#}
{# <div class="chatbot-help-topic-content">#}
{# <p>{{ 'chatbot.help.find_course'|trans({}, 'chatbot')|default('Com puc trobar un curs?') }}</p>#}
{# </div>#}
{# </div>#}
{# <div class="chatbot-help-topic" data-query="Informació sobre inscripcions">#}
{# <div class="chatbot-help-topic-icon">#}
{# <i class="fas fa-circle-info"></i>#}
{# </div>#}
{# <div class="chatbot-help-topic-content">#}
{# <p>{{ 'chatbot.help.inscriptions'|trans({}, 'chatbot')|default('Informació sobre inscripcions') }}</p>#}
{# </div>#}
{# </div>#}
{# <div class="chatbot-help-topic" data-query="Com contactar amb un punt d'orientació?">#}
{# <div class="chatbot-help-topic-icon">#}
{# <i class="fas fa-comments"></i>#}
{# </div>#}
{# <div class="chatbot-help-topic-content">#}
{# <p>{{ 'chatbot.help.orientation'|trans({}, 'chatbot')|default('Com contactar amb un punt d\'orientació?') }}</p>#}
{# </div>#}
{# </div>#}
{#`;#}
chatbotMessages.appendChild(helpTopics);
// Re-attach event listeners to new help topics
document.querySelectorAll('.chatbot-help-topic').forEach(topic => {
topic.addEventListener('click', function() {
const query = this.getAttribute('data-query');
chatbotInput.value = query;
sendMessage(query);
});
});
}
})
.catch(error => {
console.error('Error clearing conversation:', error);
});
});
// Handle help topic clicks
chatbotHelpTopics.forEach(topic => {
topic.addEventListener('click', function() {
const query = this.getAttribute('data-query');
chatbotInput.value = query;
sendMessage(query);
});
});
// Send message on button click
chatbotSendButton.addEventListener('click', function() {
sendMessage(chatbotInput.value);
});
// Send message on Enter key press
chatbotInput.addEventListener('keypress', function(e) {
if (e.key === 'Enter') {
sendMessage(chatbotInput.value);
}
});
// Function to send message to the backend
function sendMessage(message) {
if (!message.trim()) return;
// Add user message to chat
addMessage(message, 'user');
// Clear input
chatbotInput.value = '';
// Show loading indicator
addLoadingMessage();
// Send request to backend
fetch('{{ path("chatbot_query") }}', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ query: message }),
})
.then(response => response.json())
.then(data => {
// Remove loading indicator
removeLoadingMessage();
if (data.success) {
// Add bot response to chat
const botResponse = data.data.respuesta || data.data.response || '{{ 'chatbot.no_response'|trans({}, 'chatbot')|default('No s ha trobat una resposta.') }}';
addMessage(botResponse, 'bot');
// Check if we received an updated conversation from the server
if (data.conversation) {
console.log('Updated conversation received from server');
}
} else {
// Handle error
addMessage('{{ 'chatbot.error.processing'|trans({}, 'chatbot')|default('Ho sento, no he pogut processar la teva pregunta. Si us plau, intenta-ho de nou més tard.') }}', 'bot error');
console.error('Error:', data.error);
}
})
.catch(error => {
// Remove loading indicator
removeLoadingMessage();
// Handle network error
addMessage('{{ 'chatbot.error.connection'|trans({}, 'chatbot')|default('Hi ha hagut un problema de connexió. Si us plau, intenta-ho de nou més tard.') }}', 'bot error');
console.error('Error:', error);
});
}
// Function to add a message to the chat
function addMessage(message, type) {
const messageDiv = document.createElement('div');
messageDiv.className = `chatbot-message chatbot-message-${type}`;
const iconDiv = document.createElement('div');
iconDiv.className = 'chatbot-message-icon';
const icon = document.createElement('i');
if (type === 'user') {
icon.className = 'fas fa-user';
} else {
icon.className = 'fas fa-circle-info';
}
iconDiv.appendChild(icon);
const contentDiv = document.createElement('div');
contentDiv.className = 'chatbot-message-content';
const paragraph = document.createElement('p');
// For bot messages, process Markdown-like formatting and preserve line breaks
if (type.includes('bot')) {
// Convert ** text ** to <strong>text</strong>
const formattedMessage = message
.replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>')
.replace(/\n/g, '<br>');
paragraph.innerHTML = formattedMessage;
} else {
// For user messages, keep using textContent for security
paragraph.textContent = message;
}
contentDiv.appendChild(paragraph);
messageDiv.appendChild(iconDiv);
messageDiv.appendChild(contentDiv);
// Hide help topics after first user message
if (type === 'user') {
const helpTopics = document.querySelector('.chatbot-help-topics');
if (helpTopics) {
helpTopics.style.display = 'none';
}
}
chatbotMessages.appendChild(messageDiv);
// Scroll to bottom
chatbotMessages.scrollTop = chatbotMessages.scrollHeight;
}
// Function to add loading indicator
function addLoadingMessage() {
const loadingDiv = document.createElement('div');
loadingDiv.className = 'chatbot-message chatbot-message-bot chatbot-loading';
const iconDiv = document.createElement('div');
iconDiv.className = 'chatbot-message-icon';
const icon = document.createElement('i');
icon.className = 'fas fa-circle-info';
iconDiv.appendChild(icon);
const contentDiv = document.createElement('div');
contentDiv.className = 'chatbot-message-content';
const loadingDots = document.createElement('div');
loadingDots.className = 'chatbot-loading-dots';
for (let i = 0; i < 3; i++) {
const dot = document.createElement('span');
loadingDots.appendChild(dot);
}
contentDiv.appendChild(loadingDots);
loadingDiv.appendChild(iconDiv);
loadingDiv.appendChild(contentDiv);
chatbotMessages.appendChild(loadingDiv);
// Scroll to bottom
chatbotMessages.scrollTop = chatbotMessages.scrollHeight;
}
// Function to remove loading indicator
function removeLoadingMessage() {
const loadingMessage = document.querySelector('.chatbot-loading');
if (loadingMessage) {
loadingMessage.remove();
}
}
});
</script>