112 lines
4.0 KiB
JavaScript
112 lines
4.0 KiB
JavaScript
document.addEventListener('DOMContentLoaded', () => {
|
|
fetchQuotas();
|
|
fetchHistory();
|
|
});
|
|
|
|
async function fetchQuotas() {
|
|
try {
|
|
const response = await fetch('/api/quotas');
|
|
const data = await fetch('/api/history'); // Using history endpoint as mockup for latest if DB is empty? Wait, no, quotas endpoint should return latest.
|
|
const quotas = await response.json();
|
|
|
|
// If DB is empty, mock data for UI testing if quotas is empty
|
|
const activeQuotas = quotas.length > 0 ? quotas : [
|
|
{ provider: 'Antigravity', used: 730, total: 1000, percentage: 73 },
|
|
{ provider: 'POE', used: 33750, total: 75000, percentage: 45 },
|
|
{ provider: 'MiniMax', used: 60, total: 100, percentage: 60 }
|
|
];
|
|
|
|
activeQuotas.forEach(quota => {
|
|
updateCard(quota.provider.toLowerCase(), quota);
|
|
});
|
|
} catch (error) {
|
|
console.error('Error fetching quotas:', error);
|
|
}
|
|
}
|
|
|
|
function updateCard(providerId, quota) {
|
|
const fill = document.getElementById(`fill-${providerId}`);
|
|
const statusText = document.getElementById(`status-${providerId}`);
|
|
const meme = document.getElementById(`meme-${providerId}`);
|
|
|
|
if (!fill || !statusText) return;
|
|
|
|
const percentage = quota.percentage;
|
|
fill.style.width = `${percentage}%`;
|
|
|
|
// Set color gradient position based on percentage
|
|
fill.style.backgroundPosition = `${100 - percentage}% 0`;
|
|
|
|
statusText.innerText = `${percentage.toFixed(1)}% Used (${quota.used} / ${quota.total})`;
|
|
|
|
// Meme reactions based on percentage
|
|
if (percentage > 90) {
|
|
meme.style.transform = 'scale(1.2) rotate(5deg)';
|
|
statusText.style.color = 'var(--danger)';
|
|
} else if (percentage < 20) {
|
|
statusText.style.color = 'var(--success)';
|
|
}
|
|
|
|
if (percentage >= 100) {
|
|
confetti({
|
|
particleCount: 100,
|
|
spread: 70,
|
|
origin: { y: 0.6 }
|
|
});
|
|
statusText.innerText = 'LIMIT REACHED! 😱';
|
|
}
|
|
}
|
|
|
|
async function fetchHistory() {
|
|
try {
|
|
const response = await fetch('/api/history');
|
|
const history = await response.json();
|
|
|
|
// Process data for Chart.js
|
|
const labels = [...new Set(history.map(item => new Date(item.timestamp).toLocaleTimeString()))].sort();
|
|
|
|
const antigravityData = history.filter(item => item.provider === 'Antigravity').map(item => item.percentage);
|
|
const poeData = history.filter(item => item.provider === 'POE').map(item => item.percentage);
|
|
const minimaxData = history.filter(item => item.provider === 'MiniMax').map(item => item.percentage);
|
|
|
|
const ctx = document.getElementById('historyChart').getContext('2d');
|
|
new Chart(ctx, {
|
|
type: 'line',
|
|
data: {
|
|
labels: labels.length ? labels : ['10:00', '11:00', '12:00', '13:00'], // Fallback labels
|
|
datasets: [
|
|
{
|
|
label: 'Antigravity Usage (%)',
|
|
data: antigravityData.length ? antigravityData : [10, 30, 50, 73],
|
|
borderColor: '#bb86fc',
|
|
tension: 0.1
|
|
},
|
|
{
|
|
label: 'POE Usage (%)',
|
|
data: poeData.length ? poeData : [5, 10, 20, 45],
|
|
borderColor: '#03dac6',
|
|
tension: 0.1
|
|
},
|
|
{
|
|
label: 'MiniMax Usage (%)',
|
|
data: minimaxData.length ? minimaxData : [0, 0, 30, 60],
|
|
borderColor: '#f1c40f',
|
|
tension: 0.1
|
|
}
|
|
]
|
|
},
|
|
options: {
|
|
responsive: true,
|
|
scales: {
|
|
y: {
|
|
beginAtZero: true,
|
|
max: 100
|
|
}
|
|
}
|
|
}
|
|
});
|
|
} catch (error) {
|
|
console.error('Error fetching history:', error);
|
|
}
|
|
}
|