Tema admin pago: o que fazer entre a compra e a primeira versão em produção
Transforme um tema admin comprado num painel de verdade: leia a licença, apague o demo, sirva só o compilado, proteja cada rota no servidor e confira foco e contraste antes de publicar.
A licença do tema Material custou menos que uma hora de trabalho, e em uma tarde o painel da distribuidora já tinha menu lateral, gráficos e tabelas com filtro. O cliente aprovou na demonstração. Duas semanas depois da publicação, alguém descobre que /admin/tables.html abre sem login, que a página login.html do tema aceita qualquer senha porque é só HTML, e que o gráfico de "vendas do mês" mostra os números de exemplo do fornecedor.
A resposta curta: um tema admin entrega aparência, não sistema. Ele não sabe quem é o seu usuário, quais papéis existem nem quais dados cada papel pode ver. Entre a compra e a produção você precisa ler a licença, apagar as páginas e dados de demonstração, servir só os arquivos compilados, proteger cada rota no servidor e testar teclado e contraste. O tema fica sendo a casca; a regra continua sua.
Por que o tema parece pronto e não está
Temas comerciais são feitos para vender pela demonstração. Cada página mostra um componente funcionando com dados fixos: tabelas com nomes inventados, gráficos com séries escritas no JavaScript, formulários de login que levam ao painel sem conferir nada. Isso é exatamente o que um demo deve fazer. O problema começa quando a pasta inteira do tema é publicada e as páginas de exemplo continuam respondendo.
O tema também traz decisões técnicas próprias: uma versão específica do Bootstrap, plugins de gráfico e de tabela, um processo de build com Sass e npm. Se o resto do site usa outra versão do Bootstrap, as duas brigam pelo mesmo nome de classe. E o fato de um tema ser pago não garante acessibilidade: foco invisível, contraste baixo em texto cinza sobre branco e menus que só abrem com o mouse são comuns em temas bonitos. A visão geral sobre templates de admin está em template de admin não traz autorização nem conteúdo; aqui o foco é o caminho prático de um tema comprado até o ar.
Do pacote baixado ao painel publicado
- Leia a licença antes de começar. Licenças de temas costumam limitar o número de projetos, o uso em produto vendido a vários clientes e a redistribuição do código-fonte. Se o painel vai para vários clientes, confira se a sua licença cobre isso.
- Guarde o pacote original intocado numa pasta separada ou num branch, para poder comparar quando o fornecedor lançar atualização.
- Monte o build e sirva só o resultado compilado. Pasta de origem,
node_modulese páginas de exemplo não vão para o servidor. - Apague cada página e cada dado de demonstração que você não vai usar. Guarde só os componentes que viraram tela real.
- Troque o login de exemplo por autenticação de verdade, com senha protegida por hash no servidor.
- Proteja cada rota no servidor por papel, inclusive as rotas de API que alimentam tabelas e gráficos.
- Teste teclado, foco e contraste nas telas que a equipe vai usar o dia inteiro.
O que costuma sobrar do demo
- Páginas HTML de exemplo acessíveis por URL direta, como tabelas, perfis e telas de erro.
- Usuários e senhas de demonstração em arquivos de configuração ou em scripts de seed.
- Gráficos com séries fixas no JavaScript, que parecem dados reais.
- Links para a documentação do fornecedor e para CDNs de terceiros que você não revisou.
- Formulários que "enviam" para lugar nenhum ou para um endpoint de exemplo.
Protegendo as rotas no servidor (Node.js com Express)
No painel da distribuidora há três papéis: atendimento vê pedidos, financeiro vê pedidos e faturamento, gerente vê tudo e altera papéis. A regra mora no servidor, e o menu do tema só reflete o que o servidor já decidiu:
import express from 'express';
import session from 'express-session';
import { listarPedidos, resumoFaturamento, alterarPapel } from './painel.js';
const app = express();
app.set('view engine', 'ejs');
app.use(express.urlencoded({ extended: false }));
app.use(session({
secret: process.env.SESSION_SECRET,
resave: false,
saveUninitialized: false,
cookie: { httpOnly: true, secure: true, sameSite: 'lax', maxAge: 8 * 60 * 60 * 1000 }
}));
app.use('/assets', express.static('tema/dist/assets'));
function exigirLogin(req, res, next) {
if (!req.session.usuario) return res.redirect('/entrar');
next();
}
function exigirPapel(...papeis) {
return (req, res, next) => {
if (!papeis.includes(req.session.usuario?.papel)) {
return res.status(403).render('403');
}
next();
};
}
app.use('/admin', exigirLogin);
app.get('/admin/pedidos', exigirPapel('atendimento', 'financeiro', 'gerente'), async (req, res, next) => {
try {
res.render('admin/pedidos', { usuario: req.session.usuario, pedidos: await listarPedidos() });
} catch (err) {
next(err);
}
});
app.get('/admin/faturamento', exigirPapel('financeiro', 'gerente'), async (req, res, next) => {
try {
res.render('admin/faturamento', { usuario: req.session.usuario, resumo: await resumoFaturamento() });
} catch (err) {
next(err);
}
});
app.post('/admin/usuarios/:id/papel', exigirPapel('gerente'), async (req, res, next) => {
try {
await alterarPapel(req.params.id, req.body.papel, req.session.usuario.id);
res.redirect('/admin/usuarios');
} catch (err) {
next(err);
}
});
app.listen(3000);
Repare em duas coisas. Só a pasta tema/dist/assets é servida como estática: as páginas HTML do demo não têm rota e simplesmente deixam de existir. E as páginas do painel são templates renderizados pelo servidor depois da verificação de papel, não arquivos .html soltos que qualquer pessoa abre. Esconder o item "Faturamento" do menu para o atendimento é bom para a interface, mas é o exigirPapel que impede o acesso por URL direta. Para o formulário de login em si, o cuidado com a senha está em a senha que não pode ser lida nem por você. Em produção, a sessão precisa de um store persistente (Redis ou banco) em vez do armazenamento em memória padrão do express-session, que não serve para mais de um processo.
Acessibilidade que o tema não garante
Antes de publicar, navegue pelo painel só com Tab, Enter e Esc. O foco precisa ser visível em todo elemento, inclusive no menu lateral e nos dropdowns; temas escuros costumam apagar o anel de foco, como mostra anel de foco que some no tema escuro. Confira o contraste dos textos cinza de legenda e dos botões desabilitados. Se o tema usa ícones sem texto como botões, acrescente nomes acessíveis. Quem passa oito horas por dia num painel sente cada um desses detalhes.
Erros comuns
- Publicar a pasta inteira do tema. Páginas de exemplo, arquivos-fonte e às vezes
node_modulesficam acessíveis por URL. - Confiar no login HTML do demo. Ele leva ao painel sem conferir nada; quem souber a URL entra.
- Esconder menu em vez de proteger rota. O atendimento não vê o item "Faturamento", mas abre a página digitando o endereço.
- Esquecer os dados fixos dos gráficos. O cliente toma decisão olhando números do fornecedor do tema.
- Misturar duas versões do Bootstrap. Componentes do site e do tema quebram de forma intermitente, dependendo da ordem de carregamento dos arquivos.
- Ignorar a licença. Revender o painel para vários clientes com uma licença de projeto único cria um problema jurídico que nenhum código resolve.
Checklist
- A licença cobre o uso que você vai fazer (número de projetos, revenda, redistribuição).
- Só os arquivos compilados do tema estão no servidor.
- Nenhuma página ou usuário de demonstração responde em produção.
- Todo gráfico e toda tabela vêm de dados reais do seu backend.
- Cada rota de página e de API tem verificação de login e de papel no servidor.
- Há uma única versão do Bootstrap carregada nas páginas do painel.
- O painel inteiro funciona por teclado, com foco visível e contraste suficiente.
Abra uma janela anônima, sem login, e cole o endereço de cada página de exemplo que veio no pacote do tema: alguma delas ainda abre no seu servidor de produção?
Referência: https://startbootstrap.com/theme/material-admin-pro