Files
igny8/frontend/src/components/dashboard/CreditBalanceWidget.tsx

81 lines
2.7 KiB
TypeScript

import { useEffect } from 'react';
import { useBillingStore } from '../../store/billingStore';
import ComponentCard from '../common/ComponentCard';
import Button from '../ui/button/Button';
export default function CreditBalanceWidget() {
const { balance, loading, error, loadBalance } = useBillingStore();
useEffect(() => {
loadBalance();
}, [loadBalance]);
if (loading && !balance) {
return (
<ComponentCard title="Credit Balance" desc="Loading...">
<div className="animate-pulse">Loading credit balance...</div>
</ComponentCard>
);
}
if (error && !balance) {
return (
<ComponentCard title="Credit Balance" desc="Balance unavailable">
<div className="text-sm text-red-600 dark:text-red-400 mb-3">
Balance unavailable. Please retry.
</div>
<Button variant="outline" size="sm" onClick={loadBalance}>
Retry
</Button>
</ComponentCard>
);
}
if (!balance) return null;
const usagePercentage = balance.plan_credits_per_month > 0
? (balance.credits_used_this_month / balance.plan_credits_per_month) * 100
: 0;
return (
<ComponentCard title="Credit Balance" desc="Current credit status and usage">
<div className="space-y-4">
<div>
<div className="flex justify-between items-center mb-2">
<span className="text-sm text-gray-600 dark:text-gray-400">Current Credits</span>
<span className="text-2xl font-bold text-primary">{balance.credits}</span>
</div>
</div>
<div>
<div className="flex justify-between items-center mb-2">
<span className="text-sm text-gray-600 dark:text-gray-400">Used This Month</span>
<span className="text-sm font-medium">
{balance.credits_used_this_month} / {balance.plan_credits_per_month}
</span>
</div>
<div className="w-full bg-gray-200 rounded-full h-2.5 dark:bg-gray-700">
<div
className="bg-primary h-2.5 rounded-full transition-all"
style={{ width: `${Math.min(usagePercentage, 100)}%` }}
/>
</div>
</div>
<div className="pt-2 border-t border-gray-200 dark:border-gray-700">
<div className="flex justify-between items-center">
<span className="text-sm text-gray-600 dark:text-gray-400">Remaining</span>
<span className="text-sm font-medium text-success">{balance.credits_remaining}</span>
</div>
{error && (
<div className="mt-2 text-xs text-amber-600 dark:text-amber-400">
Balance may be outdated. {error}
</div>
)}
</div>
</div>
</ComponentCard>
);
}