@@ -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