# 📄 PDF Uploader Component & Service ## 🎯 Visão Geral O **PDF Uploader System** é composto por dois elementos principais: - `PdfUploaderComponent` - Componente de interface para upload de documentos PDF - `PdfUploadService` - Serviço para comunicação com APIs de upload Baseado no `ImageUploaderComponent` existente, mas otimizado especificamente para documentos PDF com funcionalidades avançadas e integração completa com backend. ## ✨ Funcionalidades ### 🔧 PdfUploaderComponent - ✅ **Upload de PDFs** - Suporte nativo para arquivos PDF - ✅ **Drag & Drop** - Interface intuitiva para arrastar arquivos - ✅ **Lista de Documentos Pendentes** - Controle de documentos obrigatórios - ✅ **Reordenação** - Arrastar e soltar para reordenar documentos - ✅ **Visualização** - Abrir PDFs em nova aba - ✅ **Validação** - Controle de tamanho e tipo de arquivo - ✅ **Responsivo** - Design adaptável para mobile e desktop - ✅ **Dark Mode** - Suporte completo ao tema escuro ### 🚀 PdfUploadService - ✅ **Upload Real** - Integração com APIs de backend - ✅ **Gerenciamento de Arquivos** - CRUD completo de documentos - ✅ **Metadados** - Atualização de nome, descrição, etc. - ✅ **Download URLs** - Geração de URLs seguras para download - ✅ **Batch Operations** - Operações em lote para múltiplos arquivos ### 📋 Lista de Documentos Pendentes - Exibe documentos que ainda precisam ser enviados - Diferencia documentos obrigatórios dos opcionais - Status visual (Pendente/Enviado) - Ícones contextuais para cada estado ## 🚀 Como Usar ### 1. Importar o Componente ```typescript import { PdfUploaderComponent, PdfDocument, PendingDocument } from "../../shared/components/pdf-uploader/pdf-uploader.component"; @Component({ selector: 'app-contract', standalone: true, imports: [CommonModule, TabSystemComponent, PdfUploaderComponent], // ... }) export class ContractComponent { // Propriedades contractDocuments: PdfDocument[] = []; pendingDocuments: PendingDocument[] = [ { name: 'Laudo de Vistoria', description: 'Documento obrigatório para finalizar o cadastro', required: true, status: 'pending' } ]; } ``` ### 2. Usar no Template ```html ``` ### 3. Implementar Event Handlers ```typescript onDocumentsChange(documents: PdfDocument[]) { this.contractDocuments = documents; console.log('Documentos atualizados:', documents); } onFilesChange(files: File[]) { console.log('Arquivos selecionados:', files); this.uploadDocuments(files); } onDocumentError(error: string) { console.error('Erro no upload:', error); // Exibir erro para o usuário } ``` ## 📝 Interfaces ### PdfDocument ```typescript interface PdfDocument { id?: string; name: string; file?: File; url?: string; size?: number; uploadDate?: Date; status?: 'pending' | 'uploaded' | 'error'; description?: string; } ``` ### PendingDocument ```typescript interface PendingDocument { name: string; description: string; required: boolean; status: 'pending' | 'uploaded'; } ``` ## ⚙️ Propriedades de Entrada (@Input) | Propriedade | Tipo | Padrão | Descrição | |-------------|------|--------|-----------| | `documents` | `PdfDocument[]` | `[]` | Lista de documentos anexados | | `pendingDocuments` | `PendingDocument[]` | `[]` | Lista de documentos pendentes | | `title` | `string` | `'Upload de Documentos'` | Título do componente | | `subtitle` | `string` | `'Faça o upload dos documentos...'` | Subtítulo explicativo | | `maxDocuments` | `number` | `10` | Máximo de documentos permitidos | | `maxSizeMb` | `number` | `10` | Tamanho máximo por arquivo (MB) | | `allowedTypes` | `string[]` | `['application/pdf']` | Tipos de arquivo aceitos | | `acceptMultiple` | `boolean` | `true` | Permitir seleção múltipla | | `showPendingList` | `boolean` | `true` | Exibir lista de pendentes | ## 📤 Eventos de Saída (@Output) | Evento | Tipo | Descrição | |--------|------|-----------| | `documentsChange` | `PdfDocument[]` | Emitido quando a lista de documentos muda | | `filesChange` | `File[]` | Emitido quando arquivos são selecionados | | `error` | `string` | Emitido quando ocorre um erro | | `documentUploaded` | `PdfDocument` | Emitido quando um documento é enviado | ## 🎨 Customização Visual ### CSS Variables Utilizadas ```scss --background --surface --text-primary --text-secondary --divider --idt-primary-color --idt-primary-shade --idt-primary-rgb --idt-danger --idt-danger-rgb --idt-success --idt-success-rgb --idt-warning --idt-warning-rgb --idt-info --idt-info-rgb ``` ### Estados Visuais - **Hover**: Área de upload com destaque - **Drag Over**: Feedback visual durante drag & drop - **Required**: Documentos obrigatórios com borda amarela - **Completed**: Documentos enviados com borda verde - **Error**: Estados de erro com cor vermelha ## 🔧 Integração com APIs ### Exemplo de Upload para Servidor ```typescript // Usando o componente com upload automático @Component({...}) export class ContractComponent { onContractFilesChange(files: File[]) { // Upload automático usando o serviço this.pdfUploaderComponent.uploadFilesToServer( files, 'contract', this.contractId ); } } ``` ### Uso Direto do PdfUploadService ```typescript import { PdfUploadService } from '../../shared/components/pdf-uploader/pdf-uploader.service'; @Injectable() export class ContractService { constructor(private pdfUploadService: PdfUploadService) {} async uploadContractDocument(file: File, contractId: string) { try { // Upload direto const response = await this.pdfUploadService.uploadPdfDirect( file, 'contract', contractId ).toPromise(); console.log('Upload concluído:', response); return response; } catch (error) { console.error('Erro no upload:', error); throw error; } } async loadContractDocuments(fileIds: number[]) { try { const documents = await this.pdfUploadService.getPdfsByIds(fileIds).toPromise(); return documents; } catch (error) { console.error('Erro ao carregar documentos:', error); return []; } } } ``` ### Métodos Disponíveis no PdfUploadService | Método | Descrição | Parâmetros | Retorno | |--------|-----------|------------|---------| | `uploadPdfDirect()` | Upload direto de arquivo | `File, entityType?, entityId?` | `PdfUploadResponse` | | `uploadPdfUrl()` | Solicita URL para upload | `filename: string` | `DataUrlFile` | | `uploadPdfConfirm()` | Confirma upload após S3 | `fileUrl: string` | `PdfUploadResponse` | | `getPdfById()` | Obtém URL de download | `id: number` | `PdfApiResponse` | | `getPdfsByIds()` | Obtém múltiplos PDFs | `ids: number[]` | `PdfUploadResponse[]` | | `deletePdf()` | Deleta PDF do servidor | `id: number` | `void` | | `updatePdfMetadata()` | Atualiza metadados | `id, metadata` | `PdfUploadResponse` | ## 📱 Responsividade O componente é totalmente responsivo e se adapta para: - **Desktop**: Layout completo com todas as funcionalidades - **Tablet**: Interface otimizada para toque - **Mobile**: Layout compacto e touch-friendly ## 🌙 Dark Mode Suporte completo ao dark mode através das CSS variables do sistema de tema da aplicação. ## 🔄 Integração com BaseDomainComponent Para usar dentro de abas do `GenericTabFormComponent`: ```typescript getFormConfig(): TabFormConfig { return { // ... outras configurações subTabs: [ { id: 'documentos', label: 'Documentos', icon: 'fa-file-pdf', templateType: 'custom', customTemplate: 'pdf-uploader', // ... } ] }; } ``` ## 🚨 Tratamento de Erros O componente valida: - ✅ Tipos de arquivo permitidos - ✅ Tamanho máximo por arquivo - ✅ Número máximo de documentos - ✅ Arquivos duplicados Erros são emitidos através do evento `error` para tratamento personalizado. ## 📊 Casos de Uso ### 1. Contratos - Upload de contratos assinados - Documentos complementares - Anexos legais ### 2. Veículos - Documentação do veículo - Laudos de vistoria - Comprovantes de pagamento ### 3. Motoristas - CNH e documentos pessoais - Certificados e cursos - Comprovantes de endereço ### 4. Fornecedores - Contratos de prestação de serviço - Certificações - Documentos fiscais ## 🎯 Próximos Passos 1. **Integração com API**: Implementar upload real para servidor 2. **Preview de PDF**: Adicionar visualização inline de PDFs 3. **Assinatura Digital**: Integração com ferramentas de assinatura 4. **Histórico**: Controle de versões de documentos 5. **Notificações**: Alertas para documentos vencidos --- **Criado por**: Equipe de Desenvolvimento PraFrota **Data**: Outubro 2024 **Versão**: 1.0.0