erp-core-frontend-web/src/features/billing-usage/components/UsageProgressBar.tsx
rckrdmrd 28b27565f8 feat(billing): Add billing-usage frontend module with components, pages and routes
- Add billing-usage feature module with types, API clients, hooks, and components
- Create PlanCard, PlanSelector, SubscriptionStatusBadge, InvoiceList, UsageSummaryCard, CouponInput components
- Add BillingPage, PlansPage, InvoicesPage, UsagePage
- Update routes to include billing section

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-18 08:23:59 -06:00

73 lines
2.0 KiB
TypeScript

import React from 'react';
interface UsageProgressBarProps {
label: string;
current: number;
limit: number;
unit?: string;
showOverage?: boolean;
}
export const UsageProgressBar: React.FC<UsageProgressBarProps> = ({
label,
current,
limit,
unit = '',
showOverage = true,
}) => {
const isUnlimited = limit === -1;
const percent = isUnlimited ? 0 : Math.min((current / limit) * 100, 100);
const overage = !isUnlimited && current > limit ? current - limit : 0;
const getColorClass = () => {
if (isUnlimited) return 'bg-gray-400';
if (percent >= 100) return 'bg-red-500';
if (percent >= 80) return 'bg-yellow-500';
return 'bg-blue-500';
};
const formatValue = (value: number) => {
if (value >= 1000000) return `${(value / 1000000).toFixed(1)}M`;
if (value >= 1000) return `${(value / 1000).toFixed(1)}K`;
return value.toString();
};
return (
<div className="space-y-1">
<div className="flex items-center justify-between text-sm">
<span className="font-medium text-gray-700">{label}</span>
<span className="text-gray-500">
{formatValue(current)}
{unit && ` ${unit}`}
{!isUnlimited && (
<>
{' / '}
{formatValue(limit)}
{unit && ` ${unit}`}
</>
)}
{isUnlimited && ' (ilimitado)'}
</span>
</div>
<div className="h-2 overflow-hidden rounded-full bg-gray-200">
<div
className={`h-full rounded-full transition-all ${getColorClass()}`}
style={{ width: isUnlimited ? '0%' : `${Math.min(percent, 100)}%` }}
/>
</div>
<div className="flex items-center justify-between text-xs">
<span className="text-gray-400">
{isUnlimited ? 'Sin límite' : `${percent.toFixed(1)}% usado`}
</span>
{showOverage && overage > 0 && (
<span className="font-medium text-red-600">
+{formatValue(overage)} excedente
</span>
)}
</div>
</div>
);
};