/**
* 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 Components...');
app.bindEvents();
app.handleRouting();
lucide.createIcons();
},
onAuthenticated: async () => {
console.log('🔑 User Authenticated, Fetching Data...');
await app.fetchData();
app.updateStats();
},
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();
} else if (hash === 'billing') {
billing.init();
} else if (hash === 'refinement') {
refinement.init();
} else if (hash === 'docs') {
docs.init();
}
},
fetchData: async () => {
const headers = auth.getAuthHeader();
try {
// Fetch Tenant
const tenantRes = await fetch('/api/auth/management/me', { headers });
if (tenantRes.ok) {
app.state.tenant = await tenantRes.json();
app.updateHeader();
}
// Fetch Keys
if (app.state.tenant) {
const keysRes = await fetch('/api/auth/management/keys', { headers });
if (keysRes.ok) {
app.state.keys = await keysRes.json();
app.renderKeysTable();
}
}
} 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.split(' ')[0]}`;
// Role-based UI visibility
if (app.state.tenant.role === 'ADMIN') {
const auditLink = document.getElementById('nav-refinement');
if (auditLink) auditLink.classList.remove('hidden');
}
// Update user avatar if photoUrl exists
if (app.state.tenant.photoUrl) {
const avatarContainer = document.querySelector('.w-10.h-10.rounded-full.bg-slate-900');
if (avatarContainer) {
avatarContainer.innerHTML = ``;
}
}
},
updateStats: async () => {
try {
const headers = auth.getAuthHeader();
const res = await fetch('/api/usage/summary', { headers });
if (res.ok) {
const data = await res.json();
// Update KPI Cards
document.getElementById('active-keys-count').textContent = app.state.keys.length;
// Detailed Stats from getUsageSummary
if (document.getElementById('stat-total-req')) {
document.getElementById('stat-total-req').textContent = data.monthlyUsage.toLocaleString();
}
if (document.getElementById('stat-success-percent')) {
document.getElementById('stat-success-percent').textContent = `${data.successRate}%`;
document.getElementById('stat-success-rate').textContent = data.successRate >= 95 ? 'Excellent' : 'Stable';
}
if (document.getElementById('stat-avg-latency')) {
document.getElementById('stat-avg-latency').textContent = `${data.avgLatency}ms`;
document.getElementById('stat-latency-val').textContent = `-${Math.round(data.avgLatency * 0.1)}ms`;
}
// Update Progress bar & Quota card
const bar = document.getElementById('usage-progress-bar');
const label = document.getElementById('usage-percentage-label');
const limitText = document.getElementById('usage-limit-text');
if (bar) bar.style.width = `${data.percentage}%`;
if (label) label.textContent = `${data.percentage}% USED`;
if (limitText) {
const remaining = Math.max(0, data.limit - data.monthlyUsage);
limitText.textContent = `${remaining.toLocaleString()} requests left`;
}
}
} catch (error) {
console.error('Failed to update stats', error);
}
// Inject sample bars for visual flair if chart not ready
const container = document.getElementById('traffic-bars');
if (container) {
container.innerHTML = '';
// High-density bars for a tech/premium feel
const values = [40, 60, 55, 80, 70, 45, 90, 85, 60, 40, 30, 55, 75, 40, 60, 55, 80, 70, 45, 90, 85, 60, 40, 30, 55, 75, 50, 65, 80, 70, 30];
values.forEach((h, index) => {
const bar = document.createElement('div');
bar.className = 'flex-1 bg-gradient-to-t from-blue-600/10 to-blue-400/60 rounded-t-[2px] relative group hover:to-blue-300 transition-all duration-500';
bar.style.height = `${h}%`;
bar.style.transitionDelay = `${index * 20}ms`;
bar.innerHTML = `
${maskedKey}