Merge remote-tracking branch 'origin/release(MVP)' into MVPTN-86

This commit is contained in:
Kenio 2025-10-20 09:24:00 -03:00
commit 77ea800aaa
518 changed files with 8933 additions and 4247 deletions

View file

@ -1,33 +0,0 @@
// .eslintrc.json
{
"extends": [
// 1. Configurações base do Next/React
"next/core-web-vitals",
// 2. Regras para ordenar e gerenciar importações
"plugin:import/recommended",
// 3. DESATIVA as regras do ESLint que conflitam com o Prettier (DEVE SER O ÚLTIMO)
"prettier"
],
"plugins": ["import"],
"rules": {
/* --- Qualidade do Código (Next.js/React) --- */
// Essa regra (já incluída no Next.js, mas bom reforçar) é a que remove imports não usados
"no-unused-vars": "error",
"react/jsx-uses-vars": "error",
/* --- Ordem e Remoção de Importações (eslint-plugin-import) --- */
// Configura a regra para a ordem das importações (groups/grupos)
"import/order": [
"error",
{
"groups": ["builtin", "external", "internal", "parent", "sibling", "index"],
"newlines-between": "always",
"alphabetize": {
"order": "asc",
"caseInsensitive": true
}
}
],
// Garante que o Next.js reconheça imports (como 'next/image', 'next/link')
"import/no-unresolved": "error"
}
}

View file

@ -1,23 +0,0 @@
import next from 'eslint-config-next';
import importPlugin from 'eslint-plugin-import';
export default [
next,
{
plugins: {
import: importPlugin,
},
rules: {
'import/order': [
'error',
{
groups: ['builtin', 'external', 'internal', ['parent', 'sibling', 'index']],
'newlines-between': 'always',
alphabetize: { order: 'asc', caseInsensitive: true },
},
],
semi: ['error', 'always'],
quotes: ['error', 'double'],
},
},
];

74
eslint.config.mjs Normal file
View file

@ -0,0 +1,74 @@
import js from "@eslint/js";
import reactPlugin from "eslint-plugin-react";
import reactHooks from "eslint-plugin-react-hooks";
import jsxA11y from "eslint-plugin-jsx-a11y";
import importPlugin from "eslint-plugin-import";
import tseslint from "typescript-eslint";
export default [
js.configs.recommended,
...tseslint.configs.recommended,
{
files: ["**/*.ts", "**/*.tsx"],
ignores: ["node_modules/**", ".next/**", "out/**", "dist/**"],
languageOptions: {
ecmaVersion: "latest",
sourceType: "module",
parser: tseslint.parser,
parserOptions: {
project: "./tsconfig.json",
},
globals: {
React: true,
JSX: true,
},
},
plugins: {
react: reactPlugin,
"react-hooks": reactHooks,
"jsx-a11y": jsxA11y,
import: importPlugin,
},
settings: {
react: { version: "detect" },
"import/resolver": {
typescript: {
alwaysTryTypes: true,
project: "./tsconfig.json",
},
node: {
extensions: [".js", ".jsx", ".ts", ".tsx"],
},
},
},
rules: {
"react/react-in-jsx-scope": "off",
"react/jsx-uses-react": "off",
"react/jsx-uses-vars": "warn",
"react-hooks/rules-of-hooks": "error",
"react-hooks/exhaustive-deps": "warn",
"import/order": [
"error",
{
groups: [
["builtin", "external"],
["internal"],
["parent", "sibling", "index"],
],
pathGroups: [
{
pattern: "@/**",
group: "internal",
position: "after",
},
],
alphabetize: { order: "asc", caseInsensitive: true },
"newlines-between": "always",
},
],
"import/no-duplicates": "error",
"import/newline-after-import": ["error", { count: 1 }],
"no-unused-vars": "warn",
},
},
];

View file

@ -3,6 +3,10 @@ import type { NextConfig } from 'next';
const nextConfig: NextConfig = {
// Isso gera um diretório otimizado que inclui tudo o que a aplicação precisa para rodar
output: 'standalone',
eslint: {
// Desativa a verificação de lint durante o build
ignoreDuringBuilds: true,
},
};
export default nextConfig;

1809
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -23,6 +23,7 @@
"@radix-ui/react-select": "^2.2.6",
"@radix-ui/react-separator": "^1.1.7",
"@radix-ui/react-slot": "^1.2.3",
"@radix-ui/react-switch": "^1.2.6",
"@radix-ui/react-tabs": "^1.1.13",
"@radix-ui/react-tooltip": "^1.2.8",
"@tanstack/react-table": "^8.21.3",
@ -49,25 +50,28 @@
"zod": "^4.0.17"
},
"devDependencies": {
"@rushstack/eslint-patch": "^1.12.0",
"@tailwindcss/postcss": "^4",
"@types/js-cookie": "^3.0.6",
"@types/jsonwebtoken": "^9.0.10",
"@types/node": "^20",
"@types/react": "^19",
"@types/react-dom": "^19",
"@typescript-eslint/eslint-plugin": "^8.45.0",
"@typescript-eslint/parser": "^8.45.0",
"eslint": "^8.57.1",
"eslint-config-next": "^15.5.4",
"@typescript-eslint/eslint-plugin": "^8.46.1",
"@typescript-eslint/parser": "^8.46.1",
"eslint": "^9.38.0",
"eslint-config-prettier": "^10.1.8",
"eslint-import-resolver-typescript": "^4.4.4",
"eslint-plugin-import": "^2.32.0",
"eslint-plugin-jsx-a11y": "^6.10.2",
"eslint-plugin-prettier": "^5.5.4",
"eslint-plugin-react": "^7.37.5",
"eslint-plugin-react-hooks": "^7.0.0",
"eslint-plugin-unused-imports": "^4.2.0",
"prettier": "^3.6.2",
"prettier-plugin-tailwindcss": "^0.6.14",
"tailwindcss": "^4",
"tw-animate-css": "^1.3.7",
"typescript": "^5"
"typescript": "5.9.3",
"typescript-eslint": "^8.46.1"
}
}
}

View file

