Painel com indicadores (KPI)
Vais criar o ecrã que um gestor abre todas as manhãs: os números-chave do negócio e um gráfico de barras com o valor de cada fase, sempre atualizados.
🎯 No fim desta aula vais conseguir
- Explicar o que é um KPI e porque é que os gestores usam painéis.
- Calcular indicadores a partir dos dados: contar (contador), somar (acumulador) e calcular uma percentagem (taxa de conversão).
- Escrever valores em euros à portuguesa (
1234,50 €) comtoLocaleString. - Desenhar um gráfico de barras só com HTML e CSS, com larguras proporcionais aos valores.
🧰 Antes de começar
- Abre a pasta
meu-crmno VS Code e oindex.htmlcom o Live Server. - Confirma que o quadro de oportunidades da aula 14 funciona.
- Para o painel ter graça, precisas de dados: tem pelo menos 5 clientes (com estados diferentes) e 4 oportunidades em fases diferentes, uma delas em «Ganho». Se fizeste o E2 da aula 14 (botão ✖), põe também uma em «Perdido».
😕 Faltaste à aula 14 ou o teu projeto não funciona? Descarrega o ponto de controlo da aula 14, descompacta-o e trabalha a partir dele.
Parte A — O negócio: o que é um KPI? (≈ 15 min)
💡 O painel do carro
Quando conduzes, não abres o motor para saber a que velocidade vais: olhas para o painel do carro. Velocímetro, combustível, temperatura — poucos números, mas os mais importantes. Numa empresa é igual. O gestor não tem tempo para ler a lista dos 500 clientes: quer ver, num só ecrã, meia dúzia de números que lhe dizem se o negócio está a correr bem.
A esses números chama-se KPI (do inglês Key Performance Indicator, ou indicador-chave de desempenho). Ao ecrã que os junta chama-se painel (ou dashboard). Quase todas as aplicações de gestão têm um: o software de faturação, o ERP, o CRM…
O nosso painel vai ter estes 5 KPI:
| KPI | Pergunta do gestor | Como se calcula |
|---|---|---|
| Clientes | Quantos clientes temos? | Contar todos os clientes. |
| Leads por converter | Quantos contactos ainda não compraram nada? | Contar os clientes com estado «Lead». |
| Valor em curso | Quanto dinheiro está «em jogo»? | Somar os valores das oportunidades em Novo, Proposta e Negociação. |
| Valor ganho | Quanto já vendemos? | Somar os valores das oportunidades em Ganho. |
| Taxa de conversão | Dos negócios que já acabaram, quantos ganhámos? | ganhos ÷ (ganhos + perdidos) × 100 |
A taxa de conversão só olha para os negócios fechados (ganhos ou perdidos), porque dos que estão em curso ainda não sabemos o resultado. Exemplo: 3 ganhos e 1 perdido → 3 ÷ 4 = 0,75 → 75%. Quer dizer que, de cada 4 negócios que fechamos, ganhamos 3.
💡 Se não fizeste o E2 da aula 14 (botão ✖), não tens maneira de marcar negócios como perdidos, por isso a tua taxa vai dar sempre 0% ou 100%. Não é um erro!
🤔 Pensa: se fosses o dono da empresa do teu setor, que outro número gostavas de ver todas as manhãs? Aponta-o — pode ser um exercício teu na aula 17.
Parte B — Construir o painel (≈ 45 min)
1 O link do menu
No index.html, dentro do <nav class="menu">, por baixo do comentário AULA 15: COLAR AQUI O LINK DO PAINEL:
2 A secção do painel (HTML)
A secção é pequena: duas caixas vazias, <div id="kpis"> para os cartões dos indicadores e <div id="barras"> para o gráfico. Quem as enche é o JavaScript.
⚠️ Atenção ao sítio: este bloco vai para o comentário AULA 15: COLAR AQUI O PAINEL, dentro do <main> (por baixo da secção das oportunidades) — não para o comentário do menu do passo 1.
✅ Deves ver: um cartão novo com o título Painel e o subtítulo Valor por fase, ainda sem números. O link Painel do menu já te leva até lá.
3 Os cálculos e o desenho do painel (JavaScript)
⚠️ Atenção ao sítio: no app.js, este bloco vai para o comentário grande // ===== AULA 15: COLAR AQUI ===== (por baixo das funções da aula 14), e não para o pequeno dentro de atualizarEcra().
São quatro funções:
formatarEuros(valor)— escreve um número como dinheiro, à portuguesa.toLocaleString('pt-PT', …)quer dizer «escreve este número como se escreve em Portugal»: vírgula nos cêntimos, espaço nos milhares e o símbolo €. Assim,12345.5fica12 345,50 €.cartaoKpi(titulo, valor)— devolve o HTML de um cartão (como olinhaClientedevolve uma linha). Assim não repetimos o mesmo HTML cinco vezes.desenharPainel()— está dividida em 4 partes, com comentários:- Contar os leads: um contador começa em 0 e, para cada cliente «Lead», faz
leads++(quer dizer «soma 1»). - Somar os valores: acumuladores que começam em 0 e vão juntando com
+=, como o total da semana da aula 7. Oif / else if / elsedecide para onde vai cada oportunidade: Ganho, Perdido ou «em curso» (todas as outras). - A taxa de conversão, com
Math.roundpara arredondar às unidades. Oif (ganhos + perdidos > 0)evita dividir por zero. - Desenhar os cartões: junta os 5 cartões com
+e mete-os no#kpis.
- Contar os leads: um contador começa em 0 e, para cada cliente «Lead», faz
desenharBarras()— primeiro soma o valor de cada fase e descobre o maior; depois desenha uma barra por fase. A fase com mais valor fica com 100% de largura e as outras ficam proporcionais:largura = total da fase ÷ maior × 100.
💡 Repara na lista de cartões em desenharPainel(): cada linha acaba em + («junta com o seguinte»), exceto a última, que acaba em ;. Vais precisar de te lembrar disto nos exercícios.
4 Atualizar o painel sempre que os dados mudam
Dentro de atualizarEcra(), por baixo do comentário pequeno // AULA 15: COLAR AQUI:
Confere a tua função — está completa:
🤔 Prevê: antes de olhares para o ecrã, calcula de cabeça (ou no caderno) quanto deve dar o Valor ganho e o Valor em curso com as tuas oportunidades.
✅ Deves ver: 5 cartões (Clientes, Leads por converter, Valor em curso, Valor ganho e Taxa de conversão) e, por baixo, 5 barras, uma por fase. A barra de «Ganho» é verde e a de «Perdido» é vermelha; a fase com mais dinheiro tem a barra mais comprida.
5 Testar
- Confirma os números do painel com o quadro de oportunidades: os valores batem certo com o que calculaste?
- Avança uma oportunidade de «Negociação» para «Ganho»: o Valor em curso desce, o Valor ganho sobe e as barras mudam — sem recarregar a página.
- Cria um cliente novo com estado «Lead»: os cartões Clientes e Leads por converter sobem 1.
- Se tens o botão ✖ (E2 da aula 14), marca um negócio como perdido e vê a taxa de conversão mudar.
😕 Não funciona?
Cannot set properties of null (setting 'innerHTML')→ falta a secção do passo 2, ou osidkpis/barrasestão escritos de outra maneira.desenharPainel is not defined→ o bloco do passo 3 não foi gravado ou está dentro deatualizarEcra().FASES is not definedouoportunidades is not defined→ falta a aula 14. Usa o ponto de controlo da aula 14.- O painel aparece, mas não muda quando avanças uma oportunidade → falta o passo 4.
- Um valor estranho, como
NaN €ou um número «colado» a outro (ex.:01500) → há uma oportunidade com o valor mal guardado (vazio ou em texto), talvez por teres mexido nos dados no DevTools ou na Consola. Apaga-a e cria-a outra vez.
🔎 Investiga
- Como se calcula a largura das barras? Imagina que «Novo» soma 1000 € e «Proposta» soma 4000 € (o maior). Que largura (em %) vai ter a barra de «Novo»? Confirma com as tuas barras: botão direito numa barra → Inspecionar e procura
style="width: …%". - Muda o valor de uma oportunidade pela Consola: escreve
oportunidades[0].valor = 5000e depoisatualizarEcra(). O que muda no painel e no quadro? Agora carrega em F5: o valor de 5000 € continua lá? Porquê? (Dica: que função grava os dados no browser?) - O que dá a taxa de conversão quando ainda não há negócios fechados? Na Consola, escreve
0 / 0e depoisMath.round(0 / 0). O que aparecia no cartão se não houvesse oif (ganhos + perdidos > 0)? - Na Consola, compara
formatarEuros(1234.5),formatarEuros(12345.5)e(1234.5).toFixed(2). Qual fica melhor para um cliente português ler?
✍️ Exercícios (fazem parte do teu projeto)
Estes exercícios não têm o código pronto: tudo o que precisas já está dentro de desenharPainel().
E1 · KPI «Ticket médio»
O ticket médio é o valor médio de cada venda: valor ganho ÷ número de negócios ganhos. Se o ticket médio é 500 € e queres faturar 5000 € num mês, sabes que precisas de 10 vendas.
Acrescenta um cartão «Ticket médio», em euros, antes da taxa de conversão. Quando ainda não há negócios ganhos, deve mostrar 0,00 € (e não NaN).
💡 Dica: as variáveis valorGanho e ganhos já existem. Imita a taxa de conversão: uma variável que começa em 0 e um if que só divide quando ganhos > 0. Depois junta um cartaoKpi(…) à lista (não te esqueças do +) e usa formatarEuros.
E2 · KPI «Clientes inativos»
Acrescenta um cartão «Clientes inativos» com o número de clientes cujo estado é «Inativo». (Um cliente inativo é alguém que já comprou mas deixou de comprar — é a ele que a empresa deve ligar com uma promoção!)
💡 Dica: copia a ideia do contador de leads — uma variável nova a começar em 0 e um if dentro do mesmo ciclo dos clientes. Depois, mais um cartão na lista.
⭐ Desafio · Top 3 oportunidades
No fim do painel, mostra uma lista numerada (<ol>) com as 3 oportunidades de maior valor, no formato «Projeto de remodelação — 3200,00 € (Proposta)».
💡 Dica: cria uma função nova e chama-a no fim de desenharPainel(). Não ordenes a lista oportunidades original (o quadro mudava de ordem!): faz primeiro uma cópia com .slice(). Para ordenar números do maior para o menor, a «receita» é sort((a, b) => b.valor - a.valor). E .slice(0, 3) dá os 3 primeiros elementos de uma lista.
📦 O que mostrar ao professor
⏱️ Se sobrar tempo
- Faz o desafio ⭐.
- Acrescenta o KPI «Interações registadas» (quantas interações há no total, de todos os clientes).
- Mostra a percentagem de cada barra junto ao valor (ex.: 1000,00 € · 25%).
- Escreve no caderno: que KPI seria o mais importante para a empresa do teu setor? Porquê?
🤖 Pedir ajuda à IA (opcional)
Pede a uma IA gratuita que te dê ideias de indicadores para o teu setor — vão ser úteis na aula 17. Copia este pedido, troca o texto entre [ ] e cola-o na IA:
📖 Palavras novas
- KPI (indicador-chave de desempenho)
- Número importante que mostra se o negócio está a correr bem (ex.: valor ganho, taxa de conversão).
- Painel (dashboard)
- Ecrã que junta os principais indicadores para se lerem de relance.
- Taxa de conversão
- Percentagem de negócios ganhos entre os que já fecharam: ganhos ÷ (ganhos + perdidos) × 100.
- Ticket médio
- Valor médio de cada venda: valor ganho ÷ número de vendas.
- Contador
- Variável que começa em 0 e soma 1 de cada vez (
leads++). - Acumulador
- Variável que começa em 0 e vai juntando valores (
valorGanho += op.valor). toLocaleString('pt-PT')- Escreve um número com as regras portuguesas (vírgula decimal, espaço nos milhares).
Math.round- Arredonda um número às unidades (
Math.round(66.7)dá67). NaN- «Not a Number» (não é um número): o resultado de contas impossíveis, como
0 / 0.