[MVPTN-86] feat(crud): Conclusão do CRUD Tipos de Serviço - t_servico_tipo
This commit is contained in:
parent
77ea800aaa
commit
4b7afd6a8f
33 changed files with 1126 additions and 332 deletions
|
|
@ -13,6 +13,7 @@ import TServicoTipoForm from '../../_components/t_servico_tipo/TServicoTipoForm'
|
|||
import { useTServicoTipoReadHook } from '../../_hooks/t_servico_tipo/useTServicoTipoReadHook';
|
||||
import { useTServicoTipoSaveHook } from '../../_hooks/t_servico_tipo/useTServicoTipoSaveHook';
|
||||
import { useTServicoTipoRemoveHook } from '../../_hooks/t_servico_tipo/useTServicoTipoRemoveHook';
|
||||
import { useTServicoTipoEditHook } from '../../_hooks/t_servico_tipo/useTServicoTipoEditHook';
|
||||
|
||||
import ConfirmDialog from '@/shared/components/confirmDialog/ConfirmDialog';
|
||||
import { useConfirmDialog } from '@/shared/components/confirmDialog/useConfirmDialog';
|
||||
|
|
@ -26,6 +27,7 @@ export default function TServicoTipoPage() {
|
|||
const { tServicoTipo, fetchTServicoTipo } = useTServicoTipoReadHook();
|
||||
const { saveTServicoTipo } = useTServicoTipoSaveHook();
|
||||
const { removeTServicoTipo } = useTServicoTipoRemoveHook();
|
||||
const { editTServicoTipo } = useTServicoTipoEditHook();
|
||||
|
||||
// Estados
|
||||
const [selectedServicoTipo, setSelectedServicoTipo] = useState<TServicoTipoInterface | null>(null);
|
||||
|
|
@ -47,10 +49,31 @@ export default function TServicoTipoPage() {
|
|||
/**
|
||||
* Abre o formulário no modo de edição ou criação
|
||||
*/
|
||||
const handleOpenForm = useCallback((data: TServicoTipoInterface | null) => {
|
||||
const handleOpenForm = useCallback(async (data: TServicoTipoInterface | null) => {
|
||||
|
||||
// Fecha o formulário antes de reabrir (garante reset limpo)
|
||||
setIsFormOpen(false);
|
||||
|
||||
// Se nenhum dado for passado, abre o formulário em modo de criação
|
||||
if (!data) {
|
||||
setSelectedServicoTipo(null);
|
||||
setIsFormOpen(true);
|
||||
return;
|
||||
}
|
||||
|
||||
// Define o item selecionado para edição
|
||||
setSelectedServicoTipo(data);
|
||||
|
||||
// Aguarda carregar/editar o registro (o hook espera o objeto TServicoTipoInterface)
|
||||
await editTServicoTipo(data);
|
||||
|
||||
// Atualiza a lista de dados
|
||||
await fetchTServicoTipo();
|
||||
|
||||
setIsFormOpen(true);
|
||||
}, []);
|
||||
|
||||
}, [editTServicoTipo, fetchTServicoTipo]);
|
||||
|
||||
|
||||
/**
|
||||
* Fecha o formulário e limpa o item selecionado
|
||||
|
|
@ -65,15 +88,20 @@ export default function TServicoTipoPage() {
|
|||
*/
|
||||
const handleSave = useCallback(async (formData: TServicoTipoInterface) => {
|
||||
|
||||
// Aguarda salvar o registro
|
||||
await saveTServicoTipo(formData);
|
||||
// Aguarda salvar o registro
|
||||
await saveTServicoTipo(formData);
|
||||
|
||||
// Atualiza a lista de dados
|
||||
fetchTServicoTipo();
|
||||
},
|
||||
[saveTServicoTipo, fetchTServicoTipo],
|
||||
|
||||
|
||||
|
||||
);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Quando o usuário clica em "remover" na tabela
|
||||
*/
|
||||
|
|
@ -88,6 +116,7 @@ export default function TServicoTipoPage() {
|
|||
[openConfirmDialog],
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* Executa a exclusão de fato quando o usuário confirma
|
||||
*/
|
||||
|
|
@ -108,6 +137,8 @@ export default function TServicoTipoPage() {
|
|||
handleCancel();
|
||||
}, [itemToDelete, removeTServicoTipo, fetchTServicoTipo, handleCancel]);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Busca inicial dos dados
|
||||
*/
|
||||
|
|
@ -147,7 +178,7 @@ export default function TServicoTipoPage() {
|
|||
title="Confirmar exclusão"
|
||||
description="Atenção"
|
||||
// Adaptação da mensagem para a interface TServicoTipo
|
||||
message={`Deseja realmente excluir o tipo de serviço "${itemToDelete?.stipo_nome}"?`}
|
||||
message={`Deseja realmente excluir o tipo de serviço "${itemToDelete?.descricao}"?`}
|
||||
confirmText="Sim, excluir"
|
||||
cancelText="Cancelar"
|
||||
onConfirm={handleDelete}
|
||||
|
|
|
|||
|
|
@ -52,6 +52,14 @@ import { GEmolumentoItemReadInterface } from "@/app/(protected)/(cadastros)/cada
|
|||
import CategoriaServicoSelect from "@/shared/components/categoriaServicoSelect/CategoriaServicoSelect";
|
||||
import CCaixaServicoSelect from "@/packages/administrativo/components/CCaixaServico/CCaixaServicoSelect";
|
||||
import { TServicoTipoSaveData } from "../../_data/TServicoTipo/TServicoTipoSaveData";
|
||||
import TTBReconhecimentoTipoSelect from "@/packages/administrativo/components/TTBReconhecimentoTipo/TTBReconhecimentoTipoSelect";
|
||||
import { ConfirmacaoCheckBox } from "@/shared/components/confirmacao/ConfirmacaoCheckBox";
|
||||
import ConfirmacaoSelect from "@/shared/components/confirmacao/ConfirmacaoSelect";
|
||||
import { TipoPessoaSelect } from "@/shared/components/tipoPessoa/tipoPessoaSelect";
|
||||
import { useTServicoEtiquetaReadHook } from "@/app/(protected)/(cadastros)/cadastros/_hooks/t_servico_etiqueta/useTServicoEtiquetaReadHook";
|
||||
import { useTServicoEtiquetaSaveHook } from "@/app/(protected)/(cadastros)/cadastros/_hooks/t_servico_etiqueta/useTServicoEtiquetaSaveHook";
|
||||
import { useTServicoEtiquetaRemoveHook } from "@/app/(protected)/(cadastros)/cadastros/_hooks/t_servico_etiqueta/useTServicoEtiquetaRemoveHook";
|
||||
|
||||
|
||||
// Propriedades esperadas pelo componente
|
||||
interface Props {
|
||||
|
|
@ -64,35 +72,179 @@ interface Props {
|
|||
// Componente principal do formulário
|
||||
export default function TServicoTipoForm({ isOpen, data, onClose, onSave }: Props) {
|
||||
|
||||
// Inicializa o react-hook-form com validação via Zod
|
||||
const form = useForm<TServicoTipoFormValues>({
|
||||
resolver: zodResolver(TServicoTipoSchema),
|
||||
defaultValues: {
|
||||
servico_tipo_id: 0,
|
||||
emolumento_id: 0,
|
||||
emolumento_obrigatorio: 0,
|
||||
descricao: "",
|
||||
maximo_pessoa: 0,
|
||||
tipo_item: "",
|
||||
frenteverso: "N",
|
||||
averbacao: "N",
|
||||
transferencia_veiculo: "N",
|
||||
usar_a4: "N",
|
||||
etiqueta_unica: "N",
|
||||
situacao: "A",
|
||||
selar: "N",
|
||||
valor_emolumento: 0,
|
||||
valor_taxa_judiciaria: 0,
|
||||
fundesp_valor: 0,
|
||||
valor_total: 0,
|
||||
tipo_pessoa: "F", // ou "J"
|
||||
} as unknown as TServicoTipoFormValues,
|
||||
});
|
||||
|
||||
|
||||
// Carrega o ID caso esteja informado no form
|
||||
const servico_tipo_id = form.getValues('servico_tipo_id') || 0;
|
||||
|
||||
// Hook responsável por buscar emolumentos no backend
|
||||
const { tServicoEtiqueta, fetchTServicoEtiqueta } = useTServicoEtiquetaReadHook();
|
||||
|
||||
// Hook responsável em salvar o a etiqueta selecionada
|
||||
const { tServicoEtiquetaSave, fetchTServicoEtiquetaSave } = useTServicoEtiquetaSaveHook();
|
||||
|
||||
// Hook responsável em excluir a etiqueta selecionada
|
||||
const { fetchTServicoEtiquetaRemove } = useTServicoEtiquetaRemoveHook();
|
||||
|
||||
// Estado para gerenciar os itens da tabela de etiquetas/carimbos
|
||||
const [itensTabela, setItensTabela] = useState<{ marcacao_tipo_id: string; descricao: string }[]>([]);
|
||||
const [itensTabela, setItensTabela] = useState<{ servico_etiqueta_id: string | number; descricao: string }[]>([]);
|
||||
|
||||
|
||||
// Função para adicionar um novo item à tabela
|
||||
const handleAddEtiquetaCarimbo = () => {
|
||||
const valorSelecionado = form.getValues('etiquetas_carimbos');
|
||||
// Carrega os dados de emolumentos apenas uma vez ao montar o componente
|
||||
React.useEffect(() => {
|
||||
|
||||
if (!valorSelecionado) return;
|
||||
// Função para consumir o endpoint da api
|
||||
const loadData = async () => {
|
||||
|
||||
// Aqui você pode buscar o texto/descrição com base no seu componente GMarcacaoTipoSelect
|
||||
// Exemplo: supondo que o valor seja um objeto { id, descricao }
|
||||
const item = {
|
||||
|
||||
marcacao_tipo_id: valorSelecionado.key ?? valorSelecionado, // ou ajusta conforme a estrutura do seu componente
|
||||
descricao: valorSelecionado.value ?? 'Sem descrição',
|
||||
// Verifica se o ID do serviço tipo foi informado
|
||||
if(servico_tipo_id > 0){
|
||||
|
||||
// Consumo o endpoint da api
|
||||
await fetchTServicoEtiqueta({servico_tipo_id});
|
||||
}
|
||||
};
|
||||
|
||||
// Evita duplicatas
|
||||
setItensTabela((prev) => {
|
||||
if (prev.some((p) => p.marcacao_tipo_id === item.marcacao_tipo_id)) return prev;
|
||||
return [...prev, item];
|
||||
});
|
||||
};
|
||||
// Chama a função para consumir o endpoint da api
|
||||
loadData();
|
||||
|
||||
}, [servico_tipo_id]);
|
||||
|
||||
const handleRemoveItem = (marcacao_tipo_id: string) => {
|
||||
setItensTabela((prev) => prev.filter((p) => p.marcacao_tipo_id !== marcacao_tipo_id));
|
||||
|
||||
// Atualiza itensTabela sempre que tServicoEtiqueta for carregado
|
||||
React.useEffect(() => {
|
||||
|
||||
// Verifica se a consulta retornou os dados como objeto
|
||||
if (Array.isArray(tServicoEtiqueta) && tServicoEtiqueta.length > 0) {
|
||||
|
||||
// Lista os itens
|
||||
const mapped = tServicoEtiqueta.map((item) => ({
|
||||
servico_etiqueta_id: Number(item.servico_etiqueta_id ?? 0),
|
||||
descricao: String(item.descricao ?? 'Sem descrição'),
|
||||
}));
|
||||
|
||||
setItensTabela(mapped);
|
||||
|
||||
} else {
|
||||
setItensTabela([]);
|
||||
}
|
||||
}, [tServicoEtiqueta]);
|
||||
|
||||
|
||||
// Função para adicionar um novo item à tabela Etiquetas/Carimbos
|
||||
const handleAddEtiquetaCarimbo = async () => {
|
||||
|
||||
// Captura o valor selecionado do formulário
|
||||
const valorSelecionado = form.getValues("etiquetas_carimbos");
|
||||
|
||||
// Se não houver valor selecionado, não faz nada
|
||||
if (!valorSelecionado) return;
|
||||
|
||||
// Verifica se o item já se encontra na tabela
|
||||
const alreadyExists = itensTabela.some(
|
||||
(p) => String(p.descricao).trim() === String(valorSelecionado.value).trim()
|
||||
);
|
||||
|
||||
// Caso o item já esteja na tabela, para o procedimento
|
||||
if (alreadyExists) {
|
||||
return;
|
||||
}
|
||||
|
||||
// --- Envio opcional para API ---
|
||||
try {
|
||||
|
||||
// Verifica se o ID do serviço tipo foi informado
|
||||
if(servico_tipo_id > 0){
|
||||
|
||||
// Monta o objeto do item selecionado
|
||||
const data = {
|
||||
etiqueta_modelo_id: valorSelecionado.key,
|
||||
servico_tipo_id: servico_tipo_id,
|
||||
};
|
||||
|
||||
// Consumo o endpoint da api
|
||||
const response = await fetchTServicoEtiquetaSave(data);
|
||||
|
||||
// Verifica se tServicoEtiquetaSave é um objeto válido (não null e não array)
|
||||
if (response && typeof response === 'object' && !Array.isArray(response)) {
|
||||
|
||||
// Monta o objeto com um único item para a tabela
|
||||
const item = {
|
||||
servico_etiqueta_id: Number(response.servico_etiqueta_id) ?? 0,
|
||||
descricao: String(valorSelecionado.value) ?? "Sem descrição",
|
||||
};
|
||||
|
||||
// Adiciona o item na tabela
|
||||
setItensTabela((prev) => {
|
||||
const idAtual = String(response.servico_etiqueta_id ?? '');
|
||||
const exists = prev.some((p) => String(p.servico_etiqueta_id ?? '') === idAtual);
|
||||
return exists ? prev : [...prev, item];
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Se ocorrer erros, informo
|
||||
} catch (error) {
|
||||
|
||||
console.log("Erro ao enviar o serviço para a API: " + error)
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Função para remover um item da tabela
|
||||
const handleRemoveItem = async (servico_etiqueta_id: number) => {
|
||||
|
||||
try{
|
||||
|
||||
// Verifica se o ID da etiqueta tipo foi informado
|
||||
if(servico_etiqueta_id > 0){
|
||||
|
||||
// Monta o objeto do item selecionado
|
||||
const data = {
|
||||
servico_etiqueta_id: servico_etiqueta_id,
|
||||
};
|
||||
|
||||
// Consumo o endpoint da api
|
||||
await fetchTServicoEtiquetaRemove(data);
|
||||
|
||||
}
|
||||
|
||||
// Atualiza a tabela no form
|
||||
setItensTabela((prev) => prev.filter((p) => Number(p.servico_etiqueta_id) !== servico_etiqueta_id));
|
||||
|
||||
// Se ocorrer erros, informo
|
||||
} catch (error) {
|
||||
|
||||
console.log("Erro ao enviar o serviço para a API: " + error)
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Parâmetros para o hook de leitura de emolumento_item
|
||||
// Inicializa com valores padrão (0) para evitar uso de propriedades não declaradas.
|
||||
const gEmolumentoItemReadParams: GEmolumentoItemReadInterface = { emolumento_id: 0, valor: 0 };
|
||||
|
|
@ -128,86 +280,109 @@ export default function TServicoTipoForm({ isOpen, data, onClose, onSave }: Prop
|
|||
}, [gEmolumentoItemReadParams.emolumento_id]);
|
||||
|
||||
|
||||
// Inicializa o react-hook-form com validação via Zod
|
||||
const form = useForm<TServicoTipoFormValues>({
|
||||
resolver: zodResolver(TServicoTipoSchema),
|
||||
defaultValues: {
|
||||
servico_tipo_id: 0,
|
||||
descricao: "",
|
||||
categoria: "",
|
||||
frenteverso: "N",
|
||||
averbacao: "N",
|
||||
transferencia_veiculo: "N",
|
||||
usar_a4: "N",
|
||||
etiqueta_unica: "N",
|
||||
situacao: "A",
|
||||
selar: "N",
|
||||
valor_emolumento: 0,
|
||||
valor_taxa_judiciaria: 0,
|
||||
fundesp_valor: 0,
|
||||
valor_total: 0,
|
||||
},
|
||||
});
|
||||
|
||||
// Captura o ID do serviço para uso local
|
||||
const servicoTipoId = Number(form.watch("servico_tipo_id") || data?.servico_tipo_id || 0);
|
||||
|
||||
// Atualiza os valores quando há dados para edição
|
||||
useEffect(() => {
|
||||
|
||||
if (data && Number(data.servico_tipo_id) > 0) {
|
||||
|
||||
//Carrega os valores no form
|
||||
form.reset(data);
|
||||
} else {
|
||||
|
||||
// Se não houver dados, reseta o
|
||||
// formulário para os valores iniciais
|
||||
// Modo novo cadastro → zera o ID manualmente
|
||||
form.reset({
|
||||
...form.getValues(), // mantém outros valores default
|
||||
servico_tipo_id: 0,
|
||||
descricao: '',
|
||||
});
|
||||
}
|
||||
}, [data, form]);
|
||||
|
||||
|
||||
// Função chamada ao clicar em "Salvar"
|
||||
const handleSave = async (formData: TServicoTipoFormValues) => {
|
||||
|
||||
try {
|
||||
// Envia os dados para API
|
||||
const response = await TServicoTipoSaveData(formData);
|
||||
|
||||
// Se a resposta contiver um ID válido
|
||||
// Se o form não trouxe o ID, tenta puxar de `data`
|
||||
const servico_tipo_id = formData.servico_tipo_id || data?.servico_tipo_id || form.getValues('servico_tipo_id') || 0;
|
||||
|
||||
// Atualiza o valor dentro do formData
|
||||
formData.servico_tipo_id = Number(servico_tipo_id);
|
||||
|
||||
// Intercepta e trata o valor de emolumento_id
|
||||
const emolumentoId = Number(formData.emolumento_id ?? 0);
|
||||
formData.emolumento_id = emolumentoId === 0 ? null : emolumentoId;
|
||||
|
||||
// Intercepta e trata o valor de emolumento_obrigatorio
|
||||
const emolumentoObrigatorio = Number(formData.emolumento_obrigatorio ?? 0);
|
||||
formData.emolumento_obrigatorio =
|
||||
emolumentoObrigatorio === 0 ? null : emolumentoObrigatorio;
|
||||
|
||||
|
||||
// Detecta automaticamente se é edição
|
||||
const isEditing = !!formData.servico_tipo_id && Number(formData.servico_tipo_id) > 0;
|
||||
|
||||
|
||||
// Envia os dados para o módulo com o método correto
|
||||
const response = await TServicoTipoSaveData({
|
||||
...formData,
|
||||
metodo: isEditing ? 'PUT' : 'POST', // 💡 Definição explícita do método
|
||||
});
|
||||
|
||||
|
||||
// Atualiza o formulário apenas se o retorno for válido
|
||||
if (response?.data?.servico_tipo_id) {
|
||||
const novoId = response.data.servico_tipo_id;
|
||||
const novoId = response.data.servico_tipo_id;
|
||||
form.setValue('servico_tipo_id', novoId); // mantém o ID atualizado
|
||||
|
||||
// Atualiza o hidden input no formulário
|
||||
form.setValue("servico_tipo_id", novoId);
|
||||
|
||||
// Atualiza todos os campos do formulário com o retorno da API
|
||||
form.reset(response.data);
|
||||
// Merge dos dados para preservar valores locais
|
||||
form.reset({ ...form.getValues(), ...response.data });
|
||||
|
||||
// Exibe mensagem de sucesso
|
||||
console.log(`Serviço salvo com sucesso (ID: ${novoId})`);
|
||||
|
||||
console.log(`Serviço ${isEditing ? 'atualizado' : 'criado'} com sucesso (ID: ${novoId})`);
|
||||
} else {
|
||||
console.log("Erro ao salvar o tipo de serviço.");
|
||||
console.log('Erro ao salvar o tipo de serviço.');
|
||||
}
|
||||
} catch (error) {
|
||||
|
||||
console.log("Erro ao salvar:", error);
|
||||
console.log('Erro ao salvar:', error);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
// Carrega os dados apenas quando o modal
|
||||
// abrir e houver um registro para editar
|
||||
useEffect(() => {
|
||||
|
||||
// Remove as etiquetas selecionadas
|
||||
setItensTabela([]);
|
||||
|
||||
if (isOpen && data && Number(data.servico_tipo_id ?? 0) > 0) {
|
||||
/** Carrega os dados no formulário */
|
||||
form.reset(data); // edição
|
||||
|
||||
} else if (isOpen && !data) {
|
||||
|
||||
/** Reseta os campos do formulário */
|
||||
form.reset({
|
||||
servico_tipo_id: 0,
|
||||
emolumento_id: 0,
|
||||
emolumento_obrigatorio: 0,
|
||||
descricao: "",
|
||||
maximo_pessoa: 0,
|
||||
tipo_item: "",
|
||||
frenteverso: "N",
|
||||
averbacao: "N",
|
||||
transferencia_veiculo: "N",
|
||||
usar_a4: "N",
|
||||
etiqueta_unica: "N",
|
||||
situacao: "A",
|
||||
selar: "N",
|
||||
valor_emolumento: 0,
|
||||
valor_taxa_judiciaria: 0,
|
||||
fundesp_valor: 0,
|
||||
valor_total: 0,
|
||||
tipo_pessoa: "F",
|
||||
});
|
||||
}
|
||||
}, [isOpen, data]);
|
||||
|
||||
function onError(errors: any) {
|
||||
console.log('Erros de validação:', errors);
|
||||
}
|
||||
|
||||
return (
|
||||
<Dialog
|
||||
open={isOpen}
|
||||
onOpenChange={(open) => {
|
||||
if (!open) onClose(null, false);
|
||||
}}
|
||||
>
|
||||
<Dialog
|
||||
open={isOpen}
|
||||
onOpenChange={(open) => {
|
||||
if (!open) onClose(null, false);
|
||||
}}
|
||||
>
|
||||
<DialogContent className="sm:max-w-[850px]">
|
||||
{/* Cabeçalho do diálogo */}
|
||||
<DialogHeader>
|
||||
|
|
@ -216,8 +391,8 @@ const form = useForm<TServicoTipoFormValues>({
|
|||
</DialogHeader>
|
||||
|
||||
{/* Estrutura do formulário */}
|
||||
<Form {...form}>
|
||||
<form onSubmit={form.handleSubmit(handleSave)} className="space-y-6">
|
||||
<Form key={data?.servico_tipo_id ?? 'new'} {...form}>
|
||||
<form onSubmit={form.handleSubmit(handleSave, onError)} className="space-y-6">
|
||||
|
||||
<Tabs defaultValue="dadosTipoServico" className="space-y-4">
|
||||
|
||||
|
|
@ -271,7 +446,7 @@ const form = useForm<TServicoTipoFormValues>({
|
|||
<div className="col-span-12 sm:col-span-6 md:col-span-4">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="categoria"
|
||||
name="tipo_item"
|
||||
render={({ field }) => (
|
||||
<FormItem className="w-full cursor-pointer">
|
||||
<FormLabel>Categoria</FormLabel>
|
||||
|
|
@ -292,20 +467,9 @@ const form = useForm<TServicoTipoFormValues>({
|
|||
render={({ field }) => (
|
||||
<FormItem className="w-full">
|
||||
<FormLabel>Serviço Padrão</FormLabel>
|
||||
<Select
|
||||
value={field.value}
|
||||
onValueChange={field.onChange}
|
||||
>
|
||||
<FormControl className="w-full">
|
||||
<SelectTrigger className="w-full cursor-pointer">
|
||||
<SelectValue placeholder="Selecione o tipo padrão" />
|
||||
</SelectTrigger>
|
||||
<FormControl>
|
||||
<ConfirmacaoSelect field={field} />
|
||||
</FormControl>
|
||||
<SelectContent>
|
||||
<SelectItem value="S" className="cursor-pointer">Sim</SelectItem>
|
||||
<SelectItem value="N" className="cursor-pointer">Não</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
|
|
@ -332,81 +496,37 @@ const form = useForm<TServicoTipoFormValues>({
|
|||
|
||||
{/* Campo: Averbação (Checkbox) */}
|
||||
<div className="col-span-12 sm:col-span-6 md:col-span-4">
|
||||
<FormField
|
||||
control={form.control}
|
||||
<ConfirmacaoCheckBox
|
||||
name="averbacao"
|
||||
render={({ field }) => (
|
||||
<FormItem className="flex flex-row items-center space-x-3 space-y-0">
|
||||
<FormControl>
|
||||
<Checkbox
|
||||
className="cursor-pointer"
|
||||
checked={field.value === "S"} // marcado se for "S"
|
||||
onCheckedChange={(checked) => field.onChange(checked ? "S" : "N")} // salva "S" ou "N"
|
||||
/>
|
||||
</FormControl>
|
||||
<FormLabel className="font-normal cursor-pointer">Averbação</FormLabel>
|
||||
</FormItem>
|
||||
)}
|
||||
label="Averbação"
|
||||
control={form.control}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Campo: Transferência de Veículo (Checkbox) */}
|
||||
<div className="col-span-12 sm:col-span-6 md:col-span-4">
|
||||
<FormField
|
||||
control={form.control}
|
||||
<ConfirmacaoCheckBox
|
||||
name="transferencia_veiculo"
|
||||
render={({ field }) => (
|
||||
<FormItem className="flex flex-row items-center space-x-3 space-y-0">
|
||||
<FormControl>
|
||||
<Checkbox
|
||||
className="cursor-pointer"
|
||||
checked={field.value === "S"} // marcado se o valor for "S"
|
||||
onCheckedChange={(checked) => field.onChange(checked ? "S" : "N")} // salva "S" ou "N"
|
||||
/>
|
||||
</FormControl>
|
||||
<FormLabel className="font-normal cursor-pointer">Transferência Veículo</FormLabel>
|
||||
</FormItem>
|
||||
)}
|
||||
label="Transferência de Veículo"
|
||||
control={form.control}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Campo: Usar A4 (Checkbox) */}
|
||||
<div className="col-span-12 sm:col-span-6 md:col-span-4">
|
||||
<FormField
|
||||
control={form.control}
|
||||
<ConfirmacaoCheckBox
|
||||
name="usar_a4"
|
||||
render={({ field }) => (
|
||||
<FormItem className="flex flex-row items-center space-x-3 space-y-0">
|
||||
<FormControl>
|
||||
<Checkbox
|
||||
className="cursor-pointer"
|
||||
checked={field.value === "S"} // marcado se o valor for "S"
|
||||
onCheckedChange={(checked) => field.onChange(checked ? "S" : "N")} // grava "S" ou "N"
|
||||
/>
|
||||
</FormControl>
|
||||
<FormLabel className="font-normal cursor-pointer">Usar A4</FormLabel>
|
||||
</FormItem>
|
||||
)}
|
||||
label="Usar A4"
|
||||
control={form.control}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Campo: Etiqueta Única (Texto normal) */}
|
||||
<div className="col-span-12 sm:col-span-6 md:col-span-4">
|
||||
<FormField
|
||||
control={form.control}
|
||||
<ConfirmacaoCheckBox
|
||||
name="etiqueta_unica"
|
||||
render={({ field }) => (
|
||||
<FormItem className="flex flex-row items-center space-x-3 space-y-0">
|
||||
<FormControl>
|
||||
<Checkbox
|
||||
className="cursor-pointer"
|
||||
checked={field.value === "S"} // marcado se o valor for "S"
|
||||
onCheckedChange={(checked) => field.onChange(checked ? "S" : "N")} // grava "S" ou "N"
|
||||
/>
|
||||
</FormControl>
|
||||
<FormLabel className="font-normal cursor-pointer">Etiqueta Única</FormLabel>
|
||||
</FormItem>
|
||||
)}
|
||||
label="Etiqueta Única"
|
||||
control={form.control}
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
|
@ -417,7 +537,7 @@ const form = useForm<TServicoTipoFormValues>({
|
|||
control={form.control}
|
||||
name="frenteverso"
|
||||
render={({ field }) => {
|
||||
const categoriaSelecionada = form.watch("categoria");
|
||||
const categoriaSelecionada = form.watch("tipo_item");
|
||||
const isEnabled = categoriaSelecionada === "A";
|
||||
|
||||
return (
|
||||
|
|
@ -478,25 +598,13 @@ const form = useForm<TServicoTipoFormValues>({
|
|||
<div className="col-span-12 sm:col-span-6 md:col-span-4">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="servico_tipo"
|
||||
name="tb_reconhecimentotipo_id"
|
||||
render={({ field }) => (
|
||||
<FormItem className="w-full">
|
||||
<FormLabel>Tipo</FormLabel>
|
||||
<Select
|
||||
value={field.value}
|
||||
onValueChange={field.onChange}
|
||||
>
|
||||
<FormControl className="w-full">
|
||||
<SelectTrigger className="w-full cursor-pointer">
|
||||
<SelectValue placeholder="Selecione uma opção" />
|
||||
</SelectTrigger>
|
||||
</FormControl>
|
||||
<SelectContent>
|
||||
<SelectItem value="1" className="cursor-pointer">Semelhança</SelectItem>
|
||||
<SelectItem value="2" className="cursor-pointer">Verdadeiro</SelectItem>
|
||||
<SelectItem value="3" className="cursor-pointer">Abono</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<TTBReconhecimentoTipoSelect
|
||||
field={field}
|
||||
/>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
|
|
@ -506,30 +614,7 @@ const form = useForm<TServicoTipoFormValues>({
|
|||
|
||||
{/* Campo: Pessoa (Select) */}
|
||||
<div className="col-span-12 sm:col-span-6 md:col-span-4">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="pessoa_tipo"
|
||||
render={({ field }) => (
|
||||
<FormItem className="w-full">
|
||||
<FormLabel>Pessoa</FormLabel>
|
||||
<Select
|
||||
value={field.value}
|
||||
onValueChange={field.onChange}
|
||||
>
|
||||
<FormControl className="w-full">
|
||||
<SelectTrigger className="w-full cursor-pointer">
|
||||
<SelectValue placeholder="Selecione uma opção" />
|
||||
</SelectTrigger>
|
||||
</FormControl>
|
||||
<SelectContent>
|
||||
<SelectItem value="F" className="cursor-pointer">Física</SelectItem>
|
||||
<SelectItem value="J" className="cursor-pointer">Juridica</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
<TipoPessoaSelect control={form.control} name="tipo_pessoa" />
|
||||
</div>
|
||||
|
||||
|
||||
|
|
@ -537,37 +622,29 @@ const form = useForm<TServicoTipoFormValues>({
|
|||
<div className="col-span-12 sm:col-span-6 md:col-span-4">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="quantidade_pessoas"
|
||||
name="maximo_pessoa"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
{/* Rótulo do campo */}
|
||||
<FormItem className="w-full">
|
||||
<FormLabel>Quantidade de pessoas</FormLabel>
|
||||
|
||||
<FormControl>
|
||||
<Input
|
||||
{...field}
|
||||
|
||||
// Garante que sempre exista um valor (evita undefined)
|
||||
value={field.value ?? ''}
|
||||
|
||||
// Placeholder explicativo
|
||||
<input
|
||||
type="number" // Aceita apenas números
|
||||
min={1}
|
||||
max={100}
|
||||
placeholder="Digite a quantidade de pessoas"
|
||||
|
||||
// Mostra teclado numérico em celulares
|
||||
inputMode="numeric"
|
||||
|
||||
// Sugere ao navegador que aceite apenas números
|
||||
pattern="[0-9]*"
|
||||
|
||||
// Intercepta a digitação e remove tudo que não for número
|
||||
className="flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm
|
||||
ring-offset-background placeholder:text-muted-foreground
|
||||
focus-visible:outline-none focus-visible:ring-2
|
||||
focus-visible:ring-ring focus-visible:ring-offset-2"
|
||||
{...field}
|
||||
value={field.value ?? ""} // Garante que nunca seja undefined
|
||||
onChange={(e) => {
|
||||
const apenasNumeros = e.target.value.replace(/[^0-9]/g, '');
|
||||
field.onChange(apenasNumeros);
|
||||
// Converte para número se houver valor
|
||||
const value = e.target.value === "" ? "" : Number(e.target.value);
|
||||
field.onChange(value);
|
||||
}}
|
||||
/>
|
||||
</FormControl>
|
||||
|
||||
{/* Exibe mensagens de erro do React Hook Form */}
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
|
|
@ -580,7 +657,7 @@ const form = useForm<TServicoTipoFormValues>({
|
|||
<div className="col-span-12 sm:col-span-6 md:col-span-3">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="biometria"
|
||||
name="requer_biometria"
|
||||
render={({ field }) => (
|
||||
<FormItem className="w-full">
|
||||
<FormLabel>Biometria</FormLabel>
|
||||
|
|
@ -588,10 +665,8 @@ const form = useForm<TServicoTipoFormValues>({
|
|||
value={field.value}
|
||||
onValueChange={field.onChange}
|
||||
>
|
||||
<FormControl className="w-full">
|
||||
<SelectTrigger className="w-full cursor-pointer">
|
||||
<SelectValue placeholder="Selecione uma opção" />
|
||||
</SelectTrigger>
|
||||
<FormControl>
|
||||
<ConfirmacaoSelect field={field} />
|
||||
</FormControl>
|
||||
<SelectContent>
|
||||
<SelectItem value="S" className="cursor-pointer">Sim</SelectItem>
|
||||
|
|
@ -608,7 +683,7 @@ const form = useForm<TServicoTipoFormValues>({
|
|||
<div className="col-span-12 sm:col-span-6 md:col-span-3">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="cpf_cnpj"
|
||||
name="requer_cpf"
|
||||
render={({ field }) => (
|
||||
<FormItem className="w-full">
|
||||
<FormLabel>CPF/CNPJ</FormLabel>
|
||||
|
|
@ -616,10 +691,8 @@ const form = useForm<TServicoTipoFormValues>({
|
|||
value={field.value}
|
||||
onValueChange={field.onChange}
|
||||
>
|
||||
<FormControl className="w-full">
|
||||
<SelectTrigger className="w-full cursor-pointer">
|
||||
<SelectValue placeholder="Selecione uma opção" />
|
||||
</SelectTrigger>
|
||||
<FormControl>
|
||||
<ConfirmacaoSelect field={field} />
|
||||
</FormControl>
|
||||
<SelectContent>
|
||||
<SelectItem value="S" className="cursor-pointer">Sim</SelectItem>
|
||||
|
|
@ -637,7 +710,7 @@ const form = useForm<TServicoTipoFormValues>({
|
|||
<div className="col-span-12 sm:col-span-6 md:col-span-3">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="autorizacao"
|
||||
name="requer_autorizacao"
|
||||
render={({ field }) => (
|
||||
<FormItem className="w-full">
|
||||
<FormLabel>Autorização</FormLabel>
|
||||
|
|
@ -645,10 +718,8 @@ const form = useForm<TServicoTipoFormValues>({
|
|||
value={field.value}
|
||||
onValueChange={field.onChange}
|
||||
>
|
||||
<FormControl className="w-full">
|
||||
<SelectTrigger className="w-full cursor-pointer">
|
||||
<SelectValue placeholder="Selecione uma opção" />
|
||||
</SelectTrigger>
|
||||
<FormControl>
|
||||
<ConfirmacaoSelect field={field} />
|
||||
</FormControl>
|
||||
<SelectContent>
|
||||
<SelectItem value="S" className="cursor-pointer">Sim</SelectItem>
|
||||
|
|
@ -666,7 +737,7 @@ const form = useForm<TServicoTipoFormValues>({
|
|||
<div className="col-span-12 sm:col-span-6 md:col-span-3">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="abonador"
|
||||
name="requer_abonador"
|
||||
render={({ field }) => (
|
||||
<FormItem className="w-full">
|
||||
<FormLabel>Abonador</FormLabel>
|
||||
|
|
@ -674,10 +745,8 @@ const form = useForm<TServicoTipoFormValues>({
|
|||
value={field.value}
|
||||
onValueChange={field.onChange}
|
||||
>
|
||||
<FormControl className="w-full">
|
||||
<SelectTrigger className="w-full cursor-pointer">
|
||||
<SelectValue placeholder="Selecione uma opção" />
|
||||
</SelectTrigger>
|
||||
<FormControl>
|
||||
<ConfirmacaoSelect field={field} />
|
||||
</FormControl>
|
||||
<SelectContent>
|
||||
<SelectItem value="S" className="cursor-pointer">Sim</SelectItem>
|
||||
|
|
@ -740,7 +809,7 @@ const form = useForm<TServicoTipoFormValues>({
|
|||
</TableHeader>
|
||||
<TableBody>
|
||||
{itensTabela.map((item, index) => (
|
||||
<TableRow key={item.marcacao_tipo_id}>
|
||||
<TableRow key={item.servico_etiqueta_id}>
|
||||
<TableCell className="w-[90px] text-center">
|
||||
{String(index + 1).padStart(3, '0')}
|
||||
</TableCell>
|
||||
|
|
@ -750,7 +819,7 @@ const form = useForm<TServicoTipoFormValues>({
|
|||
variant="outline"
|
||||
className="w-full cursor-pointer"
|
||||
type="button"
|
||||
onClick={() => handleRemoveItem(item.marcacao_tipo_id)}
|
||||
onClick={() => handleRemoveItem(item.servico_etiqueta_id)}
|
||||
>
|
||||
<Trash /> Remover
|
||||
</Button>
|
||||
|
|
@ -789,10 +858,8 @@ const form = useForm<TServicoTipoFormValues>({
|
|||
value={field.value}
|
||||
onValueChange={field.onChange}
|
||||
>
|
||||
<FormControl className="w-full">
|
||||
<SelectTrigger className="w-full cursor-pointer">
|
||||
<SelectValue placeholder="Selecione uma opção" />
|
||||
</SelectTrigger>
|
||||
<FormControl>
|
||||
<ConfirmacaoSelect field={field} />
|
||||
</FormControl>
|
||||
<SelectContent>
|
||||
<SelectItem value="S" className="cursor-pointer">Sim</SelectItem>
|
||||
|
|
@ -810,7 +877,7 @@ const form = useForm<TServicoTipoFormValues>({
|
|||
<div className="col-span-12 sm:col-span-6 md:col-span-10">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="emolumento"
|
||||
name="emolumento_id"
|
||||
render={({ field }) => (
|
||||
<FormItem className="w-full">
|
||||
<FormLabel>Emolumento</FormLabel>
|
||||
|
|
@ -851,7 +918,7 @@ const form = useForm<TServicoTipoFormValues>({
|
|||
(item.valor_taxa_judiciaria ?? 0) +
|
||||
(item.valor_outra_taxa1 ?? 0);
|
||||
|
||||
form.setValue("valor_total", total);
|
||||
form.setValue("valor", total);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Erro ao buscar item de emolumento:", error);
|
||||
|
|
@ -873,7 +940,7 @@ const form = useForm<TServicoTipoFormValues>({
|
|||
<div className="col-span-12 sm:col-span-6 md:col-span-12">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="emolumento_auxiliar"
|
||||
name="emolumento_obrigatorio"
|
||||
render={({ field }) => (
|
||||
<FormItem className="w-full">
|
||||
<FormLabel>Emolumento Adicional (Mesma etiqueta)</FormLabel>
|
||||
|
|
@ -953,7 +1020,7 @@ const form = useForm<TServicoTipoFormValues>({
|
|||
<div className="col-span-12 sm:col-span-6 md:col-span-3">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="valor_total"
|
||||
name="valor"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Total R$</FormLabel>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,26 @@
|
|||
// Importa o serviço de API que será utilizado para realizar requisições HTTP
|
||||
import API from '@/shared/services/api/Api'; //
|
||||
|
||||
// Importa o enum que contém os métodos HTTP disponíveis (GET, POST, PUT, DELETE)
|
||||
import { Methods } from '@/shared/services/api/enums/ApiMethodEnum'; //
|
||||
|
||||
// Importa a interface tipada que define a estrutura dos dados do tipo de serviço
|
||||
import { TServicoEtiquetaInterface } from '../../_interfaces/TServicoEtiquetaInterface';
|
||||
|
||||
// Importa função que encapsula chamadas assíncronas e trata erros automaticamente
|
||||
import { withClientErrorHandler } from '@/shared/actions/withClientErrorHandler/withClientErrorHandler'; //
|
||||
|
||||
// Função assíncrona que implementa a lógica de localizar um tipo de serviço
|
||||
async function executeTServicoEtiquetaService(data: TServicoEtiquetaInterface) {
|
||||
// Instancia o cliente da API para enviar a requisição
|
||||
const api = new API(); //
|
||||
|
||||
// Executa a requisição para a API com o método apropriado e envia o ID no endpoint
|
||||
return await api.send({
|
||||
method: Methods.GET, // Verbo GET para consulta
|
||||
endpoint: `administrativo/t_servico_etiqueta/servico_tipo/${data.servico_tipo_id}`, // Endpoint e ID alterados
|
||||
});
|
||||
}
|
||||
|
||||
// Exporta a função de Readr tipo de serviço já encapsulada com tratamento de erros
|
||||
export const TServicoEtiquetaReadData = withClientErrorHandler(executeTServicoEtiquetaService); // Nome da exportação alterado
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
// Importa o serviço de API que será utilizado para realizar requisições HTTP
|
||||
import API from '@/shared/services/api/Api'; //
|
||||
|
||||
// Importa o enum que contém os métodos HTTP disponíveis (GET, POST, PUT, DELETE)
|
||||
import { Methods } from '@/shared/services/api/enums/ApiMethodEnum'; //
|
||||
|
||||
// Importa a interface tipada que define a estrutura dos dados do tipo de serviço
|
||||
import { TServicoEtiquetaInterface } from '../../_interfaces/TServicoEtiquetaInterface'; // Alterado de GCidadeInterface
|
||||
|
||||
// Importa função que encapsula chamadas assíncronas e trata erros automaticamente
|
||||
import { withClientErrorHandler } from '@/shared/actions/withClientErrorHandler/withClientErrorHandler'; //
|
||||
|
||||
// Função assíncrona que implementa a lógica de remover um tipo de serviço
|
||||
async function executeTServicoEtiquetaRemoveData(data: TServicoEtiquetaInterface) { // Nome da função alterado
|
||||
|
||||
// Instancia o cliente da API para enviar a requisição
|
||||
const api = new API(); //
|
||||
|
||||
// Executa a requisição para a API com o método apropriado e envia o ID no endpoint
|
||||
return await api.send({
|
||||
method: Methods.DELETE, // Verbo DELETE para exclusão
|
||||
endpoint: `administrativo/t_servico_etiqueta/${data.servico_etiqueta_id}`, // Endpoint e ID alterados
|
||||
});
|
||||
}
|
||||
|
||||
// Exporta a função de remover tipo de serviço já encapsulada com tratamento de erros
|
||||
export const TServicoEtiquetaRemoveData = withClientErrorHandler(executeTServicoEtiquetaRemoveData); // Nome da exportação alterado
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
// Importa o serviço de API que será utilizado para realizar requisições HTTP
|
||||
import API from '@/shared/services/api/Api'; //
|
||||
|
||||
// Importa o esquema de validação de dados para tipos de serviço
|
||||
import { TServicoEtiquetaFormValues } from '../../_schemas/TServicoEtiquetaSchema';
|
||||
|
||||
// Importa o enum que contém os métodos HTTP disponíveis (GET, POST, PUT, DELETE)
|
||||
import { Methods } from '@/shared/services/api/enums/ApiMethodEnum'; //
|
||||
|
||||
// Importa a interface tipada que define a estrutura dos dados do tipo de serviço
|
||||
import { TServicoEtiquetaInterface } from '../../_interfaces/TServicoEtiquetaInterface'; // Interface alterada
|
||||
|
||||
// Importa função que encapsula chamadas assíncronas e trata erros automaticamente
|
||||
import { withClientErrorHandler } from '@/shared/actions/withClientErrorHandler/withClientErrorHandler'; //
|
||||
|
||||
// Função assíncrona que implementa a lógica de salvar (criar/atualizar) um tipo de serviço
|
||||
async function executeTServicoEtiquetaSaveData(data: TServicoEtiquetaFormValues) {
|
||||
|
||||
try{
|
||||
|
||||
// Instancia o cliente da API para enviar a requisição
|
||||
const api = new API(); //
|
||||
|
||||
// Executa a requisição para a API com o método apropriado e envia os dados no corpo
|
||||
return await api.send({
|
||||
method: Methods.POST, // PUT se atualizar, POST se criar
|
||||
endpoint: `administrativo/t_servico_etiqueta`, // Endpoint e ID alterados
|
||||
body: data, // payload enviado para a API
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
|
||||
console.error('Erro no TServicoEtiquetaSaveData:', error);
|
||||
throw error; // propaga erro para o form
|
||||
}
|
||||
}
|
||||
|
||||
// Exporta a função de salvar tipo de serviço já encapsulada com tratamento de erros
|
||||
export const TServicoEtiquetaSaveData = withClientErrorHandler(executeTServicoEtiquetaSaveData); // Nome da exportação alterado
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
// Importa o serviço de API que será utilizado para realizar requisições HTTP
|
||||
import API from '@/shared/services/api/Api'; //
|
||||
|
||||
// Importa o enum que contém os métodos HTTP disponíveis (GET, POST, PUT, DELETE)
|
||||
import { Methods } from '@/shared/services/api/enums/ApiMethodEnum'; //
|
||||
|
||||
// Importa a interface tipada que define a estrutura dos dados do tipo de serviço
|
||||
import TServicoTipoInterface from '../../_interfaces/TServicoTipoInterface'; // Alterado de GCidadeInterface
|
||||
|
||||
// Importa função que encapsula chamadas assíncronas e trata erros automaticamente
|
||||
import { withClientErrorHandler } from '@/shared/actions/withClientErrorHandler/withClientErrorHandler'; //
|
||||
|
||||
// Função assíncrona que implementa a lógica de localizar um tipo de serviço
|
||||
async function executeTServicoTipoEditService(data: TServicoTipoInterface) {
|
||||
// Instancia o cliente da API para enviar a requisição
|
||||
const api = new API(); //
|
||||
|
||||
// Executa a requisição para a API com o método apropriado e envia o ID no endpoint
|
||||
return await api.send({
|
||||
method: Methods.GET, // Verbo GET para consulta
|
||||
endpoint: `administrativo/t_servico_tipo/${data.servico_tipo_id}`, // Endpoint e ID alterados
|
||||
});
|
||||
}
|
||||
|
||||
// Exporta a função de Readr tipo de serviço já encapsulada com tratamento de erros
|
||||
export const TServicoTipoEditData = withClientErrorHandler(executeTServicoTipoEditService); // Nome da exportação alterado
|
||||
|
|
@ -19,7 +19,7 @@ async function executeTServicoTipoRemoveData(data: TServicoTipoInterface) { // N
|
|||
// Executa a requisição para a API com o método apropriado e envia o ID no endpoint
|
||||
return await api.send({
|
||||
method: Methods.DELETE, // Verbo DELETE para exclusão
|
||||
endpoint: `administrativo/t_servico_tipo/${data.servico_tipo_id}`, // Endpoint e ID alterados de g_cidade/cidade_id
|
||||
endpoint: `administrativo/t_servico_tipo/${data.servico_tipo_id}`, // Endpoint e ID alterados
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,9 @@
|
|||
// Importa o serviço de API que será utilizado para realizar requisições HTTP
|
||||
import API from '@/shared/services/api/Api'; //
|
||||
|
||||
// Importa o esquema de validação de dados para tipos de serviço
|
||||
import { TServicoTipoFormValues } from '../../_schemas/TServicoTipoSchema';
|
||||
|
||||
// Importa o enum que contém os métodos HTTP disponíveis (GET, POST, PUT, DELETE)
|
||||
import { Methods } from '@/shared/services/api/enums/ApiMethodEnum'; //
|
||||
|
||||
|
|
@ -11,20 +14,33 @@ import TServicoTipoInterface from '../../_interfaces/TServicoTipoInterface'; //
|
|||
import { withClientErrorHandler } from '@/shared/actions/withClientErrorHandler/withClientErrorHandler'; //
|
||||
|
||||
// Função assíncrona que implementa a lógica de salvar (criar/atualizar) um tipo de serviço
|
||||
async function executeTServicoTipoSaveData(data: TServicoTipoInterface) { // Nome da função alterado
|
||||
async function executeTServicoTipoSaveData(data: TServicoTipoFormValues & { metodo?: 'POST' | 'PUT' }) {
|
||||
|
||||
// Verifica se existe ID do tipo de serviço para decidir se é atualização (PUT) ou criação (POST)
|
||||
const isUpdate = Boolean(data.servico_tipo_id); // Campo de ID alterado de 'cidade_id' para 'servico_tipo_id'
|
||||
const isEditing = !!data.servico_tipo_id && Number(data.servico_tipo_id) > 0;
|
||||
|
||||
// Instancia o cliente da API para enviar a requisição
|
||||
const api = new API(); //
|
||||
// Define método: prioridade para valor passado manualmente (metodo)
|
||||
const method = data.metodo ?? (isEditing ? 'PUT' : 'POST');
|
||||
|
||||
// Executa a requisição para a API com o método apropriado e envia os dados no corpo
|
||||
return await api.send({
|
||||
method: isUpdate ? Methods.PUT : Methods.POST, // PUT se atualizar, POST se criar
|
||||
endpoint: `administrativo/t_servico_tipo/${data.servico_tipo_id || ''}`, // Endpoint e ID alterados
|
||||
body: data, // payload enviado para a API
|
||||
});
|
||||
try{
|
||||
|
||||
console.log(data)
|
||||
|
||||
// Instancia o cliente da API para enviar a requisição
|
||||
const api = new API(); //
|
||||
|
||||
// Executa a requisição para a API com o método apropriado e envia os dados no corpo
|
||||
return await api.send({
|
||||
method: isEditing ? Methods.PUT : Methods.POST, // PUT se atualizar, POST se criar
|
||||
endpoint: `administrativo/t_servico_tipo/${data.servico_tipo_id || ''}`, // Endpoint e ID alterados
|
||||
body: data, // payload enviado para a API
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
|
||||
console.error('Erro no TServicoTipoSaveData:', error);
|
||||
throw error; // propaga erro para o form
|
||||
}
|
||||
}
|
||||
|
||||
// Exporta a função de salvar tipo de serviço já encapsulada com tratamento de erros
|
||||
|
|
|
|||
|
|
@ -0,0 +1,27 @@
|
|||
// Importa o utilitário responsável por tratar erros de forma padronizada no cliente
|
||||
import { withClientErrorHandler } from '@/shared/actions/withClientErrorHandler/withClientErrorHandler';
|
||||
|
||||
// Importa a classe de serviço que gerencia requisições HTTP para a API
|
||||
import API from '@/shared/services/api/Api';
|
||||
|
||||
// Importa o enum que define os métodos HTTP disponíveis (GET, POST, PUT, DELETE, etc.)
|
||||
import { Methods } from '@/shared/services/api/enums/ApiMethodEnum';
|
||||
import { TTBReconhecimentoTipoReadInterface } from '../../_interfaces/TTBReconhecimentoTipoReadInterface';
|
||||
|
||||
// Função assíncrona responsável por executar a requisição para listar os tipos de marcação
|
||||
async function executeTTBReconhecimentoTipoIndexData(data: TTBReconhecimentoTipoReadInterface) {
|
||||
// Cria uma nova instância da classe API para enviar a requisição
|
||||
const api = new API();
|
||||
|
||||
// Concatena o endpoint com a query string (caso existam parâmetros)
|
||||
const endpoint = `administrativo/t_tb_reconhecimentotipo/`;
|
||||
|
||||
// Envia uma requisição GET para o endpoint 'administrativo/g_marcacao_tipo/'
|
||||
return await api.send({
|
||||
method: Methods.GET,
|
||||
endpoint: endpoint,
|
||||
});
|
||||
}
|
||||
|
||||
// Exporta a função encapsulada pelo handler de erro, garantindo tratamento uniforme em caso de falhas
|
||||
export const TTBReconhecimentoTipoIndexData = withClientErrorHandler(executeTTBReconhecimentoTipoIndexData);
|
||||
|
|
@ -6,14 +6,15 @@ import { useMemo, useState } from 'react';
|
|||
|
||||
// Importa a interface que define a estrutura dos dados de "GMarcacaoTipo"
|
||||
import { GMarcacaoTipoReadInterface } from '../../_interfaces/GMarcacaoTipoReadInterface';
|
||||
import { GMarcacaoTipoInterface } from '../../_interfaces/GMarcacaoTipoInterface';
|
||||
|
||||
// Importa o serviço responsável por buscar os dados de "GMarcacaoTipo" na API
|
||||
import { GMarcacaoTipoIndexService } from '../../_services/g_marcacao_tipo/GMarcacaoTipoIndexService';
|
||||
import { GMarcacaoTipoInterface } from '../../_interfaces/GMarcacaoTipoInterface';
|
||||
|
||||
|
||||
// Hook personalizado para leitura (consulta) dos tipos de marcação
|
||||
export const useGMarcacaoTipoReadHook = () => {
|
||||
|
||||
// Obtém a função que atualiza a resposta global do sistema
|
||||
const { setResponse } = useResponse();
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,44 @@
|
|||
// Importa o hook responsável por gerenciar e exibir respostas globais (sucesso, erro, etc.)
|
||||
import { useResponse } from '@/shared/components/response/ResponseContext';
|
||||
|
||||
// Importa hooks do React para gerenciamento de estado e memorização de valores
|
||||
import { useCallback, useState } from 'react';
|
||||
|
||||
// Importa a interface que define a estrutura dos dados de "TServicoEtiqueta"
|
||||
import { TServicoEtiquetaInterface } from '../../_interfaces/TServicoEtiquetaInterface';
|
||||
|
||||
// Importa o serviço responsável por buscar os dados de "TServicoEtiqueta" na API
|
||||
import { TServicoEtiquetaServicoIdService } from '../../_services/t_servico_etiqueta/TServicoEtiquetaServicoIdService';
|
||||
|
||||
// Hook personalizado para leitura (consulta) dos tipos de marcação
|
||||
export const useTServicoEtiquetaReadHook = () => {
|
||||
|
||||
// Obtém a função que atualiza a resposta global do sistema
|
||||
const { setResponse } = useResponse();
|
||||
|
||||
// Define o estado local que armazenará a lista de tipos de marcação
|
||||
const [tServicoEtiqueta, setTServicoEtiqueta] = useState<TServicoEtiquetaInterface[]>([]);
|
||||
|
||||
// Função responsável por buscar os dados da API e atualizar o estado
|
||||
const fetchTServicoEtiqueta = useCallback(async (data: TServicoEtiquetaInterface) => {
|
||||
|
||||
try{
|
||||
|
||||
// Executa o serviço que faz a requisição à API
|
||||
const response = await TServicoEtiquetaServicoIdService(data);
|
||||
|
||||
// Atualiza o estado local com os dados retornados
|
||||
setTServicoEtiqueta(response.data);
|
||||
|
||||
// Atualiza o contexto global de resposta (ex: para exibir alertas ou mensagens)
|
||||
setResponse(response);
|
||||
|
||||
} catch (error) {
|
||||
console.error('Erro ao buscar etiquetas:', error);
|
||||
return { data: [] };
|
||||
}
|
||||
}, [setResponse]);
|
||||
|
||||
// Retorna os dados e a função de busca, memorizando o valor para evitar recriações desnecessárias
|
||||
return { tServicoEtiqueta, fetchTServicoEtiqueta };
|
||||
};
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
import { useResponse } from "@/shared/components/response/ResponseContext"; // Contexto global para gerenciar respostas da API
|
||||
|
||||
// Interface tipada do tipo de serviço
|
||||
import { TServicoEtiquetaInterface } from "../../_interfaces/TServicoEtiquetaInterface";
|
||||
|
||||
// Função que remove o tipo de serviço via API
|
||||
import { TServicoEtiquetaRemoveData } from "../../_data/TServicoEtiqueta/TServicoEtiquetaRemoveData";
|
||||
|
||||
// Hook customizado para remoção de tipos de serviço
|
||||
export const useTServicoEtiquetaRemoveHook = () => {
|
||||
// Hook do contexto de resposta para feedback global (alertas, mensagens etc.)
|
||||
const { setResponse } = useResponse();
|
||||
|
||||
// Função assíncrona que remove um tipo de serviço
|
||||
const fetchTServicoEtiquetaRemove = async (data: TServicoEtiquetaInterface) => {
|
||||
// Chama a função de remoção passando os dados do tipo de serviço
|
||||
const response = await TServicoEtiquetaRemoveData(data);
|
||||
|
||||
// Atualiza o contexto global com a resposta da API
|
||||
setResponse(response);
|
||||
};
|
||||
|
||||
// Retorna a função de remoção para ser usada no componente
|
||||
return { fetchTServicoEtiquetaRemove };
|
||||
};
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
import { useState } from 'react';
|
||||
import { useResponse } from '@/shared/components/response/ResponseContext';
|
||||
|
||||
// Interface tipada do serviço etiqueta
|
||||
import { TServicoEtiquetaInterface } from '../../_interfaces/TServicoEtiquetaInterface';
|
||||
|
||||
// Serviço que salva os dados do serviço etiqueta
|
||||
import { TServicoEtiquetaSaveService } from '../../_services/t_servico_etiqueta/TServicoEtiquetaSaveService';
|
||||
|
||||
export const useTServicoEtiquetaSaveHook = () => {
|
||||
const { setResponse } = useResponse();
|
||||
|
||||
// Estado local para armazenar os dados do serviço etiqueta salvos
|
||||
const [tServicoEtiquetaSave, setTServicoEtiquetaSave] = useState<TServicoEtiquetaInterface | null>(null);
|
||||
|
||||
/**
|
||||
* Função que executa o salvamento de um serviço etiqueta.
|
||||
* @param data Os dados do serviço etiqueta a serem salvos.
|
||||
*/
|
||||
const fetchTServicoEtiquetaSave = async (data: TServicoEtiquetaInterface) => {
|
||||
|
||||
// Chama o serviço de salvamento
|
||||
const response = await TServicoEtiquetaSaveService(data);
|
||||
|
||||
// Guardar os dados localizados
|
||||
setTServicoEtiquetaSave(response.data);
|
||||
|
||||
// Manda a resposta para o verificador de resposta global
|
||||
///setResponse(response);
|
||||
|
||||
// Manda a resposta para o verificador de resposta global
|
||||
return response.data;
|
||||
}
|
||||
|
||||
// Retorna o estado e a função de salvamento para uso no componente
|
||||
return { tServicoEtiquetaSave, fetchTServicoEtiquetaSave };
|
||||
};
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
import { useResponse } from "@/shared/components/response/ResponseContext"; // Contexto global para gerenciar respostas da API
|
||||
|
||||
// Interface tipada do tipo de serviço
|
||||
import TServicoTipoInterface from "../../_interfaces/TServicoTipoInterface";
|
||||
|
||||
// Função que Edit o tipo de serviço via API
|
||||
import { TServicoTipoEditData } from "../../_data/TServicoTipo/TServicoTipoEditData";
|
||||
|
||||
// Hook customizado para remoção de tipos de serviço
|
||||
export const useTServicoTipoEditHook = () => {
|
||||
// Hook do contexto de resposta para feedback global (alertas, mensagens etc.)
|
||||
const { setResponse } = useResponse();
|
||||
|
||||
// Função assíncrona que Edit um tipo de serviço
|
||||
const editTServicoTipo = async (data: TServicoTipoInterface) => {
|
||||
|
||||
// Chama a função de remoção passando os dados do tipo de serviço
|
||||
const response = await TServicoTipoEditData(data);
|
||||
|
||||
// Atualiza o contexto global com a resposta da API
|
||||
setResponse(response);
|
||||
};
|
||||
|
||||
// Retorna a função de remoção para ser usada no componente
|
||||
return { editTServicoTipo };
|
||||
};
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
// Importa o hook responsável por gerenciar e exibir respostas globais (sucesso, erro, etc.)
|
||||
import { useResponse } from '@/shared/components/response/ResponseContext';
|
||||
|
||||
// Importa hooks do React para gerenciamento de estado e memorização de valores
|
||||
import { useMemo, useState } from 'react';
|
||||
|
||||
// Importa a interface que define a estrutura dos dados de "TTBReconhecimentoTipo"
|
||||
import { TTBReconhecimentoTipoReadInterface } from '../../_interfaces/TTBReconhecimentoTipoReadInterface';
|
||||
import { TTBReconhecimentoTipoInterface } from '../../_interfaces/TTBReconhecimentoTipoInterface';
|
||||
|
||||
// Importa o serviço responsável por buscar os dados de "TTBReconhecimentoTipo" na API
|
||||
import { TTBReconhecimentoTipoIndexService } from '../../_services/t_tb_reconhecimentotipo/TTBReconhecimentoTipoIndexService';
|
||||
|
||||
|
||||
// Hook personalizado para leitura (consulta) dos tipos de marcação
|
||||
export const useTTBReconhecimentoTipoReadHook = () => {
|
||||
// Obtém a função que atualiza a resposta global do sistema
|
||||
const { setResponse } = useResponse();
|
||||
|
||||
// Define o estado local que armazenará a lista de tipos de marcação
|
||||
const [tTBReconhecimentoTipo, setTTBReconhecimentoTipo] = useState<TTBReconhecimentoTipoInterface[]>([]);
|
||||
|
||||
// Função responsável por buscar os dados da API e atualizar o estado
|
||||
const fetchTTBReconhecimentoTipo = async (data: TTBReconhecimentoTipoReadInterface) => {
|
||||
// Executa o serviço que faz a requisição à API
|
||||
const response = await TTBReconhecimentoTipoIndexService(data);
|
||||
|
||||
// Atualiza o estado local com os dados retornados
|
||||
setTTBReconhecimentoTipo(response.data);
|
||||
|
||||
// Atualiza o contexto global de resposta (ex: para exibir alertas ou mensagens)
|
||||
setResponse(response);
|
||||
};
|
||||
|
||||
// Retorna os dados e a função de busca, memorizando o valor para evitar recriações desnecessárias
|
||||
return useMemo(() => ({ tTBReconhecimentoTipo, fetchTTBReconhecimentoTipo }), [tTBReconhecimentoTipo, fetchTTBReconhecimentoTipo]);
|
||||
};
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
// Interface que representa a tabela T_TB_RECONHECIMENTOTIPO
|
||||
export interface TServicoEtiquetaInterface {
|
||||
servico_etiqueta_id?: number; // NUMERIC(10,2) NOT NULL - Chave primária
|
||||
etiqueta_modelo_id?: number; // NUMERIC(10,2)
|
||||
servico_tipo_id?: number; // NUMERIC(10,2)
|
||||
descricao?: string
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
export interface TServicoEtiquetaServicoIdReadInterface {
|
||||
servico_tipo_id?: number
|
||||
}
|
||||
|
|
@ -1,37 +1,27 @@
|
|||
export default interface TServicoTipoInterface {
|
||||
servico_tipo_id?: number; // SERVICO_TIPO_ID NUMERIC(10,2) NOT NULL (PK)
|
||||
descricao: string; // DESCRICAO VARCHAR(60)
|
||||
valor?: number; // VALOR NUMERIC(14,3)
|
||||
tipo_item?: string; // TIPO_ITEM VARCHAR(1)
|
||||
requer_autorizacao?: string; // REQUER_AUTORIZACAO VARCHAR(1)
|
||||
requer_biometria?: string; // REQUER_BIOMETRIA VARCHAR(1)
|
||||
tipo_pessoa?: string; // TIPO_PESSOA VARCHAR(1)
|
||||
tb_reconhecimentotipo_id?: number; // TB_RECONHECIMENTOTIPO_ID NUMERIC(10,2) (FK)
|
||||
tipo_permissao_cpf?: string; // TIPO_PERMISSAO_CPF VARCHAR(1)
|
||||
requer_abonador?: string; // REQUER_ABONADOR VARCHAR(1)
|
||||
requer_representante?: string; // REQUER_REPRESENTANTE VARCHAR(1)
|
||||
situacao?: string; // SITUACAO VARCHAR(1)
|
||||
requer_cpf?: string; // REQUER_CPF VARCHAR(1)
|
||||
servico_padrao?: string; // SERVICO_PADRAO VARCHAR(1)
|
||||
maximo_pessoa?: number; // MAXIMO_PESSOA NUMERIC(10,2)
|
||||
alterar_valor?: string; // ALTERAR_VALOR VARCHAR(1)
|
||||
servico_caixa_id?: number; // SERVICO_CAIXA_ID NUMERIC(10,2)
|
||||
lancar_taxa?: string; // LANCAR_TAXA VARCHAR(1)
|
||||
lancar_fundesp?: string; // LANCAR_FUNDESP VARCHAR(1)
|
||||
liberar_desconto?: string; // LIBERAR_DESCONTO VARCHAR(1)
|
||||
fundesp_automatica?: string; // FUNDESP_AUTOMATICA VARCHAR(1)
|
||||
lancar_valor_documento?: string; // LANCAR_VALOR_DOCUMENTO VARCHAR(1)
|
||||
valor_fixo?: string; // VALOR_FIXO VARCHAR(1)
|
||||
emolumento_id?: number; // EMOLUMENTO_ID NUMERIC(10,2) (FK)
|
||||
ato_praticado?: string; // ATO_PRATICADO VARCHAR(1)
|
||||
selar?: string; // SELAR VARCHAR(1)
|
||||
frenteverso?: string; // FRENTEVERSO VARCHAR(1)
|
||||
pagina_acrescida?: string; // PAGINA_ACRESCIDA VARCHAR(1)
|
||||
emolumento_obrigatorio?: number; // EMOLUMENTO_OBRIGATORIO NUMERIC(10,2)
|
||||
apresentante_selo?: string; // APRESENTANTE_SELO VARCHAR(1)
|
||||
renovacao_cartao?: string; // RENOVACAO_CARTAO VARCHAR(1)
|
||||
etiqueta_unica?: string; // ETIQUETA_UNICA VARCHAR(1)
|
||||
transferencia_veiculo?: string; // TRANSFERENCIA_VEICULO VARCHAR(1)
|
||||
usar_a4?: string; // USAR_A4 VARCHAR(1)
|
||||
averbacao?: string; // AVERBACAO VARCHAR(1)
|
||||
}
|
||||
servico_tipo_id?: number; // SERVICO_TIPO_ID NUMERIC(10,2) NOT NULL (PK)
|
||||
descricao: string; // DESCRICAO VARCHAR(60)
|
||||
valor?: number; // VALOR NUMERIC(14,3)
|
||||
requer_autorizacao?: string; // REQUER_AUTORIZACAO VARCHAR(1)
|
||||
requer_biometria?: string; // REQUER_BIOMETRIA VARCHAR(1)
|
||||
tipo_pessoa?: string; // TIPO_PESSOA VARCHAR(1)
|
||||
tb_reconhecimentotipo_id?: number; // TB_RECONHECIMENTOTIPO_ID NUMERIC(10,2) (FK)
|
||||
requer_abonador?: string; // REQUER_ABONADOR VARCHAR(1)
|
||||
situacao?: string; // SITUACAO VARCHAR(1)
|
||||
requer_cpf?: string; // REQUER_CPF VARCHAR(1)
|
||||
servico_padrao?: string; // SERVICO_PADRAO VARCHAR(1)
|
||||
maximo_pessoa?: number; // MAXIMO_PESSOA NUMERIC(10,2)
|
||||
alterar_valor?: string; // ALTERAR_VALOR VARCHAR(1)
|
||||
servico_caixa_id?: number; // SERVICO_CAIXA_ID NUMERIC(10,2)
|
||||
caixa_servico_id?: number; // LIBERAR_DESCONTO VARCHAR(1)
|
||||
valor_fixo?: string; // VALOR_FIXO VARCHAR(1)
|
||||
emolumento_id?: number; // EMOLUMENTO_ID NUMERIC(10,2) (FK)
|
||||
emolumento_obrigatorio?: number; // EMOLUMENTO_OBRIGATORIO NUMERIC(10,2) (FK)
|
||||
ato_praticado?: string; // ATO_PRATICADO VARCHAR(1)
|
||||
selar?: string; // SELAR VARCHAR(1)
|
||||
frenteverso?: string; // FRENTEVERSO VARCHAR(1)
|
||||
etiqueta_unica?: string; // ETIQUETA_UNICA VARCHAR(1)
|
||||
transferencia_veiculo?: string; // TRANSFERENCIA_VEICULO VARCHAR(1)
|
||||
usar_a4?: string; // USAR_A4 VARCHAR(1)
|
||||
averbacao?: string; // AVERBACAO VARCHAR(1)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,6 @@
|
|||
// Interface que representa a tabela T_TB_RECONHECIMENTOTIPO
|
||||
export interface TTbReconhecimentoTipoInterface {
|
||||
tb_reconhecimentotipo_id: number; // NUMERIC(10,2) NOT NULL - Chave primária
|
||||
descricao?: string; // VARCHAR(30)
|
||||
situacao?: string; // VARCHAR(1)
|
||||
}
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
export interface TTBReconhecimentoTipoReadInterface {
|
||||
tb_reconhecimentotipo_id?: number,
|
||||
descricao?: string
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
/**
|
||||
* Interface principal baseada na DDL
|
||||
* Tabela: T_SERVICO_ETIQUETA
|
||||
*/
|
||||
export interface TServicoEtiquetaFormValues {
|
||||
/** Identificador principal (PK) */
|
||||
servico_etiqueta_id?: number;
|
||||
|
||||
/** Relacionamento com o modelo de etiqueta (FK) */
|
||||
etiqueta_modelo_id?: number;
|
||||
|
||||
/** Relacionamento com o tipo de serviço (FK) */
|
||||
servico_tipo_id?: number;
|
||||
|
||||
}
|
||||
|
|
@ -29,15 +29,15 @@ export const TServicoTipoSchema = z.object({
|
|||
etiqueta_unica: SN.optional(),
|
||||
selar: SN.optional(),
|
||||
servico_padrao: SN.optional(),
|
||||
lancar_taxa: SN.optional(),
|
||||
lancar_fundesp: SN.optional(),
|
||||
liberar_desconto: SN.optional(),
|
||||
fundesp_automatica: SN.optional(),
|
||||
lancar_valor_documento: SN.optional(),
|
||||
// lancar_taxa: SN.optional(),
|
||||
// lancar_fundesp: SN.optional(),
|
||||
// liberar_desconto: SN.optional(),
|
||||
// fundesp_automatica: SN.optional(),
|
||||
// lancar_valor_documento: SN.optional(),
|
||||
valor_fixo: SN.optional(),
|
||||
ato_praticado: SN.optional(),
|
||||
apresentante_selo: SN.optional(),
|
||||
renovacao_cartao: SN.optional(),
|
||||
// apresentante_selo: SN.optional(),
|
||||
// renovacao_cartao: SN.optional(),
|
||||
|
||||
// Situação
|
||||
situacao: AI,
|
||||
|
|
@ -46,8 +46,8 @@ export const TServicoTipoSchema = z.object({
|
|||
valor: OptionalNumber,
|
||||
maximo_pessoa: OptionalNumber,
|
||||
servico_caixa_id: OptionalNumber,
|
||||
emolumento_id: OptionalNumber,
|
||||
emolumento_obrigatorio: OptionalNumber,
|
||||
emolumento_id: z.number().nullable(),
|
||||
emolumento_obrigatorio: z.number().nullable(),
|
||||
|
||||
// Relacionamentos e permissões
|
||||
tipo_item: OneCharString,
|
||||
|
|
@ -55,12 +55,12 @@ export const TServicoTipoSchema = z.object({
|
|||
requer_biometria: OneCharString,
|
||||
tipo_pessoa: OneCharString,
|
||||
tb_reconhecimentotipo_id: OptionalNumber,
|
||||
tipo_permissao_cpf: OneCharString,
|
||||
// tipo_permissao_cpf: OneCharString,
|
||||
requer_abonador: OneCharString,
|
||||
requer_representante: OneCharString,
|
||||
// requer_representante: OneCharString,
|
||||
requer_cpf: OneCharString,
|
||||
alterar_valor: OneCharString,
|
||||
pagina_acrescida: OneCharString,
|
||||
// alterar_valor: OneCharString,
|
||||
// pagina_acrescida: OneCharString,
|
||||
|
||||
// Campos auxiliares usados apenas no formulário (não persistidos)
|
||||
valor_emolumento: z.number().optional(),
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
// Função que envolve qualquer ação assíncrona para capturar e tratar erros do cliente
|
||||
import { withClientErrorHandler } from '@/shared/actions/withClientErrorHandler/withClientErrorHandler';
|
||||
|
||||
// Função que salva os dados do serviço etiqueta via API (ou mock)
|
||||
import { TServicoEtiquetaSaveData } from '../../_data/TServicoEtiqueta/TServicoEtiquetaSaveData';
|
||||
|
||||
// Interface tipada do serviço etiqueta
|
||||
import { TServicoEtiquetaInterface } from '../../_interfaces/TServicoEtiquetaInterface';
|
||||
|
||||
// Função assíncrona que executa o salvamento de um serviço etiqueta
|
||||
async function executeTServicoEtiquetaSaveService(data: TServicoEtiquetaInterface) {
|
||||
|
||||
// Chama a função que salva os dados do serviço etiqueta
|
||||
const response = await TServicoEtiquetaSaveData(data);
|
||||
|
||||
// Retorna a resposta do salvamento
|
||||
return response;
|
||||
}
|
||||
|
||||
// Exporta o serviço de salvamento de serviço etiqueta já encapsulado com tratamento de erros
|
||||
export const TServicoEtiquetaSaveService = withClientErrorHandler(executeTServicoEtiquetaSaveService);
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
import { withClientErrorHandler } from '@/shared/actions/withClientErrorHandler/withClientErrorHandler';
|
||||
// Função que envolve qualquer ação assíncrona para capturar e tratar erros do cliente
|
||||
|
||||
import { TServicoEtiquetaReadData } from '../../_data/TServicoEtiqueta/TServicoEtiquetaReadData';
|
||||
|
||||
import { TServicoEtiquetaInterface } from '../../_interfaces/TServicoEtiquetaInterface';
|
||||
// Interface tipada do tipo de serviço
|
||||
|
||||
// Função assíncrona que executa a consulta de um tipo de serviço etiqueta
|
||||
async function executeTServicoEtiquetaServicoIdService(data: TServicoEtiquetaInterface) {
|
||||
|
||||
// Chama a função que consulta os dados do tipo de serviço etiqueta
|
||||
const response = await TServicoEtiquetaReadData(data);
|
||||
|
||||
// Retorna a resposta da remoção
|
||||
return response;
|
||||
}
|
||||
|
||||
// Exporta o serviço de remoção de tipo de serviço já encapsulado com tratamento de erros
|
||||
export const TServicoEtiquetaServicoIdService = withClientErrorHandler(executeTServicoEtiquetaServicoIdService);
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
import { withClientErrorHandler } from '@/shared/actions/withClientErrorHandler/withClientErrorHandler';
|
||||
// Função que envolve qualquer ação assíncrona para capturar e tratar erros do cliente
|
||||
|
||||
import { TServicoTipoEditData } from '../../_data/TServicoTipo/TServicoTipoEditData';
|
||||
// Função que remove os dados do tipo de serviço via API
|
||||
|
||||
import TServicoTipoInterface from '../../_interfaces/TServicoTipoInterface';
|
||||
// Interface tipada do tipo de serviço
|
||||
|
||||
// Função assíncrona que executa a remoção de um tipo de serviço
|
||||
async function executeTServicoTipoEditService(data: TServicoTipoInterface) {
|
||||
// Chama a função que remove os dados do tipo de serviço
|
||||
const response = await TServicoTipoEditData(data);
|
||||
|
||||
// Retorna a resposta da remoção
|
||||
return response;
|
||||
}
|
||||
|
||||
// Exporta o serviço de remoção de tipo de serviço já encapsulado com tratamento de erros
|
||||
export const TServicoTipoEditService = withClientErrorHandler(executeTServicoTipoEditService);
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
// Importa o utilitário responsável por lidar com erros de forma padronizada no cliente
|
||||
import { withClientErrorHandler } from '@/shared/actions/withClientErrorHandler/withClientErrorHandler';
|
||||
|
||||
// Importa a função que realiza a requisição de listagem dos tipos de marcação
|
||||
import { TTBReconhecimentoTipoIndexData } from '../../_data/TTBReconhecimentoTipo/TTBReconhecimentoTipoIndexData';
|
||||
import { TTBReconhecimentoTipoReadInterface } from '../../_interfaces/TTBReconhecimentoTipoReadInterface';
|
||||
|
||||
// Função assíncrona responsável por executar o serviço de listagem de tipos de marcação
|
||||
async function executeTTBReconhecimentoTipoIndexService(data: TTBReconhecimentoTipoReadInterface) {
|
||||
// Chama a função que realiza a requisição à API e aguarda a resposta
|
||||
const response = await TTBReconhecimentoTipoIndexData(data);
|
||||
|
||||
// Retorna a resposta obtida da requisição
|
||||
return response;
|
||||
}
|
||||
|
||||
// Exporta o serviço encapsulado pelo handler de erro, garantindo tratamento uniforme em caso de falhas
|
||||
export const TTBReconhecimentoTipoIndexService = withClientErrorHandler(
|
||||
executeTTBReconhecimentoTipoIndexService,
|
||||
);
|
||||
|
|
@ -51,12 +51,10 @@ export default function CCaixaServicoSelect({ sistema_id, field }: any) {
|
|||
className="justify-between cursor-pointer"
|
||||
>
|
||||
{isLoading
|
||||
? "Carregando..."
|
||||
: field.value && typeof field.value === 'object' && field.value.value
|
||||
? GetCapitalize(field.value.value) // Exibe a descrição do objeto
|
||||
: field.value && typeof field.value !== 'object'
|
||||
? field.value // Se for um ID (valor antigo), exibe ele
|
||||
: "Selecione o serviço"}
|
||||
? "Carregando..."
|
||||
: selected
|
||||
? GetCapitalize(selected.descricao)
|
||||
: "Selecione o serviço"}
|
||||
<ChevronsUpDownIcon className="ml-2 h-4 w-4 shrink-0 opacity-50" />
|
||||
</Button>
|
||||
</FormControl>
|
||||
|
|
@ -75,10 +73,7 @@ export default function CCaixaServicoSelect({ sistema_id, field }: any) {
|
|||
key={item.caixa_servico_id}
|
||||
value={item.descricao?.toLowerCase() ?? ""}
|
||||
onSelect={() => {
|
||||
field.onChange({
|
||||
key: Number(item.caixa_servico_id),
|
||||
value: item.descricao,
|
||||
});
|
||||
field.onChange(Number(item.caixa_servico_id)); // envia apenas o número
|
||||
setOpen(false);
|
||||
}}
|
||||
>
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ export default function GEmolumentoSelect({ sistema_id, field, onSelectChange, c
|
|||
|
||||
// Obtém o item selecionado com base no valor atual do campo
|
||||
const selected = gEmolumento?.find(
|
||||
(item) => String(item.emolumento_id) === String(field.value?.key ?? field.value)
|
||||
(item) => Number(item.emolumento_id) === Number(field.value ?? 0)
|
||||
);
|
||||
|
||||
|
||||
|
|
@ -112,6 +112,7 @@ export default function GEmolumentoSelect({ sistema_id, field, onSelectChange, c
|
|||
className="cursor-pointer w-full"
|
||||
key={item.emolumento_id}
|
||||
value={item.descricao?.toLowerCase() ?? ""}
|
||||
|
||||
// Quando o item é selecionado
|
||||
onSelect={() => {
|
||||
// Cria objeto com ID e descrição
|
||||
|
|
@ -120,15 +121,20 @@ export default function GEmolumentoSelect({ sistema_id, field, onSelectChange, c
|
|||
value: item.descricao,
|
||||
};
|
||||
|
||||
// Atualiza o valor no react-hook-form
|
||||
field.onChange(selectedValue);
|
||||
// Atualiza o valor no react-hook-form com o ID numérico
|
||||
field.onChange(Number(item.emolumento_id ?? 0));
|
||||
|
||||
// Dispara callback externo, se existir (ex: fetchGEmolumentoItem)
|
||||
if (onSelectChange) onSelectChange(selectedValue);
|
||||
// Dispara callback externo, se existir (mantém o objeto completo)
|
||||
if (onSelectChange)
|
||||
onSelectChange({
|
||||
key: Number(item.emolumento_id),
|
||||
value: item.descricao,
|
||||
});
|
||||
|
||||
// Fecha o popover
|
||||
setOpen(false);
|
||||
}}
|
||||
|
||||
>
|
||||
{/* Ícone de seleção (check) */}
|
||||
<CheckIcon
|
||||
|
|
|
|||
|
|
@ -0,0 +1,95 @@
|
|||
'use client';
|
||||
|
||||
import React from "react";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import {
|
||||
Command,
|
||||
CommandEmpty,
|
||||
CommandGroup,
|
||||
CommandInput,
|
||||
CommandItem,
|
||||
CommandList,
|
||||
} from "@/components/ui/command";
|
||||
import { FormControl } from "@/components/ui/form";
|
||||
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { CheckIcon, ChevronsUpDownIcon } from "lucide-react";
|
||||
import GetCapitalize from "@/shared/actions/text/GetCapitalize";
|
||||
import { useTTBReconhecimentoTipoReadHook } from "@/app/(protected)/(cadastros)/cadastros/_hooks/t_tb_reconhecimentotipo/useTTBReconhecimentoTipoReadHook";
|
||||
import { TTBREconhecimentoTipoReadInterface } from "@/app/(protected)/(cadastros)/cadastros/_interfaces/TTBREconhecimentoTipoReadInterface";
|
||||
|
||||
export default function TTBReconhecimentoTipoSelect({ field }: any) {
|
||||
|
||||
const [open, setOpen] = React.useState(false);
|
||||
const [isLoading, setIsLoading] = React.useState(false);
|
||||
const { tTBReconhecimentoTipo, fetchTTBReconhecimentoTipo } = useTTBReconhecimentoTipoReadHook();
|
||||
// Busca os dados uma única vez ao montar
|
||||
React.useEffect(() => {
|
||||
const loadData = async () => {
|
||||
if (!tTBReconhecimentoTipo.length) {
|
||||
setIsLoading(true);
|
||||
await fetchTTBReconhecimentoTipo();
|
||||
setIsLoading(false);
|
||||
}
|
||||
};
|
||||
loadData();
|
||||
}, []);
|
||||
const selected = tTBReconhecimentoTipo?.find(
|
||||
(item) => Number(item.tb_reconhecimentotipo_id) === Number(field.value)
|
||||
);
|
||||
return (
|
||||
<Popover open={open} onOpenChange={setOpen}>
|
||||
<PopoverTrigger asChild>
|
||||
<FormControl className="w-full">
|
||||
<Button
|
||||
variant="outline"
|
||||
role="combobox"
|
||||
aria-expanded={open}
|
||||
disabled={isLoading}
|
||||
className="justify-between cursor-pointer"
|
||||
>
|
||||
{isLoading
|
||||
? "Carregando..."
|
||||
: selected
|
||||
? GetCapitalize(selected.descricao)
|
||||
: "Selecione o serviço"}
|
||||
<ChevronsUpDownIcon className="ml-2 h-4 w-4 shrink-0 opacity-50" />
|
||||
</Button>
|
||||
</FormControl>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent className="w-full p-0">
|
||||
<Command>
|
||||
<CommandInput placeholder="Buscar etiquetas/carimbos..." />
|
||||
<CommandList>
|
||||
<CommandEmpty>
|
||||
{isLoading ? "Carregando..." : "Nenhum resultado encontrado."}
|
||||
</CommandEmpty>
|
||||
<CommandGroup>
|
||||
{tTBReconhecimentoTipo?.map((item) => (
|
||||
<CommandItem
|
||||
className="cursor-pointer"
|
||||
key={item.tb_reconhecimentotipo_id}
|
||||
value={item.descricao?.toLowerCase() ?? ""}
|
||||
onSelect={() => {
|
||||
field.onChange(Number(item.tb_reconhecimentotipo_id)); // envia apenas o número
|
||||
setOpen(false);
|
||||
}}
|
||||
>
|
||||
<CheckIcon
|
||||
className={cn(
|
||||
"mr-2 h-4 w-4",
|
||||
String(field.value) === String(item.tb_reconhecimentotipo_id)
|
||||
? "opacity-100"
|
||||
: "opacity-0"
|
||||
)}
|
||||
/>
|
||||
{GetCapitalize(item.descricao)}
|
||||
</CommandItem>
|
||||
))}
|
||||
</CommandGroup>
|
||||
</CommandList>
|
||||
</Command>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
);
|
||||
}
|
||||
28
src/shared/components/confirmacao/ConfirmacaoCheckBox.tsx
Normal file
28
src/shared/components/confirmacao/ConfirmacaoCheckBox.tsx
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
import { FormControl, FormField, FormItem, FormLabel } from "@/components/ui/form";
|
||||
import { Checkbox } from "@/components/ui/checkbox";
|
||||
|
||||
interface ConfirmacaoCheckBoxProps {
|
||||
name: string;
|
||||
label: string;
|
||||
control: any;
|
||||
}
|
||||
|
||||
export function ConfirmacaoCheckBox({ name, label, control }: ConfirmacaoCheckBoxProps) {
|
||||
return (
|
||||
<FormField
|
||||
control={control}
|
||||
name={name}
|
||||
render={({ field }) => (
|
||||
<FormItem className="flex flex-row items-center space-x-3 space-y-0">
|
||||
<FormControl>
|
||||
<Checkbox
|
||||
checked={field.value === "S"}
|
||||
onCheckedChange={(checked) => field.onChange(checked ? "S" : "N")}
|
||||
/>
|
||||
</FormControl>
|
||||
<FormLabel className="font-normal cursor-pointer">{label}</FormLabel>
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
@ -31,16 +31,16 @@ export default function ConfirmacaoSelect({ field }: any) {
|
|||
variant="outline"
|
||||
role="combobox"
|
||||
aria-expanded={open}
|
||||
className="justify-between"
|
||||
className="justify-between cursor-pointer"
|
||||
>
|
||||
{field.value
|
||||
? options.find((item) => item.value === field.value)?.label
|
||||
: 'Selecione...'}
|
||||
<ChevronsUpDownIcon className="ml-2 h-4 w-4 shrink-0 opacity-50" />
|
||||
<ChevronsUpDownIcon className="ml-2 h-4 w-4 shrink-0 opacity-50 cursor-pointer" />
|
||||
</Button>
|
||||
</FormControl>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent className="w-full p-0">
|
||||
<PopoverContent className="w-full p-0 cursor-pointer">
|
||||
<Command>
|
||||
<CommandInput placeholder="Buscar situação..." />
|
||||
<CommandList>
|
||||
|
|
@ -48,6 +48,7 @@ export default function ConfirmacaoSelect({ field }: any) {
|
|||
<CommandGroup>
|
||||
{options.map((item) => (
|
||||
<CommandItem
|
||||
className="cursor-pointer"
|
||||
key={item.value}
|
||||
value={item.label.toLowerCase()}
|
||||
onSelect={() => {
|
||||
|
|
@ -57,7 +58,7 @@ export default function ConfirmacaoSelect({ field }: any) {
|
|||
>
|
||||
<CheckIcon
|
||||
className={cn(
|
||||
'mr-2 h-4 w-4',
|
||||
'mr-2 h-4 w-4 cursor-pointer',
|
||||
field.value === item.value ? 'opacity-100' : 'opacity-0',
|
||||
)}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,68 @@
|
|||
"use client";
|
||||
|
||||
import React from "react";
|
||||
import { Control, FieldValues, Path } from "react-hook-form";
|
||||
import {
|
||||
FormField,
|
||||
FormItem,
|
||||
FormLabel,
|
||||
FormControl,
|
||||
FormMessage,
|
||||
} from "@/components/ui/form";
|
||||
import { Input } from "@/components/ui/input";
|
||||
|
||||
interface NumericInputFieldProps<T extends FieldValues> {
|
||||
control: Control<T>;
|
||||
name: Path<T>;
|
||||
label?: string;
|
||||
placeholder?: string;
|
||||
disabled?: boolean;
|
||||
min?: number;
|
||||
max?: number;
|
||||
}
|
||||
|
||||
export function NumericInputField<T extends FieldValues>({
|
||||
control,
|
||||
name,
|
||||
label = "Número",
|
||||
placeholder = "Digite um número",
|
||||
disabled = false,
|
||||
min,
|
||||
max,
|
||||
}: NumericInputFieldProps<T>) {
|
||||
return (
|
||||
<FormField
|
||||
control={control}
|
||||
name={name}
|
||||
render={({ field }) => (
|
||||
<FormItem className="w-full">
|
||||
{label && <FormLabel>{label}</FormLabel>}
|
||||
|
||||
<FormControl>
|
||||
<Input
|
||||
{...field}
|
||||
type="text"
|
||||
disabled={disabled}
|
||||
value={field.value ?? ""}
|
||||
placeholder={placeholder}
|
||||
inputMode="numeric"
|
||||
pattern="[0-9]*"
|
||||
onChange={(e) => {
|
||||
// Mantém apenas números
|
||||
let value = e.target.value.replace(/[^0-9]/g, "");
|
||||
|
||||
// Limita faixa, se definido
|
||||
if (min !== undefined && Number(value) < min) value = String(min);
|
||||
if (max !== undefined && Number(value) > max) value = String(max);
|
||||
|
||||
field.onChange(value);
|
||||
}}
|
||||
/>
|
||||
</FormControl>
|
||||
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
66
src/shared/components/tipoPessoa/tipoPessoaSelect.tsx
Normal file
66
src/shared/components/tipoPessoa/tipoPessoaSelect.tsx
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
"use client";
|
||||
|
||||
import React from "react";
|
||||
import { Control, FieldValues, Path } from "react-hook-form";
|
||||
import {
|
||||
FormField,
|
||||
FormItem,
|
||||
FormLabel,
|
||||
FormControl,
|
||||
FormMessage,
|
||||
} from "@/components/ui/form";
|
||||
import {
|
||||
Select,
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
SelectContent,
|
||||
SelectItem,
|
||||
} from "@/components/ui/select";
|
||||
|
||||
interface PessoaTipoSelectProps<T extends FieldValues> {
|
||||
control: Control<T>;
|
||||
name: Path<T>;
|
||||
label?: string;
|
||||
disabled?: boolean;
|
||||
placeholder?: string;
|
||||
}
|
||||
|
||||
export function TipoPessoaSelect<T extends FieldValues>({
|
||||
control,
|
||||
name,
|
||||
label = "Pessoa",
|
||||
disabled = false,
|
||||
placeholder = "Selecione uma opção",
|
||||
}: PessoaTipoSelectProps<T>) {
|
||||
return (
|
||||
<FormField
|
||||
control={control}
|
||||
name={name}
|
||||
render={({ field }) => (
|
||||
<FormItem className="w-full">
|
||||
{label && <FormLabel>{label}</FormLabel>}
|
||||
<Select
|
||||
value={field.value}
|
||||
onValueChange={field.onChange}
|
||||
disabled={disabled}
|
||||
>
|
||||
<FormControl className="w-full">
|
||||
<SelectTrigger className="w-full cursor-pointer">
|
||||
<SelectValue placeholder={placeholder} />
|
||||
</SelectTrigger>
|
||||
</FormControl>
|
||||
<SelectContent>
|
||||
<SelectItem value="F" className="cursor-pointer">
|
||||
Física
|
||||
</SelectItem>
|
||||
<SelectItem value="J" className="cursor-pointer">
|
||||
Jurídica
|
||||
</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue