diff --git a/apps/Backend/src/routes/payments.ts b/apps/Backend/src/routes/payments.ts index 2813e0bb..ffd59f8d 100755 --- a/apps/Backend/src/routes/payments.ts +++ b/apps/Backend/src/routes/payments.ts @@ -427,6 +427,34 @@ router.patch( } ); +// PATCH /api/payments/:id/mh-paid-amount +router.patch( + "/:id/mh-paid-amount", + async (req: Request, res: Response): Promise => { + try { + const userId = req.user?.id; + if (!userId) return res.status(401).json({ message: "Unauthorized" }); + + const paymentId = parseIntOrError(req.params.id, "Payment ID"); + const raw = req.body.mhPaidAmount; + const mhPaidAmount = parseFloat(raw); + if (isNaN(mhPaidAmount) || mhPaidAmount < 0) { + return res.status(400).json({ message: "Invalid mhPaidAmount value" }); + } + + const updated = await prisma.payment.update({ + where: { id: paymentId }, + data: { mhPaidAmount, updatedById: userId }, + }); + + return res.json({ ...updated, mhPaidAmount: Number(updated.mhPaidAmount) }); + } catch (err: unknown) { + const message = err instanceof Error ? err.message : "Failed to update MH paid amount"; + return res.status(500).json({ message }); + } + } +); + // PATCH /api/payments/:id/mh-payment-check router.patch( "/:id/mh-payment-check", diff --git a/apps/Frontend/src/components/payments/payments-recent-table.tsx b/apps/Frontend/src/components/payments/payments-recent-table.tsx index 2f195754..3d9cbae1 100755 --- a/apps/Frontend/src/components/payments/payments-recent-table.tsx +++ b/apps/Frontend/src/components/payments/payments-recent-table.tsx @@ -99,6 +99,8 @@ export default function PaymentsRecentTable({ const [selectedPaymentId, setSelectedPaymentId] = useState(null); const [checkedPaymentIds, setCheckedPaymentIds] = useState>(new Set()); const [isMhChecking, setIsMhChecking] = useState(false); + const [editingMhPaidId, setEditingMhPaidId] = useState(null); + const [editingMhPaidValue, setEditingMhPaidValue] = useState(""); const [isRevertOpen, setIsRevertOpen] = useState(false); const [revertPaymentId, setRevertPaymentId] = useState(null); @@ -741,12 +743,60 @@ export default function PaymentsRecentTable({ - {payment.mhPaidAmount != null ? ( - - ${Number(payment.mhPaidAmount).toFixed(2)} - + {editingMhPaidId === payment.id ? ( + setEditingMhPaidValue(e.target.value)} + onKeyDown={async (e) => { + if (e.key === "Enter") { + e.currentTarget.blur(); + } else if (e.key === "Escape") { + setEditingMhPaidId(null); + } + }} + onBlur={async () => { + const val = parseFloat(editingMhPaidValue); + if (!isNaN(val) && val >= 0) { + try { + const res = await apiRequest( + "PATCH", + `/api/payments/${payment.id}/mh-paid-amount`, + { mhPaidAmount: val } + ); + if (res.ok) { + await queryClient.invalidateQueries({ queryKey: QK_PAYMENTS_RECENT_BASE }); + } else { + toast({ title: "Error", description: "Failed to save MH paid amount.", variant: "destructive" }); + } + } catch { + toast({ title: "Error", description: "Failed to save MH paid amount.", variant: "destructive" }); + } + } + setEditingMhPaidId(null); + }} + /> ) : ( - + { + setEditingMhPaidId(payment.id); + setEditingMhPaidValue( + payment.mhPaidAmount != null + ? Number(payment.mhPaidAmount).toFixed(2) + : "0.00" + ); + }} + > + {payment.mhPaidAmount != null + ? `$${Number(payment.mhPaidAmount).toFixed(2)}` + : } + )}