UNPKG

luca-chatbot-embed

Version:

Luca AI Chatbot - Non-intrusive popup widget for websites

1,197 lines (1,056 loc) 41.4 kB
(function() { 'use strict'; // CSS Styles - Embedded directly in the script const styles = ` /* CSS Variables for theming */ :root { --bg-primary: #1a1a1a; --bg-secondary: #2d2d2d; --bg-tertiary: #3a3a3a; --text-primary: #ffffff; --text-secondary: rgba(255, 255, 255, 0.8); --text-muted: rgba(255, 255, 255, 0.6); --border-color: #404040; --shadow-color: rgba(0, 0, 0, 0.3); --accent-primary: #512feb; --accent-secondary: #6a5acd; --accent-hover: #4a1fd1; --success-color: #10b981; --error-color: #ef4444; --warning-color: #f59e0b; --scrollbar-color: #666666; --scrollbar-hover-color: #888888; } /* Light mode colors */ [data-theme="light"] { --bg-primary: #ffffff; --bg-secondary: #f8f9fa; --bg-tertiary: #e9ecef; --text-primary: #1a1a1a; --text-secondary: rgba(26, 26, 26, 0.8); --text-muted: rgba(26, 26, 26, 0.6); --border-color: #dee2e6; --shadow-color: rgba(0, 0, 0, 0.1); --accent-primary: #512feb; --accent-secondary: #6a5acd; --accent-hover: #4a1fd1; --success-color: #10b981; --error-color: #ef4444; --warning-color: #f59e0b; --scrollbar-color: #c1c1c1; --scrollbar-hover-color: #a8a8a8; } /* Luca Chatbot Container */ .luca-chatbot-container { position: fixed; bottom: 0; right: 0; z-index: 10000; font-family: 'DM Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; font-size: 16px; line-height: 1.5; color: var(--text-primary); pointer-events: none; } .luca-chatbot-container * { box-sizing: border-box; } /* Toggle Button */ .luca-chatbot-toggle { position: fixed; bottom: 30px; right: 35px; border: none; height: 50px; width: 50px; display: flex; cursor: pointer; align-items: center; justify-content: center; border-radius: 50%; background: var(--accent-primary); transition: all 0.4s cubic-bezier(0.34, 1.56, 0.64, 1); transform: scale(1); animation: luca-float 4s ease-in-out infinite; box-shadow: 0 8px 25px rgba(81, 47, 235, 0.3); will-change: transform, box-shadow; z-index: 10000; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; pointer-events: auto; } @keyframes luca-float { 0%, 100% { transform: translateY(0px) scale(1); box-shadow: 0 8px 25px rgba(81, 47, 235, 0.3); } 50% { transform: translateY(-8px) scale(1.02); box-shadow: 0 15px 35px rgba(81, 47, 235, 0.4); } } .luca-chatbot-toggle:hover { transform: scale(1.15); box-shadow: 0 12px 35px rgba(81, 47, 235, 0.5); animation-play-state: paused; } .luca-chatbot-toggle:active { transform: scale(0.9); transition: all 0.15s cubic-bezier(0.4, 0, 0.6, 1); box-shadow: 0 4px 15px rgba(81, 47, 235, 0.4); } .luca-chatbot-toggle.show-chatbot { transform: rotate(135deg) scale(1.1); animation: none; box-shadow: 0 10px 30px rgba(81, 47, 235, 0.4); } .luca-chatbot-toggle span { color: #fff; position: absolute; transition: all 0.4s cubic-bezier(0.34, 1.56, 0.64, 1); transform: scale(1); will-change: transform, opacity; font-family: 'Material Symbols Rounded', sans-serif; font-size: 24px; } .luca-chatbot-toggle span:last-child, .luca-chatbot-toggle.show-chatbot span:first-child { opacity: 0; transform: scale(0.8) rotate(-90deg); } .luca-chatbot-toggle.show-chatbot span:last-child { opacity: 1; transform: scale(1) rotate(0deg); } .luca-chatbot-toggle.show-chatbot span:first-child { opacity: 0; transform: scale(0.8) rotate(90deg); } /* Chatbot Popup */ .luca-chatbot-popup { position: fixed; right: 35px; bottom: 90px; width: 380px; height: 700px; overflow: hidden; background: var(--bg-primary); border: 1px solid var(--border-color); border-radius: 20px; opacity: 0; pointer-events: none; transform: scale(0.3) translateY(30px) rotateX(10deg); transform-origin: bottom right; transition: all 0.5s cubic-bezier(0.34, 1.56, 0.64, 1); backdrop-filter: blur(15px); box-shadow: 0 20px 60px var(--shadow-color); will-change: transform, opacity; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; touch-action: none; z-index: 9999; isolation: isolate; contain: layout style paint; } .luca-chatbot-container.show-chatbot .luca-chatbot-popup { opacity: 1; pointer-events: auto; transform: scale(1) translateY(0) rotateX(0deg); user-select: auto; -webkit-user-select: auto; -moz-user-select: auto; -ms-user-select: auto; touch-action: auto; contain: none; } /* Ensure all child elements of the closed chatbot don't interfere */ .luca-chatbot-popup * { pointer-events: none !important; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; touch-action: none; } /* Re-enable interactions for child elements when chatbot is open */ .luca-chatbot-container.show-chatbot .luca-chatbot-popup * { pointer-events: auto; user-select: auto; -webkit-user-select: auto; -moz-user-select: auto; -ms-user-select: auto; touch-action: auto; } /* Chat Header */ .luca-chat-header { display: flex; align-items: center; padding: 15px 22px; background: linear-gradient(135deg, var(--accent-primary) 0%, var(--accent-secondary) 100%); justify-content: space-between; position: relative; overflow: hidden; } .luca-header-info { display: flex; gap: 12px; align-items: center; } .luca-profile-container { position: relative; flex-shrink: 0; } .luca-chatbot-logo { width: 40px; height: 40px; flex-shrink: 0; object-fit: cover; border-radius: 50%; transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); animation: luca-pulse 2s ease-in-out infinite; } .luca-online-indicator { position: absolute; bottom: 2px; left: 2px; width: 12px; height: 12px; background: #FFD700; border: 2px solid #fff; border-radius: 50%; animation: luca-pulse 2s ease-in-out infinite; } @keyframes luca-pulse { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.05); } } .luca-user-info { display: flex; flex-direction: column; gap: 2px; } .luca-logo-text { color: #fff; font-weight: 600; font-size: 1.1rem; letter-spacing: 0.02rem; margin: 0; } .luca-activity-status { color: rgba(255, 255, 255, 0.8); font-size: 0.8rem; font-weight: 400; } .luca-header-controls { display: flex; align-items: center; gap: 8px; } .luca-header-controls button { border: none; color: #fff; height: 35px; width: 35px; font-size: 1.2rem; cursor: pointer; border-radius: 50%; background: none; transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); position: relative; overflow: hidden; font-family: 'Material Symbols Rounded', sans-serif; } .luca-header-controls button::before { content: ''; position: absolute; top: 50%; left: 50%; width: 0; height: 0; background: rgba(255, 255, 255, 0.1); border-radius: 50%; transform: translate(-50%, -50%); transition: all 0.3s ease; } .luca-header-controls button:hover::before { width: 100%; height: 100%; } .luca-header-controls button:hover { transform: scale(1.1); background: rgba(255, 255, 255, 0.1); } /* Chat Body */ .luca-chat-body { padding: 25px 22px 40px 22px; gap: 20px; display: flex; height: calc(100% - 160px); overflow-y: auto; flex-direction: column; scrollbar-width: thin; scrollbar-color: var(--scrollbar-color) transparent; position: relative; background: var(--bg-primary); scroll-behavior: smooth; overscroll-behavior: contain; } .luca-chat-body::-webkit-scrollbar { width: 6px; } .luca-chat-body::-webkit-scrollbar-track { background: transparent; } .luca-chat-body::-webkit-scrollbar-thumb { background: var(--scrollbar-color); border-radius: 3px; transition: all 0.3s ease; } .luca-chat-body::-webkit-scrollbar-thumb:hover { background: var(--scrollbar-hover-color); } .luca-message { display: flex; gap: 11px; align-items: center; animation: luca-messageSlideIn 0.6s cubic-bezier(0.34, 1.56, 0.64, 1); transform: translateY(0); opacity: 1; will-change: transform, opacity; } @keyframes luca-messageSlideIn { 0% { opacity: 0; transform: translateY(30px) scale(0.95); filter: blur(1px); } 70% { transform: translateY(-2px) scale(1.01); } 100% { opacity: 1; transform: translateY(0) scale(1); filter: blur(0); } } .luca-message.user-message { animation: luca-userMessageSlideIn 0.5s cubic-bezier(0.34, 1.56, 0.64, 1); } @keyframes luca-userMessageSlideIn { 0% { opacity: 0; transform: translateY(25px) translateX(25px) scale(0.9); filter: blur(1px); } 60% { transform: translateY(-3px) translateX(-3px) scale(1.02); } 100% { opacity: 1; transform: translateY(0) translateX(0) scale(1); filter: blur(0); } } .luca-message .luca-bot-avatar { width: 35px; height: 35px; flex-shrink: 0; margin-bottom: 2px; align-self: flex-end; border-radius: 50%; object-fit: cover; transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); animation: luca-avatarBounce 0.6s cubic-bezier(0.68, -0.55, 0.265, 1.55); } @keyframes luca-avatarBounce { 0% { transform: scale(0) rotate(-180deg); } 50% { transform: scale(1.2) rotate(-90deg); } 100% { transform: scale(1) rotate(0deg); } } .luca-message .luca-message-text { padding: 12px 16px; max-width: 75%; font-size: 0.95rem; word-wrap: normal; word-break: normal; overflow-wrap: normal; white-space: normal; hyphens: none; transition: all 0.4s cubic-bezier(0.34, 1.56, 0.64, 1); transform: scale(1); will-change: transform; color: var(--text-primary); } .luca-message .luca-message-text:hover { transform: scale(1.03); filter: brightness(1.05); } .luca-bot-message .luca-message-text { background: var(--bg-secondary); border: 1px solid var(--border-color); border-radius: 18px 18px 18px 4px; transition: all 0.4s cubic-bezier(0.34, 1.56, 0.64, 1); max-width: 75%; color: var(--text-primary); box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); position: relative; } .luca-user-message { flex-direction: column; align-items: flex-end; } .luca-user-message .luca-message-text { color: #fff; background: linear-gradient(135deg, var(--accent-primary) 0%, var(--accent-secondary) 100%); border-radius: 18px 18px 4px 18px; transition: all 0.4s cubic-bezier(0.34, 1.56, 0.64, 1); box-shadow: 0 4px 12px rgba(81, 47, 235, 0.3); } /* Chat Footer */ .luca-chat-footer { position: absolute; bottom: 0; left: 0; width: 100%; height: 110px; background: var(--bg-primary); border-top: 1px solid var(--border-color); padding: 15px 22px 40px; z-index: 20; box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.1); } .luca-chat-form { display: flex; align-items: center; position: relative; background: var(--bg-secondary); border-radius: 32px; outline: 1px solid var(--border-color); transition: all 0.4s cubic-bezier(0.34, 1.56, 0.64, 1); transform: translateY(0); will-change: transform, box-shadow; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05); } .luca-chat-form:hover { transform: translateY(-3px); box-shadow: 0 6px 20px rgba(0, 0, 0, 0.15); } .luca-chat-form:focus-within { outline: 2px solid var(--accent-primary); transform: translateY(-4px); box-shadow: 0 8px 25px rgba(81, 47, 235, 0.2); } .luca-message-input { width: 100%; height: 47px; outline: none; resize: none; border: none; max-height: 180px; scrollbar-width: none; -ms-overflow-style: none; border-radius: inherit; font-size: 0.95rem; padding: 14px 0 12px 18px; background: transparent; color: var(--text-primary); transition: all 0.3s ease; line-height: 1.4; font-family: inherit; } .luca-message-input::-webkit-scrollbar { display: none; } .luca-message-input::placeholder { color: var(--text-muted); transition: opacity 0.3s ease; } .luca-message-input:focus::placeholder { opacity: 0.7; } .luca-chat-controls { gap: 3px; height: 47px; display: flex; padding-right: 6px; align-items: center; align-self: flex-end; } .luca-chat-controls button { height: 35px; width: 35px; border: none; cursor: pointer; color: var(--text-secondary); border-radius: 50%; font-size: 1.15rem; background: none; transition: all 0.4s cubic-bezier(0.34, 1.56, 0.64, 1); position: relative; overflow: hidden; will-change: transform, color; font-family: 'Material Symbols Rounded', sans-serif; } .luca-chat-controls button::before { content: ''; position: absolute; top: 50%; left: 50%; width: 0; height: 0; background: var(--accent-primary); opacity: 0.1; border-radius: 50%; transform: translate(-50%, -50%); transition: all 0.3s ease; } .luca-chat-controls button:hover::before { width: 100%; height: 100%; } .luca-chat-controls button:hover { color: var(--accent-hover); transform: scale(1.2); filter: drop-shadow(0 2px 4px rgba(81, 47, 235, 0.3)); } .luca-chat-controls .luca-send-message { color: #fff; display: none; background: linear-gradient(135deg, var(--accent-primary) 0%, var(--accent-secondary) 100%); transition: all 0.4s cubic-bezier(0.34, 1.56, 0.64, 1); box-shadow: 0 2px 8px rgba(81, 47, 235, 0.3); } .luca-chat-controls .luca-send-message:hover { background: linear-gradient(135deg, var(--accent-hover) 0%, var(--accent-primary) 100%); transform: scale(1.15); box-shadow: 0 4px 12px rgba(81, 47, 235, 0.5); } .luca-chat-controls .luca-send-message:active { transform: scale(0.95); transition: all 0.1s ease; } .luca-message-input:valid ~ .luca-chat-controls .luca-send-message { display: block; } /* Action Buttons */ .luca-action-buttons-container { display: flex; justify-content: flex-end; margin-top: 15px; padding: 0; margin-bottom: 30px; position: relative; z-index: 1; } .luca-action-buttons { display: flex; flex-wrap: wrap; gap: 10px; max-width: 100%; justify-content: flex-end; position: relative; z-index: 1; } .luca-action-button { background: linear-gradient(135deg, var(--accent-primary) 0%, var(--accent-secondary) 100%); color: white; border: none; border-radius: 30px; padding: 14px 24px; font-size: 0.9rem; font-weight: 500; cursor: pointer; transition: all 0.4s cubic-bezier(0.34, 1.56, 0.64, 1); display: flex; align-items: center; gap: 8px; min-width: 140px; justify-content: center; position: relative; overflow: hidden; animation: luca-buttonSlideIn 0.6s cubic-bezier(0.34, 1.56, 0.64, 1); box-shadow: 0 4px 15px rgba(81, 47, 235, 0.3); will-change: transform, box-shadow; font-family: inherit; } .luca-action-button::before { content: ''; position: absolute; top: 0; left: -100%; width: 100%; height: 100%; background: linear-gradient(90deg, transparent, rgba(255,255,255,0.2), transparent); transition: all 0.5s ease; } .luca-action-button:hover::before { left: 100%; } .luca-action-button:hover { background: linear-gradient(135deg, var(--accent-hover) 0%, var(--accent-primary) 100%); transform: translateY(-4px) scale(1.05); box-shadow: 0 8px 25px rgba(81, 47, 235, 0.4); } .luca-action-button:active { transform: translateY(-1px) scale(0.98); transition: all 0.15s ease; box-shadow: 0 2px 10px rgba(81, 47, 235, 0.3); } @keyframes luca-buttonSlideIn { 0% { opacity: 0; transform: translateY(30px) scale(0.8) rotateX(30deg); filter: blur(2px); } 60% { transform: translateY(-5px) scale(1.05) rotateX(-5deg); } 100% { opacity: 1; transform: translateY(0) scale(1) rotateX(0deg); filter: blur(0); } } /* Watermark */ .luca-chat-watermark { position: absolute; bottom: 8px; left: 50%; transform: translateX(-50%); font-size: 0.65rem; color: var(--text-muted); opacity: 0.6; text-align: center; z-index: 15; } .luca-chat-watermark a { color: var(--accent-primary); text-decoration: none; font-weight: 500; transition: all 0.3s ease; } .luca-chat-watermark a:hover { color: var(--accent-hover); opacity: 1; } /* Mobile Responsive */ @media (max-width: 520px) { .luca-chatbot-toggle { right: 20px; bottom: 20px; width: 56px; height: 56px; font-size: 1.5rem; animation: luca-float-mobile 6s ease-in-out infinite; } @keyframes luca-float-mobile { 0%, 100% { transform: translateY(0px) scale(1); box-shadow: 0 8px 25px rgba(81, 47, 235, 0.3); } 50% { transform: translateY(-4px) scale(1.01); box-shadow: 0 12px 30px rgba(81, 47, 235, 0.35); } } .luca-chatbot-popup { right: 0; bottom: 0; height: 100vh; border-radius: 0; width: 100vw; transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1); } .luca-chat-header { padding: 12px 15px; height: 60px; min-height: 60px; display: flex; align-items: center; } .luca-logo-text { font-size: 1rem; } .luca-activity-status { font-size: 0.75rem; } .luca-chat-body { height: calc(100vh - 60px - 110px); padding: 15px 15px 120px 15px; margin-bottom: 110px; overflow-y: auto; -webkit-overflow-scrolling: touch; position: relative; overscroll-behavior: contain; } .luca-chat-footer { padding: 10px 15px 15px; height: 110px; position: absolute; bottom: 0; left: 0; width: 100%; z-index: 20; background: var(--bg-primary); border-top: 1px solid var(--border-color); } .luca-chat-form { position: relative; z-index: 25; background: var(--bg-primary); border-radius: 25px; min-height: 50px; } .luca-message-input { font-size: 16px; padding: 15px 0 15px 18px; min-height: 50px; line-height: 1.4; } .luca-action-buttons-container { margin-bottom: 120px; padding: 0 5px; } .luca-action-buttons { flex-direction: column; gap: 12px; margin-bottom: 20px; } .luca-action-button { width: 100%; min-width: auto; padding: 16px 20px; font-size: 1rem; border-radius: 25px; min-height: 56px; display: flex; align-items: center; justify-content: center; } .luca-message { margin-bottom: 12px; gap: 8px; } .luca-message .luca-bot-avatar { width: 32px; height: 32px; } .luca-message .luca-message-text { max-width: 85%; font-size: 0.95rem; padding: 12px 16px; line-height: 1.5; } .luca-chat-controls button { width: 40px; height: 40px; font-size: 1.2rem; } .luca-header-controls button { width: 40px; height: 40px; font-size: 1.1rem; } } /* Material Icons Font */ @import url('https://fonts.googleapis.com/css2?family=Material+Symbols+Rounded:opsz,wght,FILL,GRAD@48,400,1,0&display=swap'); @import url('https://fonts.googleapis.com/css2?family=DM+Sans:ital,opsz,wght@0,9..40,100..1000;1,9..40,100..1000&display=swap'); `; // Inject CSS function injectStyles() { if (document.getElementById('luca-chatbot-styles')) { return; // Already injected } const styleSheet = document.createElement('style'); styleSheet.id = 'luca-chatbot-styles'; styleSheet.textContent = styles; document.head.appendChild(styleSheet); } // Create chatbot HTML structure function createChatbotHTML() { const container = document.createElement('div'); container.className = 'luca-chatbot-container'; container.innerHTML = ` <button class="luca-chatbot-toggle" id="luca-chatbot-toggle"> <span class="material-symbols-rounded">mode_comment</span> <span class="material-symbols-rounded">close</span> </button> <div class="luca-chatbot-popup" id="luca-chatbot-popup"> <div class="luca-chat-header"> <div class="luca-header-info"> <div class="luca-profile-container"> <img class="luca-chatbot-logo" src="https://i.imgur.com/rAOFxqL.png" alt="Luca Chatbot" width="40" height="40"> <div class="luca-online-indicator"></div> </div> <div class="luca-user-info"> <h2 class="luca-logo-text">Luca</h2> <span class="luca-activity-status">Active now</span> </div> </div> <div class="luca-header-controls"> <button id="luca-theme-toggle" class="material-symbols-rounded" title="Toggle theme">dark_mode</button> <button id="luca-close-chatbot" class="material-symbols-rounded">keyboard_arrow_down</button> </div> </div> <div class="luca-chat-body" id="luca-chat-body"> <div class="luca-message luca-bot-message"> <img class="luca-bot-avatar" src="https://i.imgur.com/rAOFxqL.png" alt="Luca" width="35" height="35"> <div class="luca-message-text"> Hei! 👋 Olen Luca, Reppyn 24/7 AI-assistentti. Mitä aihetta asiasi koskee? </div> </div> <div class="luca-action-buttons-container" id="luca-action-buttons-container"> <div class="luca-action-buttons"> <button class="luca-action-button" data-action="general"> <span class="material-symbols-rounded">help</span> Yleiset kysymykset </button> <button class="luca-action-button" data-action="support"> <span class="material-symbols-rounded">support_agent</span> Tekninen tuki </button> <button class="luca-action-button" data-action="pricing"> <span class="material-symbols-rounded">payments</span> Hinnoittelu </button> </div> </div> </div> <div class="luca-chat-footer"> <form class="luca-chat-form" id="luca-chat-form"> <textarea class="luca-message-input" id="luca-message-input" placeholder="Viesti..." required ></textarea> <div class="luca-chat-controls"> <button type="button" id="luca-restart-chat" class="material-symbols-rounded" title="Aloita keskustelu uudelleen">refresh</button> <button type="submit" id="luca-send-message" class="material-symbols-rounded luca-send-message">arrow_upward</button> </div> </form> <div class="luca-chat-watermark"> Powered by <a href="https://reppy.fi" target="_blank">Reppy.fi</a> </div> </div> </div> `; return container; } // Chatbot functionality class LucaChatbot { constructor() { this.container = null; this.isOpen = false; this.messages = []; this.currentTheme = 'dark'; this.init(); } init() { // Inject styles injectStyles(); // Create and append chatbot this.container = createChatbotHTML(); document.body.appendChild(this.container); // Initialize event listeners this.initEventListeners(); // Set initial theme this.setTheme(this.currentTheme); } initEventListeners() { const toggle = document.getElementById('luca-chatbot-toggle'); const closeBtn = document.getElementById('luca-close-chatbot'); const themeToggle = document.getElementById('luca-theme-toggle'); const chatForm = document.getElementById('luca-chat-form'); const messageInput = document.getElementById('luca-message-input'); const restartBtn = document.getElementById('luca-restart-chat'); const actionButtons = document.querySelectorAll('.luca-action-button'); // Toggle chatbot toggle.addEventListener('click', () => this.toggleChatbot()); // Close chatbot closeBtn.addEventListener('click', () => this.closeChatbot()); // Theme toggle themeToggle.addEventListener('click', () => this.toggleTheme()); // Send message chatForm.addEventListener('submit', (e) => { e.preventDefault(); this.sendMessage(); }); // Auto-resize textarea messageInput.addEventListener('input', () => { this.autoResizeTextarea(messageInput); }); // Restart chat restartBtn.addEventListener('click', () => this.restartChat()); // Action buttons actionButtons.forEach(button => { button.addEventListener('click', () => { const action = button.getAttribute('data-action'); this.handleActionButton(action, button.textContent.trim()); }); }); // Close on escape key document.addEventListener('keydown', (e) => { if (e.key === 'Escape' && this.isOpen) { this.closeChatbot(); } }); } toggleChatbot() { if (this.isOpen) { this.closeChatbot(); } else { this.openChatbot(); } } openChatbot() { this.container.classList.add('show-chatbot'); this.isOpen = true; this.scrollToBottom(); // Focus on input setTimeout(() => { const input = document.getElementById('luca-message-input'); input.focus(); }, 500); } closeChatbot() { this.container.classList.remove('show-chatbot'); this.isOpen = false; } toggleTheme() { this.currentTheme = this.currentTheme === 'dark' ? 'light' : 'dark'; this.setTheme(this.currentTheme); } setTheme(theme) { document.documentElement.setAttribute('data-theme', theme); const themeBtn = document.getElementById('luca-theme-toggle'); themeBtn.textContent = theme === 'dark' ? 'light_mode' : 'dark_mode'; } sendMessage() { const input = document.getElementById('luca-message-input'); const message = input.value.trim(); if (!message) return; // Add user message this.addMessage(message, 'user'); input.value = ''; this.autoResizeTextarea(input); // Simulate bot response setTimeout(() => { this.addMessage(this.generateResponse(message), 'bot'); }, 1000); } addMessage(content, type) { const chatBody = document.getElementById('luca-chat-body'); const messageDiv = document.createElement('div'); messageDiv.className = `luca-message ${type}-message`; if (type === 'user') { messageDiv.innerHTML = ` <div class="luca-message-text">${content}</div> `; } else { messageDiv.innerHTML = ` <img class="luca-bot-avatar" src="https://i.imgur.com/rAOFxqL.png" alt="Luca" width="35" height="35"> <div class="luca-message-text">${content}</div> `; } chatBody.appendChild(messageDiv); this.scrollToBottom(); } handleActionButton(action, buttonText) { this.addMessage(buttonText, 'user'); setTimeout(() => { let response = ''; switch(action) { case 'general': response = 'Yleisiä kysymyksiä käsittelemme mielellämme! Mitä haluaisit tietää?'; break; case 'support': response = 'Teknisessä tuessa olen aina valmis auttamaan. Kerro ongelmasi yksityiskohtaisesti.'; break; case 'pricing': response = 'Hinnoittelumme on kilpailukykyinen ja läpinäkyvä. Haluatko tarkempia tietoja?'; break; default: response = 'Kiitos kysymyksestäsi! Miten voin auttaa sinua tarkemmin?'; } this.addMessage(response, 'bot'); }, 1000); } generateResponse(message) { const responses = [ 'Kiitos viestistäsi! Miten voin auttaa sinua tarkemmin?', 'Ymmärrän kysymyksesi. Haluatko lisätietoja jostain tietystä aiheesta?', 'Olen täällä auttaakseni! Onko sinulla muita kysymyksiä?', 'Kiitos yhteydenotosta! Miten voin parhaiten palvella sinua?' ]; return responses[Math.floor(Math.random() * responses.length)]; } restartChat() { const chatBody = document.getElementById('luca-chat-body'); const actionButtonsContainer = document.getElementById('luca-action-buttons-container'); // Keep only the first bot message const messages = chatBody.querySelectorAll('.luca-message'); for (let i = 1; i < messages.length; i++) { messages[i].remove(); } // Restore action buttons if they were removed if (!actionButtonsContainer.querySelector('.luca-action-buttons')) { actionButtonsContainer.innerHTML = ` <div class="luca-action-buttons"> <button class="luca-action-button" data-action="general"> <span class="material-symbols-rounded">help</span> Yleiset kysymykset </button> <button class="luca-action-button" data-action="support"> <span class="material-symbols-rounded">support_agent</span> Tekninen tuki </button> <button class="luca-action-button" data-action="pricing"> <span class="material-symbols-rounded">payments</span> Hinnoittelu </button> </div> `; // Re-add event listeners const actionButtons = actionButtonsContainer.querySelectorAll('.luca-action-button'); actionButtons.forEach(button => { button.addEventListener('click', () => { const action = button.getAttribute('data-action'); this.handleActionButton(action, button.textContent.trim()); }); }); } this.scrollToBottom(); } autoResizeTextarea(textarea) { textarea.style.height = 'auto'; textarea.style.height = Math.min(textarea.scrollHeight, 180) + 'px'; } scrollToBottom() { const chatBody = document.getElementById('luca-chat-body'); setTimeout(() => { chatBody.scrollTop = chatBody.scrollHeight; }, 100); } } // Initialize chatbot when DOM is ready if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', () => { new LucaChatbot(); }); } else { new LucaChatbot(); } // Expose to global scope for external access window.LucaChatbot = LucaChatbot; })();