2026-04-16-1
This commit is contained in:
+117
-8
@@ -11,14 +11,79 @@ const app = {
|
||||
},
|
||||
|
||||
init: async () => {
|
||||
console.log('🚀 Dashboard Initializing Components...');
|
||||
app.bindEvents();
|
||||
app.handleRouting();
|
||||
lucide.createIcons();
|
||||
try {
|
||||
console.log('🚀 Intaleq Dashboard Initializing Core UI...');
|
||||
app.updateHeader();
|
||||
app.bindEvents();
|
||||
|
||||
// Check for payment success/fail status earlier
|
||||
app.checkPaymentStatus();
|
||||
|
||||
if (window.lucide) lucide.createIcons();
|
||||
} catch (e) {
|
||||
console.error('Core UI Init failed', e);
|
||||
}
|
||||
},
|
||||
|
||||
checkPaymentStatus: () => {
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
const status = params.get('payment_status');
|
||||
const txId = params.get('id');
|
||||
|
||||
if (status === 'success') {
|
||||
console.log('🏁 Payment Success Detected! Updating UI...');
|
||||
app.showSuccessModal(txId);
|
||||
|
||||
// Force refresh stats to show PRO plan
|
||||
app.fetchStats();
|
||||
|
||||
// Clean URL without refresh
|
||||
const newUrl = window.location.pathname + window.location.hash;
|
||||
window.history.replaceState({}, document.title, newUrl);
|
||||
}
|
||||
},
|
||||
|
||||
showSuccessModal: (id) => {
|
||||
const modal = document.createElement('div');
|
||||
modal.className = 'fixed inset-0 z-[100] flex items-center justify-center p-6 bg-slate-950/90 backdrop-blur-xl animate-in fade-in duration-500';
|
||||
modal.innerHTML = `
|
||||
<div class="bg-white rounded-[3rem] p-12 max-w-lg w-full text-center shadow-[0_0_100px_rgba(37,99,235,0.3)] border border-white/20 relative overflow-hidden animate-in zoom-in-95 duration-500">
|
||||
<div class="absolute -top-24 -left-24 w-48 h-48 bg-blue-600/20 blur-[80px] rounded-full"></div>
|
||||
|
||||
<div class="relative z-10">
|
||||
<div class="w-24 h-24 bg-emerald-500 rounded-full mx-auto flex items-center justify-center mb-8 shadow-2xl">
|
||||
<i data-lucide="shield-check" class="w-12 h-12 text-white"></i>
|
||||
</div>
|
||||
|
||||
<h2 class="text-4xl font-black text-slate-900 mb-4" data-i18n="welcome">Upgrade Successful!</h2>
|
||||
<p class="text-slate-500 font-bold mb-8 italic">Your account has been upgraded to <span class="text-blue-600">PRO Plan</span>. Enjoy 50,000 monthly requests!</p>
|
||||
|
||||
<div class="p-6 bg-slate-50 rounded-3xl border border-slate-100 flex items-center justify-between mb-10">
|
||||
<div class="text-left">
|
||||
<p class="text-[10px] font-black text-slate-400 uppercase tracking-widest">Transaction ID</p>
|
||||
<p class="font-mono text-sm font-bold text-slate-600">${id || 'N/A'}</p>
|
||||
</div>
|
||||
<div class="bg-blue-600 text-white px-4 py-2 rounded-xl text-xs font-black uppercase tracking-widest shadow-lg">PRO ACTIVE</div>
|
||||
</div>
|
||||
|
||||
<button id="close-success-modal" class="w-full bg-slate-900 text-white py-5 rounded-2xl font-black text-lg hover:scale-[1.02] active:scale-95 transition-all shadow-2xl">
|
||||
LET'S BUILD
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
document.body.appendChild(modal);
|
||||
if (window.lucide) lucide.createIcons();
|
||||
|
||||
document.getElementById('close-success-modal').onclick = () => {
|
||||
modal.classList.add('animate-out', 'fade-out', 'zoom-out-95');
|
||||
setTimeout(() => modal.remove(), 400);
|
||||
};
|
||||
},
|
||||
|
||||
onAuthenticated: async () => {
|
||||
console.log('🔑 User Authenticated, Fetching Data...');
|
||||
console.log('🔑 User Authenticated. Initializing Data Flow...');
|
||||
await app.init(); // Setup UI first
|
||||
await app.fetchData();
|
||||
app.updateStats();
|
||||
},
|
||||
@@ -82,11 +147,55 @@ const app = {
|
||||
app.renderKeysTable();
|
||||
}
|
||||
}
|
||||
// Update Quota Widget
|
||||
const summaryRes = await fetch('/api/usage/summary', { headers });
|
||||
if (summaryRes.ok) {
|
||||
const summary = await summaryRes.json();
|
||||
app.updateQuotaWidget(summary);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to fetch dashboard data', error);
|
||||
console.warn('Dashboard data fetch partially failed', error);
|
||||
}
|
||||
},
|
||||
|
||||
updateQuotaWidget: (summary) => {
|
||||
const percent = parseFloat(summary.percentage) || 0;
|
||||
const used = summary.monthlyUsage || 0;
|
||||
const total = summary.limit || 8000;
|
||||
const left = Math.max(total - used, 0);
|
||||
|
||||
// Sidebar Widget
|
||||
const bar = document.getElementById('quota-bar');
|
||||
const pctText = document.getElementById('quota-percent');
|
||||
const leftText = document.getElementById('quota-text');
|
||||
|
||||
if (bar) {
|
||||
bar.style.width = `${percent}%`;
|
||||
// Color shift based on usage
|
||||
bar.classList.remove('from-blue-600', 'to-blue-400', 'from-orange-500', 'to-orange-400', 'from-red-600', 'to-red-400');
|
||||
if (percent > 90) {
|
||||
bar.classList.add('from-red-600', 'to-red-400');
|
||||
} else if (percent > 70) {
|
||||
bar.classList.add('from-orange-500', 'to-orange-400');
|
||||
} else {
|
||||
bar.classList.add('from-blue-600', 'to-blue-400');
|
||||
}
|
||||
}
|
||||
if (pctText) pctText.textContent = `${percent}%`;
|
||||
if (leftText) leftText.textContent = `${left.toLocaleString()} requests left`;
|
||||
|
||||
// Billing Section Widget (if present)
|
||||
const bBar = document.getElementById('billing-quota-bar');
|
||||
const bPct = document.getElementById('billing-quota-percent');
|
||||
const bUsed = document.getElementById('billing-quota-used');
|
||||
const bTotal = document.getElementById('billing-quota-total');
|
||||
|
||||
if (bBar) bBar.style.width = `${percent}%`;
|
||||
if (bPct) bPct.textContent = `${percent}%`;
|
||||
if (bUsed) bUsed.textContent = `${used.toLocaleString()} used`;
|
||||
if (bTotal) bTotal.textContent = `${total.toLocaleString()} limit`;
|
||||
},
|
||||
|
||||
updateHeader: () => {
|
||||
if (!app.state.tenant) return;
|
||||
document.getElementById('tenant-name').textContent = app.state.tenant.name;
|
||||
@@ -281,5 +390,5 @@ const app = {
|
||||
}
|
||||
};
|
||||
|
||||
// Start app components
|
||||
document.addEventListener('DOMContentLoaded', app.init);
|
||||
// Script sequence is now controlled by auth.js onAuthenticated lifecycle
|
||||
// document.addEventListener('DOMContentLoaded', app.init);
|
||||
|
||||
Reference in New Issue
Block a user