refactor: replace status dropdown with computed status badge
Status is now derived from the numbers — no manual switching needed: - Balance = 0 → Paid in Full (teal) - Balance > 0, Collected > 0 → Partially Paid (blue) - Balance > 0, Collected = 0 → Pending (red) VOID/DENIED/OVERPAID still show from DB as manual decisions. Removed Revert Full Due button (tied to old status system). Void button now shows for all non-VOID, non-DENIED payments. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -718,61 +718,33 @@ export default function PaymentsRecentTable({
|
||||
<TableCell>
|
||||
<div className="flex items-center gap-2">
|
||||
{(() => {
|
||||
const { label, color, icon } = getStatusInfo(
|
||||
payment.status
|
||||
);
|
||||
const switchableStatuses: PaymentStatus[] = [
|
||||
"PENDING",
|
||||
"PARTIALLY_PAID",
|
||||
"PAID",
|
||||
];
|
||||
const isSwitchable = switchableStatuses.includes(
|
||||
payment.status as PaymentStatus
|
||||
);
|
||||
if (isSwitchable) {
|
||||
// VOID and DENIED are manual decisions — show as-is
|
||||
if (payment.status === "VOID" || payment.status === "DENIED" || payment.status === "OVERPAID") {
|
||||
const { label, color, icon } = getStatusInfo(payment.status);
|
||||
return (
|
||||
<select
|
||||
value={payment.status ?? ""}
|
||||
onChange={(e) => {
|
||||
const val = e.target.value as PaymentStatus;
|
||||
if (val === "PAID") {
|
||||
handlePayAbsoluteFullDue(payment.id);
|
||||
} else if (payment.status === "PAID") {
|
||||
// revert the full payment amount, then set the new status
|
||||
fullPaymentMutation.mutate(
|
||||
{ paymentId: payment.id, type: "revert" },
|
||||
{
|
||||
onSuccess: () => {
|
||||
updatePaymentStatusMutation.mutate({
|
||||
paymentId: payment.id,
|
||||
status: val,
|
||||
});
|
||||
},
|
||||
}
|
||||
);
|
||||
} else {
|
||||
updatePaymentStatusMutation.mutate({
|
||||
paymentId: payment.id,
|
||||
status: val,
|
||||
});
|
||||
}
|
||||
}}
|
||||
className={`px-2 py-1 text-xs font-medium rounded-full border-0 cursor-pointer focus:outline-none focus:ring-2 focus:ring-offset-1 focus:ring-teal-400 ${color}`}
|
||||
>
|
||||
<option value="PENDING">Pending</option>
|
||||
<option value="PARTIALLY_PAID">Partially Paid</option>
|
||||
<option value="PAID">Paid in Full</option>
|
||||
</select>
|
||||
<span className={`px-2 py-1 text-xs font-medium rounded-full ${color}`}>
|
||||
<span className="flex items-center">{icon}{label}</span>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
// Compute status from numbers
|
||||
if (totalDue === 0) {
|
||||
return (
|
||||
<span className="px-2 py-1 text-xs font-medium rounded-full bg-teal-100 text-teal-800">
|
||||
<span className="flex items-center"><CheckCircle className="h-3 w-3 mr-1" />Paid in Full</span>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
if (totalCollected > 0) {
|
||||
return (
|
||||
<span className="px-2 py-1 text-xs font-medium rounded-full bg-blue-100 text-blue-800">
|
||||
<span className="flex items-center"><DollarSign className="h-3 w-3 mr-1" />Partially Paid</span>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<span
|
||||
className={`px-2 py-1 text-xs font-medium rounded-full ${color}`}
|
||||
>
|
||||
<span className="flex items-center">
|
||||
{icon}
|
||||
{label}
|
||||
</span>
|
||||
<span className="px-2 py-1 text-xs font-medium rounded-full bg-red-100 text-red-800">
|
||||
<span className="flex items-center"><Clock className="h-3 w-3 mr-1" />Pending</span>
|
||||
</span>
|
||||
);
|
||||
})()}
|
||||
@@ -977,9 +949,9 @@ export default function PaymentsRecentTable({
|
||||
</Button>
|
||||
)}
|
||||
|
||||
{/* When NOT PAID and NOT VOID → Void */}
|
||||
{payment.status !== "PAID" &&
|
||||
payment.status !== "VOID" && (
|
||||
{/* Show Void unless already voided or denied */}
|
||||
{payment.status !== "VOID" &&
|
||||
payment.status !== "DENIED" && (
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
@@ -992,20 +964,6 @@ export default function PaymentsRecentTable({
|
||||
</Button>
|
||||
)}
|
||||
|
||||
{/* When PAID → Revert */}
|
||||
{payment.status === "PAID" && (
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={() => {
|
||||
setRevertPaymentId(payment.id);
|
||||
setIsRevertOpen(true);
|
||||
}}
|
||||
>
|
||||
Revert Full Due
|
||||
</Button>
|
||||
)}
|
||||
|
||||
{/* When VOID → Unvoid */}
|
||||
{payment.status === "VOID" && (
|
||||
<Button
|
||||
|
||||
Reference in New Issue
Block a user