diff --git a/src/features/dashboard/bills/bills-queries.ts b/src/features/dashboard/bills/bills-queries.ts index cd2c1a9..571f85a 100644 --- a/src/features/dashboard/bills/bills-queries.ts +++ b/src/features/dashboard/bills/bills-queries.ts @@ -5,6 +5,13 @@ export type DashboardBill = { dueDate: string | null; boletoPaymentDate: string | null; isSettled: boolean; + accountId: string | null; +}; + +export type BillPaymentAccountOption = { + value: string; + label: string; + logo: string | null; }; export type DashboardBillsSnapshot = { diff --git a/src/features/dashboard/bills/use-bill-widget-controller.ts b/src/features/dashboard/bills/use-bill-widget-controller.ts index b68cf20..e725741 100644 --- a/src/features/dashboard/bills/use-bill-widget-controller.ts +++ b/src/features/dashboard/bills/use-bill-widget-controller.ts @@ -1,5 +1,6 @@ "use client"; +import { useEffect, useRef, useState } from "react"; import { type BillDialogState, getCurrentBillDateString, @@ -20,12 +21,26 @@ type BillWidgetController = Omit< > & { selectedBill: DashboardBill | null; modalState: BillDialogState; + paymentAccountId: string; + setPaymentAccountId: (accountId: string) => void; + paymentDate: Date; + setPaymentDate: (date: Date) => void; }; +const toIsoDate = (date: Date) => date.toISOString().split("T")[0] ?? ""; + export function useBillWidgetController( bills?: DashboardBill[], ): BillWidgetController { const safeBills = bills ?? EMPTY_BILLS; + const [paymentAccountId, setPaymentAccountId] = useState(""); + const [paymentDate, setPaymentDate] = useState(() => new Date()); + + const paymentAccountIdRef = useRef(paymentAccountId); + const paymentDateRef = useRef(paymentDate); + paymentAccountIdRef.current = paymentAccountId; + paymentDateRef.current = paymentDate; + const controller = usePaymentDialogController({ items: safeBills, getItemId: (bill) => bill.id, @@ -34,13 +49,36 @@ export function useBillWidgetController( toggleTransactionSettlementAction({ id: bill.id, value: true, + paymentAccountId: paymentAccountIdRef.current || null, + paymentDate: toIsoDate(paymentDateRef.current), }), applyConfirmedState: (bill) => - markBillAsSettled(bill, getCurrentBillDateString()), + markBillAsSettled( + { + ...bill, + accountId: paymentAccountIdRef.current || bill.accountId, + }, + toIsoDate(paymentDateRef.current) || getCurrentBillDateString(), + ), }); + const selectedBillId = controller.selectedItem?.id ?? null; + const selectedBillAccountId = controller.selectedItem?.accountId ?? ""; + + useEffect(() => { + if (!selectedBillId) { + return; + } + setPaymentAccountId(selectedBillAccountId ?? ""); + setPaymentDate(new Date()); + }, [selectedBillId, selectedBillAccountId]); + return { ...controller, selectedBill: controller.selectedItem, + paymentAccountId, + setPaymentAccountId, + paymentDate, + setPaymentDate, }; } diff --git a/src/features/dashboard/components/bills/bill-payment-dialog.tsx b/src/features/dashboard/components/bills/bill-payment-dialog.tsx index a574843..7195e5a 100644 --- a/src/features/dashboard/components/bills/bill-payment-dialog.tsx +++ b/src/features/dashboard/components/bills/bill-payment-dialog.tsx @@ -1,5 +1,4 @@ import { - RiBarcodeFill, RiCalendarLine, RiLoader4Line, RiMoneyDollarCircleLine, @@ -9,11 +8,18 @@ import { formatBillDateLabel, getBillStatusBadgeVariant, } from "@/features/dashboard/bills/bills-helpers"; -import type { DashboardBill } from "@/features/dashboard/bills/bills-queries"; +import type { + BillPaymentAccountOption, + DashboardBill, +} from "@/features/dashboard/bills/bills-queries"; +import { AccountCardSelectContent } from "@/features/transactions/components/select-items"; +import { EstablishmentLogo } from "@/shared/components/entity-avatar"; import MoneyValues from "@/shared/components/money-values"; import { PaymentSuccess } from "@/shared/components/payment-success"; import { Badge } from "@/shared/components/ui/badge"; import { Button } from "@/shared/components/ui/button"; +import { Card } from "@/shared/components/ui/card"; +import { DatePicker } from "@/shared/components/ui/date-picker"; import { Dialog, DialogContent, @@ -22,12 +28,26 @@ import { DialogHeader, DialogTitle, } from "@/shared/components/ui/dialog"; +import { Label } from "@/shared/components/ui/label"; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "@/shared/components/ui/select"; +import { Separator } from "@/shared/components/ui/separator"; type BillPaymentDialogProps = { bill: DashboardBill | null; open: boolean; modalState: BillDialogState; isPending: boolean; + paymentAccountId: string; + onPaymentAccountChange: (accountId: string) => void; + paymentDate: Date; + onPaymentDateChange: (date: Date) => void; + paymentAccountOptions: BillPaymentAccountOption[]; onClose: () => void; onConfirm: () => void; }; @@ -37,6 +57,11 @@ export function BillPaymentDialog({ open, modalState, isPending, + paymentAccountId, + onPaymentAccountChange, + paymentDate, + onPaymentDateChange, + paymentAccountOptions, onClose, onConfirm, }: BillPaymentDialogProps) { @@ -44,6 +69,14 @@ export function BillPaymentDialog({ const dueLabel = bill ? formatBillDateLabel(bill.dueDate, "Vencimento:") : null; + const paidLabel = bill + ? formatBillDateLabel(bill.boletoPaymentDate, "Pago em:") + : null; + const isBillPending = bill ? !bill.isSettled : false; + const paymentDateValue = paymentDate.toISOString().split("T")[0] ?? ""; + const selectedAccount = paymentAccountOptions.find( + (option) => option.value === paymentAccountId, + ); return (
-
- -
Confirmar pagamento - - Boleto + + {isBillPending + ? "Escolha a conta de origem e a data em que o boleto foi pago." + : "Boleto"}
@@ -92,62 +124,118 @@ export function BillPaymentDialog({ {bill ? (
- {/* Card principal */} -
-

- Boleto -

-

- {bill.name} -

-
+ + +
+

+ Boleto +

+

+ {bill.name} +

+
+
- {/* Métricas */}
-
-
+ +
- + Valor
-
+ -
-
+ +
- - Vencimento + + {bill.isSettled ? "Pago em" : "Vencimento"}
-

- {dueLabel?.replace("Vencimento: ", "") ?? "—"} +

+ {bill.isSettled + ? (paidLabel?.replace("Pago em: ", "") ?? "—") + : (dueLabel?.replace("Vencimento: ", "") ?? "—")}

+
+
+ + + + {isBillPending ? ( +
+
+ + +
+ +
+ + { + if (value) { + onPaymentDateChange(new Date(`${value}T00:00:00`)); + } + }} + disabled={isProcessing} + /> +
-
- - {/* Status */} -
- - Status atual - - - {bill.isSettled ? "Pago" : "Pendente"} - -
- - {/* Aviso */} -

- Você poderá editar o lançamento depois, se necessário. -

+ ) : ( +
+ + Status atual + + + Pago + +
+ )}
) : null} @@ -163,7 +251,13 @@ export function BillPaymentDialog({