CalibrationReport / index.js
DHEIVER's picture
Update index.js
63c364f verified
class PDFComplianceAnalyzer {
constructor() {
this.fileInput = document.getElementById('file-upload');
this.loadingElement = document.getElementById('loading');
this.resultsContainer = document.getElementById('analysis-results');
this.reportContainer = document.getElementById('compliance-report');
this.reportContent = document.querySelector('.report-content');
this.progressContainer = document.getElementById('progress-container');
this.progressBar = document.getElementById('progress-bar');
this.toastElement = document.getElementById('toast');
this.initializeEventListeners();
this.initializeThemeToggle();
}
initializeEventListeners() {
this.fileInput.addEventListener('change', (e) => this.handleFileChange(e));
this.setupDragAndDrop();
// Keyboard navigation
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape') this.closeToast();
});
}
initializeThemeToggle() {
const themeToggle = document.getElementById('theme-toggle');
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
document.body.classList.toggle('dark-theme', prefersDark);
themeToggle.addEventListener('click', () => {
document.body.classList.toggle('dark-theme');
this.showToast('Tema alterado');
});
}
setupDragAndDrop() {
const uploadArea = document.querySelector('.upload-area');
['dragenter', 'dragover'].forEach(eventName => {
uploadArea.addEventListener(eventName, (e) => {
e.preventDefault();
uploadArea.classList.add('drag-over');
});
});
['dragleave', 'drop'].forEach(eventName => {
uploadArea.addEventListener(eventName, (e) => {
e.preventDefault();
uploadArea.classList.remove('drag-over');
});
});
uploadArea.addEventListener('drop', (e) => {
const files = Array.from(e.dataTransfer.files);
if (files.length > 0) {
this.validateAndProcessFile(files[0]);
}
});
}
handleFileChange(e) {
const file = e.target.files[0];
if (file) {
this.validateAndProcessFile(file);
}
}
validateAndProcessFile(file) {
if (file.type !== 'application/pdf') {
this.showToast('Por favor, envie apenas arquivos PDF.', 'error');
return;
}
if (file.size > 10 * 1024 * 1024) {
this.showToast('O arquivo excede o limite de 10MB.', 'error');
return;
}
this.analyzePDF(file);
}
async analyzePDF(file) {
this.showLoading(true);
this.showSkeleton();
this.clearResults();
try {
await this.simulateFileUpload(file);
await this.validatePDF(file);
const report = await this.generateComplianceReport(file);
this.displayResults(report);
this.showToast('Análise concluída com sucesso!', 'success');
} catch (error) {
this.showError(error.message);
this.showToast(error.message, 'error');
} finally {
this.showLoading(false);
this.hideSkeleton();
}
}
simulateFileUpload(file) {
return new Promise((resolve) => {
this.progressContainer.classList.remove('hidden');
let progress = 0;
const interval = setInterval(() => {
progress += 10;
this.progressBar.style.width = `${progress}%`;
if (progress >= 100) {
clearInterval(interval);
setTimeout(() => {
this.progressContainer.classList.add('hidden');
resolve();
}, 200);
}
}, 100);
});
}
showSkeleton() {
const template = document.getElementById('skeleton-template');
const skeleton = template.content.cloneNode(true);
this.resultsContainer.appendChild(skeleton);
}
hideSkeleton() {
const skeleton = document.querySelector('.skeleton-loader');
if (skeleton) skeleton.remove();
}
showToast(message, type = 'info') {
this.toastElement.textContent = message;
this.toastElement.className = `toast toast-${type}`;
this.toastElement.classList.remove('hidden');
setTimeout(() => this.closeToast(), 3000);
}
closeToast() {
this.toastElement.classList.add('hidden');
}
async validatePDF(file) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = (e) => {
const content = new Uint8Array(e.target.result);
const header = content.slice(0, 4);
const isPDF = String.fromCharCode(...header) === '%PDF';
if (!isPDF) {
reject(new Error('O arquivo não é um PDF válido.'));
}
resolve(true);
};
reader.onerror = () => reject(new Error('Erro ao ler o arquivo.'));
reader.readAsArrayBuffer(file);
});
}
async generateComplianceReport(file) {
await new Promise(resolve => setTimeout(resolve, 1500));
return {
status: 'compliant',
confidence: 92.5,
details: {
format: 'Válido',
version: 'PDF 1.7',
pages: 1,
signature: 'Presente e válida',
metadata: 'Completo',
accessibility: 'Conforme'
},
checks: [
{ name: 'Estrutura do documento', status: 'pass', score: 100 },
{ name: 'Metadados', status: 'pass', score: 95 },
{ name: 'Assinatura digital', status: 'pass', score: 100 },
{ name: 'Acessibilidade', status: 'pass', score: 85 }
]
};
}
displayResults(report) {
this.reportContainer.classList.remove('hidden');
const statusClass = report.status === 'compliant' ? 'badge-success' : 'badge-error';
const statusText = report.status === 'compliant' ? 'Conforme' : 'Não conforme';
this.reportContent.innerHTML = `
<div class="report-header">
<span class="badge ${statusClass}">${statusText}</span>
<div class="confidence-meter">
<div class="progress">
<div class="progress-bar" style="width: ${report.confidence}%"></div>
</div>
<span>Confiança: ${report.confidence}%</span>
</div>
</div>
<div class="report-section">
<h3>Detalhes do Documento</h3>
<div class="table-container">
<table class="table">
${Object.entries(report.details).map(([key, value]) => `
<tr>
<th>${key}</th>
<td>${value}</td>
</tr>
`).join('')}
</table>
</div>
</div>
<div class="report-section">
<h3>Verificações de Conformidade</h3>
${report.checks.map(check => `
<div class="check-item">
<div class="check-header">
<span>${check.name}</span>
<span class="badge ${check.status === 'pass' ? 'badge-success' : 'badge-error'}">
${check.score}%
</span>
</div>
<div class="progress">
<div class="progress-bar" style="width: ${check.score}%"></div>
</div>
</div>
`).join('')}
</div>
`;
}
showError(message) {
this.resultsContainer.innerHTML = `
<div class="alert alert-error">
<p>${message}</p>
</div>
`;
}
showLoading(show) {
if (show) {
this.loadingElement.classList.remove('hidden');
} else {
this.loadingElement.classList.add('hidden');
}
}
clearResults() {
this.resultsContainer.innerHTML = '';
this.reportContainer.classList.add('hidden');
this.reportContent.innerHTML = '';
}
}
// Inicialização
document.addEventListener('DOMContentLoaded', () => {
new PDFComplianceAnalyzer();
});