buckets/resources/js/components/DigitalProgressBar.tsx

57 lines
1.9 KiB
TypeScript

interface DigitalProgressBarProps {
current: number;
capacity: number;
projected?: number;
}
const BAR_COUNT = 20;
function getGlow(index: number): string {
if (index < 10) return '0 0 8px rgba(239, 68, 68, 0.6)';
if (index < BAR_COUNT - 1) return '0 0 8px rgba(249, 115, 22, 0.6)';
return '0 0 8px rgba(34, 197, 94, 0.6)';
}
function getBarColor(index: number): string {
if (index < 10) return 'bg-red-500';
if (index < BAR_COUNT - 1) return 'bg-orange-500';
return 'bg-green-500';
}
const PROJECTED_GLOW = '0 0 8px rgba(234, 179, 8, 0.6)';
export default function DigitalProgressBar({ current, capacity, projected }: DigitalProgressBarProps) {
const filledBars = capacity > 0
? Math.min(Math.round((current / capacity) * BAR_COUNT), BAR_COUNT)
: 0;
const projectedBars = capacity > 0 && projected
? Math.min(Math.round(((current + projected) / capacity) * BAR_COUNT), BAR_COUNT)
: filledBars;
return (
<div
style={{
display: 'grid',
gridTemplateColumns: `repeat(${BAR_COUNT}, 1fr)`,
gap: '10px',
height: '2rem',
}}
>
{Array.from({ length: BAR_COUNT }, (_, i) => {
const filled = i < filledBars;
const isProjected = !filled && i < projectedBars;
return (
<div
key={i}
style={{
borderRadius: '3px',
transition: 'background-color 300ms, box-shadow 300ms',
boxShadow: filled ? getGlow(i) : isProjected ? PROJECTED_GLOW : 'none',
}}
className={filled ? getBarColor(i) : isProjected ? 'bg-yellow-500' : 'bg-red-500/10'}
/>
);
})}
</div>
);
}