263 lines
7.3 KiB
TypeScript
263 lines
7.3 KiB
TypeScript
import {
|
|
Dialog,
|
|
TextField,
|
|
MenuItem,
|
|
Button,
|
|
Box,
|
|
Typography,
|
|
} from "@mui/material";
|
|
import { AdapterDateFns } from "@mui/x-date-pickers/AdapterDateFns";
|
|
import { DatePicker } from "@mui/x-date-pickers/DatePicker";
|
|
import { LocalizationProvider } from "@mui/x-date-pickers/LocalizationProvider";
|
|
import { TipoCustaProcessual, StatusPagamento } from "@prisma/client";
|
|
import ptBR from "date-fns/locale/pt-BR";
|
|
import { useState, useEffect } from "react";
|
|
|
|
interface DialogCustaProcessualProps {
|
|
open: boolean;
|
|
onClose: () => void;
|
|
onSave: (data: any) => Promise<void>;
|
|
editingCusta?: any;
|
|
}
|
|
|
|
export function DialogCustaProcessual({
|
|
open,
|
|
onClose,
|
|
onSave,
|
|
editingCusta,
|
|
}: DialogCustaProcessualProps) {
|
|
const [formData, setFormData] = useState({
|
|
tipo: "",
|
|
descricao: "",
|
|
valor: "",
|
|
percentual: "",
|
|
status: "PENDENTE",
|
|
vencimento: null as Date | null,
|
|
dataPagamento: null as Date | null,
|
|
observacoes: "",
|
|
numeroParcelas: 1,
|
|
parcelaAtual: 1,
|
|
comprovante: "",
|
|
});
|
|
|
|
const [formError, setFormError] = useState<string | null>(null);
|
|
|
|
// Atualizar form quando o editingCusta muda
|
|
useEffect(() => {
|
|
if (editingCusta) {
|
|
setFormData({
|
|
tipo: editingCusta.tipo || "",
|
|
descricao: editingCusta.descricao || "",
|
|
valor: editingCusta.valor?.toString() || "",
|
|
percentual: editingCusta.percentual?.toString() || "",
|
|
status: editingCusta.status || "PENDENTE",
|
|
vencimento: editingCusta.vencimento
|
|
? new Date(editingCusta.vencimento)
|
|
: null,
|
|
dataPagamento: editingCusta.dataPagamento
|
|
? new Date(editingCusta.dataPagamento)
|
|
: null,
|
|
observacoes: editingCusta.observacoes || "",
|
|
numeroParcelas: editingCusta.numeroParcelas || 1,
|
|
parcelaAtual: editingCusta.parcelaAtual || 1,
|
|
comprovante: editingCusta.comprovante || "",
|
|
});
|
|
} else {
|
|
// Reset para os valores padrão
|
|
setFormData({
|
|
tipo: "",
|
|
descricao: "",
|
|
valor: "",
|
|
percentual: "",
|
|
status: "PENDENTE",
|
|
vencimento: null,
|
|
dataPagamento: null,
|
|
observacoes: "",
|
|
numeroParcelas: 1,
|
|
parcelaAtual: 1,
|
|
comprovante: "",
|
|
});
|
|
}
|
|
}, [editingCusta, open]);
|
|
|
|
const handleSubmit = async (e: React.FormEvent) => {
|
|
e.preventDefault();
|
|
setFormError(null);
|
|
|
|
try {
|
|
// Validar campos obrigatórios
|
|
if (!formData.tipo) {
|
|
setFormError("Selecione o tipo da custa");
|
|
return;
|
|
}
|
|
if (!formData.descricao) {
|
|
setFormError("Informe a descrição da custa");
|
|
return;
|
|
}
|
|
if (!formData.valor) {
|
|
setFormError("Informe o valor da custa");
|
|
return;
|
|
}
|
|
|
|
// Preparar dados
|
|
const preparedData = {
|
|
...formData,
|
|
valor: Number(formData.valor),
|
|
percentual: formData.percentual ? Number(formData.percentual) : null,
|
|
numeroParcelas: Number(formData.numeroParcelas),
|
|
parcelaAtual: Number(formData.parcelaAtual),
|
|
};
|
|
|
|
await onSave(preparedData);
|
|
onClose();
|
|
} catch (error: any) {
|
|
console.error("Erro ao salvar custa:", error);
|
|
setFormError(error.message || "Erro ao salvar custa. Tente novamente.");
|
|
}
|
|
};
|
|
|
|
return (
|
|
<Dialog open={open} onClose={onClose} maxWidth="sm" fullWidth>
|
|
<Box component="form" onSubmit={handleSubmit} sx={{ p: 3 }}>
|
|
<h2 className="text-lg font-semibold mb-4">
|
|
{editingCusta ? "Editar Custa Processual" : "Nova Custa Processual"}
|
|
</h2>
|
|
|
|
<div className="space-y-4">
|
|
<TextField
|
|
select
|
|
fullWidth
|
|
label="Tipo"
|
|
value={formData.tipo}
|
|
onChange={(e) => setFormData({ ...formData, tipo: e.target.value })}
|
|
required
|
|
>
|
|
{Object.values(TipoCustaProcessual).map((tipo) => (
|
|
<MenuItem key={tipo} value={tipo}>
|
|
{tipo.replace(/_/g, " ")}
|
|
</MenuItem>
|
|
))}
|
|
</TextField>
|
|
|
|
<TextField
|
|
fullWidth
|
|
label="Descrição"
|
|
value={formData.descricao}
|
|
onChange={(e) =>
|
|
setFormData({ ...formData, descricao: e.target.value })
|
|
}
|
|
required
|
|
/>
|
|
|
|
<TextField
|
|
fullWidth
|
|
label="Valor"
|
|
type="number"
|
|
value={formData.valor}
|
|
onChange={(e) =>
|
|
setFormData({ ...formData, valor: e.target.value })
|
|
}
|
|
required
|
|
inputProps={{ step: "0.01" }}
|
|
/>
|
|
|
|
<TextField
|
|
fullWidth
|
|
label="Percentual (se aplicável)"
|
|
type="number"
|
|
value={formData.percentual}
|
|
onChange={(e) =>
|
|
setFormData({ ...formData, percentual: e.target.value })
|
|
}
|
|
inputProps={{ step: "0.01", min: "0", max: "100" }}
|
|
/>
|
|
|
|
<LocalizationProvider
|
|
dateAdapter={AdapterDateFns}
|
|
adapterLocale={ptBR}
|
|
>
|
|
<DatePicker
|
|
label="Vencimento"
|
|
value={formData.vencimento}
|
|
onChange={(date) =>
|
|
setFormData({ ...formData, vencimento: date })
|
|
}
|
|
sx={{ width: "100%", mb: 2 }}
|
|
/>
|
|
|
|
{formData.status === "PAGO" && (
|
|
<DatePicker
|
|
label="Data de Pagamento"
|
|
value={formData.dataPagamento}
|
|
onChange={(date) =>
|
|
setFormData({ ...formData, dataPagamento: date })
|
|
}
|
|
sx={{ width: "100%" }}
|
|
/>
|
|
)}
|
|
</LocalizationProvider>
|
|
|
|
<TextField
|
|
select
|
|
fullWidth
|
|
label="Status"
|
|
value={formData.status}
|
|
onChange={(e) =>
|
|
setFormData({ ...formData, status: e.target.value })
|
|
}
|
|
required
|
|
>
|
|
{Object.values(StatusPagamento).map((status) => (
|
|
<MenuItem key={status} value={status}>
|
|
{status.replace(/_/g, " ")}
|
|
</MenuItem>
|
|
))}
|
|
</TextField>
|
|
|
|
<TextField
|
|
fullWidth
|
|
label="Número de Parcelas"
|
|
type="number"
|
|
value={formData.numeroParcelas}
|
|
onChange={(e) =>
|
|
setFormData({
|
|
...formData,
|
|
numeroParcelas: parseInt(e.target.value),
|
|
})
|
|
}
|
|
inputProps={{ min: 1 }}
|
|
/>
|
|
|
|
<TextField
|
|
fullWidth
|
|
label="Observações"
|
|
multiline
|
|
rows={3}
|
|
value={formData.observacoes}
|
|
onChange={(e) =>
|
|
setFormData({ ...formData, observacoes: e.target.value })
|
|
}
|
|
/>
|
|
</div>
|
|
|
|
{formError && (
|
|
<Box sx={{ mt: 2, p: 2, bgcolor: "error.light", borderRadius: 1 }}>
|
|
<Typography color="error">{formError}</Typography>
|
|
</Box>
|
|
)}
|
|
|
|
<Box
|
|
sx={{ mt: 3, display: "flex", justifyContent: "flex-end", gap: 2 }}
|
|
>
|
|
<Button onClick={onClose}>Cancelar</Button>
|
|
<Button type="submit" variant="contained" color="primary">
|
|
Salvar
|
|
</Button>
|
|
</Box>
|
|
</Box>
|
|
</Dialog>
|
|
);
|
|
}
|
|
|
|
export default DialogCustaProcessual;
|