81 lines
2.7 KiB
TypeScript
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>
|
|
);
|
|
}
|
|
|