diff --git a/public/app.js b/public/app.js index 9392859..52f9794 100644 --- a/public/app.js +++ b/public/app.js @@ -1,19 +1,116 @@ // ======================================== -// SteelBase v7.5 - PROFESSIONAL EDITION +// SteelBase v6.5 - PROFESSIONAL EDITION // Plataforma Técnica Completa com Base de Materiais // ======================================== -(function() { - 'use strict'; +// In-memory data storage WITH localStorage for preferences +const appState = { + history: [], + favorites: [], + budgetItems: [], + currentSection: 'cev', + currentTheme: 'dark', // 'dark' or 'light' + expertMode: false, + currentSidebarTab: 0 +}; -// Logger disponível globalmente (carregado antes em logger.js) -// Usar window.Logger.info('mensagem') para logs controlados +// User preferences (saved to localStorage) +let userPreferences = { + theme: 'dark', + colorScheme: 'default', // default, blue, green, purple, orange + fontSize: 'medium', // small, medium, large, xlarge + fontFamily: 'default' // default, modern, classic, mono +}; -// State e config disponíveis globalmente via script state.js (carregado antes) -// Referências para uso local -var appState = window.appState; -var userPreferences = window.userPreferences; -var adminConfig = window.adminConfig; +// Load preferences from localStorage +function loadPreferences() { + try { + const saved = localStorage.getItem('acoCalcPreferences'); + if (saved) { + userPreferences = { ...userPreferences, ...JSON.parse(saved) }; + } + } catch (e) { + console.warn('Não foi possível carregar preferências:', e); + } +} + +// Save preferences to localStorage +function savePreferences() { + try { + localStorage.setItem('acoCalcPreferences', JSON.stringify(userPreferences)); + } catch (e) { + console.warn('Não foi possível salvar preferências:', e); + } +} + +// Admin configuration (in-memory) +const adminConfig = { + appName: 'SteelBase', + appSubtitle: 'Plataforma Técnica com Base de Dados de Materiais Brasileiros', + footerText: '© 2025 SteelBase v6.5 PROFESSIONAL EDITION - Plataforma Técnica com Base de Dados de Materiais Brasileiros', + themeDefault: 'escuro', + modeDefault: 'simples', + toolsVisibility: { + // Aços Estruturais + 'cev': true, + 'seletor': true, + 'equivalencias': false, + 'comparativo': false, + 'assistente-inteligente': true, + // Consumíveis de Soldagem + 'eletrodos': false, + 'arames': false, + 'fluxos': false, + 'gases': false, + // Fixadores + 'parafusos-catalogo': false, + 'porcas': false, + 'arruelas': false, + 'chumbadores': false, + // Tintas e Revestimentos + 'tintas-catalogo': false, + 'sistemas-pintura': false, + 'abrasivos': false, + 'granalha': false, + // Elementos Complementares + 'telhas': false, + 'paineis': false, + 'steel-deck': false, + 'perfis-formados': false, + // Catálogo de Perfis + 'cantoneiras': true, + 'barras-redondas': true, + 'tubos-circulares': true, + 'perfis-i': true, + 'perfis-w': true, + 'tubos-rhs': true, + 'chapas': true, + 'perfis-hp': true, + 'barras-roscadas': true, + 'barras-chatas': true, + // Conexões + 'parafusos': true, + 'layout': true, + 'parafuso-vs-solda': false, + // Soldagem + 'preaquecimento': true, + 'dureza': true, + 'charpy': true, + 'certificado': false, + 'ultrassom': false, + // Pintura + 'area-pintura': true, + 'consumo-tinta': true, + 'galvanizacao': false, + 'custo-pintura': true, + 'secagem': false, + 'inspecao-pintura': false, + // Orçamento + 'orcamento': true, + 'peso-rigging': false, + 'referencia': false + } +}; // ======================================== // CSV MAPPING AND LOADING FUNCTIONS v6.6 @@ -334,6 +431,108 @@ function showSection(sectionId) { }, 500); } + // CÓDIGO ANTIGO REMOVIDO - mantido apenas para referência + if (false && sectionId === 'cantoneiras') { + console.log('🔧 Seção cantoneiras detectada - iniciando carregamento forçado'); + + // Tentar múltiplas vezes até conseguir + let tentativas = 0; + const maxTentativas = 10; + + const tentarCarregar = async () => { + tentativas++; + console.log(`🔄 Tentativa ${tentativas}/${maxTentativas} de carregar cantoneiras`); + + const tbody = document.getElementById('cantoneiras-tbody'); + + if (tbody) { + console.log('✅ Elemento tbody encontrado! Carregando dados...'); + + try { + // Carregar CSV diretamente + const response = await fetch('BD/perfis/cantoneiras_brasil_completo.csv'); + if (!response.ok) { + throw new Error(`HTTP ${response.status}`); + } + + const csvText = await response.text(); + const linhas = csvText.trim().split('\n'); + + console.log(`📊 CSV carregado: ${linhas.length} linhas`); + + const dados = []; + for (let i = 1; i < linhas.length; i++) { + const linha = linhas[i].trim(); + if (!linha) continue; + + const colunas = linha.split(','); + if (colunas.length >= 9) { + dados.push({ + id: colunas[0].trim(), + nome: colunas[1].trim(), + lado_mm: parseFloat(colunas[2]), + espessura_mm: parseFloat(colunas[3]), + peso_kg_m: parseFloat(colunas[4]), + area_cm2: parseFloat(colunas[5]), + momento_inercia_cm4: parseFloat(colunas[6]), + raio_giracao_cm: parseFloat(colunas[7]), + tipo: colunas[8].trim() + }); + } + } + + console.log(`✅ Processados: ${dados.length} cantoneiras`); + + // Exibir na tabela + tbody.innerHTML = dados.map(item => ` + + ${item.nome} + ${item.lado_mm} + ${item.espessura_mm} + ${item.peso_kg_m.toFixed(2)} + ${item.area_cm2.toFixed(2)} + ${item.momento_inercia_cm4.toFixed(2)} + ${item.raio_giracao_cm.toFixed(2)} + ${item.tipo} + + + `).join(''); + + console.log('🎉 Tabela preenchida com sucesso!'); + + // Atualizar contador + const totalEl = document.getElementById('cant-total'); + if (totalEl) { + totalEl.textContent = dados.length; + } + + } catch (error) { + console.error('❌ Erro ao carregar CSV:', error); + tbody.innerHTML = ` + + + ❌ Erro ao carregar dados: ${error.message} +

