/** * KI Chat Widget - Functional Chat Interface * Integrates with existing chat widget in KI Chat card * Connects to N8N webhook via send.php */ class KIChat { constructor() { this.sessionId = this.generateSessionId(); this.isTyping = false; this.messages = []; this.init(); } init() { this.bindEvents(); this.loadChatHistory(); this.setupExistingChat(); } generateSessionId() { return 'chat_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9); } bindEvents() { // Chat button clicks const chatBtn = document.getElementById('chatBtn'); const interactionBtn = document.querySelector('#chatInteraction .interaction-btn'); if (chatBtn) { chatBtn.addEventListener('click', () => this.scrollToChat()); } if (interactionBtn) { interactionBtn.addEventListener('click', () => this.focusInput()); } // Send message on Enter in existing chat const existingInput = document.querySelector('#chatInteraction .chat-input'); if (existingInput) { existingInput.addEventListener('keypress', (e) => { if (e.key === 'Enter') { e.preventDefault(); this.sendMessage(); } }); } // Send button click const sendBtn = document.querySelector('#chatInteraction .chat-send'); if (sendBtn) { sendBtn.addEventListener('click', () => this.sendMessage()); } } setupExistingChat() { const chatMessages = document.querySelector('#chatInteraction .chat-messages'); const chatInput = document.querySelector('#chatInteraction .chat-input'); const sendBtn = document.querySelector('#chatInteraction .chat-send'); // Add click event listener to the send button if (sendBtn) { sendBtn.addEventListener('click', () => this.sendMessage()); } // Add welcome message if (this.messages.length === 0 && chatMessages) { this.addMessage('ki', 'Hallo! Ich bin Ihr KI-Assistent. Wie kann ich Ihnen helfen?'); } this.updateChatDisplay(); } scrollToChat() { const chatInteraction = document.getElementById('chatInteraction'); if (chatInteraction) { chatInteraction.scrollIntoView({ behavior: 'smooth', block: 'center' }); setTimeout(() => this.focusInput(), 500); } } focusInput() { const inputField = document.querySelector('#chatInteraction .chat-input'); if (inputField) { inputField.focus(); } } addMessage(sender, text, timestamp = Date.now()) { this.messages.push({ sender: sender, text: text, timestamp: timestamp }); // Keep only last 50 messages if (this.messages.length > 50) { this.messages = this.messages.slice(-50); } this.saveChatHistory(); this.updateChatDisplay(); } updateChatDisplay() { const chatMessages = document.querySelector('#chatInteraction .chat-messages'); if (chatMessages) { // Clear existing messages except typing indicator const typingIndicator = chatMessages.querySelector('.typing-indicator'); chatMessages.innerHTML = ''; // Add all messages this.messages.forEach(msg => { const messageDiv = document.createElement('div'); messageDiv.className = `chat-message ${msg.sender}`; messageDiv.innerHTML = `
`; chatMessages.appendChild(messageDiv); }); // Re-add typing indicator if needed if (typingIndicator && this.isTyping) { chatMessages.appendChild(typingIndicator); } this.scrollToBottom(); } } async sendMessage() { const inputField = document.querySelector('#chatInteraction .chat-input'); const message = inputField?.value?.trim(); if (!message || this.isTyping) return; // Add user message this.addMessage('user', message); inputField.value = ''; // Show typing indicator this.showTypingIndicator(); this.isTyping = true; try { const response = await fetch('/scripts/add/send.php', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ type: 'chat', message: message, session_id: this.sessionId }) }); const data = await response.json(); if (data.success) { this.addMessage('ki', data.data.ai_response, data.data.timestamp); } else { this.addMessage('ki', 'Entschuldigung, es gab ein Problem. Bitte versuchen Sie es später erneut.'); } } catch (error) { console.error('Chat error:', error); this.addMessage('ki', 'Verbindung zum Server fehlgeschlagen. Bitte überprüfen Sie Ihre Internetverbindung.'); } finally { this.hideTypingIndicator(); this.isTyping = false; } } showTypingIndicator() { const chatMessages = document.querySelector('#chatInteraction .chat-messages'); if (chatMessages && !chatMessages.querySelector('.typing-indicator')) { const typingHTML = ` `; chatMessages.insertAdjacentHTML('beforeend', typingHTML); this.scrollToBottom(); } } hideTypingIndicator() { const typingIndicator = document.querySelector('#chatInteraction .typing'); if (typingIndicator) { typingIndicator.remove(); } } scrollToBottom() { const chatMessages = document.querySelector('#chatInteraction .chat-messages'); if (chatMessages) { chatMessages.scrollTop = chatMessages.scrollHeight; } } saveChatHistory() { try { localStorage.setItem(`ki_chat_${this.sessionId}`, JSON.stringify(this.messages)); } catch (e) { console.warn('Could not save chat history:', e); } } loadChatHistory() { try { const saved = localStorage.getItem(`ki_chat_${this.sessionId}`); if (saved) { this.messages = JSON.parse(saved); } } catch (e) { console.warn('Could not load chat history:', e); } } formatTime(timestamp) { const date = new Date(timestamp); return date.toLocaleTimeString('de-DE', { hour: '2-digit', minute: '2-digit' }); } escapeHtml(text) { const div = document.createElement('div'); div.textContent = text; return div.innerHTML; } } // Initialize chat when DOM is ready document.addEventListener('DOMContentLoaded', () => { window.kiChat = new KIChat(); }); // Add CSS for enhanced chat functionality const chatStyles = ` #chatInteraction { display: flex; flex-direction: column; gap: 15px; } #chatInteraction h3 { margin: 0; font-size: 24px; color: var(--primary-dark); text-align: center; } #chatInteraction p { margin: 0; color: var(--primary-mid); text-align: center; font-size: 16px; line-height: 1.5; } #chatInteraction .card-visual { height: 400px; } #chatInteraction .chat-window { width: 100%; height: 400px; background: white; border-radius: 12px; box-shadow: 0 4px 20px rgba(79, 71, 71, 0.1); display: flex; flex-direction: column; overflow: hidden; } #chatInteraction .chat-header { background: linear-gradient(135deg, var(--accent-teal), var(--accent-green)); color: white; padding: 15px 20px; font-weight: 600; font-size: 16px; } #chatInteraction .chat-messages { flex: 1; padding: 20px; overflow-y: auto !important; background: transparent; max-height: 300px !important; display: flex; flex-direction: column; gap: 12px; min-height: 0; align-items: flex-start; justify-content: flex-start; } #chatInteraction .chat-message { display: flex; width: 100%; background: transparent; } #chatInteraction .chat-message.user { justify-content: flex-end; } #chatInteraction .chat-message.ki { justify-content: flex-start; } #chatInteraction .message-content { background: transparent; padding: 12px 16px; border-radius: 16px; box-shadow: none; word-wrap: break-word; line-height: 1.4; max-width: 70%; display: inline-block; text-align: left; } #chatInteraction .chat-message.user .message-content { background: var(--accent-green); color: white; } #chatInteraction .chat-message.ki .message-content { background: var(--accent-green); color: white; } #chatInteraction .message-time { font-size: 10px; color: #666; margin-top: 4px; padding: 0 16px; } #chatInteraction .chat-message.ki .message-time { text-align: left; } #chatInteraction .chat-message.user .message-time { text-align: right; } #chatInteraction .chat-input-container .interaction-btn { flex-shrink: 0; padding: 12px 20px; font-size: 14px; } #chatInteraction .chat-send { background: var(--accent-teal); color: white; border: none; border-radius: 50%; width: 45px; height: 45px; display: flex; align-items: center; justify-content: center; cursor: pointer; transition: all 0.3s ease; flex-shrink: 0; padding: 0; margin-left: 8px; box-shadow: 0 2px 8px rgba(38, 166, 154, 0.3); } #chatInteraction .chat-send:hover { background: #1e8e82; transform: scale(1.05); box-shadow: 0 4px 12px rgba(38, 166, 154, 0.4); } #chatInteraction .chat-send:active { transform: scale(0.95); } #chatInteraction .chat-send img { width: 22px; height: 22px; filter: brightness(0) invert(1); object-fit: contain; } /* Responsive adjustments */ @media (max-width: 768px) { #chatInteraction .card-visual { min-height: 350px; } #chatInteraction .chat-messages { min-height: 200px; padding: 15px; } #chatInteraction .chat-input-container { padding: 12px 15px; } #chatInteraction .chat-input { padding: 10px 14px; } #chatInteraction .chat-send { padding: 10px 16px; font-size: 13px; } } `; // Inject CSS const styleSheet = document.createElement('style'); styleSheet.textContent = chatStyles; document.head.appendChild(styleSheet);