mirror of
https://github.com/felipegcoutinho/openmonetis.git
synced 2026-06-09 23:06:01 +00:00
Merge branch 'pr-70'
This commit is contained in:
@@ -8,6 +8,7 @@ import {
|
|||||||
PAYMENT_METHODS,
|
PAYMENT_METHODS,
|
||||||
type TRANSACTION_TYPES,
|
type TRANSACTION_TYPES,
|
||||||
} from "@/features/transactions/lib/constants";
|
} from "@/features/transactions/lib/constants";
|
||||||
|
import { ConfirmActionDialog } from "@/shared/components/confirm-action-dialog";
|
||||||
import { Button } from "@/shared/components/ui/button";
|
import { Button } from "@/shared/components/ui/button";
|
||||||
import { CurrencyInput } from "@/shared/components/ui/currency-input";
|
import { CurrencyInput } from "@/shared/components/ui/currency-input";
|
||||||
import { DatePicker } from "@/shared/components/ui/date-picker";
|
import { DatePicker } from "@/shared/components/ui/date-picker";
|
||||||
@@ -148,6 +149,9 @@ export function MassAddDialog({
|
|||||||
defaultCardId,
|
defaultCardId,
|
||||||
}: MassAddDialogProps) {
|
}: MassAddDialogProps) {
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
|
const [isDirty, setIsDirty] = useState(false);
|
||||||
|
const [confirmCloseOpen, setConfirmCloseOpen] = useState(false);
|
||||||
|
const [cancelConfirmOpen, setCancelConfirmOpen] = useState(false);
|
||||||
|
|
||||||
// Fixed fields state (sempre ativos, sem checkboxes)
|
// Fixed fields state (sempre ativos, sem checkboxes)
|
||||||
const [transactionType, setTransactionType] =
|
const [transactionType, setTransactionType] =
|
||||||
@@ -179,11 +183,22 @@ export function MassAddDialog({
|
|||||||
return groupAndSortCategories(filtered);
|
return groupAndSortCategories(filtered);
|
||||||
}, [categoryOptions, transactionType]);
|
}, [categoryOptions, transactionType]);
|
||||||
|
|
||||||
|
const resetForm = () => {
|
||||||
|
setTransactionType("Despesa");
|
||||||
|
setPaymentMethod(PAYMENT_METHODS[0]);
|
||||||
|
setPeriod(selectedPeriod);
|
||||||
|
setContaId(undefined);
|
||||||
|
setCartaoId(defaultCardId ?? undefined);
|
||||||
|
setTransactions([createEmptyTransactionRow(defaultPayerId)]);
|
||||||
|
setIsDirty(false);
|
||||||
|
};
|
||||||
|
|
||||||
const addTransaction = () => {
|
const addTransaction = () => {
|
||||||
setTransactions([
|
setTransactions([
|
||||||
...transactions,
|
...transactions,
|
||||||
createEmptyTransactionRow(defaultPayerId),
|
createEmptyTransactionRow(defaultPayerId),
|
||||||
]);
|
]);
|
||||||
|
setIsDirty(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
const removeTransaction = (id: string) => {
|
const removeTransaction = (id: string) => {
|
||||||
@@ -192,6 +207,7 @@ export function MassAddDialog({
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
setTransactions(transactions.filter((t) => t.id !== id));
|
setTransactions(transactions.filter((t) => t.id !== id));
|
||||||
|
setIsDirty(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
const updateTransaction = (
|
const updateTransaction = (
|
||||||
@@ -202,6 +218,7 @@ export function MassAddDialog({
|
|||||||
setTransactions(
|
setTransactions(
|
||||||
transactions.map((t) => (t.id === id ? { ...t, [field]: value } : t)),
|
transactions.map((t) => (t.id === id ? { ...t, [field]: value } : t)),
|
||||||
);
|
);
|
||||||
|
setIsDirty(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleSubmit = async () => {
|
const handleSubmit = async () => {
|
||||||
@@ -250,13 +267,7 @@ export function MassAddDialog({
|
|||||||
try {
|
try {
|
||||||
await onSubmit(formData);
|
await onSubmit(formData);
|
||||||
onOpenChange(false);
|
onOpenChange(false);
|
||||||
// Reset form
|
resetForm();
|
||||||
setTransactionType("Despesa");
|
|
||||||
setPaymentMethod(PAYMENT_METHODS[0]);
|
|
||||||
setPeriod(selectedPeriod);
|
|
||||||
setContaId(undefined);
|
|
||||||
setCartaoId(defaultCardId ?? undefined);
|
|
||||||
setTransactions([createEmptyTransactionRow(defaultPayerId)]);
|
|
||||||
} catch (_error) {
|
} catch (_error) {
|
||||||
// Error is handled by the onSubmit function
|
// Error is handled by the onSubmit function
|
||||||
} finally {
|
} finally {
|
||||||
@@ -265,7 +276,19 @@ export function MassAddDialog({
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog open={open} onOpenChange={onOpenChange}>
|
<Dialog
|
||||||
|
open={open}
|
||||||
|
onOpenChange={(newOpen) => {
|
||||||
|
if (!newOpen && isDirty) {
|
||||||
|
setConfirmCloseOpen(true);
|
||||||
|
} else {
|
||||||
|
onOpenChange(newOpen);
|
||||||
|
if (newOpen === false) {
|
||||||
|
resetForm();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
<DialogContent className="sm:max-w-3xl max-h-[90vh] overflow-y-auto p-6 sm:px-8">
|
<DialogContent className="sm:max-w-3xl max-h-[90vh] overflow-y-auto p-6 sm:px-8">
|
||||||
<DialogHeader>
|
<DialogHeader>
|
||||||
<DialogTitle>Adicionar múltiplos lançamentos</DialogTitle>
|
<DialogTitle>Adicionar múltiplos lançamentos</DialogTitle>
|
||||||
@@ -286,9 +309,10 @@ export function MassAddDialog({
|
|||||||
<Label htmlFor="transaction-type">Tipo de Transação</Label>
|
<Label htmlFor="transaction-type">Tipo de Transação</Label>
|
||||||
<Select
|
<Select
|
||||||
value={transactionType}
|
value={transactionType}
|
||||||
onValueChange={(value) =>
|
onValueChange={(value) => {
|
||||||
setTransactionType(value as MassAddTransactionType)
|
setTransactionType(value as MassAddTransactionType);
|
||||||
}
|
setIsDirty(true);
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<SelectTrigger id="transaction-type" className="w-full">
|
<SelectTrigger id="transaction-type" className="w-full">
|
||||||
<SelectValue>
|
<SelectValue>
|
||||||
@@ -315,6 +339,7 @@ export function MassAddDialog({
|
|||||||
value={paymentMethod}
|
value={paymentMethod}
|
||||||
onValueChange={(value) => {
|
onValueChange={(value) => {
|
||||||
setPaymentMethod(value as MassAddPaymentMethod);
|
setPaymentMethod(value as MassAddPaymentMethod);
|
||||||
|
setIsDirty(true);
|
||||||
// Reset conta/cartao when changing payment method
|
// Reset conta/cartao when changing payment method
|
||||||
if (value === "Cartão de crédito") {
|
if (value === "Cartão de crédito") {
|
||||||
setContaId(undefined);
|
setContaId(undefined);
|
||||||
@@ -346,7 +371,10 @@ export function MassAddDialog({
|
|||||||
<Label htmlFor="cartao">Cartão</Label>
|
<Label htmlFor="cartao">Cartão</Label>
|
||||||
<Select
|
<Select
|
||||||
value={cardId}
|
value={cardId}
|
||||||
onValueChange={setCartaoId}
|
onValueChange={(value) => {
|
||||||
|
setCartaoId(value);
|
||||||
|
setIsDirty(true);
|
||||||
|
}}
|
||||||
disabled={isLockedToCartao}
|
disabled={isLockedToCartao}
|
||||||
>
|
>
|
||||||
<SelectTrigger id="cartao" className="w-full">
|
<SelectTrigger id="cartao" className="w-full">
|
||||||
@@ -395,7 +423,10 @@ export function MassAddDialog({
|
|||||||
{cardId ? (
|
{cardId ? (
|
||||||
<InlinePeriodPicker
|
<InlinePeriodPicker
|
||||||
period={period}
|
period={period}
|
||||||
onPeriodChange={setPeriod}
|
onPeriodChange={(value) => {
|
||||||
|
setPeriod(value);
|
||||||
|
setIsDirty(true);
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
) : null}
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
@@ -405,7 +436,13 @@ export function MassAddDialog({
|
|||||||
{!isCartaoSelected ? (
|
{!isCartaoSelected ? (
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<Label htmlFor="conta">Conta</Label>
|
<Label htmlFor="conta">Conta</Label>
|
||||||
<Select value={accountId} onValueChange={setContaId}>
|
<Select
|
||||||
|
value={accountId}
|
||||||
|
onValueChange={(value) => {
|
||||||
|
setContaId(value);
|
||||||
|
setIsDirty(true);
|
||||||
|
}}
|
||||||
|
>
|
||||||
<SelectTrigger id="conta" className="w-full">
|
<SelectTrigger id="conta" className="w-full">
|
||||||
<SelectValue placeholder="Selecione">
|
<SelectValue placeholder="Selecione">
|
||||||
{accountId &&
|
{accountId &&
|
||||||
@@ -635,7 +672,13 @@ export function MassAddDialog({
|
|||||||
<DialogFooter>
|
<DialogFooter>
|
||||||
<Button
|
<Button
|
||||||
variant="outline"
|
variant="outline"
|
||||||
onClick={() => onOpenChange(false)}
|
onClick={() => {
|
||||||
|
if (isDirty) {
|
||||||
|
setCancelConfirmOpen(true);
|
||||||
|
} else {
|
||||||
|
onOpenChange(false);
|
||||||
|
}
|
||||||
|
}}
|
||||||
disabled={loading}
|
disabled={loading}
|
||||||
>
|
>
|
||||||
Cancelar
|
Cancelar
|
||||||
@@ -646,6 +689,36 @@ export function MassAddDialog({
|
|||||||
{transactions.length === 1 ? "lançamento" : "lançamentos"}
|
{transactions.length === 1 ? "lançamento" : "lançamentos"}
|
||||||
</Button>
|
</Button>
|
||||||
</DialogFooter>
|
</DialogFooter>
|
||||||
|
|
||||||
|
<ConfirmActionDialog
|
||||||
|
open={confirmCloseOpen}
|
||||||
|
onOpenChange={setConfirmCloseOpen}
|
||||||
|
title="Descartar alterações?"
|
||||||
|
description="Há lançamentos não salvos. Se fechar agora, todos os dados serão perdidos."
|
||||||
|
confirmLabel="Descartar"
|
||||||
|
cancelLabel="Continuar editando"
|
||||||
|
confirmVariant="destructive"
|
||||||
|
onConfirm={() => {
|
||||||
|
setConfirmCloseOpen(false);
|
||||||
|
onOpenChange(false);
|
||||||
|
resetForm();
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<ConfirmActionDialog
|
||||||
|
open={cancelConfirmOpen}
|
||||||
|
onOpenChange={setCancelConfirmOpen}
|
||||||
|
title="Cancelar adição de lançamentos?"
|
||||||
|
description="Há lançamentos não salvos. Se cancelar, todos os dados serão perdidos."
|
||||||
|
confirmLabel="Cancelar"
|
||||||
|
cancelLabel="Continuar editando"
|
||||||
|
confirmVariant="destructive"
|
||||||
|
onConfirm={() => {
|
||||||
|
setCancelConfirmOpen(false);
|
||||||
|
onOpenChange(false);
|
||||||
|
resetForm();
|
||||||
|
}}
|
||||||
|
/>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user