Files
TokenWatch/public/app.js
T
2026-08-27 07:00:29 +02:00

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);
}
}