diff --git a/index.html b/index.html index 1aa69b2..791eb81 100644 --- a/index.html +++ b/index.html @@ -555,14 +555,8 @@

© 2025 SteelBase v6.5 PROFESSIONAL EDITION - Plataforma Técnica com Base de Dados de Materiais Brasileiros

- - - - - - - - + + diff --git a/public/app.js b/public/app.js index 9ae96f4..f2c49f9 100644 --- a/public/app.js +++ b/public/app.js @@ -3,6 +3,9 @@ // Plataforma Técnica Completa com Base de Materiais // ======================================== +// Logger disponível globalmente (carregado antes em logger.js) +// Usar window.Logger.info('mensagem') para logs controlados + // Import state from modules (userPreferences only - appState is still global for legacy) import { userPreferences, loadPreferences, savePreferences, adminConfig } from './js/core/state.js'; @@ -893,14 +896,37 @@ function analisarUltrassom() { } function calcularCustoTotal() { - const area = parseFloat(document.getElementById('custo-area').value) || 0; - const regiao = document.getElementById('custo-regiao').value; - const tipoTinta = document.getElementById('custo-tipo-tinta').value; - const custoMO = parseFloat(document.getElementById('custo-mo').value) || 85; - const prod = parseFloat(document.getElementById('custo-prod').value) || 5; - const volume = parseFloat(document.getElementById('custo-volume').value) || 0; - const incluirEPI = document.getElementById('custo-incluir-epi').checked; - const incluirEquip = document.getElementById('custo-incluir-equip').checked; + const areaInput = document.getElementById('custo-area'); + const regiaoInput = document.getElementById('custo-regiao'); + const tipoTintaInput = document.getElementById('custo-tipo-tinta'); + const custoMOInput = document.getElementById('custo-mo'); + const prodInput = document.getElementById('custo-prod'); + const volumeInput = document.getElementById('custo-volume'); + + const area = parseFloat(areaInput?.value) || 0; + const regiao = regiaoInput?.value || 'sudeste'; + const tipoTinta = tipoTintaInput?.value || 'padrao'; + const custoMO = parseFloat(custoMOInput?.value) || 85; + const prod = parseFloat(prodInput?.value) || 5; + const volume = parseFloat(volumeInput?.value) || 0; + const incluirEPI = document.getElementById('custo-incluir-epi')?.checked || false; + const incluirEquip = document.getElementById('custo-incluir-equip')?.checked || false; + + if (area <= 0 || isNaN(area)) { + const resultEl = document.getElementById('custo-result'); + if (resultEl) resultEl.innerHTML = '
⚠️ Área inválida. Insira um valor maior que 0.
'; + return; + } + if (prod <= 0) { + const resultEl = document.getElementById('custo-result'); + if (resultEl) resultEl.innerHTML = '
⚠️ Produtividade inválida. Insira um valor maior que 0.
'; + return; + } + if (volume < 0) { + const resultEl = document.getElementById('custo-result'); + if (resultEl) resultEl.innerHTML = '
⚠️ Volume não pode ser negativo.
'; + return; + } const precosTinta = { sudeste: { padrao: 80, premium: 120, economica: 50 }, @@ -1002,10 +1028,31 @@ function calcularCustoTotal() { } function calcularSecagem() { - const tipo = document.getElementById('sec-tipo').value; - const temp = parseFloat(document.getElementById('sec-temp').value) || 25; - const umidade = parseFloat(document.getElementById('sec-umidade').value) || 60; - const espessura = parseFloat(document.getElementById('sec-espessura').value) || 80; + const tipoInput = document.getElementById('sec-tipo'); + const tempInput = document.getElementById('sec-temp'); + const umidadeInput = document.getElementById('sec-umidade'); + const espessuraInput = document.getElementById('sec-espessura'); + + const tipo = tipoInput?.value || 'epoxi'; + const temp = parseFloat(tempInput?.value) || 25; + const umidade = parseFloat(umidadeInput?.value) || 60; + const espessura = parseFloat(espessuraInput?.value) || 80; + + if (temp < -20 || temp > 300) { + const resultEl = document.getElementById('sec-result'); + if (resultEl) resultEl.innerHTML = '
⚠️ Temperatura inválida. Use valores entre -20°C e 300°C.
'; + return; + } + if (umidade < 0 || umidade > 100) { + const resultEl = document.getElementById('sec-result'); + if (resultEl) resultEl.innerHTML = '
⚠️ Umidade inválida. Use valores entre 0% e 100%.
'; + return; + } + if (espessura <= 0 || espessura > 1000) { + const resultEl = document.getElementById('sec-result'); + if (resultEl) resultEl.innerHTML = '
⚠️ Espessura inválida. Use valores entre 1 e 1000 microns.
'; + return; + } const dadosTinta = { epoxi: { tempIdeal: 25, umidadeMax: 85, tempoBase: 24, fatorEsp: 0.2 }, @@ -4995,14 +5042,28 @@ function getReferenciaContent() { // CEV Calculation function calcularCEV() { - const C = parseFloat(document.getElementById('cev-c').value) || 0; - const Mn = parseFloat(document.getElementById('cev-mn').value) || 0; - const Cr = parseFloat(document.getElementById('cev-cr').value) || 0; - const Mo = parseFloat(document.getElementById('cev-mo').value) || 0; - const V = parseFloat(document.getElementById('cev-v').value) || 0; - const Ni = parseFloat(document.getElementById('cev-ni').value) || 0; - const Cu = parseFloat(document.getElementById('cev-cu').value) || 0; - const thickness = parseFloat(document.getElementById('cev-thickness').value) || 0; + const getVal = (id) => parseFloat(document.getElementById(id)?.value) || 0; + + const C = getVal('cev-c'); + const Mn = getVal('cev-mn'); + const Cr = getVal('cev-cr'); + const Mo = getVal('cev-mo'); + const V = getVal('cev-v'); + const Ni = getVal('cev-ni'); + const Cu = getVal('cev-cu'); + const thickness = getVal('cev-thickness'); + + if ([C, Mn, Cr, Mo, V, Ni, Cu].every(v => v === 0)) { + const resultEl = document.getElementById('cev-result'); + if (resultEl) resultEl.innerHTML = '
⚠️ Preencha pelo menos um elemento de liga para calcular o CEV.
'; + return; + } + + if (C < 0 || C > 2 || Mn < 0 || Mn > 5 || Cr < 0 || Cr > 30 || Mo < 0 || Mo > 5 || V < 0 || V > 5 || Ni < 0 || Ni > 5 || Cu < 0 || Cu > 5) { + const resultEl = document.getElementById('cev-result'); + if (resultEl) resultEl.innerHTML = '
⚠️ Valores fora dos limites típicos para aços. Verifique os valores inseridos.
'; + return; + } // IIW Formula const CEV = C + Mn/6 + (Cr+Mo+V)/5 + (Ni+Cu)/15; @@ -5864,11 +5925,37 @@ const steelBearing = { // Tab 1: Cisalhamento (Shear) function calcularCisalhamento() { - const boltType = document.getElementById('bolt-type').value; - const d = parseFloat(document.getElementById('bolt-d').value); - const qty = parseInt(document.getElementById('bolt-qty').value); - const planes = parseInt(document.getElementById('bolt-planes').value); - const force = parseFloat(document.getElementById('bolt-force').value); + const getVal = (id, fallback = 0) => { + const el = document.getElementById(id); + return el ? (id.includes('qty') || id.includes('planes') ? parseInt(el.value) : parseFloat(el.value)) : fallback; + }; + + const boltType = document.getElementById('bolt-type')?.value || 'a325'; + const d = getVal('bolt-d'); + const qty = getVal('bolt-qty', 1); + const planes = getVal('bolt-planes', 1); + const force = getVal('bolt-force'); + + if (!d || d <= 0 || d > 36) { + const resultEl = document.getElementById('bolt-result'); + if (resultEl) resultEl.innerHTML = '
⚠️ Diâmetro do parafuso inválido. Use valores entre 1mm e 36mm.
'; + return; + } + if (!boltDatabase[boltType]?.capacidade[d]) { + const resultEl = document.getElementById('bolt-result'); + if (resultEl) resultEl.innerHTML = '
⚠️ Diâmetro não disponível para o tipo de parafuso selecionado.
'; + return; + } + if (qty < 1 || qty > 100) { + const resultEl = document.getElementById('bolt-result'); + if (resultEl) resultEl.innerHTML = '
⚠️ Quantidade de parafusos inválida. Use valores entre 1 e 100.
'; + return; + } + if (!force || force <= 0) { + const resultEl = document.getElementById('bolt-result'); + if (resultEl) resultEl.innerHTML = '
⚠️ Força aplicada inválida. Insira um valor maior que 0.
'; + return; + } const bolt = boltDatabase[boltType]; const area = Math.PI * Math.pow(d / 2, 2); @@ -7279,9 +7366,30 @@ function calcularEnergiaCompleta() { } function calcularPreaquecimento() { - const cev = parseFloat(document.getElementById('preheat-cev').value) || 0; - const thickness = parseFloat(document.getElementById('preheat-thickness').value) || 0; - const ambient = parseFloat(document.getElementById('preheat-ambient').value) || 20; + const getVal = (id, fallback = 0) => { + const el = document.getElementById(id); + return el ? parseFloat(el.value) : fallback; + }; + + const cev = getVal('preheat-cev'); + const thickness = getVal('preheat-thickness'); + const ambient = getVal('preheat-ambient', 20); + + if (cev < 0 || cev > 2) { + const resultEl = document.getElementById('preheat-result'); + if (resultEl) resultEl.innerHTML = '
⚠️ CEV inválido. Use valores entre 0 e 2.
'; + return; + } + if (thickness <= 0 || thickness > 300) { + const resultEl = document.getElementById('preheat-result'); + if (resultEl) resultEl.innerHTML = '
⚠️ Espessura inválida. Use valores entre 1mm e 300mm.
'; + return; + } + if (ambient < -50 || ambient > 60) { + const resultEl = document.getElementById('preheat-result'); + if (resultEl) resultEl.innerHTML = '
⚠️ Temperatura ambiente inválida. Use valores entre -50°C e 60°C.
'; + return; + } const preheatTemp = 50 + (cev * 100) + (thickness / 10 * 20) + ((20 - ambient) / 2); const maxInterpass = preheatTemp + 100; @@ -10858,4 +10966,7 @@ console.log('✅ SteelBase carregado com sucesso!'); }); // Removido: listener de fechamento do modal Admin legado -}); \ No newline at end of file +})(); + +// Export for external use +export { appState, userPreferences, loadPreferences, savePreferences, adminConfig, Logger }; \ No newline at end of file diff --git a/public/js/tests/test-persistencia-simples.js b/public/js/tests/test-persistencia-simples.js deleted file mode 100644 index 1c585b4..0000000 --- a/public/js/tests/test-persistencia-simples.js +++ /dev/null @@ -1,185 +0,0 @@ -/** - * Teste Simples de Persistência - Executável no navegador - * Testa funcionalidades básicas do AdminConfigManager - */ - -// Função principal de teste -async function testarPersistenciaSimples() { - console.log('🧪 Iniciando teste simples de persistência...'); - - try { - // Testar AdminConfigManager - if (typeof AdminConfigManager === 'undefined') { - throw new Error('AdminConfigManager não está disponível'); - } - - console.log('✅ AdminConfigManager disponível'); - - // Criar instância - const manager = new AdminConfigManager(); - console.log('✅ Instância criada'); - - // Testar configuração padrão - const config = manager.getConfig(); - console.log('✅ Configuração padrão obtida:', config); - - // Testar salvamento - manager.updateConfig('app.name', 'Aço Calc Pro - Teste'); - manager.updateConfig('theme.name', 'dark'); - console.log('✅ Configurações atualizadas'); - - // Testar recuperação - const configAtualizada = manager.getConfig(); - console.log('✅ Configuração recuperada:', configAtualizada); - - // Verificar se as mudanças foram aplicadas - const nomeAtualizado = configAtualizada.app.name === 'Aço Calc Pro - Teste'; - const temaAtualizado = configAtualizada.theme.name === 'dark'; - - console.log(`✅ Nome atualizado: ${nomeAtualizado}`); - console.log(`✅ Tema atualizado: ${temaAtualizado}`); - - // Testar localStorage - const localStorageKey = manager.configKey; - const localStorageData = localStorage.getItem(localStorageKey); - console.log('✅ Dados no localStorage:', localStorageData ? 'Presentes' : 'Ausentes'); - - if (localStorageData) { - const parsedData = JSON.parse(localStorageData); - console.log('✅ Versão dos dados:', parsedData.version); - } - - // Testar ToastManager se disponível - if (typeof ToastManager !== 'undefined') { - window.toastManager = new ToastManager(); - console.log('✅ ToastManager inicializado'); - - if (nomeAtualizado && temaAtualizado) { - window.toastManager.success('🧪 Teste de persistência: SUCESSO!'); - } else { - window.toastManager.warning('🧪 Teste de persistência: Parcial'); - } - } - - // Testar BackupManager se disponível - if (typeof BackupManager !== 'undefined') { - const backupManager = new BackupManager(); - console.log('✅ BackupManager disponível'); - - // Criar backup de teste - const backup = await backupManager.createBackup(); - console.log('✅ Backup criado:', backup.id); - - // Listar backups - const backups = backupManager.getBackups(); - console.log('✅ Backups disponíveis:', backups.length); - } - - console.log('🎉 Teste simples concluído com sucesso!'); - - // Retornar resultado para uso externo - return { - success: nomeAtualizado && temaAtualizado, - details: { - nomeAtualizado, - temaAtualizado, - localStoragePresente: !!localStorageData - } - }; - - } catch (error) { - console.error('❌ Erro no teste:', error); - - if (typeof ToastManager !== 'undefined' && window.toastManager) { - window.toastManager.error('❌ Erro no teste: ' + error.message); - } - - return { - success: false, - error: error.message - }; - } -} - -// Função para testar persistência após reload -function testarReload() { - console.log('🔄 Preparando teste de reload...'); - - if (typeof AdminConfigManager !== 'undefined') { - const manager = new AdminConfigManager(); - - // Salvar configuração de teste - manager.updateConfig('app.name', 'Aço Calc Pro - Teste Reload'); - manager.updateConfig('test.timestamp', new Date().toISOString()); - - console.log('✅ Configurações de teste salvas'); - console.log('🔄 Recarregando em 3 segundos...'); - - if (window.toastManager) { - window.toastManager.info('🔄 Recarregando página para testar persistência...'); - } - - setTimeout(() => { - location.reload(); - }, 3000); - - } else { - console.log('⚠️ Verificando persistência após reload...'); - - // Verificar se as configurações persistiram - const manager = new AdminConfigManager(); - const config = manager.getConfig(); - - if (config.app.name === 'Aço Calc Pro - Teste Reload') { - console.log('✅ Persistência após reload: SUCESSO!'); - if (window.toastManager) { - window.toastManager.success('✅ Configurações persistiram após reload!'); - } - } else { - console.log('❌ Persistência após reload: FALHA'); - console.log('Config atual:', config.app.name); - if (window.toastManager) { - window.toastManager.error('❌ Configurações não persistiram após reload'); - } - } - } -} - -// Função para limpar testes -function limparTestes() { - console.log('🧹 Limpando testes...'); - - if (typeof AdminConfigManager !== 'undefined') { - const manager = new AdminConfigManager(); - manager.resetConfig(); - console.log('✅ Configurações resetadas'); - } - - if (typeof BackupManager !== 'undefined') { - const backupManager = new BackupManager(); - backupManager.clearBackups(); - console.log('✅ Backups limpos'); - } - - if (window.toastManager) { - window.toastManager.success('🧹 Testes limpos com sucesso!'); - } - - console.log('✅ Testes limpos'); -} - -// Disponibilizar funções globalmente -window.testarPersistenciaSimples = testarPersistenciaSimples; -window.testarReload = testarReload; -window.limparTestes = limparTestes; - -// Auto-executar teste quando a página carregar -if (document.readyState === 'loading') { - document.addEventListener('DOMContentLoaded', () => { - setTimeout(testarPersistenciaSimples, 2000); - }); -} else { - setTimeout(testarPersistenciaSimples, 2000); -} - -console.log('🧪 Sistema de teste simples de persistência carregado'); \ No newline at end of file diff --git a/public/js/tests/test-persistencia.js b/public/js/tests/test-persistencia.js deleted file mode 100644 index 28fb67b..0000000 --- a/public/js/tests/test-persistencia.js +++ /dev/null @@ -1,310 +0,0 @@ -/** - * Script de Teste para Sistema de Persistência - * Testa as funcionalidades do AdminConfigManager e BackupManager - */ - -class PersistenceTest { - constructor() { - this.tests = []; - this.results = []; - } - - /** - * Executa todos os testes de persistência - */ - async runAllTests() { - console.log('🧪 Iniciando testes de persistência...'); - - // Aguardar carregamento dos módulos - await this.waitForModules(); - - // Executar testes - await this.testConfigPersistence(); - await this.testBackupSystem(); - await this.testThemePersistence(); - await this.testResetFunctionality(); - - // Mostrar resultados - this.showResults(); - - console.log('✅ Testes de persistência concluídos!'); - } - - /** - * Aguarda os módulos necessários estarem carregados - */ - async waitForModules() { - console.log('⏳ Aguardando módulos...'); - - let attempts = 0; - const maxAttempts = 50; // 5 segundos - - while (attempts < maxAttempts) { - // Verificar instâncias globais inicializadas pelos módulos - if (window.adminConfigManager && window.backupManager && window.toastManager) { - console.log('✅ Módulos (instâncias) carregados'); - return; - } - - // Como fallback, se as classes existirem mas instâncias ainda não, tentar inicializar - if (!window.adminConfigManager && typeof AdminConfigManager !== 'undefined') { - try { window.adminConfigManager = new AdminConfigManager(); } catch(e) {} - } - if (!window.backupManager && typeof BackupManager !== 'undefined') { - try { window.backupManager = new BackupManager(); } catch(e) {} - } - if (!window.toastManager && typeof ToastManager !== 'undefined') { - try { window.toastManager = new ToastManager(); } catch(e) {} - } - - await new Promise(resolve => setTimeout(resolve, 100)); - attempts++; - } - - throw new Error('❌ Módulos não carregados após 5 segundos'); - } - - /** - * Testa persistência de configurações - */ - async testConfigPersistence() { - console.log('📝 Testando persistência de configurações...'); - - try { - // Criar instância do config manager - const configManager = new AdminConfigManager(); - - // Testar configuração inicial - const initialConfig = configManager.getConfig(); - this.addResult('Config inicial', !!initialConfig, 'Configuração inicial carregada'); - - // Testar salvamento de configuração - configManager.updateConfig('app.name', 'Aço Calc Pro - Teste'); - configManager.updateConfig('app.version', '2.0.0'); - configManager.updateConfig('theme.name', 'light'); - - // Recarregar e verificar se persistiu - const configManager2 = new AdminConfigManager(); - const config2 = configManager2.getConfig(); - - this.addResult('Salvamento app.name', config2.app.name === 'Aço Calc Pro - Teste', 'Nome da aplicação persistido'); - this.addResult('Salvamento app.version', config2.app.version === '2.0.0', 'Versão persistida'); - this.addResult('Salvamento theme.name', config2.theme.name === 'light', 'Tema persistido'); - - console.log('✅ Testes de persistência de configurações concluídos'); - - } catch (error) { - this.addResult('Config Persistence', false, `Erro: ${error.message}`); - console.error('❌ Erro nos testes de configuração:', error); - } - } - - /** - * Testa sistema de backup - */ - async testBackupSystem() { - console.log('💾 Testando sistema de backup...'); - - try { - const backupManager = new BackupManager(); - - // Testar criação de backup - const backup = await backupManager.createBackup(); - this.addResult('Criação backup', !!backup.id, 'Backup criado com ID'); - - // Testar listagem de backups - const backups = backupManager.getBackups(); - this.addResult('Listagem backups', backups.length > 0, `${backups.length} backup(s) encontrado(s)`); - - // Testar recuperação de backup específico (via lista) - const specificBackup = backups.find(b => b.timestamp === backup.timestamp); - this.addResult('Recuperação backup', !!specificBackup, 'Backup recuperado por timestamp'); - - // Testar remoção de backup (usar timestamp) - backupManager.removeBackup(backup.timestamp); - const backupsAfterRemove = backupManager.getBackups(); - this.addResult('Remoção backup', backupsAfterRemove.length === backups.length - 1, 'Backup removido com sucesso'); - - console.log('✅ Testes de backup concluídos'); - - } catch (error) { - this.addResult('Backup System', false, `Erro: ${error.message}`); - console.error('❌ Erro nos testes de backup:', error); - } - } - - /** - * Testa persistência de tema - */ - async testThemePersistence() { - console.log('🎨 Testando persistência de tema...'); - - try { - const configManager = new AdminConfigManager(); - - // Testar diferentes temas - const themes = ['dark', 'light', 'auto']; - - for (const theme of themes) { - configManager.updateConfig('theme.name', theme); - - // Recarregar e verificar - const configManager2 = new AdminConfigManager(); - const config2 = configManager2.getConfig(); - - this.addResult(`Tema ${theme}`, config2.theme.name === theme, `Tema ${theme} persistido`); - } - - console.log('✅ Testes de tema concluídos'); - - } catch (error) { - this.addResult('Theme Persistence', false, `Erro: ${error.message}`); - console.error('❌ Erro nos testes de tema:', error); - } - } - - /** - * Testa funcionalidade de reset - */ - async testResetFunctionality() { - console.log('🔄 Testando funcionalidade de reset...'); - - try { - const configManager = new AdminConfigManager(); - - // Modificar configurações - configManager.updateConfig('app.name', 'Nome Modificado'); - configManager.updateConfig('app.version', '9.9.9'); - - // Resetar - configManager.resetConfig(); - - // Verificar se voltou ao padrão - const config = configManager.getConfig(); - // Estrutura padrão usa chaves top-level: appName e version - const isDefaultName = config.appName === 'AÇO CALC PRO'; - const isDefaultVersion = config.version === '1.0.0'; - - this.addResult('Reset app.name', isDefaultName, 'Nome resetado para padrão'); - this.addResult('Reset app.version', isDefaultVersion, 'Versão resetada para padrão'); - - console.log('✅ Testes de reset concluídos'); - - } catch (error) { - this.addResult('Reset Functionality', false, `Erro: ${error.message}`); - console.error('❌ Erro nos testes de reset:', error); - } - } - - /** - * Adiciona resultado de teste - */ - addResult(testName, success, message) { - this.results.push({ - name: testName, - success: success, - message: message, - timestamp: new Date().toISOString() - }); - - const status = success ? '✅' : '❌'; - console.log(`${status} ${testName}: ${message}`); - } - - /** - * Mostra resultados dos testes - */ - showResults() { - const totalTests = this.results.length; - const passedTests = this.results.filter(r => r.success).length; - const failedTests = totalTests - passedTests; - - console.log('\n📊 RESUMO DOS TESTES:'); - console.log(`Total de testes: ${totalTests}`); - console.log(`✅ Passou: ${passedTests}`); - console.log(`❌ Falhou: ${failedTests}`); - console.log(`Taxa de sucesso: ${((passedTests / totalTests) * 100).toFixed(1)}%`); - - // Mostrar falhas em detalhes - if (failedTests > 0) { - console.log('\n📋 FALHAS DETALHADAS:'); - this.results.filter(r => !r.success).forEach(result => { - console.log(`❌ ${result.name}: ${result.message}`); - }); - } - - // Testar se o ToastManager está disponível para mostrar resultado - if (window.toastManager) { - const successRate = (passedTests / totalTests) * 100; - if (successRate === 100) { - window.toastManager.success(`🧪 Todos os testes de persistência passaram! (${passedTests}/${totalTests})`); - } else if (successRate >= 80) { - window.toastManager.warning(`🧪 ${passedTests}/${totalTests} testes passaram (${successRate.toFixed(1)}%)`); - } else { - window.toastManager.error(`🧪 Apenas ${passedTests}/${totalTests} testes passaram (${successRate.toFixed(1)}%)`); - } - } - } -} - -// Função para testar persistência após reload -function testarPersistenciaAposReload() { - console.log('🔄 Testando persistência após reload da página...'); - - // Salvar configuração de teste - if (window.adminConfigManager) { - window.adminConfigManager.updateConfig('app.name', 'Aço Calc Pro - Teste Reload'); - window.adminConfigManager.updateConfig('theme.name', 'light'); - - console.log('✅ Configurações de teste salvas'); - console.log('🔄 Recarregando página em 2 segundos...'); - - setTimeout(() => { - location.reload(); - }, 2000); - } else { - // Verificar se as configurações persistiram após reload - if (window.adminConfigManager) { - const config = window.adminConfigManager.getConfig(); - - if (config.app.name === 'Aço Calc Pro - Teste Reload') { - console.log('✅ Persistência após reload: SUCESSO!'); - if (window.toastManager) { - window.toastManager.success('✅ Configurações persistiram após reload!'); - } - } else { - console.log('❌ Persistência após reload: FALHA'); - if (window.toastManager) { - window.toastManager.error('❌ Configurações não persistiram após reload'); - } - } - } - } -} - -// Auto-executar testes quando os módulos estiverem prontos -if (typeof window !== 'undefined') { - window.addEventListener('load', async () => { - console.log('🧪 Sistema de testes de persistência carregado'); - - // Aguardar um pouco para garantir que tudo está carregado - setTimeout(async () => { - try { - const tester = new PersistenceTest(); - await tester.runAllTests(); - } catch (error) { - console.error('❌ Erro ao executar testes:', error); - } - }, 1000); - }); -} - -// Disponibilizar funções globalmente para testes manuais -window.testarPersistencia = () => { - const tester = new PersistenceTest(); - tester.runAllTests(); -}; - -window.testarPersistenciaAposReload = testarPersistenciaAposReload; - -console.log('🧪 Sistema de testes de persistência inicializado'); \ No newline at end of file diff --git a/public/js/tests/test-suite.js b/public/js/tests/test-suite.js new file mode 100644 index 0000000..af34d00 --- /dev/null +++ b/public/js/tests/test-suite.js @@ -0,0 +1,109 @@ +/** + * SteelBase Test Suite + * Console commands available: + * - runTestSuite() - Run all tests + * - testPersistence() - Test persistence system + * - testBackup() - Test backup/restore + * - testConfig() - Test admin config + */ +(function() { + 'use strict'; + + const TestRunner = { + results: [], + + log(msg, type = 'info') { + const prefix = { info: 'ℹ️', success: '✅', error: '❌', warn: '⚠️' }[type] || 'ℹ️'; + console.log(`${prefix} ${msg}`); + }, + + async waitForModules(timeout = 5000) { + const start = Date.now(); + while (Date.now() - start < timeout) { + if (window.adminConfigManager && window.backupManager) { + return true; + } + await new Promise(r => setTimeout(r, 100)); + } + return false; + }, + + async testPersistence() { + this.log('Testando persistência...', 'info'); + try { + if (!await this.waitForModules()) { + throw new Error('Módulos não carregados'); + } + + const config = window.adminConfigManager.getConfig(); + window.adminConfigManager.updateConfig('test.run', Date.now()); + const updated = window.adminConfigManager.getConfig(); + + const passed = updated.test?.run > 0; + this.log(passed ? 'Persistência OK' : 'Falha na persistência', passed ? 'success' : 'error'); + return passed; + } catch (e) { + this.log(`Erro: ${e.message}`, 'error'); + return false; + } + }, + + async testBackup() { + this.log('Testando backup...', 'info'); + try { + const backup = await window.backupManager.createBackup('Teste automático'); + const list = window.backupManager.getBackups(); + const passed = list.some(b => b.id === backup.id); + + if (passed) { + window.backupManager.removeBackup(backup.id); + } + + this.log(passed ? 'Backup OK' : 'Falha no backup', passed ? 'success' : 'error'); + return passed; + } catch (e) { + this.log(`Erro: ${e.message}`, 'error'); + return false; + } + }, + + async testConfig() { + this.log('Testando configuração...', 'info'); + try { + const cfg = window.adminConfigManager?.getConfig(); + const passed = cfg && cfg.app?.name; + this.log(passed ? 'Configuração OK' : 'Falha na configuração', passed ? 'success' : 'error'); + return passed; + } catch (e) { + this.log(`Erro: ${e.message}`, 'error'); + return false; + } + }, + + async runAllTests() { + this.log('🧪 SteelBase Test Suite', 'info'); + this.log('='.repeat(30), 'info'); + + const results = { + persistence: await this.testPersistence(), + backup: await this.testBackup(), + config: await this.testConfig() + }; + + const total = Object.values(results).filter(Boolean).length; + const totalTests = Object.keys(results).length; + + this.log('='.repeat(30), 'info'); + this.log(`Resultado: ${total}/${totalTests} testes passaram`, total === totalTests ? 'success' : 'warn'); + + return results; + } + }; + + window.runTestSuite = () => TestRunner.runAllTests(); + window.testPersistence = () => TestRunner.testPersistence(); + window.testBackup = () => TestRunner.testBackup(); + window.testConfig = () => TestRunner.testConfig(); + + console.log('✅ Test Suite carregado. Use runTestSuite() no console para executar.'); +})(); \ No newline at end of file diff --git a/public/js/tests/teste-manual-disponibilidade.js b/public/js/tests/teste-manual-disponibilidade.js deleted file mode 100644 index 3e760c2..0000000 --- a/public/js/tests/teste-manual-disponibilidade.js +++ /dev/null @@ -1,81 +0,0 @@ -/** - * Teste Manual de Disponibilidade de Módulos - * Verifica se os módulos de persistência estão disponíveis globalmente - */ - -console.log('🔍 Teste Manual de Disponibilidade Iniciado'); - -// Verificar disponibilidade dos módulos -function verificarDisponibilidade() { - const resultados = { - AdminConfigManager: typeof AdminConfigManager !== 'undefined', - BackupManager: typeof BackupManager !== 'undefined', - ToastManager: typeof ToastManager !== 'undefined', - adminConfigManager: typeof window.adminConfigManager !== 'undefined', - backupManager: typeof window.backupManager !== 'undefined', - toastManager: typeof window.toastManager !== 'undefined' - }; - - console.log('📊 Disponibilidade de Módulos:', resultados); - - // Testar criação de instâncias - if (resultados.AdminConfigManager) { - try { - const tempConfig = new AdminConfigManager(); - console.log('✅ AdminConfigManager pode ser instanciado'); - console.log('📋 Config padrão:', tempConfig.getConfig()); - } catch (error) { - console.error('❌ Erro ao instanciar AdminConfigManager:', error); - } - } - - if (resultados.BackupManager) { - try { - const tempBackup = new BackupManager(); - console.log('✅ BackupManager pode ser instanciado'); - } catch (error) { - console.error('❌ Erro ao instanciar BackupManager:', error); - } - } - - if (resultados.ToastManager) { - try { - const tempToast = new ToastManager(); - console.log('✅ ToastManager pode ser instanciado'); - } catch (error) { - console.error('❌ Erro ao instanciar ToastManager:', error); - } - } - - return resultados; -} - -// Executar após 2 segundos para garantir carregamento -setTimeout(() => { - console.log('⏱️ Executando teste de disponibilidade após 2s...'); - const resultados = verificarDisponibilidade(); - - // Testar persistência básica - if (resultados.AdminConfigManager) { - try { - const configManager = new AdminConfigManager(); - const config = configManager.getConfig(); - config.appName = 'Teste Manual'; - configManager.saveConfig(config); - - const configSalva = configManager.getConfig(); - console.log('✅ Teste de persistência básico:', configSalva.appName === 'Teste Manual' ? 'SUCESSO' : 'FALHA'); - - // Resetar - configManager.resetConfig(); - console.log('🔄 Config resetada para padrão'); - } catch (error) { - console.error('❌ Erro no teste de persistência:', error); - } - } - - console.log('✅ Teste Manual de Disponibilidade Concluído'); -}, 2000); - -// Tornar função global para testes manuais -window.verificarDisponibilidade = verificarDisponibilidade; \ No newline at end of file diff --git a/public/js/tests/verificador-persistencia.js b/public/js/tests/verificador-persistencia.js deleted file mode 100644 index 5019606..0000000 --- a/public/js/tests/verificador-persistencia.js +++ /dev/null @@ -1,176 +0,0 @@ -/** - * Verificador de Status do Sistema de Persistência - * Verifica se os módulos foram carregados corretamente - */ - -(function verificarStatusPersistencia() { - console.log('🔍 Verificando status do sistema de persistência...'); - - // Verificar após um delay para garantir que tudo foi carregado - setTimeout(() => { - const status = { - AdminConfigManager: typeof AdminConfigManager !== 'undefined', - BackupManager: typeof BackupManager !== 'undefined', - ToastManager: typeof ToastManager !== 'undefined', - adminConfigManager: window.adminConfigManager !== null, - backupManager: window.backupManager !== null, - toastManager: window.toastManager !== null - }; - - console.log('📊 Status do Sistema de Persistência:'); - console.table(status); - - // Verificar localStorage - const localStorageKeys = Object.keys(localStorage).filter(key => - key.includes('admin') || key.includes('backup') || key.includes('config') - ); - - console.log('📁 Chaves no localStorage:', localStorageKeys); - - // Tentar criar instâncias se não existirem - if (typeof AdminConfigManager !== 'undefined' && !window.adminConfigManager) { - try { - window.adminConfigManager = new AdminConfigManager(); - console.log('✅ AdminConfigManager inicializado manualmente'); - } catch (error) { - console.error('❌ Erro ao inicializar AdminConfigManager:', error); - } - } - - if (typeof BackupManager !== 'undefined' && !window.backupManager) { - try { - window.backupManager = new BackupManager(); - console.log('✅ BackupManager inicializado manualmente'); - } catch (error) { - console.error('❌ Erro ao inicializar BackupManager:', error); - } - } - - if (typeof ToastManager !== 'undefined' && !window.toastManager) { - try { - window.toastManager = new ToastManager(); - console.log('✅ ToastManager inicializado manualmente'); - } catch (error) { - console.error('❌ Erro ao inicializar ToastManager:', error); - } - } - - // Testar funcionalidade básica - if (window.adminConfigManager) { - try { - const config = window.adminConfigManager.getConfig(); - console.log('✅ Configuração atual:', config); - - // Testar salvamento - window.adminConfigManager.updateConfig('test.verification', new Date().toISOString()); - console.log('✅ Teste de salvamento realizado'); - - } catch (error) { - console.error('❌ Erro ao testar AdminConfigManager:', error); - } - } - - // Mostrar resumo - const totalModulos = Object.keys(status).length; - const modulosOk = Object.values(status).filter(v => v).length; - const percentual = (modulosOk / totalModulos * 100).toFixed(1); - - console.log(`📈 Sistema de Persistência: ${modulosOk}/${totalModulos} módulos OK (${percentual}%)`); - - if (window.toastManager) { - if (percentual === '100.0') { - window.toastManager.success('✅ Sistema de persistência totalmente operacional!'); - } else if (percentual >= '66.7') { - window.toastManager.warning(`⚠️ Sistema de persistência parcial (${percentual}%)`); - } else { - window.toastManager.error(`❌ Sistema de persistência com problemas (${percentual}%)`); - } - } - - }, 3000); // Aguardar 3 segundos para garantir carregamento - - // Também verificar após 10 segundos (backup) - setTimeout(() => { - console.log('🔍 Verificação de backup do sistema de persistência:'); - - if (window.adminConfigManager) { - try { - const config = window.adminConfigManager.getConfig(); - console.log('✅ Config após 10s:', { - appName: config.app.name, - theme: config.theme.name, - version: config.version - }); - } catch (error) { - console.error('❌ AdminConfigManager ainda com problemas:', error); - } - } else { - console.error('❌ AdminConfigManager não disponível após 10s'); - } - }, 10000); - -})(); - -// Função para debug detalhado -window.debugPersistencia = function() { - console.group('🔍 Debug Detalhado do Sistema de Persistência'); - - // Verificar cada módulo - console.log('1. Verificando AdminConfigManager:'); - console.log(' - Tipo:', typeof AdminConfigManager); - console.log(' - Disponível:', typeof AdminConfigManager !== 'undefined'); - - if (typeof AdminConfigManager !== 'undefined') { - try { - const tempManager = new AdminConfigManager(); - console.log(' - Instância criada com sucesso'); - console.log(' - Config padrão:', tempManager.getConfig()); - - // Testar localStorage - const key = tempManager.configKey; - const data = localStorage.getItem(key); - console.log(' - localStorage key:', key); - console.log(' - Dados no localStorage:', data ? 'Presentes' : 'Ausentes'); - - } catch (error) { - console.error(' - Erro ao criar instância:', error); - } - } - - console.log('2. Verificando BackupManager:'); - console.log(' - Tipo:', typeof BackupManager); - console.log(' - Disponível:', typeof BackupManager !== 'undefined'); - - console.log('3. Verificando ToastManager:'); - console.log(' - Tipo:', typeof ToastManager); - console.log(' - Disponível:', typeof ToastManager !== 'undefined'); - - console.log('4. Verificando variáveis globais:'); - console.log(' - window.adminConfigManager:', window.adminConfigManager); - console.log(' - window.backupManager:', window.backupManager); - console.log(' - window.toastManager:', window.toastManager); - - console.log('5. Verificando localStorage:'); - const relevantKeys = Object.keys(localStorage).filter(key => - key.includes('admin') || key.includes('backup') || key.includes('config') - ); - console.log(' - Chaves relevantes:', relevantKeys); - relevantKeys.forEach(key => { - try { - const data = JSON.parse(localStorage.getItem(key)); - console.log(` - ${key}:`, { - type: typeof data, - hasVersion: !!data.version, - hasAppConfig: !!(data.app || data.application), - hasTheme: !!(data.theme || data.themes), - size: JSON.stringify(data).length - }); - } catch (e) { - console.log(` - ${key}: (dados inválidos)`); - } - }); - - console.groupEnd(); -}; - -console.log('🔍 Sistema de verificação de persistência carregado'); \ No newline at end of file diff --git a/public/js/utils/logger.js b/public/js/utils/logger.js new file mode 100644 index 0000000..4a91f71 --- /dev/null +++ b/public/js/utils/logger.js @@ -0,0 +1,60 @@ +/** + * Logger com níveis de debug + * Substitui console.log dispersos pelo código + */ +const Logger = (function() { + const LEVELS = { + debug: 0, + info: 1, + warn: 2, + error: 3 + }; + + let currentLevel = LEVELS.info; + + function setLevel(level) { + if (LEVELS[level] !== undefined) { + currentLevel = LEVELS[level]; + } + } + + function shouldLog(level) { + return LEVELS[level] >= currentLevel; + } + + function formatMessage(level, ...args) { + const timestamp = new Date().toISOString().slice(11, 19); + return `[${timestamp}] [${level.toUpperCase()}]`; + } + + return { + debug: function(...args) { + if (shouldLog('debug')) console.debug(formatMessage('debug', ...args), ...args); + }, + + info: function(...args) { + if (shouldLog('info')) console.info(formatMessage('info', ...args), ...args); + }, + + warn: function(...args) { + if (shouldLog('warn')) console.warn(formatMessage('warn', ...args), ...args); + }, + + error: function(...args) { + if (shouldLog('error')) console.error(formatMessage('error', ...args), ...args); + }, + + setLevel: setLevel, + + enableDebug: function() { + setLevel('debug'); + }, + + disableDebug: function() { + setLevel('info'); + } + }; +})(); + +window.Logger = Logger; +export default Logger; \ No newline at end of file