Fix script paths and move assets to public/ folder for Vite build compatibility

This commit is contained in:
Marcos
2026-03-22 20:45:20 -03:00
parent 304504b758
commit 57ba9d1c5f
155 changed files with 10614 additions and 26 deletions

View File

@@ -0,0 +1,417 @@
/**
* TEMPLATES PARA CATÁLOGO DE PERFIS
* Sistema automatizado para gerar conteúdo de todos os perfis
*/
// Configuração de cada tipo de perfil
const PERFIS_CONFIG = {
'barras-redondas': {
nome: 'Barras Redondas',
icone: '⚫',
descricao: 'Barras de aço redondas laminadas a quente',
quantidade: 25,
csv: 'BD/perfis/barras_brasil_completo.csv',
colunas: ['id', 'nome', 'diametro_mm', 'peso_kg_m', 'area_cm2', 'tipo'],
colunasTabel: [
{ key: 'nome', label: 'Designação' },
{ key: 'diametro_mm', label: 'Diâmetro (mm)' },
{ key: 'peso_kg_m', label: 'Peso (kg/m)', decimals: 2 },
{ key: 'area_cm2', label: 'Área (cm²)', decimals: 2 },
{ key: 'tipo', label: 'Categoria', badge: true }
],
filtros: [
{ id: 'tamanho', label: 'Tamanho', type: 'select', options: [
{ value: '', label: 'Todos' },
{ value: 'Pequeno', label: 'Pequeno (Ø6-Ø16)' },
{ value: 'Médio', label: 'Médio (Ø20-Ø32)' },
{ value: 'Grande', label: 'Grande (Ø38-Ø50)' },
{ value: 'Extra-Grande', label: 'Extra-Grande (Ø63+)' }
]},
{ id: 'peso-max', label: 'Peso Máximo (kg/m)', type: 'number', placeholder: 'Ex: 20' },
{ id: 'busca', label: 'Buscar por Nome', type: 'text', placeholder: 'Ex: Ø25' }
]
},
'tubos-circulares': {
nome: 'Tubos Circulares',
icone: '⭕',
descricao: 'Tubos de aço circulares sem costura e com costura',
quantidade: 30,
csv: 'BD/perfis/tubos_circulares_brasil_completo.csv',
colunas: ['id', 'nome', 'diametro_externo_mm', 'espessura_mm', 'peso_kg_m', 'area_cm2', 'tipo'],
colunasTabel: [
{ key: 'nome', label: 'Designação' },
{ key: 'diametro_externo_mm', label: 'Ø Externo (mm)' },
{ key: 'espessura_mm', label: 'Espessura (mm)' },
{ key: 'peso_kg_m', label: 'Peso (kg/m)', decimals: 2 },
{ key: 'area_cm2', label: 'Área (cm²)', decimals: 2 },
{ key: 'tipo', label: 'Categoria', badge: true }
],
filtros: [
{ id: 'tamanho', label: 'Diâmetro', type: 'select', options: [
{ value: '', label: 'Todos' },
{ value: 'Pequeno', label: 'Pequeno (Ø21-Ø60)' },
{ value: 'Médio', label: 'Médio (Ø73-Ø114)' },
{ value: 'Grande', label: 'Grande (Ø141-Ø219)' },
{ value: 'Extra-Grande', label: 'Extra-Grande (Ø273+)' }
]},
{ id: 'peso-max', label: 'Peso Máximo (kg/m)', type: 'number', placeholder: 'Ex: 50' },
{ id: 'busca', label: 'Buscar por Nome', type: 'text', placeholder: 'Ex: Ø114' }
]
},
'perfis-i': {
nome: 'Perfis I (IPE)',
icone: '🏗️',
descricao: 'Perfis I laminados a quente - Série IPE',
quantidade: 20,
csv: 'BD/perfis/perfis_i_brasil_completo.csv',
colunas: ['id', 'nome', 'altura_mm', 'largura_mm', 'espessura_alma_mm', 'espessura_mesa_mm', 'peso_kg_m', 'area_cm2', 'tipo'],
colunasTabel: [
{ key: 'nome', label: 'Designação' },
{ key: 'altura_mm', label: 'Altura (mm)' },
{ key: 'largura_mm', label: 'Largura (mm)' },
{ key: 'peso_kg_m', label: 'Peso (kg/m)', decimals: 2 },
{ key: 'area_cm2', label: 'Área (cm²)', decimals: 2 },
{ key: 'tipo', label: 'Categoria', badge: true }
],
filtros: [
{ id: 'tamanho', label: 'Tamanho', type: 'select', options: [
{ value: '', label: 'Todos' },
{ value: 'Pequeno', label: 'Pequeno (IPE80-IPE160)' },
{ value: 'Médio', label: 'Médio (IPE180-IPE270)' },
{ value: 'Grande', label: 'Grande (IPE300-IPE400)' },
{ value: 'Extra-Grande', label: 'Extra-Grande (IPE450+)' }
]},
{ id: 'peso-max', label: 'Peso Máximo (kg/m)', type: 'number', placeholder: 'Ex: 100' },
{ id: 'busca', label: 'Buscar por Nome', type: 'text', placeholder: 'Ex: IPE200' }
]
},
'perfis-w': {
nome: 'Perfis W',
icone: '🏛️',
descricao: 'Perfis W laminados a quente - Série americana',
quantidade: 25,
csv: 'BD/perfis/perfis_w_brasil_completo.csv',
colunas: ['id', 'nome', 'altura_mm', 'largura_mm', 'espessura_alma_mm', 'espessura_mesa_mm', 'peso_kg_m', 'area_cm2', 'tipo'],
colunasTabel: [
{ key: 'nome', label: 'Designação' },
{ key: 'altura_mm', label: 'Altura (mm)' },
{ key: 'largura_mm', label: 'Largura (mm)' },
{ key: 'peso_kg_m', label: 'Peso (kg/m)', decimals: 2 },
{ key: 'area_cm2', label: 'Área (cm²)', decimals: 2 },
{ key: 'tipo', label: 'Categoria', badge: true }
],
filtros: [
{ id: 'tamanho', label: 'Tamanho', type: 'select', options: [
{ value: '', label: 'Todos' },
{ value: 'Pequeno', label: 'Pequeno (W150-W250)' },
{ value: 'Médio', label: 'Médio (W310-W410)' },
{ value: 'Grande', label: 'Grande (W460-W610)' },
{ value: 'Extra-Grande', label: 'Extra-Grande (W690+)' }
]},
{ id: 'peso-max', label: 'Peso Máximo (kg/m)', type: 'number', placeholder: 'Ex: 150' },
{ id: 'busca', label: 'Buscar por Nome', type: 'text', placeholder: 'Ex: W310' }
]
},
'tubos-rhs': {
nome: 'Tubos RHS',
icone: '▭',
descricao: 'Tubos retangulares e quadrados estruturais',
quantidade: 35,
csv: 'BD/perfis/tubos_rhs_brasil_completo.csv',
colunas: ['id', 'nome', 'largura_mm', 'altura_mm', 'espessura_mm', 'peso_kg_m', 'area_cm2', 'tipo'],
colunasTabel: [
{ key: 'nome', label: 'Designação' },
{ key: 'largura_mm', label: 'Largura (mm)' },
{ key: 'altura_mm', label: 'Altura (mm)' },
{ key: 'espessura_mm', label: 'Espessura (mm)' },
{ key: 'peso_kg_m', label: 'Peso (kg/m)', decimals: 2 },
{ key: 'area_cm2', label: 'Área (cm²)', decimals: 2 },
{ key: 'tipo', label: 'Categoria', badge: true }
],
filtros: [
{ id: 'tamanho', label: 'Tamanho', type: 'select', options: [
{ value: '', label: 'Todos' },
{ value: 'Pequeno', label: 'Pequeno (até 50x50)' },
{ value: 'Médio', label: 'Médio (60x40 a 100x100)' },
{ value: 'Grande', label: 'Grande (120x80 a 200x100)' },
{ value: 'Extra-Grande', label: 'Extra-Grande (200x200+)' }
]},
{ id: 'peso-max', label: 'Peso Máximo (kg/m)', type: 'number', placeholder: 'Ex: 80' },
{ id: 'busca', label: 'Buscar por Nome', type: 'text', placeholder: 'Ex: 100x100' }
]
},
'chapas': {
nome: 'Chapas',
icone: '📄',
descricao: 'Chapas de aço laminadas a quente e a frio',
quantidade: 15,
csv: 'BD/perfis/chapas_brasil_completo.csv',
colunas: ['id', 'nome', 'espessura_mm', 'peso_kg_m2', 'tipo'],
colunasTabel: [
{ key: 'nome', label: 'Designação' },
{ key: 'espessura_mm', label: 'Espessura (mm)' },
{ key: 'peso_kg_m2', label: 'Peso (kg/m²)', decimals: 2 },
{ key: 'tipo', label: 'Categoria', badge: true }
],
filtros: [
{ id: 'tamanho', label: 'Espessura', type: 'select', options: [
{ value: '', label: 'Todas' },
{ value: 'Fina', label: 'Fina (até 6mm)' },
{ value: 'Média', label: 'Média (8-16mm)' },
{ value: 'Grossa', label: 'Grossa (19-32mm)' },
{ value: 'Extra-Grossa', label: 'Extra-Grossa (38mm+)' }
]},
{ id: 'peso-max', label: 'Peso Máximo (kg/m²)', type: 'number', placeholder: 'Ex: 100' },
{ id: 'busca', label: 'Buscar por Nome', type: 'text', placeholder: 'Ex: 12.5mm' }
]
},
'perfis-hp': {
nome: 'Perfis HP',
icone: '🏗️',
descricao: 'Perfis HP para estacas e pilares',
quantidade: 12,
csv: 'BD/perfis/perfis_hp_brasil_completo.csv',
colunas: ['id', 'nome', 'altura_mm', 'largura_mm', 'espessura_alma_mm', 'espessura_mesa_mm', 'peso_kg_m', 'area_cm2', 'tipo'],
colunasTabel: [
{ key: 'nome', label: 'Designação' },
{ key: 'altura_mm', label: 'Altura (mm)' },
{ key: 'largura_mm', label: 'Largura (mm)' },
{ key: 'peso_kg_m', label: 'Peso (kg/m)', decimals: 2 },
{ key: 'area_cm2', label: 'Área (cm²)', decimals: 2 },
{ key: 'tipo', label: 'Categoria', badge: true }
],
filtros: [
{ id: 'tamanho', label: 'Tamanho', type: 'select', options: [
{ value: '', label: 'Todos' },
{ value: 'Pequeno', label: 'Pequeno (HP200-HP250)' },
{ value: 'Médio', label: 'Médio (HP310-HP360)' },
{ value: 'Grande', label: 'Grande (HP400+)' }
]},
{ id: 'peso-max', label: 'Peso Máximo (kg/m)', type: 'number', placeholder: 'Ex: 150' },
{ id: 'busca', label: 'Buscar por Nome', type: 'text', placeholder: 'Ex: HP310' }
]
},
'barras-roscadas': {
nome: 'Barras Roscadas',
icone: '🔩',
descricao: 'Barras roscadas de aço para fixação',
quantidade: 18,
csv: 'BD/perfis/barras_roscadas_brasil_completo.csv',
colunas: ['id', 'nome', 'diametro_mm', 'passo_mm', 'peso_kg_m', 'area_cm2', 'tipo'],
colunasTabel: [
{ key: 'nome', label: 'Designação' },
{ key: 'diametro_mm', label: 'Diâmetro (mm)' },
{ key: 'passo_mm', label: 'Passo (mm)' },
{ key: 'peso_kg_m', label: 'Peso (kg/m)', decimals: 2 },
{ key: 'area_cm2', label: 'Área (cm²)', decimals: 2 },
{ key: 'tipo', label: 'Categoria', badge: true }
],
filtros: [
{ id: 'tamanho', label: 'Diâmetro', type: 'select', options: [
{ value: '', label: 'Todos' },
{ value: 'Pequeno', label: 'Pequeno (M6-M12)' },
{ value: 'Médio', label: 'Médio (M16-M24)' },
{ value: 'Grande', label: 'Grande (M30-M36)' },
{ value: 'Extra-Grande', label: 'Extra-Grande (M42+)' }
]},
{ id: 'peso-max', label: 'Peso Máximo (kg/m)', type: 'number', placeholder: 'Ex: 10' },
{ id: 'busca', label: 'Buscar por Nome', type: 'text', placeholder: 'Ex: M20' }
]
},
'barras-chatas': {
nome: 'Barras Chatas',
icone: '▬',
descricao: 'Barras chatas de aço laminadas a quente',
quantidade: 22,
csv: 'BD/perfis/barras_chatas_brasil_completo.csv',
colunas: ['id', 'nome', 'largura_mm', 'espessura_mm', 'peso_kg_m', 'area_cm2', 'tipo'],
colunasTabel: [
{ key: 'nome', label: 'Designação' },
{ key: 'largura_mm', label: 'Largura (mm)' },
{ key: 'espessura_mm', label: 'Espessura (mm)' },
{ key: 'peso_kg_m', label: 'Peso (kg/m)', decimals: 2 },
{ key: 'area_cm2', label: 'Área (cm²)', decimals: 2 },
{ key: 'tipo', label: 'Categoria', badge: true }
],
filtros: [
{ id: 'tamanho', label: 'Tamanho', type: 'select', options: [
{ value: '', label: 'Todas' },
{ value: 'Pequena', label: 'Pequena (até 25mm)' },
{ value: 'Média', label: 'Média (32-50mm)' },
{ value: 'Grande', label: 'Grande (63-100mm)' },
{ value: 'Extra-Grande', label: 'Extra-Grande (125mm+)' }
]},
{ id: 'peso-max', label: 'Peso Máximo (kg/m)', type: 'number', placeholder: 'Ex: 30' },
{ id: 'busca', label: 'Buscar por Nome', type: 'text', placeholder: 'Ex: 50x6' }
]
}
};
/**
* Gera o HTML completo para um tipo de perfil
*/
function gerarConteudoPerfil(tipo) {
const config = PERFIS_CONFIG[tipo];
if (!config) {
console.error(`Configuração não encontrada para: ${tipo}`);
return '<p>Erro: Tipo de perfil não configurado</p>';
}
const tipoId = tipo.replace(/-/g, '_');
return `
<div class="section-header">
<div class="section-title">${config.icone} ${config.nome} - Catálogo Completo Brasil</div>
<div class="section-description">${config.descricao} - ${config.quantidade} modelos disponíveis</div>
</div>
<!-- Tabs de Navegação -->
<div class="tabs-container">
<div class="tabs-nav">
<button class="tab-btn active" onclick="switchPerfilTab(0)">📊 Tabela Técnica</button>
<button class="tab-btn" onclick="switchPerfilTab(1)">📋 Especificações</button>
<button class="tab-btn" onclick="switchPerfilTab(2)">🏭 Fabricantes</button>
<button class="tab-btn" onclick="switchPerfilTab(3)">💰 Preços 2025</button>
<button class="tab-btn" onclick="switchPerfilTab(4)">🔧 Aplicações</button>
</div>
<!-- TAB 1: TABELA TÉCNICA -->
<div class="tab-content active" id="perfil-tab-0">
<div class="card">
<div class="card-title">🔍 Filtros de Busca</div>
<div class="form-grid">
${config.filtros.map((filtro, index) => `
<div class="form-group">
<label class="form-label">${filtro.label}</label>
${filtro.type === 'select' ? `
<select class="form-control" id="${tipoId}-${filtro.id}" onchange="filtrar${capitalize(tipoId)}()">
${filtro.options.map(opt => `<option value="${opt.value}">${opt.label}</option>`).join('')}
</select>
` : `
<input type="${filtro.type}" class="form-control" id="${tipoId}-${filtro.id}"
placeholder="${filtro.placeholder}"
${filtro.type === 'number' ? 'onchange' : 'oninput'}="filtrar${capitalize(tipoId)}()">
`}
</div>
`).join('')}
</div>
<button class="btn btn-secondary" onclick="limparFiltros${capitalize(tipoId)}()">🔄 Limpar Filtros</button>
</div>
<div class="card">
<div class="card-title">
📊 Tabela de ${config.nome} (${config.quantidade} modelos)
<button class="btn btn-primary" id="btn-carregar-${tipoId}"
onclick="forcarCarregamento${capitalize(tipoId)}()"
style="float: right; margin-top: -4px;">
🔄 Carregar Dados
</button>
${tipo === 'tubos-rhs' ? `
<button class="btn btn-secondary" id="btn-atualizar-${tipoId}"
onclick="atualizarFonte${capitalize(tipoId)}()"
style="float: right; margin-right: 8px; margin-top: -4px;">
🗄️ Atualizar da Fonte
</button>
` : ''}
</div>
<div id="${tipoId}-table-container">
<div class="table-container">
<table id="${tipoId}-table">
<thead>
<tr>
${config.colunasTabel.map(col => `<th>${col.label}</th>`).join('')}
<th>Ações</th>
</tr>
</thead>
<tbody id="${tipoId}-tbody">
<!-- Será preenchido via JavaScript -->
</tbody>
</table>
</div>
</div>
<div style="margin-top: 16px; padding: 12px; background: var(--color-bg-2); border-radius: 8px;">
<strong>📌 Total:</strong> <span id="${tipoId}-total">${config.quantidade}</span> modelos encontrados
${tipo === 'tubos-rhs' ? `
<div style="margin-top:8px; font-size:12px; color: var(--color-text-secondary);">
Fonte: <span id="${tipoId}-fonte">${config.csv}</span> |
Última atualização: <span id="${tipoId}-last">—</span>
</div>
` : ''}
</div>
</div>
</div>
<!-- TAB 2: ESPECIFICAÇÕES -->
<div class="tab-content" id="perfil-tab-1">
<div class="card" style="background: var(--color-bg-1);">
<div class="card-title">📋 Especificações Técnicas Completas</div>
<h3 style="color: var(--color-primary); margin-top: 20px;">🔧 Descrição Geral</h3>
<p><strong>${config.descricao}</strong></p>
<p>Perfis estruturais amplamente utilizados em construção civil, naval e industrial.</p>
</div>
</div>
<!-- TAB 3: FABRICANTES -->
<div class="tab-content" id="perfil-tab-2">
<div class="card" style="background: var(--color-bg-1);">
<div class="card-title">🏭 Fabricantes e Distribuição no Brasil</div>
<p>Principais fabricantes nacionais disponíveis.</p>
</div>
</div>
<!-- TAB 4: PREÇOS -->
<div class="tab-content" id="perfil-tab-3">
<div class="card" style="background: var(--color-bg-1);">
<div class="card-title">💰 Preços e Fatores de Custo (2025)</div>
<p>Informações de preços atualizadas para ${new Date().getFullYear()}.</p>
</div>
</div>
<!-- TAB 5: APLICAÇÕES -->
<div class="tab-content" id="perfil-tab-4">
<div class="card" style="background: var(--color-bg-1);">
<div class="card-title">🔧 Aplicações Principais e Recomendações</div>
<p>Aplicações típicas e recomendações de uso.</p>
</div>
</div>
</div>
`;
}
/**
* Capitaliza primeira letra
*/
function capitalize(str) {
return str.split('_').map(word =>
word.charAt(0).toUpperCase() + word.slice(1)
).join('');
}
// Exportar configurações e funções
window.PERFIS_CONFIG = PERFIS_CONFIG;
window.gerarConteudoPerfil = gerarConteudoPerfil;
console.log('✅ Templates de perfis carregados');
// Fallback: registrar switchPerfilTab global se não existir
if (typeof window.switchPerfilTab !== 'function') {
window.switchPerfilTab = function(index) {
try {
const btns = document.querySelectorAll('.tabs-nav .tab-btn');
const tabs = document.querySelectorAll('.tab-content');
btns.forEach((btn, i) => btn.classList.toggle('active', i === index));
tabs.forEach((tab, i) => tab.classList.toggle('active', i === index));
} catch (err) {
console.warn('⚠️ Fallback switchPerfilTab falhou:', err);
}
};
console.log('✅ Fallback switchPerfilTab registrado no templates');
}