/** * Main App Logic for Intaleq Dashboard (Vanilla Version) */ const app = { state: { tenant: null, keys: [], showKeys: {}, // { id: boolean } activePage: 'home' }, init: async () => { console.log('🚀 Dashboard Initializing...'); app.bindEvents(); app.handleRouting(); await app.fetchData(); lucide.createIcons(); }, bindEvents: () => { window.addEventListener('hashchange', app.handleRouting); // Form submission for new key const createKeyForm = document.getElementById('create-key-form'); if (createKeyForm) { createKeyForm.addEventListener('submit', async (e) => { e.preventDefault(); await app.createKey(); }); } }, handleRouting: () => { const hash = window.location.hash.replace('#', '') || 'home'; app.state.activePage = hash; // Update UI document.querySelectorAll('.page-section').forEach(s => s.classList.remove('active')); const activeSection = document.getElementById(hash); if (activeSection) activeSection.classList.add('active'); // Update Nav document.querySelectorAll('.nav-link').forEach(l => l.classList.remove('active')); const activeLink = document.getElementById(`nav-${hash}`); if (activeLink) activeLink.classList.add('active'); // Specialized page logic if (hash === 'playground') { playground.init(app.state.keys); } else if (hash === 'analytics') { analytics.init(); } }, fetchData: async () => { try { // Fetch Tenant const tenantRes = await fetch('/api/auth/management/me'); if (tenantRes.ok) { app.state.tenant = await tenantRes.data || await tenantRes.json(); app.updateHeader(); } // Fetch Keys if (app.state.tenant && app.state.tenant.id) { const keysRes = await fetch(`/api/auth/management/keys/${app.state.tenant.id}`); if (keysRes.ok) { app.state.keys = await keysRes.json(); app.renderKeysTable(); app.updateStats(); } } } catch (error) { console.error('Failed to fetch dashboard data', error); } }, updateHeader: () => { if (!app.state.tenant) return; document.getElementById('tenant-name').textContent = app.state.tenant.name; document.getElementById('tenant-email').textContent = app.state.tenant.email; document.getElementById('welcome-msg').textContent = `Welcome back, ${app.state.tenant.name}`; }, updateStats: () => { document.getElementById('active-keys-count').textContent = app.state.keys.length; // Inject random bars for traffic const container = document.getElementById('traffic-bars'); if (container) { container.innerHTML = ''; const values = [40, 60, 55, 80, 70, 45, 90, 85, 60, 40, 30, 55, 75, 40, 60, 55, 80, 70, 45, 90]; values.forEach(h => { const bar = document.createElement('div'); bar.className = 'flex-1 bg-gradient-to-t from-blue-600/20 to-blue-400/80 rounded-t-sm relative group hover:to-blue-300 transition-all'; bar.style.height = `${h}%`; bar.innerHTML = `
${h}k
`; container.appendChild(bar); }); } }, renderKeysTable: () => { const tbody = document.getElementById('keys-table-body'); const createBtn = document.getElementById('create-key-btn'); if (!tbody) return; if (app.state.keys.length === 0) { tbody.innerHTML = `No API keys found. Create one to get started.`; return; } // Disable create button if limit reached (per React logic) if (app.state.keys.length >= 1) { createBtn.disabled = true; createBtn.title = "Limit of 1 API key per developer reached"; createBtn.innerHTML = ' Limit Reached'; } tbody.innerHTML = app.state.keys.map(key => { const isVisible = app.state.showKeys[key.id]; const maskedKey = isVisible ? key.key : "in_••••••••••••••••••••••••"; const eyeIcon = isVisible ? 'eye-off' : 'eye'; return ` ${key.name}
${maskedKey}
${key.isActive ? 'Active' : 'Inactive'}
${(key.allowedOrigins && key.allowedOrigins.length > 0) ? key.allowedOrigins.map(org => ` ${org}`).join('') : ` Universal` }
`; }).join(''); lucide.createIcons(); }, toggleKeyVisibility: (id) => { app.state.showKeys[id] = !app.state.showKeys[id]; app.renderKeysTable(); }, copyToClipboard: (text) => { navigator.clipboard.writeText(text); // Simple toast or just feedback console.log('Copied to clipboard'); }, toggleModal: (id, show) => { const modal = document.getElementById(id); if (modal) { if (show) modal.classList.remove('hidden'); else modal.classList.add('hidden'); } }, createKey: async () => { const name = document.getElementById('new-key-name').value; const btn = document.getElementById('btn-submit-key'); if (!app.state.tenant) return; try { btn.disabled = true; btn.textContent = 'Creating...'; const res = await fetch(`/api/auth/management/keys/${app.state.tenant.id}`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ name, rateLimit: 100 }) }); if (res.ok) { app.toggleModal('create-key-modal', false); await app.fetchData(); document.getElementById('new-key-name').value = ''; } else { alert('Failed to create key'); } } catch (error) { console.error(error); } finally { btn.disabled = false; btn.textContent = 'Create Key'; } } }; // Start app document.addEventListener('DOMContentLoaded', app.init);