// CyberGuard AI Assistant Main Script document.addEventListener('DOMContentLoaded', function() { // DOM Elements const sidebar = document.getElementById('sidebar'); const menuToggle = document.getElementById('menu-toggle'); const chatContainer = document.querySelector('.chat-container'); const userInput = document.getElementById('user-input'); const sendButton = document.getElementById('send-btn'); const chatMessages = document.getElementById('chat-messages'); const typingIndicator = document.getElementById('typing-indicator'); const infoButton = document.getElementById('info-btn'); const infoModal = document.getElementById('info-modal'); const closeModalButtons = document.querySelectorAll('.close-modal'); const languageSelector = document.getElementById('language-selector'); const languageDropdown = document.getElementById('language-dropdown'); const currentLanguageSpan = document.getElementById('current-language'); const languageOptions = document.querySelectorAll('.language-option'); const exampleQueries = document.querySelectorAll('.example-query'); const newChatButtons = document.querySelectorAll('#sidebar-new-chat-btn, #header-new-chat-btn'); const conversationList = document.getElementById('conversation-list'); // App State const state = { currentLanguage: CONFIG.app.defaultLanguage, conversations: [], // All conversations currentConversationId: null, // Current active conversation ID loading: false, systemContext: CONFIG.openai.system_message, }; // Initialize the application function init() { loadConversations(); createNewConversation(); setupEventListeners(); updateUIText(); } // Setup Event Listeners function setupEventListeners() { // Menu toggle menuToggle.addEventListener('click', toggleSidebar); // Send message on button click sendButton.addEventListener('click', sendMessage); // Send message on Enter key (but allow Shift+Enter for new line) userInput.addEventListener('keydown', (e) => { if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); if (!sendButton.disabled) { sendMessage(); } } }); // Enable/disable send button based on input userInput.addEventListener('input', () => { sendButton.disabled = userInput.value.trim() === ''; // Auto-resize textarea userInput.style.height = 'auto'; userInput.style.height = (userInput.scrollHeight) + 'px'; }); // Info button infoButton.addEventListener('click', () => { infoModal.classList.add('active'); }); // Close modals closeModalButtons.forEach(button => { button.addEventListener('click', (e) => { e.target.closest('.modal').classList.remove('active'); }); }); // Language selector languageSelector.addEventListener('click', (e) => { e.stopPropagation(); languageDropdown.classList.toggle('active'); }); // Close language dropdown when clicking outside document.addEventListener('click', () => { languageDropdown.classList.remove('active'); }); // Language selection languageOptions.forEach(option => { option.addEventListener('click', (e) => { const lang = e.target.getAttribute('data-lang'); changeLanguage(lang); languageDropdown.classList.remove('active'); }); }); // Example queries exampleQueries.forEach(query => { query.addEventListener('click', () => { const queryText = query.getAttribute('data-query'); userInput.value = queryText; sendButton.disabled = false; userInput.focus(); sendMessage(); }); }); // New chat button newChatButtons.forEach(button => { button.addEventListener('click', () => { createNewConversation(); if (window.innerWidth <= 768) { toggleSidebar(); } }); }); } // Toggle sidebar function toggleSidebar() { sidebar.classList.toggle('active'); chatContainer.classList.toggle('sidebar-open'); } // Send message to AI async function sendMessage() { if (userInput.value.trim() === '' || state.loading) return; const userMessage = userInput.value.trim(); userInput.value = ''; userInput.style.height = 'auto'; sendButton.disabled = true; // Auto-detect language from user input detectAndUpdateLanguage(userMessage); // Add user message to UI const userMessageId = 'msg-' + Date.now(); addMessageToUI('user', userMessage, userMessageId); // Scroll to bottom scrollToBottom(); // Add to conversation history addMessageToConversation('user', userMessage); // Show typing indicator typingIndicator.classList.add('active'); // Set loading state state.loading = true; try { // Get current conversation const conversation = state.conversations.find(c => c.id === state.currentConversationId); // Create messages array for API - including conversation history for context const messages = [ { role: "system", content: state.systemContext }, ...conversation.messages.map(msg => ({ role: msg.role, content: msg.content })) ]; // Call OpenAI API const response = await callOpenAI(messages); // Hide typing indicator typingIndicator.classList.remove('active'); // Parse response if (response && response.choices && response.choices[0]) { const botResponse = response.choices[0].message.content; // Add bot message to UI with typing effect const botMessageId = 'msg-' + Date.now(); addMessageToUI('bot', '', botMessageId); // Add bot message to conversation immediately but update UI with typing effect addMessageToConversation('assistant', botResponse); // Apply typing effect await typeMessage(botMessageId, botResponse); // Update the first message of the conversation as the title if this is a new conversation if (conversation.messages.length <= 2) { updateConversationTitle(conversation.id, userMessage); } // Save conversations to local storage saveConversations(); // Update sidebar updateConversationList(); } } catch (error) { console.error('Error sending message:', error); // Add error message to UI addMessageToUI('bot', 'Sorry, I encountered an error. Please try again later.'); // Hide typing indicator typingIndicator.classList.remove('active'); } // Reset loading state state.loading = false; // Enable send button if there's text in the input sendButton.disabled = userInput.value.trim() === ''; // Scroll to bottom scrollToBottom(); } // Add message to UI function addMessageToUI(role, content, id = null) { const messageDiv = document.createElement('div'); messageDiv.className = `message ${role}`; if (id) { messageDiv.id = id; } const avatar = document.createElement('div'); avatar.className = 'message-avatar'; if (role === 'user') { avatar.innerHTML = ''; } else { avatar.innerHTML = ''; } const messageContent = document.createElement('div'); messageContent.className = 'message-content'; // Format message content with Markdown-like syntax if (content) { // Handle code blocks content = content.replace(/```([\s\S]*?)```/g, function(match, p1) { return `
${p1}
`; }); // Handle bold text content = content.replace(/\*\*(.*?)\*\*/g, '$1'); // Handle italic text content = content.replace(/\*(.*?)\*/g, '$1'); // Handle line breaks content = content.replace(/\n/g, '
'); messageContent.innerHTML = content; } const timestamp = document.createElement('div'); timestamp.className = 'message-time'; timestamp.textContent = new Date().toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }); messageContent.appendChild(timestamp); messageDiv.appendChild(avatar); messageDiv.appendChild(messageContent); // Remove welcome container if present const welcomeContainer = document.querySelector('.welcome-container'); if (welcomeContainer) { welcomeContainer.remove(); } chatMessages.appendChild(messageDiv); scrollToBottom(); } // Type effect for bot messages async function typeMessage(messageId, content) { const messageContent = document.querySelector(`#${messageId} .message-content`);