BillTracker/client/components/tracker/PaymentProgress.jsx

62 lines
2.3 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { cn, fmt } from '@/lib/utils';
import { paymentSummary } from '@/lib/trackerUtils';
export function PaymentProgress({ row, threshold, onOpen, onMarkFullAmount, compact = false, className }) {
const summary = paymentSummary(row, threshold);
const barTone = summary.remaining === 0
? 'bg-emerald-500'
: summary.paid > 0
? 'bg-amber-500'
: 'bg-muted-foreground/40';
const amountLabel = (() => {
if (summary.paid === 0) return '—';
if (summary.overpaid > 0) return `${fmt(summary.paidTowardDue)} · overpaid`;
if (summary.remaining > 0) return `${fmt(summary.paidTowardDue)} paid`;
return fmt(summary.paidTowardDue);
})();
const showQuickFix = onMarkFullAmount && summary.partial && summary.paid > 0;
return (
<div className={cn('w-full', className)}>
<button
type="button"
onClick={onOpen}
className={cn(
'w-full rounded-md text-left transition-colors hover:bg-accent/60 focus-visible:outline-none focus-visible:ring-[3px] focus-visible:ring-ring/50',
compact ? 'p-2' : 'px-2 py-1.5',
)}
title="View payment history"
>
<div className="flex items-center justify-between gap-2 text-xs">
<span className={cn('tracker-number text-[13px] font-semibold', summary.paid > 0 ? 'text-emerald-300' : 'text-muted-foreground/85')}>
{amountLabel}
</span>
{summary.count > 1 && (
<span className="shrink-0 rounded-full bg-muted px-1.5 py-0.5 text-[10px] font-medium text-muted-foreground">
{summary.count}×
</span>
)}
</div>
<div className="mt-1.5 h-1.5 overflow-hidden rounded-full bg-muted">
<div
className={cn('h-full rounded-full transition-all', barTone)}
style={{ width: `${summary.percent}%` }}
/>
</div>
</button>
{showQuickFix && (
<button
type="button"
onClick={onMarkFullAmount}
className="mt-0.5 w-full rounded px-2 py-0.5 text-left text-[10px] text-muted-foreground/60 transition-colors hover:bg-accent/50 hover:text-foreground"
title={`Set ${fmt(summary.paidTowardDue)} as the full amount due this month`}
>
{fmt(summary.paidTowardDue)} is the full amount
</button>
)}
</div>
);
}