feat: integrate jsPDF and jsPDF-autotable for document generation; enhance employee management with print functionality and improved data handling in employee forms
This commit is contained in:
352
.cursor/plans/sistema-de-documentos-e-impress-o-de0a1ea6.plan.md
Normal file
352
.cursor/plans/sistema-de-documentos-e-impress-o-de0a1ea6.plan.md
Normal file
@@ -0,0 +1,352 @@
|
||||
<!-- de0a1ea6-0e97-42bf-a867-941b2346132b c70cab4f-9f78-4c1a-9087-09a2bf0196c8 -->
|
||||
# Plano: Sistema Completo de Documentos e Cadastro de Funcionários
|
||||
|
||||
## 1. Atualizar Schema do Banco de Dados
|
||||
|
||||
**Arquivo:** `packages/backend/convex/schema.ts`
|
||||
|
||||
### Campos de Dados Pessoais Adicionais (todos opcionais):
|
||||
|
||||
- `nomePai: v.optional(v.string())`
|
||||
- `nomeMae: v.optional(v.string())`
|
||||
- `naturalidade: v.optional(v.string())` - cidade natal
|
||||
- `naturalidadeUF: v.optional(v.string())` - UF com máscara (2 letras)
|
||||
- `sexo: v.optional(v.union(v.literal("masculino"), v.literal("feminino"), v.literal("outro")))`
|
||||
- `estadoCivil: v.optional(v.union(v.literal("solteiro"), v.literal("casado"), v.literal("divorciado"), v.literal("viuvo"), v.literal("uniao_estavel")))`
|
||||
- `nacionalidade: v.optional(v.string())`
|
||||
- `rgOrgaoExpedidor: v.optional(v.string())`
|
||||
- `rgDataEmissao: v.optional(v.string())` - formato dd/mm/aaaa
|
||||
- `carteiraProfissionalNumero: v.optional(v.string())`
|
||||
- `carteiraProfissionalSerie: v.optional(v.string())`
|
||||
- `carteiraProfissionalDataEmissao: v.optional(v.string())`
|
||||
- `reservistaNumero: v.optional(v.string())`
|
||||
- `reservistaSerie: v.optional(v.string())`
|
||||
- `tituloEleitorNumero: v.optional(v.string())`
|
||||
- `tituloEleitorZona: v.optional(v.string())`
|
||||
- `tituloEleitorSecao: v.optional(v.string())`
|
||||
- `grauInstrucao: v.optional(v.union(...))` - fundamental, medio, superior, pos_graduacao, mestrado, doutorado
|
||||
- `formacao: v.optional(v.string())` - curso/formação
|
||||
- `formacaoRegistro: v.optional(v.string())` - número de registro do diploma
|
||||
- `pisNumero: v.optional(v.string())`
|
||||
- `grupoSanguineo: v.optional(v.union(v.literal("A"), v.literal("B"), v.literal("AB"), v.literal("O")))`
|
||||
- `fatorRH: v.optional(v.union(v.literal("positivo"), v.literal("negativo")))`
|
||||
- `nomeacaoPortaria: v.optional(v.string())` - número do ato/portaria
|
||||
- `nomeacaoData: v.optional(v.string())`
|
||||
- `nomeacaoDOE: v.optional(v.string())`
|
||||
- `descricaoCargo: v.optional(v.string())`
|
||||
- `pertenceOrgaoPublico: v.optional(v.boolean())`
|
||||
- `orgaoOrigem: v.optional(v.string())`
|
||||
- `aposentado: v.optional(v.union(v.literal("nao"), v.literal("funape_ipsep"), v.literal("inss")))`
|
||||
- `contaBradescoNumero: v.optional(v.string())`
|
||||
- `contaBradescoDV: v.optional(v.string())`
|
||||
- `contaBradescoAgencia: v.optional(v.string())`
|
||||
|
||||
### Campos de Documentos (Storage IDs opcionais) - 23 campos:
|
||||
|
||||
Todos como `v.optional(v.id("_storage"))`:
|
||||
|
||||
- `certidaoAntecedentesPF`, `certidaoAntecedentesJFPE`, `certidaoAntecedentesSDS`, `certidaoAntecedentesTJPE`, `certidaoImprobidade`, `rgFrente`, `rgVerso`, `cpfFrente`, `cpfVerso`, `situacaoCadastralCPF`, `tituloEleitorFrente`, `tituloEleitorVerso`, `comprovanteVotacao`, `carteiraProfissionalFrente`, `carteiraProfissionalVerso`, `comprovantePIS`, `certidaoRegistroCivil`, `certidaoNascimentoDependentes`, `cpfDependentes`, `reservistaDoc`, `comprovanteEscolaridade`, `comprovanteResidencia`, `comprovanteContaBradesco`
|
||||
|
||||
## 2. Atualizar Backend Convex
|
||||
|
||||
**Arquivo:** `packages/backend/convex/funcionarios.ts`
|
||||
|
||||
- Adicionar todos os novos campos nas mutations `create` e `update`
|
||||
- Criar mutation `uploadDocumento(funcionarioId, tipoDocumento, storageId)` para vincular uploads
|
||||
- Criar query `getDocumentosUrls(funcionarioId)` retornando objeto com URLs de todos os documentos
|
||||
- Criar query `getFichaCompleta(funcionarioId)` retornando todos os dados formatados para impressão
|
||||
|
||||
## 3. Criar Componente de Upload de Arquivo
|
||||
|
||||
**Arquivo:** `apps/web/src/lib/components/FileUpload.svelte`
|
||||
|
||||
Props:
|
||||
|
||||
- `label: string` - nome do documento
|
||||
- `helpUrl?: string` - URL de referência
|
||||
- `value?: string` - storageId atual
|
||||
- `onUpload: (file: File) => Promise<void>`
|
||||
- `onRemove: () => Promise<void>`
|
||||
|
||||
Recursos:
|
||||
|
||||
- Input aceita PDF e imagens (jpg, png, jpeg)
|
||||
- Preview com thumbnail para imagens, ícone para PDF
|
||||
- Botão remover com confirmação
|
||||
- Validação de tamanho máximo 10MB
|
||||
- Loading state durante upload
|
||||
- Tooltip com link de ajuda (ícone ?)
|
||||
|
||||
## 4. Atualizar Formulário de Cadastro
|
||||
|
||||
**Arquivo:** `apps/web/src/routes/(dashboard)/recursos-humanos/funcionarios/cadastro/+page.svelte`
|
||||
|
||||
### Reorganizar em 8 cards:
|
||||
|
||||
**Card 1 - Informações Pessoais:**
|
||||
|
||||
- Nome, Matrícula, CPF (máscara), RG, Órgão Expedidor, Data Emissão RG
|
||||
- Nome Pai, Nome Mãe
|
||||
- Data Nascimento, Naturalidade, UF (máscara 2 letras)
|
||||
- Sexo (select), Estado Civil (select), Nacionalidade
|
||||
|
||||
**Card 2 - Documentos Pessoais:**
|
||||
|
||||
- Carteira Profissional Nº, Série, Data Emissão
|
||||
- Reservista Nº, Série
|
||||
- Título Eleitor Nº, Zona, Seção
|
||||
- PIS/PASEP Nº
|
||||
|
||||
**Card 3 - Formação e Saúde:**
|
||||
|
||||
- Grau Instrução (select), Formação, Registro Nº
|
||||
- Grupo Sanguíneo (select), Fator RH (select)
|
||||
|
||||
**Card 4 - Endereço e Contato:**
|
||||
|
||||
- CEP, Cidade, UF, Endereço
|
||||
- Telefone, Email
|
||||
|
||||
**Card 5 - Cargo e Vínculo:**
|
||||
|
||||
- Símbolo Tipo (CC/FG)
|
||||
- Símbolo (select filtrado)
|
||||
- Descrição Cargo/Função (novo campo opcional)
|
||||
- Nomeação/Portaria Nº, Data, DOE
|
||||
- Data Admissão
|
||||
- Pertence a Órgão Público? (checkbox)
|
||||
- Órgão de Origem (se extra-quadro)
|
||||
- Aposentado (select: Não/FUNAPE-IPSEP/INSS)
|
||||
|
||||
**Card 6 - Dados Bancários:**
|
||||
|
||||
- Conta Bradesco Nº, DV, Agência
|
||||
|
||||
**Card 7 - Documentação Anexa (23 uploads):**
|
||||
|
||||
Organizar em subcategorias com ícones:
|
||||
|
||||
- Antecedentes Criminais (4 docs)
|
||||
- Documentos Pessoais (6 docs)
|
||||
- Documentos Eleitorais (3 docs)
|
||||
- Documentos Profissionais (4 docs)
|
||||
- Certidões e Comprovantes (6 docs)
|
||||
|
||||
Cada campo com tooltip (?) linkando para URL de referência
|
||||
|
||||
**Card 8 - Ações:**
|
||||
|
||||
- Botão Cancelar
|
||||
- Botão Cadastrar
|
||||
|
||||
## 5. Atualizar Formulário de Edição
|
||||
|
||||
**Arquivo:** `apps/web/src/routes/(dashboard)/recursos-humanos/funcionarios/[funcionarioId]/editar/+page.svelte`
|
||||
|
||||
- Mesma estrutura do cadastro
|
||||
- Carregar valores existentes
|
||||
- Mostrar documentos já enviados com opção de substituir
|
||||
- Preview de documentos existentes
|
||||
|
||||
## 6. Criar Página de Detalhes do Funcionário
|
||||
|
||||
**Arquivo:** `apps/web/src/routes/(dashboard)/recursos-humanos/funcionarios/[funcionarioId]/+page.svelte`
|
||||
|
||||
Layout com 3 colunas de cards:
|
||||
|
||||
- Coluna 1: Dados Pessoais, Filiação, Naturalidade
|
||||
- Coluna 2: Documentos, Formação, Saúde
|
||||
- Coluna 3: Cargo, Vínculo, Bancários
|
||||
|
||||
Seção inferior: Grid de documentos anexados com status (enviado/pendente)
|
||||
|
||||
Cabeçalho: Botões "Editar", "Ver Documentos", "Imprimir Ficha"
|
||||
|
||||
## 7. Criar Página de Gerenciamento de Documentos
|
||||
|
||||
**Arquivo:** `apps/web/src/routes/(dashboard)/recursos-humanos/funcionarios/[funcionarioId]/documentos/+page.svelte`
|
||||
|
||||
Grid 3x8 de cards, cada um com:
|
||||
|
||||
- Nome do documento
|
||||
- Ícone de status (verde=enviado, amarelo=pendente)
|
||||
- Preview ou ícone
|
||||
- Botões: Upload/Substituir, Download, Visualizar, Remover
|
||||
- Link de ajuda (?)
|
||||
|
||||
Filtros: Mostrar Todos / Apenas Enviados / Apenas Pendentes
|
||||
|
||||
## 8. Adicionar Botões de Impressão
|
||||
|
||||
**Arquivo:** `apps/web/src/routes/(dashboard)/recursos-humanos/funcionarios/+page.svelte`
|
||||
|
||||
No dropdown de ações de cada linha:
|
||||
|
||||
- Editar
|
||||
- Ver Documentos
|
||||
- **Imprimir Ficha** (novo)
|
||||
- Excluir
|
||||
|
||||
## 9. Criar Modal de Impressão
|
||||
|
||||
**Arquivo:** `apps/web/src/lib/components/PrintModal.svelte`
|
||||
|
||||
Props: `funcionarioId: string`
|
||||
|
||||
Layout em 2 colunas:
|
||||
|
||||
- Coluna esquerda: Checkboxes organizados por seção
|
||||
- Coluna direita: Preview em tempo real (opcional)
|
||||
|
||||
Seções de campos selecionáveis:
|
||||
|
||||
1. Dados Pessoais (15 campos)
|
||||
2. Filiação (2 campos)
|
||||
3. Naturalidade (2 campos)
|
||||
4. Documentos (8 campos)
|
||||
5. Formação (3 campos)
|
||||
6. Saúde (2 campos)
|
||||
7. Endereço (4 campos)
|
||||
8. Contato (2 campos)
|
||||
9. Cargo e Vínculo (9 campos)
|
||||
10. Dados Bancários (3 campos)
|
||||
11. Documentos Anexos (23 campos)
|
||||
|
||||
Botões:
|
||||
|
||||
- Selecionar Todos / Desmarcar Todos (por seção)
|
||||
- Cancelar
|
||||
- Gerar PDF
|
||||
|
||||
Geração do PDF:
|
||||
|
||||
- Usar jsPDF + autotable
|
||||
- Cabeçalho com logo da secretaria
|
||||
- Título "FICHA CADASTRAL DE FUNCIONÁRIO"
|
||||
- Dados em formato de tabela (label: valor)
|
||||
- Seções separadas visualmente
|
||||
- Rodapé com data de geração
|
||||
|
||||
## 10. Criar Helper de Máscaras
|
||||
|
||||
**Arquivo:** `apps/web/src/lib/utils/masks.ts`
|
||||
|
||||
Funções reutilizáveis:
|
||||
|
||||
- `maskCPF(value: string): string`
|
||||
- `maskUF(value: string): string` - força uppercase, 2 chars
|
||||
- `maskCEP(value: string): string`
|
||||
- `maskPhone(value: string): string`
|
||||
- `maskDate(value: string): string`
|
||||
- `validateCPF(value: string): boolean`
|
||||
- `validateDate(value: string): boolean`
|
||||
|
||||
## 11. Criar Seção de Modelos de Declarações
|
||||
|
||||
### Estrutura de Arquivos
|
||||
|
||||
**Pasta:** `apps/web/static/modelos/declaracoes/`
|
||||
|
||||
Armazenar os 5 modelos de declarações em PDF que os funcionários devem preencher e assinar.
|
||||
|
||||
### Componente de Modelos
|
||||
|
||||
**Arquivo:** `apps/web/src/lib/components/ModelosDeclaracoes.svelte`
|
||||
|
||||
Componente exibindo card com:
|
||||
|
||||
- Título: "Modelos de Declarações"
|
||||
- Descrição: "Baixe os modelos, preencha, assine e faça upload no sistema"
|
||||
- Lista dos 5 modelos com:
|
||||
- Nome do documento
|
||||
- Ícone de PDF
|
||||
- Botão "Baixar Modelo"
|
||||
- Botão "Gerar Preenchido" (se dados disponíveis)
|
||||
- Layout em grid responsivo
|
||||
|
||||
### Gerador de Declarações
|
||||
|
||||
**Arquivo:** `apps/web/src/lib/utils/declaracoesGenerator.ts`
|
||||
|
||||
Funções para gerar cada uma das 5 declarações preenchidas com dados do funcionário:
|
||||
|
||||
- `gerarDeclaracao1(funcionario): Blob`
|
||||
- `gerarDeclaracao2(funcionario): Blob`
|
||||
- `gerarDeclaracao3(funcionario): Blob`
|
||||
- `gerarDeclaracao4(funcionario): Blob`
|
||||
- `gerarDeclaracao5(funcionario): Blob`
|
||||
|
||||
Cada função usa jsPDF para:
|
||||
|
||||
- Replicar o layout do modelo
|
||||
- Preencher com dados do funcionário
|
||||
- Deixar campo de assinatura em branco
|
||||
- Retornar PDF pronto para download
|
||||
|
||||
### Modal Seletor de Modelos
|
||||
|
||||
**Arquivo:** `apps/web/src/lib/components/SeletorModelosModal.svelte`
|
||||
|
||||
Modal para escolher quais modelos baixar:
|
||||
|
||||
- Checkboxes para cada um dos 5 modelos
|
||||
- Opção: "Baixar modelos vazios" ou "Gerar preenchidos"
|
||||
- Botão "Selecionar Todos"
|
||||
- Botão "Baixar Selecionados"
|
||||
- Se "gerar preenchidos", preenche com dados do funcionário
|
||||
|
||||
### Integração nas Páginas
|
||||
|
||||
Adicionar componente `<ModelosDeclaracoes />` em:
|
||||
|
||||
1. Formulário de cadastro (antes do card de documentação anexa)
|
||||
2. Página de gerenciamento de documentos (seção superior)
|
||||
3. Página de detalhes do funcionário (botão "Baixar Modelos" no cabeçalho)
|
||||
|
||||
## 12. Instalar Dependências
|
||||
|
||||
**Arquivo:** `apps/web/package.json`
|
||||
|
||||
```bash
|
||||
npm install jspdf jspdf-autotable
|
||||
npm install -D @types/jspdf
|
||||
```
|
||||
|
||||
## Referências dos Documentos
|
||||
|
||||
Manter estrutura de dados com URLs:
|
||||
|
||||
1. Cert. Antecedentes PF: https://servicos.pf.gov.br/epol-sinic-publico/
|
||||
2. Cert. Antecedentes JFPE: https://certidoes.trf5.jus.br/certidoes2022/paginas/certidaocriminal.faces
|
||||
3. Cert. Antecedentes SDS-PE: http://www.servicos.sds.pe.gov.br/antecedentes/...
|
||||
4. Cert. Antecedentes TJPE: https://certidoesunificadas.app.tjpe.jus.br/certidao-criminal-pf
|
||||
5. Cert. Improbidade: https://www.cnj.jus.br/improbidade_adm/consultar_requerido
|
||||
|
||||
6-10. RG, CPF, Situação CPF: URLs fornecidas
|
||||
|
||||
11-23. Demais documentos com URLs correspondentes
|
||||
|
||||
## Design e UX
|
||||
|
||||
- DaisyUI para consistência
|
||||
- Cards com sombras suaves
|
||||
- Ícones lucide-svelte ou heroicons
|
||||
- Cores: verde para sucesso, amarelo para pendente, vermelho para erro
|
||||
- Animações suaves de transição
|
||||
- Layout responsivo (mobile-first)
|
||||
- Tooltips discretos
|
||||
- Feedback imediato em ações
|
||||
- Progress indicators durante uploads
|
||||
|
||||
### To-dos
|
||||
|
||||
- [ ] Atualizar schema do banco com campo descricaoCargo e 23 campos de documentos
|
||||
- [ ] Criar mutations e queries no backend para upload e gerenciamento de documentos
|
||||
- [ ] Criar componente reutilizável FileUpload.svelte com preview e validação
|
||||
- [ ] Adicionar campo descricaoCargo e seção de documentos no formulário de cadastro
|
||||
- [ ] Adicionar campo descricaoCargo e seção de documentos no formulário de edição
|
||||
- [ ] Criar página de detalhes do funcionário com visualização de documentos
|
||||
- [ ] Criar página de gerenciamento centralizado de documentos
|
||||
- [ ] Adicionar botões de impressão na listagem e página de detalhes
|
||||
- [ ] Criar modal de impressão com checkboxes e geração de PDF
|
||||
- [ ] Instalar jspdf e jspdf-autotable no package.json do web
|
||||
Reference in New Issue
Block a user