@ -4,8 +4,8 @@ import { useEffect } from 'react';
import { useParams } from 'next/navigation';
import { Card, CardContent } from '@/components/ui/card';
import { useGUsuarioReadHooks } from '@/app/(protected)/(administrativo)/_hooks/g_usuario/useGUsuarioReadHooks';
import Usuario from '@/app/(protected)/(administrativo)/_interfaces/GUsuarioInterface';
import { useGUsuarioReadHooks } from '@/packages/administrativo/hooks/GUsuario/useGUsuarioReadHooks';
import Usuario from '@/packages/administrativo/interfaces/GUsuario/GUsuarioInterface';
import Loading from '@/shared/components/loading/loading';
export default function UsuarioDetalhes() {

View file

@ -4,7 +4,7 @@ import { zodResolver } from '@hookform/resolvers/zod';
import { useForm } from 'react-hook-form';
import { z } from 'zod';
import { Input } from '@/components/ui/input';
import { GUsuarioSchema } from '../../../_schemas/GUsuarioSchema';
import { GUsuarioSchema } from '../../../../../../packages/administrativo/schemas/GUsuario/GUsuarioSchema';
import { Button } from '@/components/ui/button';
@ -19,7 +19,7 @@ import {
FormMessage,
} from '@/components/ui/form';
import { useGUsuarioSaveHook } from '../../../_hooks/g_usuario/useGUsuarioSaveHook';
import { useGUsuarioSaveHook } from '../../../../../../packages/administrativo/hooks/GUsuario/useGUsuarioSaveHook';
type FormValues = z.infer<typeof GUsuarioSchema>;

View file

@ -11,10 +11,10 @@ import {
TableRow,
} from '@/components/ui/table';
import Usuario from '../../_interfaces/GUsuarioInterface';
import Usuario from '../../../../../packages/administrativo/interfaces/GUsuario/GUsuarioInterface';
import { Button } from '@/components/ui/button';
import Link from 'next/link';
import { useGUsuarioIndexHook } from '../../_hooks/g_usuario/useGUsuarioIndexHook';
import { useGUsuarioIndexHook } from '../../../../../packages/administrativo/hooks/GUsuario/useGUsuarioIndexHook';
import { useEffect } from 'react';
import Loading from '@/shared/components/loading/loading';

View file

@ -0,0 +1,9 @@
import TTBAndamentoServicoIndex from "@/packages/administrativo/components/TTBAndamentoServico/TTBAndamentoServicoIndex";
export default function TAtoParteTipo() {
return (
< TTBAndamentoServicoIndex />
);
}

View file

@ -0,0 +1,9 @@
import TAtoParteTipoIndex from "@/packages/administrativo/components/TAtoParteTipo/TAtoParteTipoIndex";
export default function TAtoParteTipo() {
return (
< TAtoParteTipoIndex />
);
}

View file

@ -0,0 +1,9 @@
'use client';
import GTBBairroIndex from "@/packages/administrativo/components/GTBBairro/GTBBairroIndex";
export default function GCidadePage() {
return (
< GTBBairroIndex />
);
}

View file

@ -0,0 +1,9 @@
'use client';
import TCensecTipoNaturezaIndex from "@/packages/administrativo/components/TCensecTipoNatureza/TCensecTipoNaturezaIndex";
export default function TCensecTipoNaturezaPage() {
return (
< TCensecTipoNaturezaIndex />
);
}

View file

@ -0,0 +1,9 @@
'use client';
import TCensecQualidadeIndex from "@/packages/administrativo/components/TCensecQualidade/TCensecQualidadeIndex";
export default function TCensecQualidadePage() {
return (
< TCensecQualidadeIndex />
);
}

View file

@ -0,0 +1,9 @@
'use client';
import TCensecIndex from "@/packages/administrativo/components/TCensec/TCensecIndex";
export default function GTBEstadoCivilPage() {
return (
< TCensecIndex />
);
}

View file

@ -0,0 +1,9 @@
'use client';
import TCensecNaturezaLitigioIndex from "@/packages/administrativo/components/TCensecNaturezaLitigio/TCensecNaturezaLitigioIndex";
export default function GCidadePage() {
return (
< TCensecNaturezaLitigioIndex />
);
}

View file

@ -0,0 +1,9 @@
'use client';
import TCensecQualidadeIndex from "@/packages/administrativo/components/TCensecQualidade/TCensecQualidadeIndex";
export default function GTBEstadoCivilPage() {
return (
< TCensecQualidadeIndex />
);
}

View file

@ -0,0 +1,9 @@
'use client';
import TCensecTipoAtoIndex from "@/packages/administrativo/components/TCensecTipoAto/TCensecTipoAtoIndex";
export default function GTBEstadoCivilPage() {
return (
< TCensecTipoAtoIndex />
);
}

View file

@ -0,0 +1,9 @@
'use client';
import GCidadeIndex from "@/packages/administrativo/components/GCidade/GCidadeIndex";
export default function GCidadePage() {
return (
< GCidadeIndex />
);
}

View file

@ -0,0 +1,9 @@
'use client';
import GTBTipoLogradouroIndex from "@/packages/administrativo/components/GTBTipoLogradouro/GTBTipoLogradouroIndex";
export default function GMedidaTipoPage() {
return (
< GTBTipoLogradouroIndex />
);
}

View file

@ -0,0 +1,9 @@
'use client';
import GMedidaTipoIndex from "@/packages/administrativo/components/GMedidaTipo/GMedidaTipoIndex";
export default function GMedidaTipoPage() {
return (
< GMedidaTipoIndex />
);
}

View file

@ -0,0 +1,11 @@
import GNaturezaIndex from "@/packages/administrativo/components/GNatureza/GNaturezaIndex";
export default function GNaturezaPage() {
return (
<GNaturezaIndex
sistema_id={2}
/>
);
}

View file

@ -0,0 +1,9 @@
'use client';
import GTBEstadoCivilIndex from "@/packages/administrativo/components/GTBEstadoCivil/GTBEstadoCivilIndex";
export default function GTBEstadoCivilPage() {
return (
< GTBEstadoCivilIndex />
);
}

View file

@ -0,0 +1,9 @@
'use client';
import GTBProfissaoIndex from "@/packages/administrativo/components/GTBProfissao/GTBProfissaoIndex";
export default function GTBEstadoCivilPage() {
return (
< GTBProfissaoIndex />
);
}

View file

@ -0,0 +1,9 @@
'use client';
import GTBRegimeBensIndex from "@/packages/administrativo/components/GTBRegimeBens/GTBRegimeBensIndex";
export default function GTBRegimeBensPage() {
return (
< GTBRegimeBensIndex />
);
}

View file

@ -0,0 +1,9 @@
'use client';
import GTBRegimeComunhaoIndex from "@/packages/administrativo/components/GTBRegimeComunhao/GTBRegimeComunhaoIndex";
export default function GTBRegimeBensPage() {
return (
< GTBRegimeComunhaoIndex />
);
}

View file

@ -0,0 +1,9 @@
import TTBReconhecimentoTipoIndex from "@/packages/administrativo/components/TTBReconhecimentoTipo/TTBReconhecimentoTipoIndex";
export default function TAtoParteTipo() {
return (
< TTBReconhecimentoTipoIndex />
);
}

View file

@ -7,8 +7,8 @@ import { Card, CardContent } from '@/components/ui/card';
import MainEditor from '@/components/MainEditor';
import Loading from '@/shared/components/loading/loading';
import { useTMinutaReadHook } from '../../../../_hooks/t_minuta/useTMinutaReadHook';
import { TMinutaInterface } from '../../../../_interfaces/TMinutaInterface';
import { useTMinutaReadHook } from '@/packages/administrativo/hooks/TMinuta/useTMinutaReadHook';
import { TMinutaInterface } from '@/packages/administrativo/interfaces/TMinuta/TMinutaInterface';
export default function TMinutaDetalhes() {
const params = useParams();

View file

@ -19,8 +19,8 @@ import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import MainEditor from '@/components/MainEditor';
import { TMinutaSchema } from '../../../_schemas/TMinutaSchema';
import { useTMinutaSaveHook } from '../../../_hooks/t_minuta/useTMinutaSaveHook';
import { TMinutaSchema } from '@/packages/administrativo/schemas/TMinuta/TMinutaSchema';
import { useTMinutaSaveHook } from '@/packages/administrativo/hooks/TMinuta/useTMinutaSaveHook';
import { Card, CardContent } from '@/components/ui/card';
type FormValues = z.infer<typeof TMinutaSchema>;

View file

@ -8,15 +8,15 @@ import Header from '@/shared/components/structure/Header';
import ConfirmDialog from '@/shared/components/confirmDialog/ConfirmDialog';
import Loading from '@/shared/components/loading/loading';
import TMinutaTable from '../../_components/t_minuta/TMinutaTable';
import TMinutaForm from '../../_components/t_minuta/TMinutaForm';
import TMinutaTable from '@/packages/administrativo/components/TMinuta/TMinutaTable';
import TMinutaForm from '@/packages/administrativo/components/TMinuta/TMinutaForm';
import { useTMinutaReadHook } from '../../_hooks/t_minuta/useTMinutaReadHook';
import { useTMinutaSaveHook } from '../../_hooks/t_minuta/useTMinutaSaveHook';
import { useTMinutaRemoveHook } from '../../_hooks/t_minuta/useTMinutaRemoveHook';
import { useTMinutaReadHook } from '@/packages/administrativo/hooks/TMinuta/useTMinutaReadHook';
import { useTMinutaSaveHook } from '@/packages/administrativo/hooks/TMinuta/useTMinutaSaveHook';
import { useTMinutaRemoveHook } from '@/packages/administrativo/hooks/TMinuta/useTMinutaRemoveHook';
import { TMinutaInterface } from '../../_interfaces/TMinutaInterface';
import { useTMinutaIndexHook } from '../../_hooks/t_minuta/useTMinutaIndexHook';
import { TMinutaInterface } from '@/packages/administrativo/interfaces/TMinuta/TMinutaInterface';
import { useTMinutaIndexHook } from '@/packages/administrativo/hooks/TMinuta/useTMinutaIndexHook';
export default function TMinutaPage() {
// Hooks de leitura e escrita

View file

@ -1,226 +0,0 @@
'use client';
import z from "zod";
import { useEffect } from "react";
import { useForm, Controller } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { Checkbox } from "@/components/ui/checkbox";
import LoadingButton from "@/shared/components/loadingButton/LoadingButton";
import { Button } from "@/components/ui/button";
import {
Dialog,
DialogClose,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle
} from "@/components/ui/dialog";
import {
Form,
FormControl,
FormField,
FormItem,
FormLabel,
FormMessage,
} from "@/components/ui/form";
import { Input } from "@/components/ui/input";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Label } from "@/components/ui/label";
import { TCensecTipoAtoSchema } from "../../_schemas/TCensecTipoAtoSchema";
import { TCensecTipoAtoInterface } from "../../_interfaces/TCensecTipoAtoInterface";
import TCensecInterface from "../../_interfaces/TCensecInterface";
import { SituacoesEnum } from "@/shared/enums/SituacoesEnum";
type FormValues = z.infer<typeof TCensecTipoAtoSchema>;
interface TCensecTipoAtoFormProps {
isOpen: boolean;
data: FormValues | null;
tCensec: TCensecInterface[];
onClose: (item: null, isFormStatus: boolean) => void;
onSave: (data: FormValues) => void;
buttonIsLoading: boolean;
}
export default function TCensecTipoAtoForm({
isOpen,
data,
tCensec,
onClose,
onSave,
buttonIsLoading
}: TCensecTipoAtoFormProps) {
// react-hook-form com schema Zod
const form = useForm<FormValues>({
resolver: zodResolver(TCensecTipoAtoSchema),
defaultValues: {
censec_tipoato_id: 0,
censec_id: 0,
codigo: null,
descricao: "",
situacao: SituacoesEnum.A,
tipo_separacao: null,
tipo_revogacao: null,
},
});
// Atualiza o formulário se houver dados para edição
useEffect(() => {
if (data) form.reset(data);
}, [data, form]);
return (
<Dialog
open={isOpen}
onOpenChange={(open) => {
if (!open) onClose(null, false);
}}
>
<DialogContent className="sm:max-w-[500px]">
<DialogHeader>
<DialogTitle>Tipo de Ato CENSEC</DialogTitle>
<DialogDescription>
Crie ou edite um tipo de ato da CENSEC
</DialogDescription>
</DialogHeader>
<Form {...form}>
<form onSubmit={form.handleSubmit(onSave)} className="space-y-6">
{/* Descrição */}
<FormField
control={form.control}
name="descricao"
render={({ field }) => (
<FormItem>
<FormLabel>Descrição</FormLabel>
<FormControl>
<Input {...field} placeholder="Digite a descrição" />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
{/* Select Censec */}
<FormField
control={form.control}
name="censec_id"
render={({ field }) => (
<FormItem>
<FormLabel>Central do Censec</FormLabel>
<Select
value={field.value?.toString()}
onValueChange={(val) => field.onChange(Number(val))}
>
<FormControl>
<SelectTrigger className="w-full">
<SelectValue placeholder="Selecione um Censec" />
</SelectTrigger>
</FormControl>
<SelectContent className="w-full">
{tCensec.map((c) => (
<SelectItem key={c.censec_id} value={String(c.censec_id)}>
{c.descricao}
</SelectItem>
))}
</SelectContent>
</Select>
<FormMessage />
</FormItem>
)}
/>
{/* Situação */}
<Controller
name="situacao"
control={form.control}
render={({ field }) => (
<div className="flex items-center space-x-2">
<Checkbox
checked={field.value === "A"}
onCheckedChange={(checked) => field.onChange(checked ? "A" : "I")}
/>
<Label>Ativo</Label>
</div>
)}
/>
{/* Tipo de Separação */}
<FormField
control={form.control}
name="tipo_separacao"
render={({ field }) => (
<FormItem>
<FormLabel>Tipo de Separação</FormLabel>
<Select
onValueChange={(val) => field.onChange(val || null)}
value={field.value ?? ""}
>
<FormControl>
<SelectTrigger className="w-full">
<SelectValue placeholder="Selecione" />
</SelectTrigger>
</FormControl>
<SelectContent className="w-full">
<SelectItem value="S">Sim</SelectItem>
<SelectItem value="N">Não</SelectItem>
</SelectContent>
</Select>
<FormMessage />
</FormItem>
)}
/>
{/* Tipo de Revogação */}
<FormField
control={form.control}
name="tipo_revogacao"
render={({ field }) => (
<FormItem>
<FormLabel>Tipo de Revogação</FormLabel>
<Select
onValueChange={(val) => field.onChange(val || null)}
value={field.value ?? ""}
>
<FormControl>
<SelectTrigger className="w-full">
<SelectValue placeholder="Selecione" />
</SelectTrigger>
</FormControl>
<SelectContent className="w-full">
<SelectItem value="S">Sim</SelectItem>
<SelectItem value="N">Não</SelectItem>
</SelectContent>
</Select>
<FormMessage />
</FormItem>
)}
/>
{/* Rodapé */}
<DialogFooter className="mt-4">
<DialogClose asChild>
<Button
variant="outline"
type="button"
onClick={() => onClose(null, false)}
className="cursor-pointer"
>
Cancelar
</Button>
</DialogClose>
<LoadingButton text="Salvar" textLoading="Aguarde..." type="submit" loading={buttonIsLoading} />
</DialogFooter>
{/* Campos ocultos */}
<input type="hidden" {...form.register("censec_tipoato_id")} />
<input type="hidden" {...form.register("codigo")} />
</form>
</Form>
</DialogContent>
</Dialog>
);
}

View file

@ -1,127 +0,0 @@
'use client';
import { Button } from "@/components/ui/button";
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuGroup,
DropdownMenuItem,
DropdownMenuSeparator,
DropdownMenuTrigger
} from "@/components/ui/dropdown-menu";
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow
} from "@/components/ui/table";
import { EllipsisIcon, PencilIcon, Trash2Icon } from "lucide-react";
import { TCensecTipoAtoInterface } from "../../_interfaces/TCensecTipoAtoInterface";
import TCensecInterface from "../../_interfaces/TCensecInterface";
interface TCensecTipoAtoTableProps {
data: TCensecTipoAtoInterface[];
tCensec: TCensecInterface[];
onEdit: (item: TCensecTipoAtoInterface, isEditingFormStatus: boolean) => void;
onDelete: (item: TCensecTipoAtoInterface, isEditingFormStatus: boolean) => void;
}
function StatusBadge({ situacao }: { situacao: string }) {
const isActive = situacao === "A";
const baseClasses =
"text-xs font-medium px-2.5 py-0.5 rounded-sm me-2";
const activeClasses =
"bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-300";
const inactiveClasses =
"bg-yellow-100 text-yellow-800 dark:bg-yellow-900 dark:text-yellow-300";
return (
<span className={`${baseClasses} ${isActive ? activeClasses : inactiveClasses}`}>
{isActive ? "Ativo" : "Inativo"}
</span>
);
}
export default function TCensecTipoAtoTable({
data,
tCensec,
onEdit,
onDelete
}: TCensecTipoAtoTableProps) {
return (
<Table>
<TableHeader>
<TableRow>
<TableHead>#</TableHead>
<TableHead>Situação</TableHead>
<TableHead>Central do CENSEC</TableHead>
{/*<TableHead>Código</TableHead>*/}
<TableHead>Descrição</TableHead>
<TableHead>Separação</TableHead>
<TableHead>Revogação</TableHead>
<TableHead className="text-right">Ações</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{data.map((item) => {
const censecDesc = tCensec.find(c => c.censec_id === item.censec_id)?.descricao || "N/A"
return (
<TableRow key={item.censec_tipoato_id} className="cursor-pointer">
<TableCell className="font-medium">
{item.censec_tipoato_id}
</TableCell>
<TableCell>
<StatusBadge situacao={item.situacao} />
</TableCell>
<TableCell>{censecDesc}</TableCell>
{/*<TableCell>{item.codigo ?? "-"}</TableCell>*/}
<TableCell>{item.descricao}</TableCell>
<TableCell>{item.tipo_separacao ?? "-"}</TableCell>
<TableCell>{item.tipo_revogacao ?? "-"}</TableCell>
<TableCell className="text-right">
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button
variant="outline"
size="icon"
className="cursor-pointer"
>
<EllipsisIcon />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent side="left" align="start">
<DropdownMenuGroup>
<DropdownMenuItem
className="cursor-pointer"
onSelect={() => onEdit(item, true)}
>
<PencilIcon className="mr-2 h-4 w-4" />
Editar
</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem
className="cursor-pointer"
onSelect={() => onDelete(item, true)}
>
<Trash2Icon className="mr-2 h-4 w-4" />
Remover
</DropdownMenuItem>
</DropdownMenuGroup>
</DropdownMenuContent>
</DropdownMenu>
</TableCell>
</TableRow>
)})}
</TableBody>
</Table>
);
}

View file

@ -1,17 +0,0 @@
import API from "@/shared/services/api/Api";
import { Methods } from "@/shared/services/api/enums/ApiMethodEnum";
import TCensecTipoAtoMockDeDados from "./mockCensecTipoAto";
import { withClientErrorHandler } from "@/shared/actions/withClientErrorHandler/withClientErrorHandler";
const useMock = true
async function executeTCensecTipoAtoIndexData() {
const api = new API();
return await api.send({
method: Methods.GET,
endpoint: `administrativo/t_censec_tipoato/`
});
}
export const TCensecTipoAtoIndexData = withClientErrorHandler(executeTCensecTipoAtoIndexData)

View file

@ -1,17 +0,0 @@
import API from "@/shared/services/api/Api";
import { TCensecTipoAtoInterface } from "../../_interfaces/TCensecTipoAtoInterface";
import { Methods } from "@/shared/services/api/enums/ApiMethodEnum";
import { withClientErrorHandler } from "@/shared/actions/withClientErrorHandler/withClientErrorHandler";
async function executeTCensecTipoAtoRemoveData(data: TCensecTipoAtoInterface) {
const api = new API();
return await api.send({
method: Methods.DELETE,
endpoint: `administrativo/t_censec_tipoato/${data.censec_tipoato_id}`
});
}
export const TCensecTipoAtoRemoveData = withClientErrorHandler(executeTCensecTipoAtoRemoveData)

View file

@ -1,20 +0,0 @@
import API from "@/shared/services/api/Api";
import { TCensecTipoAtoInterface } from "../../_interfaces/TCensecTipoAtoInterface";
import { Methods } from "@/shared/services/api/enums/ApiMethodEnum";
import { withClientErrorHandler } from "@/shared/actions/withClientErrorHandler/withClientErrorHandler";
async function executeTCensecTipoAtoSaveData(data: TCensecTipoAtoInterface) {
const isUpdate = Boolean(data.censec_tipoato_id);
const api = new API();
return await api.send({
method: isUpdate ? Methods.PUT : Methods.POST,
endpoint: `administrativo/t_censec_tipoato/${data.censec_tipoato_id || ''}`,
body: data
});
}
export const TCensecTipoAtoSaveData = withClientErrorHandler(executeTCensecTipoAtoSaveData)

View file

@ -1,251 +0,0 @@
export default async function TCensecTipoAtoMockDeDados() {
return Promise.resolve({
status: 200,
message: 'Dados localizados',
data: [
{
censec_tipoato_id: 1,
censec_id: 2,
codigo: 1,
descricao: "Escritura",
situacao: "I",
tipo_separacao: "N",
tipo_revogacao: "N"
},
{
censec_tipoato_id: 2,
censec_id: 1,
codigo: 2,
descricao: "Procuração",
situacao: "A",
tipo_separacao: "N",
tipo_revogacao: "N"
},
{
censec_tipoato_id: 3,
censec_id: 1,
codigo: 3,
descricao: "Procuração para Fins Previdenciários",
situacao: "A",
tipo_separacao: "N",
tipo_revogacao: "N"
},
{
censec_tipoato_id: 4,
censec_id: 1,
codigo: 5,
descricao: "Renúncia de Procuração",
situacao: "A",
tipo_separacao: "N",
tipo_revogacao: "N"
},
{
censec_tipoato_id: 5,
censec_id: 1,
codigo: 6,
descricao: "Revogação de Procuração",
situacao: "A",
tipo_separacao: "N",
tipo_revogacao: "N"
},
{
censec_tipoato_id: 6,
censec_id: 1,
codigo: 7,
descricao: "Substabelecimento",
situacao: "A",
tipo_separacao: "N",
tipo_revogacao: "N"
},
{
censec_tipoato_id: 7,
censec_id: 1,
codigo: 8,
descricao: "Ata Notarial",
situacao: "A",
tipo_separacao: "N",
tipo_revogacao: "N"
},
{
censec_tipoato_id: 8,
censec_id: 2,
codigo: 1,
descricao: "Separação",
situacao: "A",
tipo_separacao: "S",
tipo_revogacao: "N"
},
{
censec_tipoato_id: 9,
censec_id: 2,
codigo: 2,
descricao: "Reconciliação",
situacao: "A",
tipo_separacao: "N",
tipo_revogacao: "N"
},
{
censec_tipoato_id: 10,
censec_id: 2,
codigo: 3,
descricao: "Conversão de Separação em Divórcio",
situacao: "A",
tipo_separacao: "S",
tipo_revogacao: "N"
},
{
censec_tipoato_id: 11,
censec_id: 2,
codigo: 4,
descricao: "Divórcio Direto",
situacao: "A",
tipo_separacao: "S",
tipo_revogacao: "N"
},
{
censec_tipoato_id: 12,
censec_id: 2,
codigo: 5,
descricao: "Inventário",
situacao: "A",
tipo_separacao: "N",
tipo_revogacao: "N"
},
{
censec_tipoato_id: 13,
censec_id: 2,
codigo: 6,
descricao: "Sobrepartilha",
situacao: "A",
tipo_separacao: "N",
tipo_revogacao: "N"
},
{
censec_tipoato_id: 14,
censec_id: 2,
codigo: 7,
descricao: "Retificação",
situacao: "A",
tipo_separacao: "N",
tipo_revogacao: "N"
},
{
censec_tipoato_id: 15,
censec_id: 3,
codigo: 1,
descricao: "Aditamento",
situacao: "A",
tipo_separacao: "N",
tipo_revogacao: "N"
},
{
censec_tipoato_id: 16,
censec_id: 3,
codigo: 2,
descricao: "Cerrado",
situacao: "A",
tipo_separacao: "N",
tipo_revogacao: "N"
},
{
censec_tipoato_id: 17,
censec_id: 3,
codigo: 3,
descricao: "Revogação",
situacao: "A",
tipo_separacao: "N",
tipo_revogacao: "S"
},
{
censec_tipoato_id: 18,
censec_id: 3,
codigo: 4,
descricao: "Testamento",
situacao: "A",
tipo_separacao: "N",
tipo_revogacao: "N"
},
{
censec_tipoato_id: 19,
censec_id: 3,
codigo: 5,
descricao: "Testamento com Revogação",
situacao: "A",
tipo_separacao: "N",
tipo_revogacao: "N"
},
{
censec_tipoato_id: 20,
censec_id: 3,
codigo: 6,
descricao: "Testamento sem Conteúdo Patrimonial",
situacao: "A",
tipo_separacao: "N",
tipo_revogacao: "N"
},
{
censec_tipoato_id: 21,
censec_id: 9,
codigo: null,
descricao: "Atos Diversos",
situacao: "A",
tipo_separacao: null,
tipo_revogacao: null
},
{
censec_tipoato_id: 204,
censec_id: 1,
codigo: 75,
descricao: "Conciliação",
situacao: "A",
tipo_separacao: null,
tipo_revogacao: null
},
{
censec_tipoato_id: 208,
censec_id: 1,
codigo: 76,
descricao: "Mediação",
situacao: "A",
tipo_separacao: null,
tipo_revogacao: null
},
{
censec_tipoato_id: 209,
censec_id: 1,
codigo: 8,
descricao: "Compra e Venda",
situacao: "A",
tipo_separacao: null,
tipo_revogacao: null
},
{
censec_tipoato_id: 210,
censec_id: 1,
codigo: 1,
descricao: "Escritura",
situacao: "A",
tipo_separacao: null,
tipo_revogacao: null
},
{
censec_tipoato_id: 211,
censec_id: 2,
codigo: 8,
descricao: "Nomeação de Inventariante",
situacao: "A",
tipo_separacao: null,
tipo_revogacao: null
},
{
censec_tipoato_id: 212,
censec_id: 2,
codigo: 9,
descricao: "Partilha",
situacao: "A",
tipo_separacao: null,
tipo_revogacao: null
}
]
});
}

View file

@ -1,23 +0,0 @@
import { useResponse } from "@/shared/components/response/ResponseContext"
import { useState } from "react";
import { TCensecTipoAtoInterface } from "../../_interfaces/TCensecTipoAtoInterface";
import { TCensecTipoAtoIndexService } from "../../_services/t_censec_tipoato/TCensecTipoAtoIndexService";
export const useTCensecTipoAtoReadHook = () => {
const { setResponse } = useResponse();
const [tCensecTipoAto, setTCensecTipoAto] = useState<TCensecTipoAtoInterface[]>([]);
const fetchTCensecTipoAto = async () => {
const response = await TCensecTipoAtoIndexService();
setTCensecTipoAto(response.data);
setResponse(response);
}
return { tCensecTipoAto, fetchTCensecTipoAto }
}

View file

@ -1,19 +0,0 @@
import { useResponse } from "@/shared/components/response/ResponseContext"
import { TCensecTipoAtoInterface } from "../../_interfaces/TCensecTipoAtoInterface";
import { TCensecTipoAtoRemoveService } from "../../_services/t_censec_tipoato/TCensecTipoAtoRemoveService";
export const useTCensecTipoAtoRemoveHook = () => {
const { setResponse } = useResponse();
const removeTCensecTipoAto = async (data: TCensecTipoAtoInterface) => {
const response = await TCensecTipoAtoRemoveService(data);
setResponse(response);
}
return { removeTCensecTipoAto }
}

View file

@ -1,28 +0,0 @@
import { useResponse } from "@/shared/components/response/ResponseContext"
import { useState } from "react";
import { TCensecTipoAtoInterface } from "../../_interfaces/TCensecTipoAtoInterface";
import { TCensecTipoAtoSaveService } from "../../_services/t_censec_tipoato/TCensecTipoAtoSaveService";
export const useTCensecTipoAtoSaveHook = () => {
const { setResponse } = useResponse();
const [tCensecTipoAto, setTCensecTipoAto] = useState<TCensecTipoAtoInterface | null>(null);
const [isOpen, setIsOpen] = useState(false);
const saveTCensecTipoAto = async (data: TCensecTipoAtoInterface) => {
const response = await TCensecTipoAtoSaveService(data);
setTCensecTipoAto(response.data);
setResponse(response);
setIsOpen(false);
return response;
}
return { tCensecTipoAto, saveTCensecTipoAto }
}

View file

@ -1,12 +0,0 @@
import { z } from "zod";
import { SituacoesEnum } from "@/shared/enums/SituacoesEnum";
export const TCensecTipoAtoSchema = z.object({
censec_tipoato_id: z.number().int(),
censec_id: z.number("Precisa referir a qual Central do Censec pertence").int(),
codigo: z.number().int().nullable(),
descricao: z.string().min(1, "Campo descrição deve ser preenchido"),
situacao: z.enum(SituacoesEnum, { message: "Tipo inválido" }),
tipo_separacao: z.enum(["S", "N"]).nullable(),
tipo_revogacao: z.enum(["S", "N"]).nullable(),
});

View file

@ -1,8 +0,0 @@
import GTBProfissaoRemoveData from '../../_data/GTBProfissao/GTBProfissaoRemoveData';
import GTBProfissaoInterface from '../../_interfaces/GTBProfissaoInterface';
export default async function GTBProfissaoRemoveService(data: GTBProfissaoInterface) {
const response = await GTBProfissaoRemoveData(data);
return response;
}

View file

@ -1,7 +0,0 @@
import GTBProfissaoSaveData from '../../_data/GTBProfissao/GTBProfissaoSaveData';
import GTBProfissaoInterface from '../../_interfaces/GTBProfissaoInterface';
export default async function GTProfissaoSaveService(data: GTBProfissaoInterface) {
const response = await GTBProfissaoSaveData(data);
return response;
}

View file

@ -1,8 +0,0 @@
import GTBRegimeBensRemoveData from '../../_data/GTBRegimeBens/GTBRegimeBensRemoveData';
import GTBRegimeBensInterface from '../../_interfaces/GTBRegimeBensInterface';
export default async function GTBRegimeBensRemoveService(data: GTBRegimeBensInterface) {
const response = await GTBRegimeBensRemoveData(data);
return response;
}

View file

@ -1,10 +0,0 @@
import { withClientErrorHandler } from "@/shared/actions/withClientErrorHandler/withClientErrorHandler";
import { TCensecTipoAtoIndexData } from "../../_data/TCensecTipoAto/GMedidaTipoIndexData";
async function executeTCensecTipoAtoIndexService() {
const response = await TCensecTipoAtoIndexData();
return response;
}
export const TCensecTipoAtoIndexService = withClientErrorHandler(executeTCensecTipoAtoIndexService)

View file

@ -1,13 +0,0 @@
import { withClientErrorHandler } from "@/shared/actions/withClientErrorHandler/withClientErrorHandler";
import { TCensecTipoAtoRemoveData } from "../../_data/TCensecTipoAto/GMedidaTipoRemoveData";
import { TCensecTipoAtoInterface } from "../../_interfaces/TCensecTipoAtoInterface";
async function executeTCensecTipoAtoRemoveService(data: TCensecTipoAtoInterface) {
const response = await TCensecTipoAtoRemoveData(data);
return response;
}
export const TCensecTipoAtoRemoveService = withClientErrorHandler(executeTCensecTipoAtoRemoveService)

View file

@ -1,13 +0,0 @@
import { withClientErrorHandler } from "@/shared/actions/withClientErrorHandler/withClientErrorHandler";
import { TCensecTipoAtoSaveData } from "../../_data/TCensecTipoAto/GMedidaTipoSaveData";
import { TCensecTipoAtoInterface } from "../../_interfaces/TCensecTipoAtoInterface";
async function executeTCensecTipoAtoSaveService(data: TCensecTipoAtoInterface) {
const response = await TCensecTipoAtoSaveData(data);
return response;
}
export const TCensecTipoAtoSaveService = withClientErrorHandler(executeTCensecTipoAtoSaveService)

View file

@ -1,7 +0,0 @@
import TMinutaIndexData from '../../_data/TMinuta/TMinutaIndexData';
import { TMinutaInterface } from '../../_interfaces/TMinutaInterface';
export default async function TMinutaIndex() {
const response = await TMinutaIndexData();
return response;
}

View file

@ -1,70 +0,0 @@
import { FileText, Heart, Briefcase, Scale, Link as LinkIcon, MapPin } from 'lucide-react';
import { Card, CardContent } from '@/components/ui/card';
import Link from 'next/link';
export default function CadastrosPage() {
const items = [
{
title: 'Documentos',
description: 'Gerencie os tipos de documentos aceitos e suas configurações no sistema.',
icon: FileText,
},
{
title: 'Estado Civil',
description: 'Cadastre e mantenha os diferentes estados civis utilizados nos registros.',
icon: Heart,
},
{
title: 'Profissão',
description: 'Gerencie a lista de profissões para utilização em cadastros e registros.',
icon: Briefcase,
},
{
title: 'Regime de Comunhão',
description: 'Defina os regimes de comunhão aplicáveis em matrimônios e registros civis.',
icon: Scale,
},
{
title: 'Vínculo de Sinal Público',
description:
'Controle e cadastre vínculos relacionados a sinais públicos para autenticações.',
icon: LinkIcon,
},
{
title: 'Municípios',
description: 'Gerencie a base de municípios para utilização em endereços e cadastros.',
icon: MapPin,
},
];
return (
<div>
<div className="mb-4 flex items-center justify-between">
<div>
<h1 className="mb-1 text-4xl font-semibold">Complementos de Cadastro pessoal</h1>
<p className="text-muted-foreground text-base">
Gerencie os cadastros relacionados a regimes, como estado civil, regime de comunhão e
outras informações complementares necessárias para o registro de pessoas.
</p>
</div>
</div>
<div className="grid grid-cols-5 gap-3">
{items.map((item, key) => (
<Link key={key} href={'/'}>
<Card className="hover:bg-muted cursor-pointer transition-colors">
<CardContent>
<span className="mb-2 inline-flex shrink-0 rounded-md border border-blue-300 bg-blue-100 p-2 dark:border-blue-300/10 dark:bg-blue-400/10">
<item.icon className="size-6 stroke-blue-700 dark:stroke-blue-500" />
</span>
<h3 className="mt-3 text-2xl font-medium tracking-tight text-gray-900 dark:text-white">
{item.title}
</h3>
<p className="mt-1 text-sm text-gray-500 dark:text-gray-400">{item.description}</p>
</CardContent>
</Card>
</Link>
))}
</div>
</div>
);
}

View file

@ -1,100 +0,0 @@
'use client';
import { Card, CardAction, CardContent, CardDescription, CardTitle } from '@/components/ui/card';
import {
BabyIcon,
CrossIcon,
FileCheckIcon,
FileTextIcon,
GavelIcon,
GlobeIcon,
HeartIcon,
PenIcon,
ScrollIcon,
UsersIcon,
} from 'lucide-react';
const services = [
{
title: 'Registro de Nascimento',
description:
'Emissão e registro de certidões de nascimento, garantindo a cidadania e identidade legal do recém-nascido.',
icon: BabyIcon,
},
{
title: 'Registro de Casamento',
description: 'Processo completo para habilitação, registro e emissão da certidão de casamento.',
icon: HeartIcon,
},
{
title: 'Registro de Óbito',
description:
'Lavratura do registro de óbito e emissão da certidão correspondente para fins legais.',
icon: CrossIcon,
},
{
title: 'Reconhecimento de Firma',
description: 'Autenticação da assinatura de documentos, garantindo sua validade jurídica.',
icon: PenIcon,
},
{
title: 'Autenticação de Documentos',
description: 'Confirmação de que cópias estão de acordo com o documento original apresentado.',
icon: FileCheckIcon,
},
{
title: 'Procurações',
description:
'Elaboração e registro de procurações públicas para representação legal de pessoas físicas ou jurídicas.',
icon: ScrollIcon,
},
{
title: 'Testamentos',
description: 'Lavratura e registro de testamentos públicos com segurança jurídica.',
icon: GavelIcon,
},
{
title: 'Divórcio Extrajudicial',
description:
'Formalização do divórcio por via administrativa, de forma rápida e sem processo judicial.',
icon: UsersIcon,
},
{
title: 'Apostilamento de Documentos',
description:
'Apostilamento conforme a Convenção da Haia para validade internacional de documentos.',
icon: GlobeIcon,
},
{
title: 'Certidões e Segunda Via',
description: 'Emissão de segundas vias e certidões de nascimento, casamento e óbito.',
icon: FileTextIcon,
},
];
export default function ServicosPage() {
return (
<div>
<div className="bg-primary/10 border-primary/20 w-full rounded-xl border p-6">
<h2 className="text-primary text-2xl font-semibold">Bem-vindo(a)!</h2>
<p className="mt-2 text-base text-gray-700">
Olá, <span className="text-primary font-bold">Keven</span>! É um prazer ter você conosco.
</p>
</div>
<div className="mt-3 grid grid-cols-4 space-y-2 space-x-2">
{services.map((item: any, index) => (
<Card className="cursor-pointer" key={index}>
<CardContent>
<div className="bg-primary flex h-12 w-12 items-center justify-center rounded-2xl">
<item.icon className="h-6 w-6 text-white" />
</div>
<CardTitle className="mt-3">{item.title}</CardTitle>
<CardDescription className="mt-3">{item.description}</CardDescription>
</CardContent>
</Card>
))}
</div>
</div>
);
}

View file

@ -83,64 +83,76 @@ const data = {
items: [
{
title: 'Reconhecimentos',
url: '/cadastros/reconhecimentos/',
url: '/administrativo/reconhecimentos/',
},
{
title: 'Andamentos',
url: '/cadastros/andamentos/',
url: '/administrativo/andamentos/',
},
{
title: 'Profissões',
url: '/cadastros/profissoes/',
url: '/administrativo/pessoas/profissoes/',
},
{
title: 'Regimes/Bens',
url: '/cadastros/regime-bens/',
url: '/administrativo/pessoas/regimes-bens/',
},
{
title: 'Tipos de Logradouros',
url: '/cadastros/tipo-logradouro',
},
{
title: 'Bairro',
url: '/cadastros/bairro',
url: '/administrativo/imoveis/tipos-logradouro',
},
{
title: 'Estado Civil',
url: '/cadastros/estado-civil',
url: '/administrativo/pessoas/estados-civis',
},
{
title: "Regimes/Comunhão",
url: "/administrativo/pessoas/regimes-comunhao/",
},
{
title: 'Tipo de Medida',
url: '/cadastros/medida-tipo',
},
{
title: 'Pessoas',
url: '/cadastros/pessoas/complementos/',
url: '/administrativo/medidas/tipos',
},
{
title: 'Cidades',
url: '/cadastros/cidades/',
url: '/administrativo/cidades/',
},
{
title: 'Bairro',
url: '/administrativo/bairros',
},
{
title: 'Minuta',
url: '/cadastros/minuta/',
url: '/administrativo/minutas/',
},
{
title: 'Minuta/Naturezas',
url: '/administrativo/minutas/naturezas',
},
{
title: "Censec/Tipo do Ato",
url: "/cadastros/censec-tipoato"
url: "/administrativo/centrais/censec/tipos-atos"
},
{
title: "Censec/Qualidades",
url: "/administrativo/centrais/censec/qualidades"
},
{
title: 'Censec/Centrais',
url: '/cadastros/censec/',
url: '/administrativo/centrais/censec/centrais',
},
{
title: 'Censec/Natureza Litígio',
url: '/cadastros/censec-natureza-litigio',
url: '/administrativo/centrais/censec/naturezas-litigios',
},
{
title: "Serviços/Tipos",
url: "/cadastros/servicos-tipo/",
},
{
title: "Atos/Partes Tipos",
url: "/administrativo/atos/partes-tipos",
},
],
},

View file

@ -6,13 +6,13 @@ import { Card, CardContent } from '@/components/ui/card';
import { Input } from '@/components/ui/input';
import z from 'zod';
import { zodResolver } from '@hookform/resolvers/zod';
import GUsuarioLoginService from '@/app/(protected)/(administrativo)/_services/g_usuario/GUsuarioLogin';
import GUsuarioLoginService from '@/packages/administrativo/services/GUsuario/GUsuarioLogin';
import { useForm } from 'react-hook-form';
import { useState } from 'react';
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from './ui/form';
import LoadingButton from '@/shared/components/loadingButton/LoadingButton';
import { Button } from './ui/button';
import { GUsuarioLoginSchema } from '@/app/(protected)/(administrativo)/_schemas/GUsuarioLoginSchema';
import { GUsuarioLoginSchema } from '@/packages/administrativo/schemas/GUsuario/GUsuarioLoginSchema';
type FormValues = z.infer<typeof GUsuarioLoginSchema>;

View file

@ -20,7 +20,7 @@ import {
import GUsuarioAuthenticatedInterface from '@/shared/interfaces/GUsuarioAuthenticatedInterface';
import ConfirmDialog from '@/shared/components/confirmDialog/ConfirmDialog';
import { useGUsuarioLogoutHook } from '@/app/(protected)/(administrativo)/_hooks/g_usuario/useGUsuarioLogoutHook';
import { useGUsuarioLogoutHook } from '@/packages/administrativo/hooks/GUsuario/useGUsuarioLogoutHook';
import { use, useCallback, useState } from 'react';
export function NavUser({ user }: { user: GUsuarioAuthenticatedInterface }) {

View file

@ -0,0 +1,31 @@
"use client"
import * as React from "react"
import * as SwitchPrimitive from "@radix-ui/react-switch"
import { cn } from "@/lib/utils"
function Switch({
className,
...props
}: React.ComponentProps<typeof SwitchPrimitive.Root>) {
return (
<SwitchPrimitive.Root
data-slot="switch"
className={cn(
"peer data-[state=checked]:bg-primary data-[state=unchecked]:bg-input focus-visible:border-ring focus-visible:ring-ring/50 dark:data-[state=unchecked]:bg-input/80 inline-flex h-[1.15rem] w-8 shrink-0 items-center rounded-full border border-transparent shadow-xs transition-all outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50",
className
)}
{...props}
>
<SwitchPrimitive.Thumb
data-slot="switch-thumb"
className={cn(
"bg-background dark:data-[state=unchecked]:bg-foreground dark:data-[state=checked]:bg-primary-foreground pointer-events-none block size-4 rounded-full ring-0 transition-transform data-[state=checked]:translate-x-[calc(100%-2px)] data-[state=unchecked]:translate-x-0"
)}
/>
</SwitchPrimitive.Root>
)
}
export { Switch }

View file

@ -1,8 +1,9 @@
'use client';
import z from 'zod';
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { useEffect } from 'react';
import { useForm } from 'react-hook-form';
import z from 'zod';
import { Button } from '@/components/ui/button';
import {
@ -23,12 +24,6 @@ import {
FormMessage,
} from '@/components/ui/form';
import { Input } from '@/components/ui/input';
import { GCidadeSchema } from '../../_schemas/GCidadeSchema';
import { useEffect } from 'react';
// Hook responsável em trazer todos os estados brasileiros
import { useGUfReadHook } from '../../_hooks/g_uf/useGUfReadHook';
import {
Select,
SelectContent,
@ -36,6 +31,12 @@ import {
SelectTrigger,
SelectValue,
} from '@/components/ui/select';
import { useGUfReadHook } from '@/packages/administrativo/hooks/GUF/useGUfReadHook';
import { GCidadeSchema } from '../../schemas/GCidade/GCidadeSchema';
// Hook responsável em trazer todos os estados brasileiros
// Define o tipo do formulário com base no schema Zod
type FormValues = z.infer<typeof GCidadeSchema>;
@ -67,7 +68,6 @@ export default function GCidadeForm({ isOpen, data, onClose, onSave }: Props) {
// Quando recebe dados para edição, atualiza os valores do formulário
useEffect(() => {
if (data) {
// Se for edição, carrega os dados recebidos
form.reset({
@ -88,7 +88,7 @@ export default function GCidadeForm({ isOpen, data, onClose, onSave }: Props) {
});
}
// Carrega todos os estados
// Carrega todos os estados
// brasileiros para o formulário
const loadData = async () => {
// Aguarda a busca terminar
@ -97,7 +97,6 @@ export default function GCidadeForm({ isOpen, data, onClose, onSave }: Props) {
// Dispara a função
loadData();
}, [data, form]);
return (
@ -155,10 +154,10 @@ export default function GCidadeForm({ isOpen, data, onClose, onSave }: Props) {
render={({ field }) => (
<FormItem>
<FormLabel>UF</FormLabel>
<Select
value={field.value ?? ''} // garante que não será null
onValueChange={(val) => field.onChange(val)}
>
<Select
value={field.value ?? ''} // garante que não será null
onValueChange={(val) => field.onChange(val)}
>
<FormControl className="w-full">
<SelectTrigger>
<SelectValue placeholder="Selecione o estado desejado" />

View file

@ -1,23 +1,20 @@
'use client';
import { useEffect, useState, useCallback } from 'react';
import { Card, CardContent } from '@/components/ui/card';
import Loading from '@/shared/components/loading/loading';
import GCidadeTable from '../../_components/g_cidade/GCidadeTable';
import GCidadeForm from '../../_components/g_cidade/GCidadeForm';
import { useGCidadeReadHook } from '../../_hooks/g_cidade/useGCidadeReadHook';
import { useGCidadeSaveHook } from '../../_hooks/g_cidade/useGCidadeSaveHook';
import { useGCidadeRemoveHook } from '../../_hooks/g_cidade/useGCidadeRemoveHook';
import GCidadeForm from '@/packages/administrativo/components/GCidade/GCidadeForm';
import GCidadeTable from '@/packages/administrativo/components/GCidade/GCidadeTable';
import { useGCidadeReadHook } from '@/packages/administrativo/hooks/GCidade/useGCidadeReadHook';
import { useGCidadeRemoveHook } from '@/packages/administrativo/hooks/GCidade/useGCidadeRemoveHook';
import { useGCidadeSaveHook } from '@/packages/administrativo/hooks/GCidade/useGCidadeSaveHook';
import GCidadeInterface from '@/packages/administrativo/interfaces/GCidade/GCidadeInterface';
import ConfirmDialog from '@/shared/components/confirmDialog/ConfirmDialog';
import { useConfirmDialog } from '@/shared/components/confirmDialog/useConfirmDialog';
import GCidadeInterface from '../../_interfaces/GCidadeInterface';
import Loading from '@/shared/components/loading/loading';
import Header from '@/shared/components/structure/Header';
export default function GCidadePage() {
export default function GCidadeIndex() {
// Hooks para leitura e salvamento
const { gCidade, fetchGCidade } = useGCidadeReadHook();
const { saveGCidade } = useGCidadeSaveHook();
@ -48,22 +45,21 @@ export default function GCidadePage() {
setIsFormOpen(true);
}, []);
/**
* Fecha o formulário e limpa o andamento selecionado
*/
const handleCloseForm = useCallback((_: null, __: boolean) => {
setSelectedCidade(null);
setIsFormOpen(false);
}, []);
/**
* Fecha o formulário e limpa o andamento selecionado
*/
const handleCloseForm = useCallback((_: null, __: boolean) => {
setSelectedCidade(null);
setIsFormOpen(false);
}, []);
/**
* Salva os dados do formulário
*/
const handleSave = useCallback(async (formData: GCidadeInterface) => {
// Aguarda salvar o registro
await saveGCidade(formData);
/**
* Salva os dados do formulário
*/
const handleSave = useCallback(
async (formData: GCidadeInterface) => {
// Aguarda salvar o registro
await saveGCidade(formData);
// Atualiza a lista de dados
fetchGCidade();

View file

@ -1,5 +1,7 @@
'use client';
import { EllipsisIcon, PencilIcon, Trash2Icon } from 'lucide-react';
import { Button } from '@/components/ui/button';
import {
DropdownMenu,
@ -18,8 +20,7 @@ import {
TableRow,
} from '@/components/ui/table';
import { EllipsisIcon, PencilIcon, Trash2Icon } from 'lucide-react';
import GCidadeInterface from '../../_interfaces/GCidadeInterface';
import GCidadeInterface from '../../interfaces/GCidade/GCidadeInterface';
// Tipagem das props do componente da tabela
interface GCidadeTableProps {

View file

@ -1,9 +1,9 @@
'use client';
import z from 'zod';
import { zodResolver } from '@hookform/resolvers/zod';
import { useEffect } from 'react';
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import z from 'zod';
import { Button } from '@/components/ui/button';
import {
@ -25,8 +25,9 @@ import {
} from '@/components/ui/form';
import { Input } from '@/components/ui/input';
import LoadingButton from '@/shared/components/loadingButton/LoadingButton';
import { GMedidaTipoSchema } from '../../_schemas/GMedidaTipoSchema';
import { GMedidaTipoInterface } from '../../_interfaces/GMedidaTipoInterface';
import { GMedidaTipoInterface } from '../../interfaces/GMedidaTipo/GMedidaTipoInterface';
import { GMedidaTipoSchema } from '../../schemas/GMedidaTipo/GMedidaTipoSchema';
type FormValues = z.infer<typeof GMedidaTipoSchema>;

View file

@ -1,30 +1,30 @@
'use client';
import { useEffect, useState, useCallback } from 'react';
import { Card, CardContent } from '@/components/ui/card';
import { useConfirmDialog } from '@/shared/components/confirmDialog/useConfirmDialog';
import { useResponse } from '@/shared/components/response/ResponseContext';
import Header from '@/shared/components/structure/Header';
import ConfirmDialog from '@/shared/components/confirmDialog/ConfirmDialog';
import { useConfirmDialog } from '@/shared/components/confirmDialog/useConfirmDialog';
import Loading from '@/shared/components/loading/loading';
import GMedidaTipoTable from '../../_components/g_medidatipo/GMedidaTipoTable';
import GMedidaTipoForm from '../../_components/g_medidatipo/GMedidaTipoForm';
import { useGMedidaTipoReadHook } from '../../_hooks/g_medidatipo/useGMedidaTipoReadHook';
import { useGMedidaTipoSaveHook } from '../../_hooks/g_medidatipo/useGMedidaTipoSaveHook';
import { useGMedidaTipoRemoveHook } from '../../_hooks/g_medidatipo/useGMedidaTipoRemoveHook';
import { GMedidaTipoInterface } from '../../_interfaces/GMedidaTipoInterface';
import { useResponse } from '@/shared/components/response/ResponseContext';
import Header from '@/shared/components/structure/Header';
import { SituacoesEnum } from '@/shared/enums/SituacoesEnum';
import GMedidaTipoForm from './GMedidaTipoForm';
import GMedidaTipoTable from './GMedidaTipoTable';
import { useGMedidaTipoReadHook } from '../../hooks/GMedidaTipo/useGMedidaTipoReadHook';
import { useGMedidaTipoRemoveHook } from '../../hooks/GMedidaTipo/useGMedidaTipoRemoveHook';
import { useGMedidaTipoSaveHook } from '../../hooks/GMedidaTipo/useGMedidaTipoSaveHook';
import { GMedidaTipoInterface } from '../../interfaces/GMedidaTipo/GMedidaTipoInterface';
const initialMedidaTipo: GMedidaTipoInterface = {
medida_tipo_id: 0,
sigla: '',
descricao: '',
};
export default function GMedidaTipoPage() {
export default function GMedidaTipoIndex() {
// Controle de exibição de respostas
const { setResponse } = useResponse();

View file

@ -1,5 +1,7 @@
'use client';
import { EllipsisIcon, PencilIcon, Trash2Icon } from 'lucide-react';
import { Button } from '@/components/ui/button';
import {
DropdownMenu,
@ -17,8 +19,8 @@ import {
TableHeader,
TableRow,
} from '@/components/ui/table';
import { EllipsisIcon, PencilIcon, Trash2Icon } from 'lucide-react';
import { GMedidaTipoInterface } from '../../_interfaces/GMedidaTipoInterface';
import { GMedidaTipoInterface } from '../../interfaces/GMedidaTipo/GMedidaTipoInterface';
interface GMedidaTipoTableProps {
data: GMedidaTipoInterface[];

View file

@ -0,0 +1,120 @@
import { ColumnDef } from '@tanstack/react-table';
import { EllipsisIcon, PencilIcon, Trash2Icon } from 'lucide-react';
import { Button } from '@/components/ui/button';
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuGroup,
DropdownMenuItem,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu';
import GetCapitalize from '@/shared/actions/text/GetCapitalize';
import { SortableHeader } from '@/shared/components/dataTable/SortableHeader';
import GNaturezaInterface from '../../interfaces/GNatureza/GNaturezaInterface';
export default function GNaturezaColumns(
onEdit: (item: GNaturezaInterface, isEditingFormStatus: boolean) => void,
onDelete: (item: GNaturezaInterface, isEditingFormStatus: boolean) => void,
): ColumnDef<GNaturezaInterface>[] {
return [
// ID
{
accessorKey: 'natureza_id',
header: ({ column }) => SortableHeader('ID', column),
cell: ({ row }) => Number(row.getValue('natureza_id')),
enableSorting: true,
},
// Descrição
{
accessorKey: 'descricao',
header: ({ column }) => SortableHeader('Descrição', column),
cell: ({ row }) => GetCapitalize(String(row.getValue('descricao') || '')),
},
// Situação
{
accessorKey: 'situacao',
header: ({ column }) => SortableHeader('Situação', column),
cell: ({ row }) => {
const value = String(row.getValue('situacao') || '').toUpperCase();
if (value === 'A') return 'Ativo';
if (value === 'I') return 'Inativo';
return '-';
},
},
// Sistema ID
{
accessorKey: 'sistema_id',
header: ({ column }) => SortableHeader('Sistema ID', column),
cell: ({ row }) => {
const value = row.getValue('sistema_id');
return value ? Number(value) : '-';
},
},
// Pedir Número Imóvel
{
accessorKey: 'pedir_numero_imovel',
header: ({ column }) => SortableHeader('Pedir Nº Imóvel', column),
cell: ({ row }) => {
const value = String(row.getValue('pedir_numero_imovel') || '').toUpperCase();
return value === 'S' ? 'Sim' : 'Não';
},
},
// Controle Frente/Verso
{
accessorKey: 'controle_frenteverso',
header: ({ column }) => SortableHeader('Controle Frente/Verso', column),
cell: ({ row }) => {
const value = String(row.getValue('controle_frenteverso') || '').toUpperCase();
return value === 'S' ? 'Sim' : 'Não';
},
},
// Ações
{
id: 'actions',
header: 'Ações',
cell: ({ row }) => {
const natureza = row.original;
return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="ghost" size="icon">
<EllipsisIcon />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent side="left" align="start">
<DropdownMenuGroup>
<DropdownMenuItem onSelect={() => onEdit(natureza, true)}>
<PencilIcon className="mr-2 h-4 w-4" />
Editar
</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem
className="text-red-600"
onSelect={() => onDelete(natureza, true)}
>
<Trash2Icon className="mr-2 h-4 w-4" />
Remover
</DropdownMenuItem>
</DropdownMenuGroup>
</DropdownMenuContent>
</DropdownMenu>
);
},
enableSorting: false,
enableHiding: false,
},
];
}

View file

@ -0,0 +1,171 @@
'use client';
import React, { useEffect } from 'react';
import { Button } from '@/components/ui/button';
import {
Dialog,
DialogClose,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle,
} from '@/components/ui/dialog';
import {
Form,
FormControl,
FormField,
FormItem,
FormLabel,
FormMessage,
} from '@/components/ui/form';
import { Input } from '@/components/ui/input';
import { Switch } from '@/components/ui/switch';
import { ResetFormIfData } from '@/shared/actions/form/ResetFormIfData';
import LoadingButton from '@/shared/components/loadingButton/LoadingButton';
import SituacoesSelect from '@/shared/components/situacoes/SituacoesSelect';
import { useGNaturezaFormHook } from '../../hooks/GNatureza/useGNaturezaFormHook';
import { GNaturezaFormInterface } from '../../interfaces/GNatureza/GNaturezaFormInterface';
/**
* Formulário de cadastro/edição de Natureza
* Baseado nos campos da tabela G_NATUREZA
*/
export default function GNaturezaForm({
isOpen,
data,
onClose,
onSave,
buttonIsLoading,
}: GNaturezaFormInterface) {
const form = useGNaturezaFormHook({});
// Atualiza o formulário quando recebe dados para edição
useEffect(() => {
ResetFormIfData(form, data);
}, [data, form]);
function onError(error: any) {
console.log('Erro no formulário:', error);
}
return (
<Dialog
open={isOpen}
onOpenChange={(open) => {
if (!open) onClose(null, false);
}}
>
<DialogContent className="w-full max-w-full p-6 sm:max-w-3xl md:max-w-2xl lg:max-w-2xl">
<DialogHeader>
<DialogTitle className="text-lg sm:text-xl">Natureza de Minutas</DialogTitle>
<DialogDescription className="text-muted-foreground text-sm">
Natureza de MInutas
</DialogDescription>
</DialogHeader>
{/* Formulário principal */}
<Form {...form}>
<form onSubmit={form.handleSubmit(onSave, onError)} className="space-y-6">
{/* GRID MOBILE FIRST */}
<div className="grid w-full grid-cols-12 gap-4">
{/* DESCRIÇÃO */}
<div className="col-span-12 sm:col-span-6 md:col-span-12">
<FormField
control={form.control}
name="descricao"
render={({ field }) => (
<FormItem className="col-span-1 sm:col-span-2">
<FormLabel>Descrição</FormLabel>
<FormControl>
<Input
{...field}
type="text"
placeholder="Digite a descrição da natureza"
maxLength={60}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
</div>
{/* SITUAÇÃO */}
<div className="col-span-12 sm:col-span-6 md:col-span-12">
<FormField
control={form.control}
name="situacao"
render={({ field }) => (
<FormItem>
<FormLabel>Situação</FormLabel>
<SituacoesSelect field={field} />
<FormMessage />
</FormItem>
)}
/>
</div>
{/* PEDIR_NUMERO_IMOVEL */}
<div className="col-span-12 sm:col-span-6 md:col-span-6">
<FormField
control={form.control}
name="pedir_numero_imovel"
render={({ field }) => (
<FormItem className="flex flex-col space-y-1">
<FormLabel>Pedir do Imóvel</FormLabel>
<FormControl>
<Switch
checked={field.value === 'S'}
onCheckedChange={(checked: boolean) =>
field.onChange(checked ? 'S' : 'N')
}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
</div>
{/* CONTROLE_FRENTEVERSO */}
<div className="col-span-12 sm:col-span-6 md:col-span-6">
<FormField
control={form.control}
name="controle_frenteverso"
render={({ field }) => (
<FormItem className="flex flex-col space-y-1">
<FormLabel>Controle Frente/Verso</FormLabel>
<FormControl>
<Switch
checked={field.value === 'S'}
onCheckedChange={(checked: boolean) =>
field.onChange(checked ? 'S' : 'N')
}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
</div>
</div>
{/* Rodapé */}
<DialogFooter className="mt-6 flex flex-col justify-end gap-2 sm:flex-row">
<DialogClose asChild>
<Button variant="outline" type="button">
Cancelar
</Button>
</DialogClose>
<LoadingButton
text="Salvar"
textLoading="Salvando..."
type="submit"
loading={buttonIsLoading}
/>
</DialogFooter>
</form>
</Form>
</DialogContent>
</Dialog>
);
}

View file

@ -0,0 +1,168 @@
'use client';
import { useEffect, useState, useCallback } from 'react';
import { useGNaturezaDeleteHook } from '@/packages/administrativo/hooks/GNatureza/useGNaturezaDeleteHook';
import { useGNaturezaIndexHook } from '@/packages/administrativo/hooks/GNatureza/useGNaturezaIndexHook';
import { useGNaturezaSaveHook } from '@/packages/administrativo/hooks/GNatureza/useGNaturezaSaveHook';
import GNaturezaInterface from '@/packages/administrativo/interfaces/GNatureza/GNaturezaInterface';
import ConfirmDialog from '@/shared/components/confirmDialog/ConfirmDialog';
import { useConfirmDialog } from '@/shared/components/confirmDialog/useConfirmDialog';
import Loading from '@/shared/components/loading/loading';
import Header from '@/shared/components/structure/Header';
import GNaturezaForm from './GNaturezaForm';
import GNaturezaTable from './GNaturezaTable';
import { GNaturezaIndexInterface } from '../../interfaces/GNatureza/GNaturezaIndexInterface';
export default function GNaturezaIndex({ sistema_id }: GNaturezaIndexInterface) {
const GNaturezaIndexParams: GNaturezaIndexInterface = {
sistema_id: sistema_id,
};
// Controle de estado do botão
const [buttonIsLoading, setButtonIsLoading] = useState(false);
// Hooks para leitura e salvamento
const { gNatureza, indexGNatureza } = useGNaturezaIndexHook();
const { saveGNatureza } = useGNaturezaSaveHook();
const { deleteGNatureza } = useGNaturezaDeleteHook();
// Estados
const [selectedData, setSelectedData] = useState<GNaturezaInterface | null>(null);
const [isFormOpen, setIsFormOpen] = useState(false);
// Estado para saber qual item será deletado
const [itemToDelete, setItemToDelete] = useState<GNaturezaInterface | null>(null);
/**
* Hook do modal de confirmação
*/
const { isOpen: isConfirmOpen, openDialog: openConfirmDialog, handleCancel } = useConfirmDialog();
/**
* Abre o formulário no modo de edição ou criação
*/
const handleOpenForm = useCallback((data: GNaturezaInterface | null) => {
// Se não houver dados (criação), cria um objeto inicial com pessoa_tipo
const initialData: GNaturezaInterface =
data ?? ({ sistema_id: GNaturezaIndexParams.sistema_id } as GNaturezaInterface);
setSelectedData(initialData);
setIsFormOpen(true);
}, []);
/**
* Fecha o formulário e limpa o andamento selecionado
*/
const handleCloseForm = useCallback(() => {
setSelectedData(null);
setIsFormOpen(false);
}, []);
/**
* Salva os dados do formulário
*/
const handleSave = useCallback(
async (formData: GNaturezaInterface) => {
// Coloca o botão em estado de loading
setButtonIsLoading(true);
// Aguarda salvar o registro
await saveGNatureza(formData);
// Remove o botão em estado de loading
setButtonIsLoading(false);
// Atualiza a lista de dados
indexGNatureza(GNaturezaIndexParams);
},
[saveGNatureza, indexGNatureza, handleCloseForm],
);
/**
* Quando o usuário clica em "remover" na tabela
*/
const handleConfirmDelete = useCallback(
(item: GNaturezaInterface) => {
// Define o item atual para remoção
setItemToDelete(item);
// Abre o modal de confirmação
openConfirmDialog();
},
[openConfirmDialog],
);
/**
* Executa a exclusão de fato quando o usuário confirma
*/
const handleDelete = useCallback(async () => {
// Protege contra null
if (!itemToDelete) return;
// Executa o Hook de remoção
await deleteGNatureza(itemToDelete);
// Atualiza a lista
await indexGNatureza(GNaturezaIndexParams);
// Limpa o item selecionado
setItemToDelete(null);
// Fecha o modal
handleCancel();
}, [itemToDelete, indexGNatureza, handleCancel]);
/**
* Busca inicial dos dados
*/
useEffect(() => {
indexGNatureza(GNaturezaIndexParams);
}, []);
/**
* Tela de loading enquanto carrega os dados
*/
if (gNatureza?.length == 0) {
return <Loading type={2} />;
}
return (
<div>
{/* Cabeçalho */}
<Header
title={'Naturezas de Minutas'}
description={'Naturezas de Minutas'}
buttonText={'Novo imóvel'}
buttonAction={() => {
handleOpenForm(null);
}}
/>
{/* Tabela de andamentos */}
<GNaturezaTable data={gNatureza} onEdit={handleOpenForm} onDelete={handleConfirmDelete} />
{/* Modal de confirmação */}
{isConfirmOpen && (
<ConfirmDialog
isOpen={isConfirmOpen}
title="Confirmar exclusão"
description="Atenção"
message={`Deseja realmente excluir o imóvel "${itemToDelete?.descricao}"?`}
confirmText="Sim, excluir"
cancelText="Cancelar"
onConfirm={handleDelete}
onCancel={handleCancel}
/>
)}
{/* Formulário de criação/edição */}
{isFormOpen && (
<GNaturezaForm
isOpen={isFormOpen}
data={selectedData}
onClose={handleCloseForm}
onSave={handleSave}
buttonIsLoading={buttonIsLoading}
/>
)}
</div>
);
}

View file

@ -0,0 +1,23 @@
'use client';
import { DataTable } from '@/shared/components/dataTable/DataTable';
import GNaturezaColumns from './GNaturezaColumns';
import GNaturezaTableInterface from '../../interfaces/GNatureza/GNaturezaTableInterface';
/**
* Componente principal da tabela de Naturezas
*/
export default function GNaturezaTable({ data, onEdit, onDelete }: GNaturezaTableInterface) {
const columns = GNaturezaColumns(onEdit, onDelete);
return (
<div>
<DataTable
data={data}
columns={columns}
filterColumn="descricao"
filterPlaceholder="Buscar por descrição da natureza..."
/>
</div>
);
}

View file

@ -1,9 +1,9 @@
'use client';
import z from 'zod';
import { zodResolver } from '@hookform/resolvers/zod';
import { useEffect } from 'react';
import { useForm, Controller } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import z from 'zod';
import { Button } from '@/components/ui/button';
import { Checkbox } from '@/components/ui/checkbox';
@ -26,11 +26,12 @@ import {
} from '@/components/ui/form';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { GTBBairroSchema } from '../../_schemas/GTBBairroSchema';
import LoadingButton from '@/shared/components/loadingButton/LoadingButton';
import SituacoesSelect from '@/shared/components/situacoes/SituacoesSelect';
import { SituacoesEnum } from '@/shared/enums/SituacoesEnum';
import { GTBBairroSchema } from '../../schemas/GTBBairro/GTBBairroSchema';
type FormValues = z.infer<typeof GTBBairroSchema>;
interface GTBBairroFormProps {
@ -73,12 +74,8 @@ export default function GTBBairroForm({
>
<DialogContent className="sm:max-w-[425px]">
<DialogHeader>
<DialogTitle>
Bairro
</DialogTitle>
<DialogDescription>
Crie ou edite um bairro
</DialogDescription>
<DialogTitle>Bairro</DialogTitle>
<DialogDescription>Crie ou edite um bairro</DialogDescription>
</DialogHeader>
<Form {...form}>
<form onSubmit={form.handleSubmit(onSave)} className="space-y-6">
@ -102,10 +99,7 @@ export default function GTBBairroForm({
control={form.control}
render={({ field }) => (
<div className="flex items-center space-x-2">
<Checkbox
checked={field.value === 'A'}
onCheckedChange={(checked) => field.onChange(checked ? 'A' : 'I')}
/>
<SituacoesSelect field={field} />
<Label>Ativo</Label>
</div>
)}

View file

@ -1,23 +1,23 @@
'use client';
import { useEffect, useState, useCallback } from 'react';
import { Card, CardContent } from '@/components/ui/card';
import { useConfirmDialog } from '@/shared/components/confirmDialog/useConfirmDialog';
import { useResponse } from '@/shared/components/response/ResponseContext';
import Header from '@/shared/components/structure/Header';
import { useGTBBairroReadHook } from '@/packages/administrativo/hooks/GTBBairro/useGTBBairroReadHook';
import { useGTBBairroRemoveHook } from '@/packages/administrativo/hooks/GTBBairro/useGTBBairroRemoveHook';
import { useGTBBairroSaveHook } from '@/packages/administrativo/hooks/GTBBairro/useGTBBairroSaveHook';
import ConfirmDialog from '@/shared/components/confirmDialog/ConfirmDialog';
import { useConfirmDialog } from '@/shared/components/confirmDialog/useConfirmDialog';
import Loading from '@/shared/components/loading/loading';
import GTBBairroTable from '../../_components/g_tb_bairro/GTBBairroTable';
import GTBBairroForm from '../../_components/g_tb_bairro/GTBBairroForm';
import { useGTBBairroReadHook } from '../../_hooks/g_tb_bairro/useGTBBairroReadHook';
import { useGTBBairroSaveHook } from '../../_hooks/g_tb_bairro/useGTBBairroSaveHook';
import { useGTBBairroRemoveHook } from '../../_hooks/g_tb_bairro/useGTBBairroRemoveHook';
import { GTBBairroInterface } from '../../_interfaces/GTBBairroInterface';
import { useResponse } from '@/shared/components/response/ResponseContext';
import Header from '@/shared/components/structure/Header';
import { SituacoesEnum } from '@/shared/enums/SituacoesEnum';
import GTBBairroForm from './GTBBairroForm';
import GTBBairroTable from './GTBBairroTable';
import { GTBBairroInterface } from '../../interfaces/GTBBairro/GTBBairroInterface';
const initialBairro: GTBBairroInterface = {
sistema_id: null,
tb_bairro_id: 0,
@ -25,7 +25,7 @@ const initialBairro: GTBBairroInterface = {
situacao: SituacoesEnum.A,
};
export default function GTBBairroPage() {
export default function GTBBairroIndex() {
// Controle de exibição de respostas
const { setResponse } = useResponse();

View file

@ -1,114 +1,115 @@
'use client';
import { CheckIcon, ChevronsUpDownIcon } from 'lucide-react';
import React, { useState, useEffect, useCallback, useMemo } from 'react';
import { Button } from '@/components/ui/button';
import {
Command,
CommandEmpty,
CommandGroup,
CommandInput,
CommandItem,
CommandList,
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 { useGTBBairroReadHook } from '@/packages/administrativo/hooks/GTBBairro/useGTBBairroReadHook';
import GetCapitalize from '@/shared/actions/text/GetCapitalize';
import { useGTBBairroReadHook } from '@/app/(protected)/(cadastros)/cadastros/_hooks/g_tb_bairro/useGTBBairroReadHook';
import GTBairroSelectInterface from './GTBairroSelectInterface';
import GTBairroSelectInterface from '../../interfaces/GTBBairro/GTBairroSelectInterface';
export default function GTBBairroSelect({ field }: GTBairroSelectInterface) {
const [open, setOpen] = useState(false);
const [isLoading, setIsLoading] = useState(false);
const { gTBBairro = [], fetchGTBBairro } = useGTBBairroReadHook();
const [open, setOpen] = useState(false);
const [isLoading, setIsLoading] = useState(false);
const { gTBBairro = [], fetchGTBBairro } = useGTBBairroReadHook();
/**
* Efeito para buscar os dados apenas uma vez.
* useCallback evita recriação desnecessária da função.
*/
const loadData = useCallback(async () => {
if (gTBBairro.length) return;
setIsLoading(true);
await fetchGTBBairro();
setIsLoading(false);
}, [gTBBairro.length, fetchGTBBairro]);
/**
* Efeito para buscar os dados apenas uma vez.
* useCallback evita recriação desnecessária da função.
*/
const loadData = useCallback(async () => {
if (gTBBairro.length) return;
setIsLoading(true);
await fetchGTBBairro();
setIsLoading(false);
}, [gTBBairro.length, fetchGTBBairro]);
useEffect(() => {
loadData();
}, [loadData]);
useEffect(() => {
loadData();
}, [loadData]);
/**
* Memoriza o bairro selecionado para evitar reprocessamentos.
*/
const selected = useMemo(
() => gTBBairro.find((b) => String(b.tb_bairro_id) === String(field?.value ?? '')),
[gTBBairro, field?.value],
);
/**
* Memoriza o bairro selecionado para evitar reprocessamentos.
*/
const selected = useMemo(
() => gTBBairro.find((b) => String(b.tb_bairro_id) === String(field?.value ?? '')),
[gTBBairro, field?.value]
);
/**
* Manipulador de seleção com verificação segura.
*/
const handleSelect = useCallback(
(bairroId: string | number) => {
if (!field?.onChange) return;
field.onChange(bairroId);
setOpen(false);
},
[field],
);
/**
* Manipulador de seleção com verificação segura.
*/
const handleSelect = useCallback(
(bairroId: string | number) => {
if (!field?.onChange) return;
field.onChange(bairroId);
setOpen(false);
},
[field]
);
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"
>
{isLoading
? 'Carregando...'
: selected
? GetCapitalize(selected.descricao)
: 'Selecione...'}
<ChevronsUpDownIcon className="ml-2 h-4 w-4 shrink-0 opacity-50" />
</Button>
</FormControl>
</PopoverTrigger>
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"
>
{isLoading
? 'Carregando...'
: selected
? GetCapitalize(selected.descricao)
: 'Selecione...'}
<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 bairro..." disabled={isLoading} />
<CommandList>
<CommandEmpty>
{isLoading ? 'Carregando...' : 'Nenhum resultado encontrado.'}
</CommandEmpty>
<CommandGroup>
{gTBBairro.map((item) => (
<CommandItem
key={item.tb_bairro_id}
value={item.descricao?.toLowerCase() ?? ''}
onSelect={() => handleSelect(item.tb_bairro_id)}
>
<CheckIcon
className={cn(
'mr-2 h-4 w-4',
String(field?.value ?? '') === String(item.tb_bairro_id)
? 'opacity-100'
: 'opacity-0'
)}
/>
{GetCapitalize(item.descricao ?? '')}
</CommandItem>
))}
</CommandGroup>
</CommandList>
</Command>
</PopoverContent>
</Popover>
);
<PopoverContent className="w-full p-0">
<Command>
<CommandInput placeholder="Buscar bairro..." disabled={isLoading} />
<CommandList>
<CommandEmpty>
{isLoading ? 'Carregando...' : 'Nenhum resultado encontrado.'}
</CommandEmpty>
<CommandGroup>
{gTBBairro.map((item) => (
<CommandItem
key={item.tb_bairro_id}
value={item.descricao?.toLowerCase() ?? ''}
onSelect={() => handleSelect(item.tb_bairro_id)}
>
<CheckIcon
className={cn(
'mr-2 h-4 w-4',
String(field?.value ?? '') === String(item.tb_bairro_id)
? 'opacity-100'
: 'opacity-0',
)}
/>
{GetCapitalize(item.descricao ?? '')}
</CommandItem>
))}
</CommandGroup>
</CommandList>
</Command>
</PopoverContent>
</Popover>
);
}

View file

@ -1,5 +1,7 @@
'use client';
import { EllipsisIcon, PencilIcon, Trash2Icon } from 'lucide-react';
import { Button } from '@/components/ui/button';
import {
DropdownMenu,
@ -17,8 +19,10 @@ import {
TableHeader,
TableRow,
} from '@/components/ui/table';
import { EllipsisIcon, PencilIcon, Trash2Icon } from 'lucide-react';
import { GTBBairroInterface } from '../../_interfaces/GTBBairroInterface';
import { SituacoesEnum } from '@/shared/enums/SituacoesEnum';
import { GTBBairroInterface } from '../../interfaces/GTBBairro/GTBBairroInterface';
interface GTBBairroTableProps {
data: GTBBairroInterface[];
@ -29,18 +33,15 @@ interface GTBBairroTableProps {
/**
* Renderiza o badge de situação
*/
function StatusBadge({ situacao }: { situacao: 'A' | 'I' }) {
const isActive = situacao === 'A';
function StatusBadge({ situacao }: { situacao: SituacoesEnum }) {
const isActive = situacao === SituacoesEnum.A;
const baseClasses = 'text-xs font-medium px-2.5 py-0.5 rounded-sm me-2';
const activeClasses = 'bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-300';
const inactiveClasses = 'bg-yellow-100 text-yellow-800 dark:bg-yellow-900 dark:text-yellow-300';
return (
<span className={`${baseClasses} ${isActive ? activeClasses : inactiveClasses}`}>
{isActive ? 'Ativo' : 'Inativo'}
{situacao}
</span>
);
}

View file

@ -1,6 +0,0 @@
export default interface GTBairroSelectInterface {
field?: {
value?: number | string;
onChange?: (value: string | number) => void;
};
}

View file

@ -1,11 +1,10 @@
'use client';
import z from 'zod';
import { zodResolver } from '@hookform/resolvers/zod';
import { useEffect } from 'react';
import { useForm, Controller } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import z from 'zod';
import LoadingButton from '@/shared/components/loadingButton/LoadingButton';
import { Button } from '@/components/ui/button';
import { Checkbox } from '@/components/ui/checkbox';
import {
@ -27,9 +26,10 @@ import {
} from '@/components/ui/form';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import LoadingButton from '@/shared/components/loadingButton/LoadingButton';
import { GTBEstadoCivilSchema } from '../../_schemas/GTBEstadoCivilSchema';
import { GTBEstadoCivilInterface } from '../../_interfaces/GTBEstadoCivilInterface';
import { GTBEstadoCivilInterface } from '../../interfaces/GTBEstadoCivil/GTBEstadoCivilInterface';
import { GTBEstadoCivilSchema } from '../../schemas/GTBEstadoCivil/GTBEstadoCivilSchema';
type FormValues = z.infer<typeof GTBEstadoCivilSchema>;

View file

@ -1,21 +1,21 @@
'use client';
import { useEffect, useState, useCallback } from 'react';
import { Card, CardContent } from '@/components/ui/card';
import { useConfirmDialog } from '@/shared/components/confirmDialog/useConfirmDialog';
import Header from '@/shared/components/structure/Header';
import ConfirmDialog from '@/shared/components/confirmDialog/ConfirmDialog';
import { useConfirmDialog } from '@/shared/components/confirmDialog/useConfirmDialog';
import Loading from '@/shared/components/loading/loading';
import GTBEstadoCivilTable from '../../_components/g_tb_estadocivil/GTBEstadoCivilTable';
import GTBEstadoCivilForm from '../../_components/g_tb_estadocivil/GTBEstadoCivilForm';
import { useGTBEstadoCivilReadHook } from '../../_hooks/g_tb_estadocivil/useGTBEstadoCivilReadHook';
import { useGTBEstadoCivilSaveHook } from '../../_hooks/g_tb_estadocivil/useGTBEstadoCivilSaveHook';
import { useGTBEstadoCivilRemoveHook } from '../../_hooks/g_tb_estadocivil/useGTBEstadoCivilRemoveHook';
import { GTBEstadoCivilInterface } from '../../_interfaces/GTBEstadoCivilInterface';
import { useResponse } from '@/shared/components/response/ResponseContext';
import Header from '@/shared/components/structure/Header';
import GTBEstadoCivilForm from './GTBEstadoCivilForm';
import GTBEstadoCivilTable from './GTBEstadoCivilTable';
import { useGTBEstadoCivilReadHook } from '../../hooks/GTBEstadoCivil/useGTBEstadoCivilReadHook';
import { useGTBEstadoCivilRemoveHook } from '../../hooks/GTBEstadoCivil/useGTBEstadoCivilRemoveHook';
import { useGTBEstadoCivilSaveHook } from '../../hooks/GTBEstadoCivil/useGTBEstadoCivilSaveHook';
import { GTBEstadoCivilInterface } from '../../interfaces/GTBEstadoCivil/GTBEstadoCivilInterface';
const initalEstadoCivil: GTBEstadoCivilInterface = {
tb_estadocivil_id: 0,
@ -24,7 +24,7 @@ const initalEstadoCivil: GTBEstadoCivilInterface = {
situacao: 'A',
};
export default function TBEstadoCivilPage() {
export default function GTBEstadoCivilIndex() {
// Controle de exibição de respostas
const { setResponse } = useResponse();

View file

@ -1,5 +1,7 @@
'use client';
import { EllipsisIcon, PencilIcon, Trash2Icon } from 'lucide-react';
import { Button } from '@/components/ui/button';
import {
DropdownMenu,
@ -17,8 +19,8 @@ import {
TableHeader,
TableRow,
} from '@/components/ui/table';
import { EllipsisIcon, PencilIcon, Trash2Icon } from 'lucide-react';
import { GTBEstadoCivilInterface } from '../../_interfaces/GTBEstadoCivilInterface';
import { GTBEstadoCivilInterface } from '../../interfaces/GTBEstadoCivil/GTBEstadoCivilInterface';
interface TBEstadoCivilTableProps {
data: GTBEstadoCivilInterface[];

View file

@ -1,9 +1,9 @@
'use client';
import z from 'zod';
import { zodResolver } from '@hookform/resolvers/zod';
import { useEffect } from 'react';
import { useForm, Controller } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import z from 'zod';
import { Button } from '@/components/ui/button';
import { Checkbox } from '@/components/ui/checkbox';
@ -27,7 +27,7 @@ import {
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { GTBProfissaoSchema } from '../../_schemas/GTBProfissaoSchema';
import { GTBProfissaoSchema } from '../../schemas/GTBProfissao/GTBProfissaoSchema';
type FormValues = z.infer<typeof GTBProfissaoSchema>;

View file

@ -1,23 +1,21 @@
'use client';
import { useEffect, useState, useCallback } from 'react';
import { Card, CardContent } from '@/components/ui/card';
import Loading from '@/shared/components/loading/loading';
import GTBProfissaoTable from '../../_components/g_tb_profissao/GTBProfissaoTable';
import GTBProfissaoForm from '../../_components/g_tb_profissao/GTBProfissaoForm';
import { useGTBProfissaoReadHook } from '../../_hooks/g_tb_profissao/useGTBProfissaoReadHook';
import { useGTBProfissaoSaveHook } from '../../_hooks/g_tb_profissao/useGTBProfissaoSaveHook';
import { useGTBProfissaoRemoveHook } from '../../_hooks/g_tb_profissao/useGTBProfissaoRemoveHook';
import { useGTBProfissaoReadHook } from '@/packages/administrativo/hooks/GTBProfissao/useGTBProfissaoReadHook';
import { useGTBProfissaoRemoveHook } from '@/packages/administrativo/hooks/GTBProfissao/useGTBProfissaoRemoveHook';
import { useGTBProfissaoSaveHook } from '@/packages/administrativo/hooks/GTBProfissao/useGTBProfissaoSaveHook';
import ConfirmDialog from '@/shared/components/confirmDialog/ConfirmDialog';
import { useConfirmDialog } from '@/shared/components/confirmDialog/useConfirmDialog';
import GTBProfissaoInterface from '../../_interfaces/GTBProfissaoInterface';
import Loading from '@/shared/components/loading/loading';
import Header from '@/shared/components/structure/Header';
export default function TTBAndamentoServico() {
import GTBProfissaoForm from './GTBProfissaoForm';
import GTBProfissaoTable from './GTBProfissaoTable';
import GTBProfissaoInterface from '../../interfaces/GTBProfissao/GTBProfissaoInterface';
export default function GTBProfissaoIndex() {
// Hooks para leitura e salvamento
const { gTBProfissao, fetchGTBProfissao } = useGTBProfissaoReadHook();
const { saveGTBProfissao } = useGTBProfissaoSaveHook();

View file

@ -1,5 +1,7 @@
'use client';
import { EllipsisIcon, PencilIcon, Trash2Icon } from 'lucide-react';
import { Button } from '@/components/ui/button';
import {
DropdownMenu,
@ -18,8 +20,7 @@ import {
TableRow,
} from '@/components/ui/table';
import { EllipsisIcon, PencilIcon, Trash2Icon } from 'lucide-react';
import GTBProfissaoInterface from '../../_interfaces/GTBProfissaoInterface';
import GTBProfissaoInterface from '../../interfaces/GTBProfissao/GTBProfissaoInterface';
interface GTBProfissaoTableProps {
data: GTBProfissaoInterface[];

View file

@ -1,8 +1,9 @@
'use client';
import z from 'zod';
import { useForm, Controller } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { useEffect } from 'react';
import { useForm, Controller } from 'react-hook-form';
import z from 'zod';
import { Button } from '@/components/ui/button';
import { Checkbox } from '@/components/ui/checkbox';
@ -25,9 +26,8 @@ import {
} from '@/components/ui/form';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { GTBRegimeBensSchema } from '@/packages/administrativo/schemas/GTBRegimeBens/GTBRegimeBensSchema';
import { GTBRegimeBensSchema } from '../../_schemas/GTBRegimeBensSchema';
import { useEffect } from 'react';
type FormValues = z.infer<typeof GTBRegimeBensSchema>;

View file

@ -1,23 +1,21 @@
'use client';
import { useEffect, useState, useCallback } from 'react';
import { Card, CardContent } from '@/components/ui/card';
import Loading from '@/shared/components/loading/loading';
import GTBRegimeBensTable from '../../_components/g_tb_regimebens/GTBRegimeBensTable';
import GTBRegimeBensForm from '../../_components/g_tb_regimebens/GTBRegimeBensForm';
import { useGTBRegimeBensReadHook } from '../../_hooks/g_tb_regimebens/useGTBRegimeBensReadHook';
import { useGTBRegimeBensSaveHook } from '../../_hooks/g_tb_regimebens/useGTBRegimeBensSaveHook';
import { useGTBRegimeBensRemoveHook } from '../../_hooks/g_tb_regimebens/useGTBRegimeBensRemoveHook';
import GTBRegimeBensForm from '@/packages/administrativo/components/GTBRegimeBens/GTBRegimeBensForm';
import GTBRegimeBensTable from '@/packages/administrativo/components/GTBRegimeBens/GTBRegimeBensTable';
import ConfirmDialog from '@/shared/components/confirmDialog/ConfirmDialog';
import { useConfirmDialog } from '@/shared/components/confirmDialog/useConfirmDialog';
import GTBRegimeBensInterface from '../../_interfaces/GTBRegimeBensInterface';
import Loading from '@/shared/components/loading/loading';
import Header from '@/shared/components/structure/Header';
export default function TTBAndamentoServico() {
import { useGTBRegimeBensReadHook } from '../../hooks/GTBRegimeBens/useGTBRegimeBensReadHook';
import { useGTBRegimeBensRemoveHook } from '../../hooks/GTBRegimeBens/useGTBRegimeBensRemoveHook';
import { useGTBRegimeBensSaveHook } from '../../hooks/GTBRegimeBens/useGTBRegimeBensSaveHook';
import GTBRegimeBensInterface from '../../interfaces/GTBRegimeBens/GTBRegimeBensInterface';
export default function GTBRegimeBensIndex() {
// Hooks para leitura e salvamento
const { gTBRegimeBens, fetchGTBRegimeBens } = useGTBRegimeBensReadHook();
const { saveGTBRegimeComunhao } = useGTBRegimeBensSaveHook();

View file

@ -1,5 +1,7 @@
'use client';
import { EllipsisIcon, PencilIcon, Trash2Icon } from 'lucide-react';
import { Button } from '@/components/ui/button';
import {
DropdownMenu,
@ -17,9 +19,7 @@ import {
TableHeader,
TableRow,
} from '@/components/ui/table';
import { EllipsisIcon, PencilIcon, Trash2Icon } from 'lucide-react';
import GTBRegimeBensInterface from '../../_interfaces/GTBRegimeBensInterface';
import GTBRegimeBensInterface from '@/packages/administrativo/interfaces/GTBRegimeBens/GTBRegimeBensInterface';
interface GTBRegimeBensTableProps {
data: GTBRegimeBensInterface[];

View file

@ -1,9 +1,9 @@
'use client';
import z from 'zod';
import { zodResolver } from '@hookform/resolvers/zod';
import { useEffect } from 'react';
import { useForm, Controller } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import z from 'zod';
import { Button } from '@/components/ui/button';
import { Checkbox } from '@/components/ui/checkbox';
@ -26,8 +26,6 @@ import {
} from '@/components/ui/form';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { GTBRegimeComunhaoSchema } from '../../_schemas/GTBRegimeComunhaoSchema';
import {
Select,
SelectContent,
@ -35,7 +33,9 @@ import {
SelectTrigger,
SelectValue,
} from '@/components/ui/select';
import { useGTBRegimeBensReadHook } from '../../_hooks/g_tb_regimebens/useGTBRegimeBensReadHook';
import { useGTBRegimeBensReadHook } from '../../hooks/GTBRegimeBens/useGTBRegimeBensReadHook';
import { GTBRegimeComunhaoSchema } from '../../schemas/GTBRegimeComunhao/GTBRegimeComunhaoSchema';
type FormValues = z.infer<typeof GTBRegimeComunhaoSchema>;

View file

@ -1,23 +1,22 @@
'use client';
import { useEffect, useState, useCallback } from 'react';
import { Card, CardContent } from '@/components/ui/card';
import Loading from '@/shared/components/loading/loading';
import GTBRegimeComunhaoTable from '../../_components/g_tb_regimecomunhao/GTBRegimeComunhaoTable';
import GTBRegimeComunhaoForm from '../../_components/g_tb_regimecomunhao/GTBRegimeComunhaoForm';
import { useGTBRegimeComunhaoReadHook } from '../../_hooks/g_tb_regimecomunhao/useGTBRegimeComunhaoReadHook';
import { useGTBRegimeComunhaoSaveHook } from '../../_hooks/g_tb_regimecomunhao/useGTBRegimeComunhaoSaveHook';
import { useGTBRegimeComunhaoRemoveHook } from '../../_hooks/g_tb_regimecomunhao/useGTBRegimeComunhaoRemoveHook';
import ConfirmDialog from '@/shared/components/confirmDialog/ConfirmDialog';
import { useConfirmDialog } from '@/shared/components/confirmDialog/useConfirmDialog';
import GTBRegimeComunhaoInterface from '../../_interfaces/GTBRegimeComunhaoInterface';
import Loading from '@/shared/components/loading/loading';
import Header from '@/shared/components/structure/Header';
export default function TTBAndamentoServico() {
import GTBRegimeComunhaoForm from './GTBRegimeComunhaoForm';
import GTBRegimeComunhaoTable from './GTBRegimeComunhaoTable';
import { useGTBRegimeComunhaoReadHook } from '../../hooks/GTBRegimeComunhao/useGTBRegimeComunhaoReadHook';
import { useGTBRegimeComunhaoRemoveHook } from '../../hooks/GTBRegimeComunhao/useGTBRegimeComunhaoRemoveHook';
import { useGTBRegimeComunhaoSaveHook } from '../../hooks/GTBRegimeComunhao/useGTBRegimeComunhaoSaveHook';
import GTBRegimeComunhaoInterface from '../../interfaces/GTBRegimeComunhao/GTBRegimeComunhaoInterface';
export default function GTBRegimeComunhaoIndex() {
// Hooks para leitura e salvamento
const { gTBRegimeComunhao, fetchGTBRegimeComunhao } = useGTBRegimeComunhaoReadHook();
const { saveGTBRegimeComunhao } = useGTBRegimeComunhaoSaveHook();

View file

@ -1,5 +1,7 @@
'use client';
import { EllipsisIcon, PencilIcon, Trash2Icon } from 'lucide-react';
import { Button } from '@/components/ui/button';
import {
DropdownMenu,
@ -18,8 +20,7 @@ import {
TableRow,
} from '@/components/ui/table';
import { EllipsisIcon, PencilIcon, Trash2Icon } from 'lucide-react';
import GTBRegimeComunhaoInterface from '../../_interfaces/GTBRegimeComunhaoInterface';
import GTBRegimeComunhaoInterface from '../../interfaces/GTBRegimeComunhao/GTBRegimeComunhaoInterface';
interface GTBRegimeComunhaoTableProps {
data: GTBRegimeComunhaoInterface[];

View file

@ -1,9 +1,9 @@
'use client';
import z from 'zod';
import { zodResolver } from '@hookform/resolvers/zod';
import { useEffect } from 'react';
import { useForm, Controller } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import z from 'zod';
import { Button } from '@/components/ui/button';
import { Checkbox } from '@/components/ui/checkbox';
@ -26,11 +26,10 @@ import {
} from '@/components/ui/form';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import LoadingButton from '@/shared/components/loadingButton/LoadingButton';
import { GTBTipoLogradouroSchema } from '../../_schemas/GTBTipoLogradouroSchema';
import { GTBTipoLogradouroInterface } from '../../_interfaces/GTBTipoLogradouroInterface';
import { GTBTipoLogradouroInterface } from '../../interfaces/GTBTipoLogradouro/GTBTipoLogradouroInterface';
import { GTBTipoLogradouroSchema } from '../../schemas/GTBTipoLogradouro/GTBTipoLogradouroSchema';
type FormValues = z.infer<typeof GTBTipoLogradouroSchema>;

View file

@ -1,24 +1,23 @@
'use client';
import { useEffect, useState, useCallback } from 'react';
import { Card, CardContent } from '@/components/ui/card';
import { useConfirmDialog } from '@/shared/components/confirmDialog/useConfirmDialog';
import Header from '@/shared/components/structure/Header';
import ConfirmDialog from '@/shared/components/confirmDialog/ConfirmDialog';
import { useConfirmDialog } from '@/shared/components/confirmDialog/useConfirmDialog';
import Loading from '@/shared/components/loading/loading';
import GTBTipoLogradouroTable from '../../_components/g_tb_tipologradouro/GTBTipoLogradouroTable';
import GTBTipoLogradouroForm from '../../_components/g_tb_tipologradouro/GTBTipoLogradouroForm';
import { useGTBTipoLogradouroReadHook } from '../../_hooks/g_tb_tipologradouro/useGTBTipoLogradouroReadHook';
import { useGTBTipoLogradouroSaveHook } from '../../_hooks/g_tb_tipologradouro/useGTBTipoLogradouroSaveHook';
import { useGTBTipoLogradouroRemoveHook } from '../../_hooks/g_tb_tipologradouro/useGTBTipoLogradouroRemoveHook';
import { GTBTipoLogradouroInterface } from '../../_interfaces/GTBTipoLogradouroInterface';
import { useResponse } from '@/shared/components/response/ResponseContext';
import Header from '@/shared/components/structure/Header';
export default function TTBAndamentoServico() {
import GTBTipoLogradouroForm from './GTBTipoLogradouroForm';
import GTBTipoLogradouroTable from './GTBTipoLogradouroTable';
import { useGTBTipoLogradouroReadHook } from '../../hooks/GTBTipoLogradouro/useGTBTipoLogradouroReadHook';
import { useGTBTipoLogradouroRemoveHook } from '../../hooks/GTBTipoLogradouro/useGTBTipoLogradouroRemoveHook';
import { useGTBTipoLogradouroSaveHook } from '../../hooks/GTBTipoLogradouro/useGTBTipoLogradouroSaveHook';
import { GTBTipoLogradouroInterface } from '../../interfaces/GTBTipoLogradouro/GTBTipoLogradouroInterface';
export default function GTBTipoLogradouroIndex() {
// Controle de exibição de respostas
const { setResponse } = useResponse();

View file

@ -1,5 +1,7 @@
'use client';
import { EllipsisIcon, PencilIcon, Trash2Icon } from 'lucide-react';
import { Button } from '@/components/ui/button';
import {
DropdownMenu,
@ -17,8 +19,8 @@ import {
TableHeader,
TableRow,
} from '@/components/ui/table';
import { EllipsisIcon, PencilIcon, Trash2Icon } from 'lucide-react';
import { GTBTipoLogradouroInterface } from '../../_interfaces/GTBTipoLogradouroInterface';
import { GTBTipoLogradouroInterface } from '../../interfaces/GTBTipoLogradouro/GTBTipoLogradouroInterface';
interface GTBTipoLogradouroTableProps {
data: GTBTipoLogradouroInterface[];

View file

@ -0,0 +1,124 @@
import { ColumnDef } from '@tanstack/react-table';
import { EllipsisIcon, PencilIcon, Trash2Icon } from 'lucide-react';
import { Button } from '@/components/ui/button';
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuGroup,
DropdownMenuItem,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu';
import GetCapitalize from '@/shared/actions/text/GetCapitalize';
import { SortableHeader } from '@/shared/components/dataTable/SortableHeader';
import { ConfirmacaoEnum } from '@/shared/enums/ConfirmacaoEnum';
import { SituacoesEnum } from '@/shared/enums/SituacoesEnum';
import { TipoDaParteEnum } from '@/shared/enums/TIpoDaParteEnum';
import TAtoParteTipoInterface from '../../interfaces/TAtoParteTipo/TAtoParteTipoInterface';
export default function TAtoParteTipoColumns(
onEdit: (item: TAtoParteTipoInterface, isEditingFormStatus: boolean) => void,
onDelete: (item: TAtoParteTipoInterface, isEditingFormStatus: boolean) => void,
): ColumnDef<TAtoParteTipoInterface>[] {
return [
// ID
{
accessorKey: 'ato_partetipo_id',
header: ({ column }) => SortableHeader('#', column),
cell: ({ row }) => Number(row.getValue('ato_partetipo_id')),
enableSorting: false,
},
// Descrição
{
accessorKey: 'descricao',
header: ({ column }) => SortableHeader('Descrição', column),
cell: ({ row }) => GetCapitalize(row.getValue('descricao')),
},
// Tipo de Parte
{
accessorKey: 'tipo_parte',
header: ({ column }) => SortableHeader('Tipo Parte', column),
cell: ({ row }) => {
const value = row.getValue('tipo_parte') as keyof typeof TipoDaParteEnum;
return TipoDaParteEnum[value] ?? '-';
},
},
// Auto Qualifica
{
accessorKey: 'auto_qualifica',
header: ({ column }) => SortableHeader('Auto Qualifica', column),
cell: ({ row }) => {
const value = row.getValue('auto_qualifica') as keyof typeof ConfirmacaoEnum;
return ConfirmacaoEnum[value] ?? '-';
},
},
// Declara DOI
{
accessorKey: 'declara_doi',
header: ({ column }) => SortableHeader('Declara DOI', column),
cell: ({ row }) => {
const value = row.getValue('declara_doi') as keyof typeof ConfirmacaoEnum;
return ConfirmacaoEnum[value] ?? '-';
},
},
// Possui Documento Externo
{
accessorKey: 'possui_documento_ext',
header: ({ column }) => SortableHeader('Doc. Externo', column),
cell: ({ row }) => {
const value = row.getValue('possui_documento_ext') as keyof typeof ConfirmacaoEnum;
return ConfirmacaoEnum[value] ?? '-';
},
},
// Situação
{
accessorKey: 'situacao',
header: ({ column }) => SortableHeader('Situação', column),
cell: ({ row }) => {
const value = row.getValue('situacao') as keyof typeof SituacoesEnum;
return SituacoesEnum[value] ?? '-';
},
},
// Ações
{
id: 'actions',
header: 'Ações',
cell: ({ row }) => {
const imovel = row.original;
return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="ghost" size="icon">
<EllipsisIcon />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent side="left" align="start">
<DropdownMenuGroup>
<DropdownMenuItem onSelect={() => onEdit(imovel, true)}>
<PencilIcon className="mr-2 h-4 w-4" />
Editar
</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem className="text-red-600" onSelect={() => onDelete(imovel, true)}>
<Trash2Icon className="mr-2 h-4 w-4" />
Remover
</DropdownMenuItem>
</DropdownMenuGroup>
</DropdownMenuContent>
</DropdownMenu>
);
},
enableSorting: false,
enableHiding: false,
},
];
}

View file

@ -0,0 +1,217 @@
'use client';
import React, { useEffect } from 'react';
import { Button } from '@/components/ui/button';
import {
Dialog,
DialogClose,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle,
} from '@/components/ui/dialog';
import {
Form,
FormControl,
FormField,
FormItem,
FormLabel,
FormMessage,
} from '@/components/ui/form';
import { Input } from '@/components/ui/input';
import { Switch } from '@/components/ui/switch';
import { parseNumberInput } from '@/shared/actions/form/parseNumberInput';
import { ResetFormIfData } from '@/shared/actions/form/ResetFormIfData';
import LoadingButton from '@/shared/components/loadingButton/LoadingButton';
import TipoDaParteSelect from '@/shared/components/tipoDaParte/TipoDaParteSelect';
import { useTAtoParteTipoFormHook } from '../../hooks/TAtoParteTipo/useTAtoParteTipoFormHook';
import { TAtoParteTipoFormInterface } from '../../interfaces/TAtoParteTipo/TAtoParteTipoFormInterface';
import TCensecQualidadeSelect from '../TCensecQualidade/TCensecQualidadeSelect';
export default function TAtoParteTipoForm({
isOpen,
data,
onClose,
onSave,
buttonIsLoading,
}: TAtoParteTipoFormInterface) {
// Inicializa o react-hook-form com schema zod
const form = useTAtoParteTipoFormHook({});
// Atualiza o formulário quando recebe dados para edição
useEffect(() => {
// Se existir dados, reseta o formulário com os mesmos
ResetFormIfData(form, data);
}, [data, form]);
function onError(error: any) {
console.log(error);
}
return (
<Dialog
open={isOpen}
onOpenChange={(open) => {
if (!open) onClose(null, false);
}}
>
<DialogContent className="w-full max-w-full p-6 sm:max-w-3xl md:max-w-2xl lg:max-w-2xl">
<DialogHeader>
<DialogTitle>Tipo de Partes do Ato</DialogTitle>
<DialogDescription>Tipo de Partes do Ato</DialogDescription>
</DialogHeader>
<Form {...form}>
<form onSubmit={form.handleSubmit(onSave, onError)} className="space-y-6">
<div className="grid w-full grid-cols-12 gap-4">
{/* Descrição */}
<div className="col-span-12 sm:col-span-12 md:col-span-12">
<FormField
control={form.control}
name="descricao"
render={({ field }) => (
<FormItem>
<FormLabel>Descrição</FormLabel>
<FormControl>
<Input {...field} type="text" placeholder="Descrição" />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
</div>
{/* Tipo da Parte */}
<div className="col-span-12 sm:col-span-12 md:col-span-12">
<FormField
control={form.control}
name="tipo_parte"
render={({ field }) => (
<FormItem>
<FormLabel>Tipo da Parte</FormLabel>
<TipoDaParteSelect field={field} />
<FormMessage />
</FormItem>
)}
/>
</div>
{/* Qualidade */}
<div className="col-span-12 sm:col-span-12 md:col-span-12">
<FormField
control={form.control}
name="censec_qualidade_id"
render={({ field }) => (
<FormItem>
<FormLabel>Censec Qualidade</FormLabel>
<TCensecQualidadeSelect field={field} />
<FormMessage />
</FormItem>
)}
/>
</div>
{/* Auto Qualifica */}
<div className="col-span-12 sm:col-span-6 md:col-span-4">
<FormField
control={form.control}
name="auto_qualifica"
render={({ field }) => (
<FormItem className="flex flex-col space-y-1">
<FormLabel>Auto Qualifica</FormLabel>
<FormControl>
<Switch
checked={field.value === 'S'}
onCheckedChange={(checked: boolean) =>
field.onChange(checked ? 'S' : 'N')
}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
</div>
{/* Declara Doi */}
<div className="col-span-12 sm:col-span-6 md:col-span-4">
<FormField
control={form.control}
name="declara_doi"
render={({ field }) => (
<FormItem className="flex flex-col space-y-1">
<FormLabel>Declarar Doi</FormLabel>
<FormControl>
<Switch
checked={field.value === 'S'}
onCheckedChange={(checked: boolean) =>
field.onChange(checked ? 'S' : 'N')
}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
</div>
{/* Possui Documento Externo */}
<div className="col-span-12 sm:col-span-6 md:col-span-4">
<FormField
control={form.control}
name="possui_documento_ext"
render={({ field }) => (
<FormItem className="flex flex-col space-y-1">
<FormLabel>Possui Documento Externo</FormLabel>
<FormControl>
<Switch
checked={field.value === 'S'}
onCheckedChange={(checked: boolean) =>
field.onChange(checked ? 'S' : 'N')
}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
</div>
{/* Situação */}
<div className="col-span-12 sm:col-span-6 md:col-span-4">
<FormField
control={form.control}
name="situacao"
render={({ field }) => (
<FormItem className="flex flex-col space-y-1">
<FormLabel>Situação</FormLabel>
<FormControl>
<Switch
checked={field.value === 'S'}
onCheckedChange={(checked: boolean) =>
field.onChange(checked ? 'A' : 'I')
}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
</div>
</div>
{/* Rodapé do Dialog */}
<DialogFooter className="mt-4 flex flex-col justify-end gap-2 sm:flex-row">
<DialogClose asChild>
<Button variant="outline" type="button" onClick={() => onClose(null, false)}>
Cancelar
</Button>
</DialogClose>
<LoadingButton
text="Salvar"
textLoading="Aguarde..."
type="submit"
loading={buttonIsLoading}
/>
</DialogFooter>
</form>
</Form>
</DialogContent>
</Dialog>
);
}

View file

@ -0,0 +1,170 @@
'use client';
import { useEffect, useState, useCallback } from 'react';
import { useTAtoParteTipoDeleteHook } from '@/packages/administrativo/hooks/TAtoParteTipo/useTAtoParteTipoDeleteHook';
import { useTAtoParteTipoIndexHook } from '@/packages/administrativo/hooks/TAtoParteTipo/useTAtoParteTipoIndexHook';
import { useTAtoParteTipoSaveHook } from '@/packages/administrativo/hooks/TAtoParteTipo/useTAtoParteTipoSaveHook';
import TAtoParteTipoInterface from '@/packages/administrativo/interfaces/TAtoParteTipo/TAtoParteTipoInterface';
import ConfirmDialog from '@/shared/components/confirmDialog/ConfirmDialog';
import { useConfirmDialog } from '@/shared/components/confirmDialog/useConfirmDialog';
import Loading from '@/shared/components/loading/loading';
import Header from '@/shared/components/structure/Header';
import TAtoParteTipoForm from './TAtoParteTipoForm';
import TAtoParteTipoTable from './TAtoParteTipoTable';
export default function TAtoParteTipoIndex() {
// Controle de estado do botão
const [buttonIsLoading, setButtonIsLoading] = useState(false);
// Hooks para leitura e salvamento
const { tAtoParteTipo, indexTAtoParteTipo } = useTAtoParteTipoIndexHook();
const { saveTAtoParteTipo } = useTAtoParteTipoSaveHook();
const { deleteTAtoParteTipo } = useTAtoParteTipoDeleteHook();
// Estados
const [selectedData, setSelectedData] = useState<TAtoParteTipoInterface | null>(null);
const [isFormOpen, setIsFormOpen] = useState(false);
// Estado para saber qual item será deletado
const [itemToDelete, setItemToDelete] = useState<TAtoParteTipoInterface | null>(null);
/**
* Hook do modal de confirmação
*/
const {
isOpen: isConfirmOpen,
openDialog: openConfirmDialog,
handleConfirm,
handleCancel,
} = useConfirmDialog();
/**
* Abre o formulário no modo de edição ou criação
*/
const handleOpenForm = useCallback((data: TAtoParteTipoInterface | null) => {
// Se não houver dados (criação), cria um objeto inicial com pessoa_tipo
setSelectedData(data);
setIsFormOpen(true);
}, []);
/**
* Fecha o formulário e limpa o andamento selecionado
*/
const handleCloseForm = useCallback(() => {
setSelectedData(null);
setIsFormOpen(false);
}, []);
/**
* Salva os dados do formulário
*/
const handleSave = useCallback(
async (formData: TAtoParteTipoInterface) => {
// Coloca o botão em estado de loading
setButtonIsLoading(true);
// Aguarda salvar o registro
await saveTAtoParteTipo(formData);
// Remove o botão em estado de loading
setButtonIsLoading(false);
// Atualiza a lista de dados
indexTAtoParteTipo();
},
[saveTAtoParteTipo, indexTAtoParteTipo, handleCloseForm],
);
/**
* Quando o usuário clica em "remover" na tabela
*/
const handleConfirmDelete = useCallback(
(item: TAtoParteTipoInterface) => {
// Define o item atual para remoção
setItemToDelete(item);
// Abre o modal de confirmação
openConfirmDialog();
},
[openConfirmDialog],
);
/**
* Executa a exclusão de fato quando o usuário confirma
*/
const handleDelete = useCallback(async () => {
// Protege contra null
if (!itemToDelete) return;
// Executa o Hook de remoção
await deleteTAtoParteTipo(itemToDelete);
// Atualiza a lista
await indexTAtoParteTipo();
// Limpa o item selecionado
setItemToDelete(null);
// Fecha o modal
handleCancel();
}, [itemToDelete, indexTAtoParteTipo, handleCancel]);
/**
* Busca inicial dos dados
*/
useEffect(() => {
indexTAtoParteTipo();
}, []);
/**
* Tela de loading enquanto carrega os dados
*/
if (tAtoParteTipo?.length == 0) {
return <Loading type={2} />;
}
return (
<div>
{/* Cabeçalho */}
<Header
title={'Tipos de Partes'}
description={'Tipos de Partes'}
buttonText={'Novo tipo de parte'}
buttonAction={() => {
handleOpenForm(null);
}}
/>
{/* Tabela de andamentos */}
<TAtoParteTipoTable
data={tAtoParteTipo}
onEdit={handleOpenForm}
onDelete={handleConfirmDelete}
/>
{/* Modal de confirmação */}
{isConfirmOpen && (
<ConfirmDialog
isOpen={isConfirmOpen}
title="Confirmar exclusão"
description="Atenção"
message={`Deseja realmente excluir o imóvel "${itemToDelete?.descricao}"?`}
confirmText="Sim, excluir"
cancelText="Cancelar"
onConfirm={handleDelete}
onCancel={handleCancel}
/>
)}
{/* Formulário de criação/edição */}
{isFormOpen && (
<TAtoParteTipoForm
isOpen={isFormOpen}
data={selectedData}
onClose={handleCloseForm}
onSave={handleSave}
buttonIsLoading={buttonIsLoading}
/>
)}
</div>
);
}

View file

@ -0,0 +1,27 @@
'use client';
import { DataTable } from '@/shared/components/dataTable/DataTable';
import TAtoParteTipoColumns from './TAtoParteTipoColumns';
import TAtoParteTipoTableInterface from '../../interfaces/TAtoParteTipo/TAtoParteTipoTableInterface';
/**
* Componente principal da tabela
*/
export default function TAtoParteTipoTable({
data,
onEdit,
onDelete,
}: TAtoParteTipoTableInterface) {
const columns = TAtoParteTipoColumns(onEdit, onDelete);
return (
<div>
<DataTable
data={data}
columns={columns}
filterColumn="descricao"
filterPlaceholder="Busque pela descrição..."
/>
</div>
);
}

View file

@ -1,9 +1,9 @@
'use client';
import z from 'zod';
import { zodResolver } from '@hookform/resolvers/zod';
import { useEffect } from 'react';
import { useForm, Controller } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import z from 'zod';
import { Button } from '@/components/ui/button';
import { Checkbox } from '@/components/ui/checkbox';
@ -26,10 +26,9 @@ import {
} from '@/components/ui/form';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { TCensecSchema } from '../../_schemas/TCensecSchema';
import { SituacoesEnum } from '@/shared/enums/SituacoesEnum';
import { TCensecSchema } from '@/packages/administrativo/schemas/TCensec/TCensecSchema';
import LoadingButton from '@/shared/components/loadingButton/LoadingButton';
import { SituacoesEnum } from '@/shared/enums/SituacoesEnum';
type FormValues = z.infer<typeof TCensecSchema>;

View file

@ -1,23 +1,22 @@
'use client';
import { useEffect, useState, useCallback } from 'react';
import { Card, CardContent } from '@/components/ui/card';
import Loading from '@/shared/components/loading/loading';
import TCensecTable from '../../_components/t_censec/TCensecTable';
import TCensecForm from '../../_components/t_censec/TCensecForm';
import { useTCensecReadHook } from '../../_hooks/t_censec/useTCensecReadHook';
import { useTCensecSaveHook } from '../../_hooks/t_censec/useTCensecSaveHook';
import { useTCensecDeleteHook } from '../../_hooks/t_censec/useTCensecDeleteHook';
import ConfirmDialog from '@/shared/components/confirmDialog/ConfirmDialog';
import { useConfirmDialog } from '@/shared/components/confirmDialog/useConfirmDialog';
import TCensecInterface from '../../_interfaces/TCensecInterface';
import Loading from '@/shared/components/loading/loading';
import Header from '@/shared/components/structure/Header';
export default function TTBAndamentoServico() {
import TCensecForm from './TCensecForm';
import TCensecTable from './TCensecTable';
import { useTCensecDeleteHook } from '../../hooks/TCensec/useTCensecDeleteHook';
import { useTCensecReadHook } from '../../hooks/TCensec/useTCensecReadHook';
import { useTCensecSaveHook } from '../../hooks/TCensec/useTCensecSaveHook';
import TCensecInterface from '../../interfaces/TCensec/TCensecInterface';
export default function TCensecIndex() {
// Controle de estado do botão
const [buttonIsLoading, setButtonIsLoading] = useState(false);

View file

@ -1,5 +1,7 @@
'use client';
import { EllipsisIcon, PencilIcon, Trash2Icon } from 'lucide-react';
import { Button } from '@/components/ui/button';
import {
DropdownMenu,
@ -17,9 +19,7 @@ import {
TableHeader,
TableRow,
} from '@/components/ui/table';
import { EllipsisIcon, PencilIcon, Trash2Icon } from 'lucide-react';
import TCensecInterface from '../../_interfaces/TCensecInterface';
import TCensecInterface from '@/packages/administrativo/interfaces/TCensec//TCensecInterface';
interface TCensecTableProps {
data: TCensecInterface[];

View file

@ -1,11 +1,10 @@
'use client';
import z from 'zod';
import { zodResolver } from '@hookform/resolvers/zod';
import { useEffect } from 'react';
import { useForm, Controller } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import z from 'zod';
import LoadingButton from '@/shared/components/loadingButton/LoadingButton';
import { Button } from '@/components/ui/button';
import { Checkbox } from '@/components/ui/checkbox';
import {
@ -27,8 +26,10 @@ import {
} from '@/components/ui/form';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { TCensecNaturezaLitigioSchema } from '../../_schemas/TCensecNaturezaLitigioSchema';
import { TCensecNaturezaLitigioSchema } from '@/packages/administrativo/schemas/TCensecNaturezaLitigio/TCensecNaturezaLitigioSchema';
import LoadingButton from '@/shared/components/loadingButton/LoadingButton';
import SituacoesSelect from '@/shared/components/situacoes/SituacoesSelect';
import { SituacoesEnum } from '@/shared/enums/SituacoesEnum';
type FormValues = z.infer<typeof TCensecNaturezaLitigioSchema>;
@ -52,7 +53,7 @@ export default function TCensecNaturezaLitigioForm({
defaultValues: {
censec_naturezalitigio_id: 0,
descricao: '',
situacao: 'A',
situacao: SituacoesEnum.A,
},
});
@ -96,10 +97,7 @@ export default function TCensecNaturezaLitigioForm({
control={form.control}
render={({ field }) => (
<div className="flex items-center space-x-2">
<Checkbox
checked={field.value === 'A'}
onCheckedChange={(checked) => field.onChange(checked ? 'A' : 'I')}
/>
<SituacoesSelect field={field} />
<Label>Ativo</Label>
</div>
)}

View file

@ -1,31 +1,30 @@
'use client';
import { useEffect, useState, useCallback } from 'react';
import { Card, CardContent } from '@/components/ui/card';
import { useConfirmDialog } from '@/shared/components/confirmDialog/useConfirmDialog';
import { useResponse } from '@/shared/components/response/ResponseContext';
import Header from '@/shared/components/structure/Header';
import { useTCensecNaturezaLitigioReadHook } from '@/packages/administrativo/hooks/TCensecNaturezaLitigio/useTCensecNaturezaLitigioReadHook';
import { useTCensecNaturezaLitigioRemoveHook } from '@/packages/administrativo/hooks/TCensecNaturezaLitigio/useTCensecNaturezaLitigioRemoveHook';
import { useTCensecNaturezaLitigioSaveHook } from '@/packages/administrativo/hooks/TCensecNaturezaLitigio/useTCensecNaturezaLitigioSaveHook';
import ConfirmDialog from '@/shared/components/confirmDialog/ConfirmDialog';
import { useConfirmDialog } from '@/shared/components/confirmDialog/useConfirmDialog';
import Loading from '@/shared/components/loading/loading';
import TCensecNaturezaLitigioTable from '../../_components/t_censecnaturezalitigio/TCensecNaturezaLitigioTable';
import TCensecNaturezaLitigioForm from '../../_components/t_censecnaturezalitigio/TCensecNaturezaLitigioForm';
import { useTCensecNaturezaLitigioReadHook } from '../../_hooks/t_censecnaturezalitigio/useTCensecNaturezaLitigioReadHook';
import { useTCensecNaturezaLitigioSaveHook } from '../../_hooks/t_censecnaturezalitigio/useTCensecNaturezaLitigioSaveHook';
import { useTCensecNaturezaLitigioRemoveHook } from '../../_hooks/t_censecnaturezalitigio/useTCensecNaturezaLitigioRemoveHook';
import { TCensecNaturezaLitigioInterface } from '../../_interfaces/TCensecNaturezaLitigioInterface';
import { useResponse } from '@/shared/components/response/ResponseContext';
import Header from '@/shared/components/structure/Header';
import { SituacoesEnum } from '@/shared/enums/SituacoesEnum';
import TCensecNaturezaLitigioForm from './TCensecNaturezaLitigioForm';
import TCensecNaturezaLitigioTable from './TCensecNaturezaLitigioTable';
import { TCensecNaturezaLitigioInterface } from '../../interfaces/TCensecNaturezaLitigio/TCensecNaturezaLitigioInterface';
const initialCensecNaturezaLitigio: TCensecNaturezaLitigioInterface = {
censec_naturezalitigio_id: 0,
descricao: '',
situacao: SituacoesEnum.A,
};
export default function TCensecNaturezaLitigioPage() {
export default function TCensecNaturezaLitigioIndex() {
// Controle de exibição de respostas
const { setResponse } = useResponse();

View file

@ -1,5 +1,7 @@
'use client';
import { EllipsisIcon, PencilIcon, Trash2Icon } from 'lucide-react';
import { Button } from '@/components/ui/button';
import {
DropdownMenu,
@ -17,8 +19,8 @@ import {
TableHeader,
TableRow,
} from '@/components/ui/table';
import { EllipsisIcon, PencilIcon, Trash2Icon } from 'lucide-react';
import { TCensecNaturezaLitigioInterface } from '../../_interfaces/TCensecNaturezaLitigioInterface';
import { TCensecNaturezaLitigioInterface } from '@/packages/administrativo/interfaces/TCensecNaturezaLitigio/TCensecNaturezaLitigioInterface';
import { SituacoesEnum } from '@/shared/enums/SituacoesEnum';
interface TCensecNaturezaLitigioTableProps {
data: TCensecNaturezaLitigioInterface[];
@ -29,18 +31,15 @@ interface TCensecNaturezaLitigioTableProps {
/**
* Renderiza o badge de situação
*/
function StatusBadge({ situacao }: { situacao: 'A' | 'I' }) {
const isActive = situacao === 'A';
function StatusBadge({ situacao }: { situacao: SituacoesEnum }) {
const isActive = situacao === SituacoesEnum.A;
const baseClasses = 'text-xs font-medium px-2.5 py-0.5 rounded-sm me-2';
const activeClasses = 'bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-300';
const inactiveClasses = 'bg-yellow-100 text-yellow-800 dark:bg-yellow-900 dark:text-yellow-300';
return (
<span className={`${baseClasses} ${isActive ? activeClasses : inactiveClasses}`}>
{isActive ? 'Ativo' : 'Inativo'}
{situacao}
</span>
);
}

View file

@ -0,0 +1,71 @@
import { ColumnDef } from '@tanstack/react-table';
import { EllipsisIcon, PencilIcon, Trash2Icon } from 'lucide-react';
import { Button } from '@/components/ui/button';
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuGroup,
DropdownMenuItem,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu';
import GetCapitalize from '@/shared/actions/text/GetCapitalize';
import { SortableHeader } from '@/shared/components/dataTable/SortableHeader';
import TCensecQualidadeInterface from '../../interfaces/TCensecQualidade/TCensecQualidadeInterface';
export default function TCensecQualidadeColumns(
onEdit: (item: TCensecQualidadeInterface, isEditingFormStatus: boolean) => void,
onDelete: (item: TCensecQualidadeInterface, isEditingFormStatus: boolean) => void,
): ColumnDef<TCensecQualidadeInterface>[] {
return [
// ID
{
accessorKey: 'censec_qualidade_id',
header: ({ column }) => SortableHeader('#', column),
cell: ({ row }) => Number(row.getValue('censec_qualidade_id')),
enableSorting: false,
},
// Descrição
{
accessorKey: 'descricao',
header: ({ column }) => SortableHeader('Descrição', column),
cell: ({ row }) => GetCapitalize(row.getValue('descricao')),
},
// Ações
{
id: 'actions',
header: 'Ações',
cell: ({ row }) => {
const imovel = row.original;
return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="ghost" size="icon">
<EllipsisIcon />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent side="left" align="start">
<DropdownMenuGroup>
<DropdownMenuItem onSelect={() => onEdit(imovel, true)}>
<PencilIcon className="mr-2 h-4 w-4" />
Editar
</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem className="text-red-600" onSelect={() => onDelete(imovel, true)}>
<Trash2Icon className="mr-2 h-4 w-4" />
Remover
</DropdownMenuItem>
</DropdownMenuGroup>
</DropdownMenuContent>
</DropdownMenu>
);
},
enableSorting: false,
enableHiding: false,
},
];
}

View file

@ -0,0 +1,132 @@
'use client';
import React, { useEffect } from 'react';
import { Button } from '@/components/ui/button';
import {
Dialog,
DialogClose,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle,
} from '@/components/ui/dialog';
import {
Form,
FormControl,
FormField,
FormItem,
FormLabel,
FormMessage,
} from '@/components/ui/form';
import { Input } from '@/components/ui/input';
import { ResetFormIfData } from '@/shared/actions/form/ResetFormIfData';
import ConfirmacaoSelect from '@/shared/components/confirmacao/ConfirmacaoSelect';
import LoadingButton from '@/shared/components/loadingButton/LoadingButton';
import SituacoesSelect from '@/shared/components/situacoes/SituacoesSelect';
import { useTCensecQualidadeFormHook } from '../../hooks/TCensecQualidade/useTCensecQualidadeHook';
import { TCensecQualidadeFormInterface } from '../../interfaces/TCensecQualidade/TCensecQualidadeFormInterface';
export default function TCensecQualidadeForm({
isOpen,
data,
onClose,
onSave,
buttonIsLoading,
}: TCensecQualidadeFormInterface) {
// Inicializa o react-hook-form com schema zod
const form = useTCensecQualidadeFormHook({});
// Atualiza o formulário quando recebe dados para edição
useEffect(() => {
// Se existir dados, reseta o formulário com os mesmos
ResetFormIfData(form, data);
}, [data, form]);
function onError(error: any) {
console.log(error);
}
return (
<Dialog
open={isOpen}
onOpenChange={(open) => {
if (!open) onClose(null, false);
}}
>
<DialogContent className="w-full max-w-full p-6 sm:max-w-3xl md:max-w-2xl lg:max-w-2xl">
<DialogHeader>
<DialogTitle>Tipo de Partes do Ato</DialogTitle>
<DialogDescription>Tipo de Partes do Ato</DialogDescription>
</DialogHeader>
<Form {...form}>
<form onSubmit={form.handleSubmit(onSave, onError)} className="space-y-6">
<div className="grid w-full grid-cols-12 gap-4">
{/* Descrição */}
<div className="col-span-12 sm:col-span-12 md:col-span-12">
<FormField
control={form.control}
name="descricao"
render={({ field }) => (
<FormItem>
<FormLabel>Descrição</FormLabel>
<FormControl>
<Input {...field} type="text" placeholder="Descrição" />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
</div>
{/* SITUAÇÃO */}
<div className="col-span-12 sm:col-span-6 md:col-span-12">
<FormField
control={form.control}
name="situacao"
render={({ field }) => (
<FormItem>
<FormLabel>Situação</FormLabel>
<SituacoesSelect field={field} />
<FormMessage />
</FormItem>
)}
/>
</div>
{/* Aceita CNPJ */}
<div className="col-span-12 sm:col-span-6 md:col-span-12">
<FormField
control={form.control}
name="aceita_cnpj"
render={({ field }) => (
<FormItem>
<FormLabel>Aceita CNPJ</FormLabel>
<ConfirmacaoSelect field={field} />
<FormMessage />
</FormItem>
)}
/>
</div>
</div>
{/* Rodapé do Dialog */}
<DialogFooter className="mt-4 flex flex-col justify-end gap-2 sm:flex-row">
<DialogClose asChild>
<Button variant="outline" type="button" onClick={() => onClose(null, false)}>
Cancelar
</Button>
</DialogClose>
<LoadingButton
text="Salvar"
textLoading="Aguarde..."
type="submit"
loading={buttonIsLoading}
/>
</DialogFooter>
</form>
</Form>
</DialogContent>
</Dialog>
);
}

View file

@ -0,0 +1,170 @@
'use client';
import { useEffect, useState, useCallback } from 'react';
import { useTCensecQualidadeDeleteHook } from '@/packages/administrativo/hooks/TCensecQualidade/useTCensecQualidadeDeleteHook';
import { useTCensecQualidadeIndexHook } from '@/packages/administrativo/hooks/TCensecQualidade/useTCensecQualidadeIndexHook';
import { useTCensecQualidadeSaveHook } from '@/packages/administrativo/hooks/TCensecQualidade/useTCensecQualidadeSaveHook';
import TCensecQualidadeInterface from '@/packages/administrativo/interfaces/TCensecQualidade/TCensecQualidadeInterface';
import ConfirmDialog from '@/shared/components/confirmDialog/ConfirmDialog';
import { useConfirmDialog } from '@/shared/components/confirmDialog/useConfirmDialog';
import Loading from '@/shared/components/loading/loading';
import Header from '@/shared/components/structure/Header';
import TCensecQualidadeForm from './TCensecQualidadeForm';
import TCensecQualidadeTable from './TCensecQualidadeTable';
export default function TCensecQualidadeIndex() {
// Controle de estado do botão
const [buttonIsLoading, setButtonIsLoading] = useState(false);
// Hooks para leitura e salvamento
const { tCensecQualidade, indexTCensecQualidade } = useTCensecQualidadeIndexHook();
const { saveTCensecQualidade } = useTCensecQualidadeSaveHook();
const { deleteTCensecQualidade } = useTCensecQualidadeDeleteHook();
// Estados
const [selectedData, setSelectedData] = useState<TCensecQualidadeInterface | null>(null);
const [isFormOpen, setIsFormOpen] = useState(false);
// Estado para saber qual item será deletado
const [itemToDelete, setItemToDelete] = useState<TCensecQualidadeInterface | null>(null);
/**
* Hook do modal de confirmação
*/
const {
isOpen: isConfirmOpen,
openDialog: openConfirmDialog,
handleConfirm,
handleCancel,
} = useConfirmDialog();
/**
* Abre o formulário no modo de edição ou criação
*/
const handleOpenForm = useCallback((data: TCensecQualidadeInterface | null) => {
// Se não houver dados (criação), cria um objeto inicial com pessoa_tipo
setSelectedData(data);
setIsFormOpen(true);
}, []);
/**
* Fecha o formulário e limpa o andamento selecionado
*/
const handleCloseForm = useCallback(() => {
setSelectedData(null);
setIsFormOpen(false);
}, []);
/**
* Salva os dados do formulário
*/
const handleSave = useCallback(
async (formData: TCensecQualidadeInterface) => {
// Coloca o botão em estado de loading
setButtonIsLoading(true);
// Aguarda salvar o registro
await saveTCensecQualidade(formData);
// Remove o botão em estado de loading
setButtonIsLoading(false);
// Atualiza a lista de dados
indexTCensecQualidade();
},
[saveTCensecQualidade, indexTCensecQualidade, handleCloseForm],
);
/**
* Quando o usuário clica em "remover" na tabela
*/
const handleConfirmDelete = useCallback(
(item: TCensecQualidadeInterface) => {
// Define o item atual para remoção
setItemToDelete(item);
// Abre o modal de confirmação
openConfirmDialog();
},
[openConfirmDialog],
);
/**
* Executa a exclusão de fato quando o usuário confirma
*/
const handleDelete = useCallback(async () => {
// Protege contra null
if (!itemToDelete) return;
// Executa o Hook de remoção
await deleteTCensecQualidade(itemToDelete);
// Atualiza a lista
await indexTCensecQualidade();
// Limpa o item selecionado
setItemToDelete(null);
// Fecha o modal
handleCancel();
}, [itemToDelete, indexTCensecQualidade, handleCancel]);
/**
* Busca inicial dos dados
*/
useEffect(() => {
indexTCensecQualidade();
}, []);
/**
* Tela de loading enquanto carrega os dados
*/
if (tCensecQualidade?.length == 0) {
return <Loading type={2} />;
}
return (
<div>
{/* Cabeçalho */}
<Header
title={'Qualidades do CENSEC'}
description={'Qualidades do CENSEC'}
buttonText={'Nova qualdiade'}
buttonAction={() => {
handleOpenForm(null);
}}
/>
{/* Tabela de andamentos */}
<TCensecQualidadeTable
data={tCensecQualidade}
onEdit={handleOpenForm}
onDelete={handleConfirmDelete}
/>
{/* Modal de confirmação */}
{isConfirmOpen && (
<ConfirmDialog
isOpen={isConfirmOpen}
title="Confirmar exclusão"
description="Atenção"
message={`Deseja realmente excluir o imóvel "${itemToDelete?.descricao}"?`}
confirmText="Sim, excluir"
cancelText="Cancelar"
onConfirm={handleDelete}
onCancel={handleCancel}
/>
)}
{/* Formulário de criação/edição */}
{isFormOpen && (
<TCensecQualidadeForm
isOpen={isFormOpen}
data={selectedData}
onClose={handleCloseForm}
onSave={handleSave}
buttonIsLoading={buttonIsLoading}
/>
)}
</div>
);
}

View file

@ -0,0 +1,94 @@
'use client';
import { CheckIcon, ChevronsUpDownIcon } from 'lucide-react';
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 GetCapitalize from '@/shared/actions/text/GetCapitalize';
import { useTCensecQualidadeIndexHook } from '../../hooks/TCensecQualidade/useTCensecQualidadeIndexHook';
export default function TCensecQualidadeSelect({ field }: any) {
const [open, setOpen] = React.useState(false);
const [isLoading, setIsLoading] = React.useState(false);
const { tCensecQualidade, indexTCensecQualidade } = useTCensecQualidadeIndexHook();
// Busca os dados uma única vez ao montar
React.useEffect(() => {
const loadData = async () => {
if (!tCensecQualidade.length) {
setIsLoading(true);
await indexTCensecQualidade();
setIsLoading(false);
}
};
loadData();
}, []);
const selected = tCensecQualidade.find(
(item) => String(item.censec_qualidade_id) === String(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"
>
{isLoading
? 'Carregando...'
: selected
? GetCapitalize(selected.descricao)
: 'Selecione...'}
<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 tipo logradouro..." />
<CommandList>
<CommandEmpty>
{isLoading ? 'Carregando...' : 'Nenhum resultado encontrado.'}
</CommandEmpty>
<CommandGroup>
{tCensecQualidade?.map((item) => (
<CommandItem
key={item.censec_qualidade_id}
value={item.descricao?.toLowerCase() ?? ''}
onSelect={() => {
field.onChange(Number(item.censec_qualidade_id));
setOpen(false);
}}
>
<CheckIcon
className={cn(
'mr-2 h-4 w-4',
String(field.value) === String(item.censec_qualidade_id)
? 'opacity-100'
: 'opacity-0',
)}
/>
{GetCapitalize(item.descricao)}
</CommandItem>
))}
</CommandGroup>
</CommandList>
</Command>
</PopoverContent>
</Popover>
);
}

View file

@ -0,0 +1,27 @@
'use client';
import { DataTable } from '@/shared/components/dataTable/DataTable';
import TCensecQualidadeColumns from './TCensecQualidadeColumns';
import TCensecQualidadeTableInterface from '../../interfaces/TCensecQualidade/TCensecQualidadeTableInterface';
/**
* Componente principal da tabela
*/
export default function TCensecQualidadeTable({
data,
onEdit,
onDelete,
}: TCensecQualidadeTableInterface) {
const columns = TCensecQualidadeColumns(onEdit, onDelete);
return (
<div>
<DataTable
data={data}
columns={columns}
filterColumn="descricao"
filterPlaceholder="Busque pela descrição..."
/>
</div>
);
}

View file

@ -0,0 +1,72 @@
import { ColumnDef } from '@tanstack/react-table';
import { ArrowUpDownIcon, EllipsisIcon, Trash2Icon } from 'lucide-react';
import { Button } from '@/components/ui/button';
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuGroup,
DropdownMenuItem,
DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu';
import GetCapitalize from '@/shared/actions/text/GetCapitalize';
import { SortableHeader } from '@/shared/components/dataTable/SortableHeader';
import TCensecQualidadeAtoJoinedInterface from '../../interfaces/TCensecQualidadeAto/TCensecQualidadeAtoPageInterface';
export default function TCensecQualidadeAtoColumns(
onDelete: (item: TCensecQualidadeAtoJoinedInterface, isEditingFormStatus: boolean) => void,
): ColumnDef<TCensecQualidadeAtoJoinedInterface>[] {
return [
// ID
{
accessorKey: 'censec_qualidadeato_id',
header: ({ column }) => (
<Button
variant="ghost"
onClick={() => column.toggleSorting(column.getIsSorted() === 'asc')}
>
# <ArrowUpDownIcon className="ml-1 h-4 w-4" />
</Button>
),
cell: ({ row }) => Number(row.getValue('censec_qualidadeato_id')),
enableSorting: false,
},
// Descrição
{
accessorKey: 'tcq_descricao',
header: ({ column }) => SortableHeader('Descrição', column),
cell: ({ row }) => GetCapitalize(row.getValue('tcq_descricao')),
},
// Ações
{
id: 'actions',
header: 'Ações',
cell: ({ row }) => {
const pessoa = row.original;
return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="ghost" size="icon" className="cursor-pointer">
<EllipsisIcon />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent side="left" align="start">
<DropdownMenuGroup>
<DropdownMenuItem
className="cursor-pointer text-red-600"
onSelect={() => onDelete(pessoa, true)}
>
<Trash2Icon className="mr-2 h-4 w-4" />
Remover
</DropdownMenuItem>
</DropdownMenuGroup>
</DropdownMenuContent>
</DropdownMenu>
);
},
enableSorting: false,
enableHiding: false,
},
];
}

Some files were not shown because too many files have changed in this diff Show more