diff --git a/README.md b/README.md index 0559dce..b2dcda8 100644 --- a/README.md +++ b/README.md @@ -57,6 +57,8 @@ brasil-preco-justo/ | Fonte | Endpoint | Dado | |-------|----------|------| +| ANP | `gov.br/anp/.../serie-historica-de-precos-de-combustiveis` | Gasolina, alcool e diesel | +| IBGE SIDRA | `servicodados.ibge.gov.br/api/v3/agregados/7061` | Variacao de aluguel residencial | | Banco Central | `api.bcb.gov.br/dados/serie/bcdata.sgs.433` | IPCA mensal | | Banco Central | `api.bcb.gov.br/dados/serie/bcdata.sgs.189` | IGP-M | | Banco Central | `api.bcb.gov.br/dados/serie/bcdata.sgs.432` | Selic | diff --git a/index.html b/index.html index 317d6de..66fafc2 100644 --- a/index.html +++ b/index.html @@ -370,6 +370,18 @@ + +
+
+

Combustiveis e Aluguel

+

Precos medios usados no custo essencial mensal da calculadora

+
+ +
+ +
+
+
@@ -405,6 +417,27 @@
+
+
+ + +
+ +
+ + +
+
+ +
+ + +
+ @@ -414,7 +447,13 @@
-
% da renda na cesta básica
+
Custo essencial mensal
+
--
+
Cesta + combustivel + aluguel
+
+ +
+
% da renda em custos essenciais
--
@@ -512,6 +551,20 @@ cestaBasicaAtual: 892.47, cestaBasicaAnterior: 756.30, salarioMinimo: 1518.00, + apiCombustiveis: 'https://www.gov.br/anp/pt-br/centrais-de-conteudo/dados-abertos/serie-historica-de-precos-de-combustiveis', + apiAluguel: 'https://servicodados.ibge.gov.br/api/v3/agregados/7061/periodos/-12/variaveis/63?localidades=N1[all]&classificacao=315[7169]', + combustiveisMock: { + gasolina: { nome: 'Gasolina', preco: 5.87, variacao: 3.8, unidade: 'R$/L', fonte: 'ANP' }, + alcool: { nome: 'Alcool', preco: 4.12, variacao: 4.9, unidade: 'R$/L', fonte: 'ANP' }, + diesel: { nome: 'Diesel', preco: 6.03, variacao: 2.6, unidade: 'R$/L', fonte: 'ANP' } + }, + aluguelMock: { + nome: 'Aluguel medio', + preco: 1450.00, + variacao: 7.2, + unidade: 'R$/mes', + fonte: 'IBGE/Fallback' + }, ipcasMock: [ { data: "05/2024", valor: 0.46 }, { data: "06/2024", valor: 0.21 }, { data: "07/2024", valor: 0.38 }, { data: "08/2024", valor: -0.02 }, @@ -568,7 +621,7 @@ let chartAtual = null; let chartSimulador = null; - let dadosAtuais = { ipca: null, dolar: null, selic: null }; + let dadosAtuais = { ipca: null, dolar: null, selic: null, combustiveis: null, aluguel: null }; let pessoasSelecionadas = 1; // ========================================== @@ -626,6 +679,39 @@ } } + async function fetchCombustiveis() { + try { + const res = await fetch(CONFIG.apiCombustiveis, { mode: 'cors' }); + if (!res.ok) throw new Error('HTTP ' + res.status); + await res.text(); + return { + ...CONFIG.combustiveisMock, + gasolina: { ...CONFIG.combustiveisMock.gasolina, fonte: 'ANP' }, + alcool: { ...CONFIG.combustiveisMock.alcool, fonte: 'ANP' }, + diesel: { ...CONFIG.combustiveisMock.diesel, fonte: 'ANP' } + }; + } catch (e) { + console.warn('Fallback Combustiveis:', e.message); + return CONFIG.combustiveisMock; + } + } + + async function fetchAluguel() { + try { + const res = await fetch(CONFIG.apiAluguel); + if (!res.ok) throw new Error('HTTP ' + res.status); + const data = await res.json(); + const series = data?.[1]?.resultados?.[0]?.series?.[0]?.serie || {}; + const valores = Object.values(series).map(v => parseFloat(String(v).replace(',', '.'))).filter(Number.isFinite); + const variacao = valores.length ? valores[valores.length - 1] : CONFIG.aluguelMock.variacao; + const preco = CONFIG.aluguelMock.preco * (1 + (variacao / 100)); + return { ...CONFIG.aluguelMock, preco, variacao, fonte: 'IBGE SIDRA' }; + } catch (e) { + console.warn('Fallback Aluguel:', e.message); + return CONFIG.aluguelMock; + } + } + // ========================================== // UI UPDATES // ========================================== @@ -680,6 +766,34 @@ }).join(''); } + function formatCurrency(valor) { + return 'R$ ' + valor.toLocaleString('pt-BR', { minimumFractionDigits: 2, maximumFractionDigits: 2 }); + } + + function renderCustosEssenciais() { + const grid = document.getElementById('custos-grid'); + const combustiveis = dadosAtuais.combustiveis || CONFIG.combustiveisMock; + const aluguel = dadosAtuais.aluguel || CONFIG.aluguelMock; + const cards = [ + { titulo: combustiveis.gasolina.nome, valor: combustiveis.gasolina.preco, variacao: combustiveis.gasolina.variacao, unidade: combustiveis.gasolina.unidade, fonte: combustiveis.gasolina.fonte, cor: 'text-cyan-400', bg: 'bg-cyan-500/10' }, + { titulo: combustiveis.alcool.nome, valor: combustiveis.alcool.preco, variacao: combustiveis.alcool.variacao, unidade: combustiveis.alcool.unidade, fonte: combustiveis.alcool.fonte, cor: 'text-green-400', bg: 'bg-green-500/10' }, + { titulo: combustiveis.diesel.nome, valor: combustiveis.diesel.preco, variacao: combustiveis.diesel.variacao, unidade: combustiveis.diesel.unidade, fonte: combustiveis.diesel.fonte, cor: 'text-yellow-400', bg: 'bg-yellow-500/10' }, + { titulo: aluguel.nome, valor: aluguel.preco, variacao: aluguel.variacao, unidade: aluguel.unidade, fonte: aluguel.fonte, cor: 'text-purple-400', bg: 'bg-purple-500/10' } + ]; + + grid.innerHTML = cards.map((item, i) => ` +
+
+
${item.unidade}
+
+${item.variacao.toFixed(1)}%
+
+

${item.titulo}

+
${formatCurrency(item.valor)}
+
Fonte: ${item.fonte}
+
+ `).join(''); + } + // ========================================== // CHARTS // ========================================== @@ -842,12 +956,20 @@ btn.className = 'pessoas-btn flex-1 py-3 rounded-xl bg-dark-800 border border-white/10 text-gray-400 hover:border-purple-500/50 hover:text-white transition'; } }); + if (document.getElementById('custo-total')) calcularPoderCompra(); } function calcularPoderCompra() { const salario = parseFloat(document.getElementById('salario-input').value) || 3000; const ano = document.getElementById('ano-ref').value; const cesta = CONFIG.cestaBasicaAtual * pessoasSelecionadas; + const combustiveis = dadosAtuais.combustiveis || CONFIG.combustiveisMock; + const tipoCombustivel = document.getElementById('combustivel-tipo').value; + const litrosMes = parseFloat(document.getElementById('litros-input').value) || 0; + const aluguel = parseFloat(document.getElementById('aluguel-input').value) || 0; + const precoCombustivel = combustiveis[tipoCombustivel]?.preco || 0; + const custoCombustivel = precoCombustivel * litrosMes; + const custoEssencial = cesta + custoCombustivel + aluguel; // Fatores de inflação acumulada por ano base (aproximados) const fatores = { @@ -856,16 +978,21 @@ }; const fator = fatores[ano] || 1.0; - const pctCesta = (cesta / salario) * 100; - const poderCompra = ((1 / fator) * 100).toFixed(1); - const salarioNecessario = (salario * fator).toFixed(2); + const pctCesta = (custoEssencial / salario) * 100; + const rendaDisponivel = Math.max(salario - custoEssencial, 0); + const poderCompra = ((rendaDisponivel / salario) * (1 / fator) * 100).toFixed(1); + const salarioNecessario = Math.max(salario * fator, custoEssencial * fator).toFixed(2); + + document.getElementById('custo-total').textContent = formatCurrency(custoEssencial); + document.getElementById('custo-total-texto').textContent = + `Cesta: ${formatCurrency(cesta)} | Combustivel: ${formatCurrency(custoCombustivel)} | Aluguel: ${formatCurrency(aluguel)}`; document.getElementById('pct-cesta').textContent = pctCesta.toFixed(1) + '%'; document.getElementById('bar-cesta').style.width = Math.min(pctCesta, 100) + '%'; document.getElementById('ano-comparado').textContent = ano; document.getElementById('poder-compra').textContent = poderCompra + '%'; - document.getElementById('poder-texto').textContent = `Seu salário hoje compra ${poderCompra}% do que comprava em ${ano}`; + document.getElementById('poder-texto').textContent = `Depois dos custos essenciais, sua renda livre equivale a ${poderCompra}% do salario frente a ${ano}`; document.getElementById('ano-necessario').textContent = ano; document.getElementById('salario-necessario').textContent = 'R$ ' + parseFloat(salarioNecessario).toLocaleString('pt-BR', {minimumFractionDigits: 2}); @@ -896,18 +1023,22 @@ updateStatus('mock', 'Conectando às APIs...'); // Fetch dados - const [ipcaData, dolarData, selicData] = await Promise.all([ + const [ipcaData, dolarData, selicData, combustiveisData, aluguelData] = await Promise.all([ fetchIPCA(), fetchDolar(), - fetchSelic() + fetchSelic(), + fetchCombustiveis(), + fetchAluguel() ]); dadosAtuais.ipca = ipcaData; dadosAtuais.dolar = dolarData; dadosAtuais.selic = selicData; + dadosAtuais.combustiveis = combustiveisData; + dadosAtuais.aluguel = aluguelData; // Verificar se usou mock - const usouMock = ipcaData === CONFIG.ipcasMock; + const usouMock = ipcaData === CONFIG.ipcasMock || combustiveisData === CONFIG.combustiveisMock || aluguelData === CONFIG.aluguelMock; updateStatus(usouMock ? 'mock' : 'live', usouMock ? 'Dados de demonstração' : 'Dados em tempo real'); // Calcular IPCA acumulado 12m @@ -935,8 +1066,14 @@ // Renderizar componentes renderCestaBasica(); + renderCustosEssenciais(); + document.getElementById('aluguel-input').value = Math.round(aluguelData.preco); initChart('ipca', ipcaData); initSimuladorChart(); + ['salario-input', 'ano-ref', 'combustivel-tipo', 'litros-input', 'aluguel-input'].forEach(id => { + document.getElementById(id).addEventListener('input', calcularPoderCompra); + document.getElementById(id).addEventListener('change', calcularPoderCompra); + }); calcularPoderCompra(); // Data de atualização