buckets/resources/js/components/BucketCard.tsx

58 lines
2.5 KiB
TypeScript
Raw Normal View History

import DigitalProgressBar from '@/components/DigitalProgressBar';
import { type Bucket } from '@/types';
const centsToDollars = (cents: number): number => cents / 100;
const basisPointsToPercent = (bp: number): number => bp / 100;
const formatDollars = (cents: number): string => `$${centsToDollars(cents).toFixed(0)}`;
export default function BucketCard({ bucket, projectedAmount }: { bucket: Bucket; projectedAmount?: number }) {
const hasFiniteCapacity = bucket.allocation_type === 'fixed_limit' && bucket.effective_capacity !== null;
return (
<div className="divide-y-4 divide-red-500">
{/* Name */}
<div className="px-3 py-1.5">
<span className="text-red-500 font-mono font-bold uppercase tracking-wider text-sm truncate block">
{bucket.name}
</span>
</div>
{/* Progress bars or text — fixed height */}
<div className="px-3 py-3 h-14 flex items-center">
{hasFiniteCapacity ? (
<div className="w-full">
<DigitalProgressBar
current={bucket.current_balance}
capacity={bucket.effective_capacity!}
projected={projectedAmount}
/>
</div>
) : (
<div className="w-full text-center">
<span className="font-mono text-red-500/30 text-xs uppercase tracking-widest">
{bucket.allocation_type === 'unlimited' ? '~ ALL REMAINING ~' : `~ ${basisPointsToPercent(bucket.allocation_value ?? 0).toFixed(2)}% ~`}
</span>
</div>
)}
</div>
{/* Amount */}
<div className="px-3 py-1.5 text-center">
<span className="font-digital text-red-500 text-sm">
{formatDollars(bucket.current_balance)}
</span>
{projectedAmount && projectedAmount > 0 && (
<span className="font-digital text-yellow-500 text-sm">
{' '}+{formatDollars(projectedAmount)}
</span>
)}
{hasFiniteCapacity && (
<span className="font-digital text-red-500/50 text-sm">
{' '}/ {formatDollars(bucket.effective_capacity!)}
</span>
)}
</div>
</div>
);
}