+ + + + `; + } + } else { + console.warn(`⚠️ Elemento tbody não encontrado (tentativa ${tentativas})`); + + if (tentativas < maxTentativas) { + setTimeout(tentarCarregar, 300); + } else { + console.error('❌ Falha após todas as tentativas'); + } + } + }; + + // Iniciar tentativas após um pequeno delay + setTimeout(tentarCarregar, 200); + } + // Add help button after content loads setTimeout(() => { if (sectionId === 'preaquecimento') { @@ -893,37 +1092,14 @@ function analisarUltrassom() { } function calcularCustoTotal() { - 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 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 precosTinta = { sudeste: { padrao: 80, premium: 120, economica: 50 }, @@ -1025,31 +1201,10 @@ function calcularCustoTotal() { } function calcularSecagem() { - 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 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 dadosTinta = { epoxi: { tempIdeal: 25, umidadeMax: 85, tempoBase: 24, fatorEsp: 0.2 }, @@ -5039,28 +5194,14 @@ function getReferenciaContent() { // CEV Calculation function calcularCEV() { - 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; - } + 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; // IIW Formula const CEV = C + Mn/6 + (Cr+Mo+V)/5 + (Ni+Cu)/15; @@ -5922,37 +6063,11 @@ const steelBearing = { // Tab 1: Cisalhamento (Shear) function calcularCisalhamento() { - 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 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 bolt = boltDatabase[boltType]; const area = Math.PI * Math.pow(d / 2, 2); @@ -7363,30 +7478,9 @@ function calcularEnergiaCompleta() { } function calcularPreaquecimento() { - 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 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 preheatTemp = 50 + (cev * 100) + (thickness / 10 * 20) + ((20 - ambient) / 2); const maxInterpass = preheatTemp + 100; @@ -10963,4 +11057,4 @@ console.log('✅ SteelBase carregado com sucesso!'); }); // Removido: listener de fechamento do modal Admin legado -})(); \ No newline at end of file +}); \ No newline at end of file