first commit
This commit is contained in:
commit
c9fb67e751
423 files changed
+53287
No files matched your search
@@ -0,0 +1,262 @@
|
||||
import {
|
||||
Dialog,
|
||||
TextField,
|
||||
MenuItem,
|
||||
Button,
|
||||
Box,
|
||||
Typography,
|
||||
} from "@mui/material";
|
||||
import { useState, useEffect } from "react";
|
||||
import { TipoCustaProcessual, StatusPagamento } from "@prisma/client";
|
||||
import { AdapterDateFns } from "@mui/x-date-pickers/AdapterDateFns";
|
||||
import { LocalizationProvider } from "@mui/x-date-pickers/LocalizationProvider";
|
||||
import { DatePicker } from "@mui/x-date-pickers/DatePicker";
|
||||
import ptBR from "date-fns/locale/pt-BR";
|
||||
|
||||
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;
|
||||
Reference in new issue
Block a user