BillTracker/client/components/tracker/StatusBadge.jsx

45 lines
1.6 KiB
JavaScript

import React, { useMemo } from 'react';
import { Loader2, AlertCircle } from 'lucide-react';
import { cn } from '@/lib/utils';
import { STATUS_META } from '@/lib/trackerUtils';
export const StatusBadge = React.memo(function StatusBadge({ status, clickable, onClick, loading }) {
const meta = useMemo(() => STATUS_META[status] || STATUS_META.upcoming, [status]);
const isSkipped = status === 'skipped';
const isUrgent = status === 'late' || status === 'missed';
const canClick = clickable && !isSkipped && !loading;
return (
<button
type="button"
disabled={!canClick || loading}
onClick={onClick}
className={cn(
'inline-flex items-center px-2.5 py-0.5 text-[11px] rounded-md font-semibold',
'uppercase tracking-wide whitespace-nowrap',
'transition-all duration-150',
isUrgent && 'gap-1.5 px-2.5 py-1 text-xs',
canClick && 'cursor-pointer hover:scale-105 hover:shadow-sm',
canClick && status === 'paid' && 'hover:bg-red-500/20 hover:text-red-600 hover:border-red-500/40',
canClick && status !== 'paid' && 'hover:bg-emerald-500/20 hover:text-emerald-600 hover:border-emerald-500/40',
loading && 'opacity-60 cursor-wait',
meta.cls,
)}
title={canClick ? (status === 'paid' || status === 'autodraft' ? 'Click to mark unpaid' : 'Click to mark paid') : undefined}
>
{loading ? (
<>
<Loader2 className="h-3 w-3 mr-1 animate-spin" />
{meta.label}
</>
) : (
<>
{isUrgent && <AlertCircle className="h-3.5 w-3.5" />}
{meta.label}
</>
)}
</button>
);
});