// Wave 2b — Financeiro (4 telas): Assinaturas, Faturas, Despesas, Relatórios (DRE)
// =============================================================
// 6. Assinaturas (recorrência)
// =============================================================
const PageAssinaturas = ({ onNavigate }) => {
const [filter, setFilter] = React.useState('todas');
const subs = [
{ id: 1, cliente: 'Supermercado Vila Rica ME', plano: 'Profissional Anual', valor: 8400, freq: 'Mensal', proxima: '15/05/26', status: 'ativa', since: 'jun/2024' },
{ id: 2, cliente: 'Distribuidora RC Ltda', plano: 'Profissional', valor: 3200, freq: 'Mensal', proxima: '18/04/26', status: 'ativa', since: 'mar/2025' },
{ id: 3, cliente: 'Construtora AV', plano: 'Essencial', valor: 2400, freq: 'Mensal', proxima: '22/04/26', status: 'atrasada', since: 'jul/2024' },
{ id: 4, cliente: 'Pet Shop Amigo Fiel', plano: 'Essencial', valor: 680, freq: 'Mensal', proxima: '25/04/26', status: 'ativa', since: 'nov/2025' },
{ id: 5, cliente: 'Mecânica Rápida', plano: 'Básico', valor: 540, freq: 'Mensal', proxima: '10/05/26', status: 'pausada', since: 'ago/2024' },
{ id: 6, cliente: 'Hamburgueria 22', plano: 'Profissional', valor: 1240, freq: 'Mensal', proxima: '20/04/26', status: 'ativa', since: 'jan/2026' },
{ id: 7, cliente: 'Farmácia Bem Estar', plano: 'Essencial', valor: 960, freq: 'Mensal', proxima: '30/04/26', status: 'ativa', since: 'set/2025' },
{ id: 8, cliente: 'Escola Aprender +', plano: 'Profissional Anual', valor: 14400, freq: 'Anual', proxima: '01/02/27', status: 'ativa', since: 'fev/2025' },
];
const filtered = filter === 'todas' ? subs : subs.filter(s => s.status === filter);
const mrr = subs.filter(s => s.status === 'ativa').reduce((t, s) => t + (s.freq === 'Anual' ? s.valor / 12 : s.valor), 0);
const arr = mrr * 12;
const statusChip = (s) => ({
ativa: { bg: 'rgba(34,197,94,.14)', c: '#86efac', l: 'Ativa' },
atrasada: { bg: 'rgba(239,68,68,.14)', c: '#fca5a5', l: 'Atrasada' },
pausada: { bg: 'rgba(245,158,11,.14)', c: '#fcd34d', l: 'Pausada' },
cancelada: { bg: 'rgba(139,139,139,.2)', c: 'var(--text-3)', l: 'Cancelada' },
})[s];
return (
>}
>
{/* MRR / ARR / Churn / NRR */}
{/* MRR trend */}
Evolução do MRR · últimos 12 meses
+42% YoY
{/* Filters */}
{[
{ id: 'todas', l: 'Todas', c: subs.length },
{ id: 'ativa', l: 'Ativas', c: subs.filter(s => s.status === 'ativa').length },
{ id: 'atrasada', l: 'Atrasadas', c: subs.filter(s => s.status === 'atrasada').length },
{ id: 'pausada', l: 'Pausadas', c: subs.filter(s => s.status === 'pausada').length },
].map(c => (
))}
Total filtrado:
{BRL(filtered.reduce((t, s) => t + s.valor, 0))}
| Cliente |
Plano |
Valor |
Frequência |
Próxima cobrança |
Cliente desde |
Status |
Ações |
{filtered.map(s => {
const st = statusChip(s.status);
return (
|
|
{s.plano} |
{BRL(s.valor)} |
{s.freq} |
{s.proxima} |
{s.since} |
{st.l} |
|
);
})}
);
};
// =============================================================
// 7. Faturas
// =============================================================
const PageFaturas = ({ onNavigate }) => {
const [modal, setModal] = React.useState(false);
const [filter, setFilter] = React.useState('todas');
const invoices = [
{ id: 'FAT-2026-00184', cliente: 'Supermercado Vila Rica ME', email: 'financeiro@vilarica.com.br', emissao: '15/04/26', vencimento: '22/04/26', valor: 8400.00, status: 'pendente', metodo: 'Boleto' },
{ id: 'FAT-2026-00183', cliente: 'Distribuidora RC Ltda', email: 'rc@distribuidora.com.br', emissao: '15/04/26', vencimento: '25/04/26', valor: 3200.00, status: 'pendente', metodo: 'PIX' },
{ id: 'FAT-2026-00182', cliente: 'Hamburgueria 22', email: 'contato@hambu22.com', emissao: '10/04/26', vencimento: '18/04/26', valor: 1240.00, status: 'atrasada', metodo: 'Boleto' },
{ id: 'FAT-2026-00181', cliente: 'Farmácia Bem Estar', email: 'adm@bemestar.com.br', emissao: '10/04/26', vencimento: '28/04/26', valor: 960.00, status: 'pendente', metodo: 'Cartão' },
{ id: 'FAT-2026-00180', cliente: 'Pet Shop Amigo Fiel', email: 'financeiro@amigofiel.com', emissao: '05/04/26', vencimento: '15/04/26', valor: 680.00, status: 'paga', metodo: 'PIX' },
{ id: 'FAT-2026-00179', cliente: 'Escola Aprender +', email: 'tesouraria@aprender.edu', emissao: '01/04/26', vencimento: '10/04/26', valor: 1200.00, status: 'paga', metodo: 'Boleto' },
{ id: 'FAT-2026-00178', cliente: 'Mecânica Rápida Eireli', email: 'mecrapida@mec.com', emissao: '01/04/26', vencimento: '12/04/26', valor: 540.00, status: 'atrasada', metodo: 'Boleto' },
{ id: 'FAT-2026-00177', cliente: 'Construtora AV SA', email: 'pagto@constav.com.br', emissao: '28/03/26', vencimento: '08/04/26', valor: 2400.00, status: 'paga', metodo: 'PIX' },
];
const filtered = filter === 'todas' ? invoices : invoices.filter(i => i.status === filter);
const totals = {
pendente: invoices.filter(i => i.status === 'pendente').reduce((t, i) => t + i.valor, 0),
atrasada: invoices.filter(i => i.status === 'atrasada').reduce((t, i) => t + i.valor, 0),
paga: invoices.filter(i => i.status === 'paga').reduce((t, i) => t + i.valor, 0),
};
const statusChip = (s) => ({
paga: { bg: 'rgba(34,197,94,.14)', c: '#86efac', l: 'Paga', icon: 'check' },
pendente: { bg: 'rgba(245,158,11,.14)', c: '#fcd34d', l: 'Pendente', icon: 'clock' },
atrasada: { bg: 'rgba(239,68,68,.14)', c: '#fca5a5', l: 'Atrasada', icon: 'alert' },
})[s];
const methodIcon = (m) => ({ PIX: 'pix', Boleto: 'receipt', Cartão: 'wallet' })[m] || 'receipt';
return (
>}
>
t + i.valor, 0))} total`}/>
{/* Filters */}
{[
{ id: 'todas', l: 'Todas', c: invoices.length },
{ id: 'pendente', l: 'Pendentes', c: invoices.filter(i => i.status === 'pendente').length },
{ id: 'atrasada', l: 'Atrasadas', c: invoices.filter(i => i.status === 'atrasada').length },
{ id: 'paga', l: 'Pagas', c: invoices.filter(i => i.status === 'paga').length },
].map(c => (
))}
| Fatura |
Cliente |
Emissão |
Vencimento |
Valor |
Método |
Status |
Ações |
{filtered.map(r => {
const st = statusChip(r.status);
return (
| {r.id} |
{r.cliente}
{r.email}
|
{r.emissao} |
{r.vencimento} |
{BRL(r.valor)} |
{r.metodo}
|
{st.l} |
{r.status !== 'paga' && (
)}
|
);
})}
{modal && setModal(false)}/>}
);
};
const FaturaModal = ({ onClose }) => (
<>
Nova fatura
{[
{ t: 'Enviar e-mail no envio da fatura', a: true },
{ t: 'Lembrete 3 dias antes do vencimento via WhatsApp', a: true },
{ t: 'Notificação no dia do vencimento', a: true },
{ t: 'Cobrança após atraso (D+1, D+5, D+10)', a: false },
].map((opt, i) => (
))}
>
);
// =============================================================
// 8. Despesas
// =============================================================
const PageDespesas = ({ onNavigate }) => {
const desp = [
{ id: 'DSP-0421', data: '17/04', fornecedor: 'Farinha SP Ltda', cat: 'Insumos', valor: 3680.00, venc: '25/04', status: 'pendente', nf: '5892', anexo: true },
{ id: 'DSP-0420', data: '17/04', fornecedor: 'CEMIG', cat: 'Utilidades', valor: 1240.55, venc: '19/04', status: 'pendente', nf: null, anexo: true },
{ id: 'DSP-0419', data: '16/04', fornecedor: 'Automatiza Tech', cat: 'Software', valor: 499.00, venc: '16/04', status: 'paga', nf: '18234', anexo: true },
{ id: 'DSP-0418', data: '15/04', fornecedor: 'Posto Ipiranga', cat: 'Combustível', valor: 348.80, venc: '15/04', status: 'paga', nf: null, anexo: false },
{ id: 'DSP-0417', data: '14/04', fornecedor: 'Escritório Contábil BH', cat: 'Serviços', valor: 890.00, venc: '20/04', status: 'pendente', nf: '2041', anexo: true },
{ id: 'DSP-0416', data: '12/04', fornecedor: 'Imobiliária Central', cat: 'Imóvel', valor: 4200.00, venc: '10/05', status: 'agendada', nf: null, anexo: true },
{ id: 'DSP-0415', data: '10/04', fornecedor: 'AWS Amazon', cat: 'Software', valor: 840.20, venc: '10/04', status: 'paga', nf: null, anexo: true },
{ id: 'DSP-0414', data: '08/04', fornecedor: 'Café Central', cat: 'Alimentação', valor: 142.60, venc: '08/04', status: 'paga', nf: '842', anexo: false },
];
const byCategory = desp.reduce((acc, d) => { acc[d.cat] = (acc[d.cat] || 0) + d.valor; return acc; }, {});
const catColors = {
'Insumos': '#f59e0b', 'Utilidades': '#06b6d4', 'Software': 'var(--accent-1)', 'Combustível': '#ef4444',
'Serviços': '#3b82f6', 'Imóvel': '#22c55e', 'Alimentação': '#ec4899',
};
const statusChip = (s) => ({
paga: { bg: 'rgba(34,197,94,.14)', c: '#86efac', l: 'Paga' },
pendente: { bg: 'rgba(245,158,11,.14)', c: '#fcd34d', l: 'Pendente' },
agendada: { bg: 'rgba(59,130,246,.14)', c: '#93c5fd', l: 'Agendada' },
})[s];
return (
>}
>
t + d.valor, 0))} sub={`${desp.length} despesas`}/>
d.status === 'pendente').reduce((t, d) => t + d.valor, 0))} sub="3 pendentes" accent="rgba(245,158,11,.18)"/>
d.status === 'agendada').reduce((t, d) => t + d.valor, 0))} sub="próximos 30d" accent="rgba(59,130,246,.18)"/>
d.status === 'paga').reduce((t, d) => t + d.valor, 0))} sub="4 quitadas" accent="rgba(34,197,94,.18)"/>
{/* Category breakdown */}
Despesas por categoria · abril/26
({ name: k, value: v, color: catColors[k] || '#8b5cf6' }))} size={160}/>
{Object.entries(byCategory).sort((a, b) => b[1] - a[1]).map(([k, v]) => (
{k}
{BRL(v)}
))}
| Despesa |
Fornecedor |
Categoria |
Vencimento |
Valor |
NF |
Anexo |
Status |
Ações |
{desp.map(d => {
const st = statusChip(d.status);
return (
| {d.id} |
{d.fornecedor} |
{d.cat}
|
{d.venc} |
-{BRL(d.valor)} |
{d.nf || '—'} |
{d.anexo ? (
) : —}
|
{st.l} |
{d.status !== 'paga' && }
|
);
})}
);
};
// =============================================================
// 9. Relatórios Financeiros (DRE)
// =============================================================
const PageDRE = ({ onNavigate }) => {
const [period, setPeriod] = React.useState('abr26');
// Periods for comparison
const dre = [
{ group: 'receita', title: 'RECEITA BRUTA OPERACIONAL', children: [
{ label: 'Receita de vendas', v: 91200, prev: 85900 },
{ label: 'Receita de serviços', v: 18420, prev: 16800 },
{ label: 'Receita de assinaturas', v: 12400, prev: 11200 },
], total: 122020, prev: 113900 },
{ group: 'deducao', title: '(-) DEDUÇÕES DA RECEITA', children: [
{ label: 'Impostos sobre vendas (ICMS, ISS, PIS, COFINS)', v: -14820, prev: -13980 },
{ label: 'Devoluções e abatimentos', v: -1840, prev: -2100 },
], total: -16660, prev: -16080 },
{ group: 'liquida', title: 'RECEITA LÍQUIDA', total: 105360, prev: 97820, highlight: true },
{ group: 'custo', title: '(-) CUSTO DOS PRODUTOS VENDIDOS', children: [
{ label: 'Custo das mercadorias (CMV)', v: -38400, prev: -35800 },
{ label: 'Custo dos serviços prestados (CSP)', v: -4200, prev: -3600 },
], total: -42600, prev: -39400 },
{ group: 'bruto', title: 'LUCRO BRUTO', total: 62760, prev: 58420, highlight: true, margin: 59.6 },
{ group: 'despesa', title: '(-) DESPESAS OPERACIONAIS', children: [
{ label: 'Folha e encargos CLT', v: -14820, prev: -13920 },
{ label: 'Pró-labore sócios', v: -8000, prev: -8000 },
{ label: 'Aluguel e condomínio', v: -4200, prev: -4200 },
{ label: 'Utilidades (energia, água, internet)', v: -2180, prev: -1940 },
{ label: 'Software e assinaturas', v: -1840, prev: -1840 },
{ label: 'Marketing e publicidade', v: -1200, prev: -840 },
{ label: 'Outras despesas administrativas', v: -2860, prev: -2400 },
], total: -35100, prev: -33140 },
{ group: 'operacional', title: 'LUCRO OPERACIONAL (EBITDA)', total: 27660, prev: 25280, highlight: true, margin: 26.3 },
{ group: 'financeiro', title: '(±) RESULTADO FINANCEIRO', children: [
{ label: 'Receitas financeiras (aplicações, juros)', v: 840, prev: 620 },
{ label: 'Despesas financeiras (tarifas, juros)', v: -340, prev: -280 },
], total: 500, prev: 340 },
{ group: 'liquido', title: 'LUCRO LÍQUIDO DO PERÍODO', total: 28160, prev: 25620, highlight: true, final: true, margin: 26.7 },
];
const [expanded, setExpanded] = React.useState({ receita: true, deducao: true, custo: true, despesa: true, financeiro: true });
return (
>}
>
{/* KPI strip */}
{/* DRE Hierarchy */}
Demonstração de Resultados · abril/26
+9,9% vs. março
| Conta |
Abril/26 |
Março/26 |
Δ% |
AV |
{dre.map((row, i) => {
const delta = row.prev ? ((row.total - row.prev) / Math.abs(row.prev)) * 100 : 0;
const av = (row.total / 105360 * 100);
const isExp = expanded[row.group];
const isHighlight = row.highlight;
return (
row.children && setExpanded({ ...expanded, [row.group]: !isExp })}>
|
{row.children && }
{row.title}
|
= 0 ? 'var(--text-0)' : '#fca5a5', fontVariantNumeric: 'tabular-nums', fontSize: isHighlight ? 14 : 13 }}>
{row.total < 0 ? '(' : ''}{BRL(Math.abs(row.total))}{row.total < 0 ? ')' : ''}
|
{row.prev < 0 ? '(' : ''}{BRL(Math.abs(row.prev))}{row.prev < 0 ? ')' : ''} |
= 0 ? '#86efac' : '#fca5a5', fontWeight: 600, fontVariantNumeric: 'tabular-nums', fontSize: 12 }}>
{delta >= 0 ? '+' : ''}{delta.toFixed(1)}%
|
{row.margin ? row.margin.toFixed(1) + '%' : (av !== 100 && av < 500 && av > -500 ? av.toFixed(1) + '%' : '—')}
|
{row.children && isExp && row.children.map((c, j) => (
| {c.label} |
{c.v < 0 ? '(' : ''}{BRL(Math.abs(c.v))}{c.v < 0 ? ')' : ''}
|
{c.prev < 0 ? '(' : ''}{BRL(Math.abs(c.prev))}{c.prev < 0 ? ')' : ''} |
— |
{(c.v / 105360 * 100).toFixed(1)}% |
))}
);
})}
{/* Right column: charts */}
{[
{ l: 'Receita líquida', v: '100%', c: '#22c55e' },
{ l: 'CPV', v: '40,4%', c: '#ef4444' },
{ l: 'Despesas oper.', v: '33,3%', c: '#f59e0b' },
{ l: 'Lucro líquido', v: '26,7%', c: 'var(--accent-1)' },
].map(x => (
{x.l}
{x.v}
))}
Evolução do lucro líquido
{[
{ t: 'Margem bruta estável em ~59,6%', sub: 'Efeito do melhor mix de serviços vs. produto.', icon: 'trending-up', c: '#86efac' },
{ t: 'Despesa com Marketing +42,9%', sub: 'Aumento justificável pela campanha de abril — monitorar ROI.', icon: 'alert', c: '#fcd34d' },
{ t: 'Folha CLT cresceu 6,5%', sub: 'Abaixo da inflação do dissídio (7,1%).', icon: 'check', c: '#86efac' },
].map((x, i) => (
))}
);
};
Object.assign(window, { PageAssinaturas, PageFaturas, PageDespesas, PageDRE });