// DOM Elements const adminMenu = document.querySelector('.admin-menu'); const tabContents = document.querySelectorAll('.tab-content'); const logoutBtn = document.getElementById('logout-btn'); const sectionTitle = document.getElementById('section-title'); // OpenRouter API Configuration let openRouterConfig = { apiKey: localStorage.getItem('openRouterApiKey') || '', siteUrl: localStorage.getItem('openRouterSiteUrl') || window.location.origin, siteName: localStorage.getItem('openRouterSiteName') || 'Muhafiz AI Chat' }; // Model Settings let modelSettings = { selectedModel: localStorage.getItem('selectedModel') || 'openai/gpt-3.5-turbo', temperature: parseFloat(localStorage.getItem('temperature')) || 0.7, maxTokens: parseInt(localStorage.getItem('maxTokens')) || 2048, streamResponse: localStorage.getItem('streamResponse') === 'true' }; // Initialize admin panel function initAdminPanel() { // Check authentication if (localStorage.getItem('adminLoggedIn') !== 'true') { window.location.href = 'login.html'; return; } // Add event listeners adminMenu.addEventListener('click', handleMenuClick); logoutBtn.addEventListener('click', handleLogout); // Load saved settings loadSettings(); // Set up form change tracking setupChangeTracking(); } // Handle menu item clicks function handleMenuClick(e) { const menuItem = e.target.closest('li'); if (!menuItem || menuItem.id === 'logout-btn') return; // Update active menu item document.querySelectorAll('.admin-menu li').forEach(item => { item.classList.remove('active'); }); menuItem.classList.add('active'); // Show corresponding tab content const tabId = menuItem.getAttribute('data-tab'); tabContents.forEach(tab => { tab.classList.remove('active'); if (tab.id === tabId) { tab.classList.add('active'); } }); // Update section title sectionTitle.textContent = menuItem.textContent.trim(); } // Handle logout function handleLogout() { if (hasUnsavedChanges()) { if (!confirm('You have unsaved changes. Are you sure you want to logout?')) { return; } } // Clear admin session localStorage.removeItem('adminLoggedIn'); // Redirect to login page window.location.href = 'login.html'; } // Track unsaved changes let hasUnsavedChanges = () => false; // Set up change tracking function setupChangeTracking() { const formElements = document.querySelectorAll('input, select, textarea'); let initialValues = new Map(); formElements.forEach(element => { initialValues.set(element, element.value); element.addEventListener('change', () => { const hasChanges = Array.from(formElements).some(el => initialValues.get(el) !== el.value ); hasUnsavedChanges = () => hasChanges; }); }); } // Load saved settings function loadSettings() { const savedConfig = localStorage.getItem('chatConfig'); if (savedConfig) { const config = JSON.parse(savedConfig); // Apply saved settings to form elements Object.entries(config).forEach(([key, value]) => { const element = document.getElementById(key); if (element) { element.value = value; } }); } } // Save settings function saveSettings() { // OpenRouter API Configuration openRouterConfig = { apiKey: document.getElementById('openRouterApiKey').value, siteUrl: document.getElementById('openRouterSiteUrl').value, siteName: document.getElementById('openRouterSiteName').value }; // Model Settings modelSettings = { selectedModel: document.getElementById('modelSelect').value, temperature: parseFloat(document.getElementById('temperature').value), maxTokens: parseInt(document.getElementById('maxTokens').value), streamResponse: document.getElementById('streamResponse').checked }; // Save to localStorage Object.entries(openRouterConfig).forEach(([key, value]) => { localStorage.setItem(`openRouter${key.charAt(0).toUpperCase() + key.slice(1)}`, value); }); Object.entries(modelSettings).forEach(([key, value]) => { localStorage.setItem(key, value); }); showNotification('Settings saved successfully!', 'success'); } // Show notification function showNotification(message, type = 'info') { const notification = document.createElement('div'); notification.classList.add('notification', `notification-${type}`); notification.textContent = message; document.body.appendChild(notification); setTimeout(() => { notification.classList.add('notification-hide'); setTimeout(() => notification.remove(), 300); }, 3000); } // Initialize when DOM is loaded document.addEventListener('DOMContentLoaded', initAdminPanel); // Handle beforeunload window.addEventListener('beforeunload', (e) => { if (hasUnsavedChanges()) { e.preventDefault(); e.returnValue = ''; } }); // Initialize form values function initializeFormValues() { // OpenRouter API Configuration document.getElementById('openRouterApiKey').value = openRouterConfig.apiKey; document.getElementById('openRouterSiteUrl').value = openRouterConfig.siteUrl; document.getElementById('openRouterSiteName').value = openRouterConfig.siteName; // Model Settings document.getElementById('modelSelect').value = modelSettings.selectedModel; document.getElementById('temperature').value = modelSettings.temperature; document.getElementById('temperatureValue').textContent = modelSettings.temperature; document.getElementById('maxTokens').value = modelSettings.maxTokens; document.getElementById('streamResponse').checked = modelSettings.streamResponse; } // Copy to clipboard function function copyToClipboard(elementId) { const element = document.getElementById(elementId); navigator.clipboard.writeText(element.value).then(() => { showNotification('Copied to clipboard!', 'success'); }).catch(err => { showNotification('Failed to copy text', 'error'); }); } // Test model function async function testModel() { const testButton = document.getElementById('testModel'); const originalText = testButton.textContent; testButton.disabled = true; testButton.textContent = 'Testing...'; try { const response = await fetch('https://openrouter.ai/api/v1/chat/completions', { method: 'POST', headers: { 'Authorization': `Bearer ${openRouterConfig.apiKey}`, 'HTTP-Referer': openRouterConfig.siteUrl, 'X-Title': openRouterConfig.siteName, 'Content-Type': 'application/json' }, body: JSON.stringify({ model: modelSettings.selectedModel, messages: [ { role: 'user', content: 'Say "Hello! I am working correctly!"' } ], temperature: modelSettings.temperature, max_tokens: modelSettings.maxTokens, stream: false }) }); const data = await response.json(); if (!response.ok) { console.error('OpenRouter API Error:', data); throw new Error(data.error?.message || `HTTP error! status: ${response.status}`); } showNotification('Model test successful! Response: ' + data.choices[0].message.content, 'success'); } catch (error) { console.error('Model test failed:', error); showNotification('Model test failed: ' + error.message, 'error'); } finally { testButton.disabled = false; testButton.textContent = originalText; } } // Update temperature value display document.getElementById('temperature')?.addEventListener('input', (e) => { document.getElementById('temperatureValue').textContent = e.target.value; }); // Test API Response async function testApiResponse() { const testButton = document.getElementById('testApiBtn'); const testMessage = document.getElementById('testMessage'); const testResponse = document.getElementById('testResponse'); const testError = document.getElementById('testError'); const responseContainer = document.querySelector('.test-response-container'); // Validate inputs if (!openRouterConfig.apiKey) { showNotification('Please enter your API key first', 'error'); return; } // Update button state testButton.classList.add('loading'); testButton.disabled = true; const originalText = testButton.innerHTML; testButton.innerHTML = ' Testing...'; // Clear previous results testResponse.textContent = ''; testError.textContent = ''; responseContainer.style.display = 'none'; try { console.log('Testing API with configuration:', { model: modelSettings.selectedModel, siteUrl: openRouterConfig.siteUrl, siteName: openRouterConfig.siteName }); const response = await fetch('https://openrouter.ai/api/v1/chat/completions', { method: 'POST', headers: { 'Authorization': `Bearer ${openRouterConfig.apiKey}`, 'HTTP-Referer': openRouterConfig.siteUrl, 'X-Title': openRouterConfig.siteName, 'Content-Type': 'application/json' }, body: JSON.stringify({ model: modelSettings.selectedModel, messages: [ { role: 'user', content: testMessage.value || 'Hello! Can you hear me?' } ], temperature: modelSettings.temperature, max_tokens: modelSettings.maxTokens, stream: false }) }); const data = await response.json(); if (!response.ok) { console.error('OpenRouter API Error:', data); throw new Error(data.error?.message || `HTTP error! status: ${response.status}`); } // Display the full response for debugging responseContainer.style.display = 'block'; testResponse.textContent = JSON.stringify(data, null, 2); // Show success notification showNotification('API test successful!', 'success'); } catch (error) { console.error('API Test Error:', error); responseContainer.style.display = 'block'; testError.textContent = `Error: ${error.message}`; showNotification('API test failed. Check the error details below.', 'error'); } finally { // Reset button state testButton.classList.remove('loading'); testButton.disabled = false; testButton.innerHTML = originalText; } } // Initialize form values when DOM is loaded document.addEventListener('DOMContentLoaded', () => { initializeFormValues(); // Add event listeners for copy buttons document.querySelectorAll('.copy-btn').forEach(button => { button.addEventListener('click', (e) => { const inputId = e.target.closest('.input-with-copy').querySelector('input').id; copyToClipboard(inputId); }); }); // Add event listener for test model button document.getElementById('testModel')?.addEventListener('click', testModel); // Add test API button handler document.getElementById('testApiBtn')?.addEventListener('click', testApiResponse); // Add form submit handler document.getElementById('modelSettingsForm')?.addEventListener('submit', (e) => { e.preventDefault(); saveSettings(); }); });