9.1 KiB
9.1 KiB
📄 PDF Uploader Component & Service
🎯 Visão Geral
O PDF Uploader System é composto por dois elementos principais:
PdfUploaderComponent- Componente de interface para upload de documentos PDFPdfUploadService- 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
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
<app-pdf-uploader
title="Upload de Documentos do Contrato"
subtitle="Faça o upload dos documentos assinados do contrato"
[documents]="contractDocuments"
[pendingDocuments]="pendingDocuments"
[maxDocuments]="5"
[maxSizeMb]="10"
[showPendingList]="true"
(documentsChange)="onDocumentsChange($event)"
(filesChange)="onFilesChange($event)"
(error)="onDocumentError($event)">
</app-pdf-uploader>
3. Implementar Event Handlers
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
interface PdfDocument {
id?: string;
name: string;
file?: File;
url?: string;
size?: number;
uploadDate?: Date;
status?: 'pending' | 'uploaded' | 'error';
description?: string;
}
PendingDocument
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
--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
// 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
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:
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
- Integração com API: Implementar upload real para servidor
- Preview de PDF: Adicionar visualização inline de PDFs
- Assinatura Digital: Integração com ferramentas de assinatura
- Histórico: Controle de versões de documentos
- Notificações: Alertas para documentos vencidos
Criado por: Equipe de Desenvolvimento PraFrota
Data: Outubro 2024
Versão: 1.0.0