feat: Initialize ComFi project with Vite

Setup project structure, dependencies, and basic configuration for the ComFi application. Includes initial setup for Vite, React, TypeScript, Tailwind CSS, and essential development tools. Defines core types and provides a basic README for local development.
This commit is contained in:
MMrp89
2026-02-09 20:28:37 -03:00
parent 1e6a56d866
commit 1a57ac7754
28 changed files with 6070 additions and 8 deletions

View File

@@ -0,0 +1,467 @@
import React, { useState, useMemo } from 'react';
import { FinancialReportType, Expense, Receivable } from '../types';
import { Download, Printer, Filter, ChevronRight, X, Calendar, Building2, CheckCircle2, FileText } from 'lucide-react';
import { useToast } from '../contexts/ToastContext';
import { CustomSelect } from './CustomSelect';
interface FinancialReportsViewProps {
expenses: Expense[];
receivables: Receivable[];
}
const ReportTab = ({ active, label, onClick }: { active: boolean, label: string, onClick: () => void }) => (
<button
onClick={onClick}
className={`px-5 py-2.5 rounded-xl text-sm font-medium transition-all duration-300 ${
active
? 'bg-primary-500 text-white shadow-lg shadow-primary-200'
: 'text-slate-500 hover:bg-slate-100'
}`}
>
{label}
</button>
);
const TableRow = ({ label, value, indent = 0, isTotal = false, isHeader = false }: { label: string, value: string | React.ReactNode, indent?: number, isTotal?: boolean, isHeader?: boolean }) => (
<div className={`flex justify-between items-center py-3 border-b border-slate-50 hover:bg-slate-50 transition-colors px-4
${isHeader ? 'bg-slate-50 font-bold text-slate-800 border-t mt-2' : ''}
${isTotal ? 'bg-slate-50/50 font-bold' : ''}`}>
<span className={`text-slate-700 ${indent === 1 ? 'pl-4' : indent === 2 ? 'pl-8' : ''} ${isTotal ? 'text-slate-900' : ''}`}>
{label}
</span>
<span className={`${isTotal ? 'text-primary-600' : 'text-slate-600'} ${isHeader ? 'text-slate-800' : ''}`}>{value}</span>
</div>
);
export const FinancialReportsView: React.FC<FinancialReportsViewProps> = ({ expenses, receivables }) => {
const { addToast } = useToast();
const [activeTab, setActiveTab] = useState<FinancialReportType>('DRE');
const [showFilters, setShowFilters] = useState(false);
const [filters, setFilters] = useState({
period: 'mensal',
costCenter: 'Todos'
});
const handleExport = () => {
addToast({ type: 'info', title: 'Gerando PDF...', message: 'O download iniciará em instantes.', duration: 2000 });
setTimeout(() => {
addToast({ type: 'success', title: 'Exportação Concluída', message: `Relatório ${activeTab} salvo com sucesso.` });
}, 2000);
};
// --- ACCOUNTING ENGINE (Cálculos Reais) ---
const reportData = useMemo(() => {
// 1. Data Preparation
const paidRevenue = receivables.filter(r => r.status === 'paid').reduce((sum, r) => sum + r.value, 0);
const pendingRevenue = receivables.filter(r => r.status === 'pending').reduce((sum, r) => sum + r.value, 0);
const totalRevenue = paidRevenue + pendingRevenue; // Competência
const paidExpenses = expenses.filter(e => e.status === 'paid');
const pendingExpenses = expenses.filter(e => e.status === 'pending');
// Categorização de Despesas Pagas
const taxExpenses = paidExpenses.filter(e => e.category === 'Impostos').reduce((sum, e) => sum + e.amount, 0);
const costExpenses = paidExpenses.filter(e => e.category === 'Operacional').reduce((sum, e) => sum + e.amount, 0); // Mocking Op as CMV/CPV
const adminExpenses = paidExpenses.filter(e => e.category === 'Administrativo' || e.category === 'TI').reduce((sum, e) => sum + e.amount, 0);
const salesExpenses = paidExpenses.filter(e => e.category === 'Marketing').reduce((sum, e) => sum + e.amount, 0);
const personnelExpenses = paidExpenses.filter(e => e.category === 'Pessoal').reduce((sum, e) => sum + e.amount, 0);
// Totais
const totalDeductions = taxExpenses; // Simplificação
const netRevenue = paidRevenue - totalDeductions;
const grossProfit = netRevenue - costExpenses;
const totalOpExpenses = adminExpenses + salesExpenses + personnelExpenses;
const netIncome = grossProfit - totalOpExpenses;
// 2. Balance Sheet (BP) Calculations (Estimated)
// Assets
const cashAndEquivalents = 50000 + (netIncome > 0 ? netIncome : 0); // Mock Start Cash + Profit
const accountsReceivable = pendingRevenue;
const fixedAssets = 150000; // Mocked Fixed Assets (Computers, Furniture)
const totalCurrentAssets = cashAndEquivalents + accountsReceivable;
const totalNonCurrentAssets = fixedAssets;
const totalAssets = totalCurrentAssets + totalNonCurrentAssets;
// Liabilities
const accountsPayable = pendingExpenses.reduce((sum, e) => sum + e.amount, 0);
const loansShortTerm = 20000; // Mock
const loansLongTerm = 100000; // Mock
const totalCurrentLiabilities = accountsPayable + loansShortTerm;
const totalNonCurrentLiabilities = loansLongTerm;
// Equity
const shareCapital = 50000; // Mock
const retainedEarnings = totalAssets - (totalCurrentLiabilities + totalNonCurrentLiabilities + shareCapital); // Balancing figure
const totalEquity = shareCapital + retainedEarnings;
// 3. Cash Flow (DFC) - Direct Method Simplified
const cashInflow = paidRevenue;
const cashOutflowOp = paidExpenses.reduce((sum, e) => sum + e.amount, 0);
const netCashOperating = cashInflow - cashOutflowOp;
// 4. Value Added (DVA)
const inputs = costExpenses + adminExpenses + salesExpenses; // Consumo de terceiros
const grossValueAdded = paidRevenue - inputs;
const netValueAdded = grossValueAdded; // Assuming no depreciation for simplicity
return {
dre: {
grossRevenue: paidRevenue,
taxes: taxExpenses,
netRevenue,
costs: costExpenses,
grossProfit,
adminExpenses,
salesExpenses,
personnelExpenses,
netIncome
},
bp: {
cashAndEquivalents,
accountsReceivable,
totalCurrentAssets,
fixedAssets,
totalAssets,
accountsPayable,
loansShortTerm,
totalCurrentLiabilities,
loansLongTerm,
shareCapital,
retainedEarnings,
totalEquityAndLiabilities: totalCurrentLiabilities + totalNonCurrentLiabilities + totalEquity
},
dfc: {
netCashOperating,
cashInflow,
cashOutflowOp
},
dva: {
grossRevenue: paidRevenue,
inputs,
grossValueAdded,
personnelExpenses,
taxExpenses,
rentals: 0,
equityRemuneration: netIncome
}
};
}, [expenses, receivables]);
const formatCurrency = (val: number) => val.toLocaleString('pt-BR', { style: 'currency', currency: 'BRL' });
const formatNegative = (val: number) => `(${formatCurrency(val)})`;
const periodLabel = filters.period === 'anual' ? '2024' : filters.period === 'trimestral' ? '1º Trimestre 2024' : 'Maio/2024';
const renderContent = () => {
switch (activeTab) {
case 'DRE':
return (
<div className="bg-white rounded-2xl border border-slate-100 p-0 overflow-hidden animate-fade-in max-w-4xl mx-auto">
<div className="p-6 border-b border-slate-100 flex justify-between items-center">
<div>
<h3 className="text-lg font-bold text-slate-800">Demonstração do Resultado do Exercício (DRE)</h3>
<p className="text-slate-400 text-sm">Período: {periodLabel} | Centro de Custo: {filters.costCenter}</p>
</div>
<div className="w-10 h-10 bg-primary-50 rounded-lg flex items-center justify-center text-primary-500"><FileText size={20}/></div>
</div>
<TableRow label="RECEITA OPERACIONAL BRUTA" value="" isHeader />
<TableRow label="Receita de Serviços / Vendas" value={formatCurrency(reportData.dre.grossRevenue)} indent={1} />
<TableRow label="DEDUÇÕES DA RECEITA BRUTA" value="" isHeader />
<TableRow label="(-) Impostos sobre Vendas" value={formatNegative(reportData.dre.taxes)} indent={1} />
<TableRow label="= RECEITA OPERACIONAL LÍQUIDA" value={formatCurrency(reportData.dre.netRevenue)} isTotal />
<TableRow label="CUSTOS OPERACIONAIS" value="" isHeader />
<TableRow label="(-) Custos dos Serviços Prestados (CSP)" value={formatNegative(reportData.dre.costs)} indent={1} />
<TableRow label="= LUCRO BRUTO" value={formatCurrency(reportData.dre.grossProfit)} isTotal />
<TableRow label="DESPESAS OPERACIONAIS" value="" isHeader />
<TableRow label="(-) Despesas com Pessoal" value={formatNegative(reportData.dre.personnelExpenses)} indent={1} />
<TableRow label="(-) Despesas Administrativas & TI" value={formatNegative(reportData.dre.adminExpenses)} indent={1} />
<TableRow label="(-) Despesas Comerciais / Mkt" value={formatNegative(reportData.dre.salesExpenses)} indent={1} />
<div className="p-4 bg-primary-50 mt-4 flex justify-between font-bold text-primary-700 rounded-b-2xl">
<span>= LUCRO / PREJUÍZO LÍQUIDO</span>
<span>{formatCurrency(reportData.dre.netIncome)}</span>
</div>
</div>
);
case 'BP':
return (
<div className="space-y-6 animate-fade-in">
<div className="grid grid-cols-1 md:grid-cols-2 gap-8">
{/* ATIVO */}
<div className="bg-white rounded-2xl border border-slate-100 p-0 overflow-hidden h-fit">
<div className="bg-slate-50 p-4 border-b border-slate-100 font-bold text-slate-700">ATIVO</div>
<TableRow label="ATIVO CIRCULANTE" value={formatCurrency(reportData.bp.totalCurrentAssets)} isHeader />
<TableRow label="Caixa e Equivalentes" value={formatCurrency(reportData.bp.cashAndEquivalents)} indent={1} />
<TableRow label="Contas a Receber (Clientes)" value={formatCurrency(reportData.bp.accountsReceivable)} indent={1} />
<TableRow label="ATIVO NÃO CIRCULANTE" value={formatCurrency(reportData.bp.fixedAssets)} isHeader />
<TableRow label="Imobilizado (Móveis/Equip.)" value={formatCurrency(reportData.bp.fixedAssets)} indent={1} />
<div className="p-4 bg-primary-50 mt-4 flex justify-between font-bold text-primary-700">
<span>TOTAL DO ATIVO</span>
<span>{formatCurrency(reportData.bp.totalAssets)}</span>
</div>
</div>
{/* PASSIVO */}
<div className="bg-white rounded-2xl border border-slate-100 p-0 overflow-hidden h-fit">
<div className="bg-slate-50 p-4 border-b border-slate-100 font-bold text-slate-700">PASSIVO E PATRIMÔNIO LÍQUIDO</div>
<TableRow label="PASSIVO CIRCULANTE" value={formatCurrency(reportData.bp.totalCurrentLiabilities)} isHeader />
<TableRow label="Fornecedores a Pagar" value={formatCurrency(reportData.bp.accountsPayable)} indent={1} />
<TableRow label="Empréstimos Curto Prazo" value={formatCurrency(reportData.bp.loansShortTerm)} indent={1} />
<TableRow label="PASSIVO NÃO CIRCULANTE" value={formatCurrency(reportData.bp.loansLongTerm)} isHeader />
<TableRow label="Empréstimos Longo Prazo" value={formatCurrency(reportData.bp.loansLongTerm)} indent={1} />
<TableRow label="PATRIMÔNIO LÍQUIDO" value={formatCurrency(reportData.bp.shareCapital + reportData.bp.retainedEarnings)} isHeader />
<TableRow label="Capital Social" value={formatCurrency(reportData.bp.shareCapital)} indent={1} />
<TableRow label="Lucros/Prejuízos Acumulados" value={formatCurrency(reportData.bp.retainedEarnings)} indent={1} />
<div className="p-4 bg-primary-50 mt-4 flex justify-between font-bold text-primary-700">
<span>TOTAL PASSIVO + PL</span>
<span>{formatCurrency(reportData.bp.totalEquityAndLiabilities)}</span>
</div>
</div>
</div>
</div>
);
case 'DFC':
return (
<div className="bg-white rounded-2xl border border-slate-100 p-0 overflow-hidden animate-fade-in max-w-4xl mx-auto">
<div className="p-6 border-b border-slate-100">
<h3 className="text-lg font-bold text-slate-800">Demonstração do Fluxo de Caixa (Método Direto)</h3>
<p className="text-slate-400 text-sm">Período: {periodLabel}</p>
</div>
<TableRow label="ATIVIDADES OPERACIONAIS" value="" isHeader />
<TableRow label="(+) Recebimento de Clientes" value={formatCurrency(reportData.dfc.cashInflow)} indent={1} />
<TableRow label="(-) Pagamento a Fornecedores/Despesas" value={formatNegative(reportData.dfc.cashOutflowOp)} indent={1} />
<TableRow label="(=) Caixa Líquido das Atividades Operacionais" value={formatCurrency(reportData.dfc.netCashOperating)} isTotal indent={1} />
<TableRow label="ATIVIDADES DE INVESTIMENTO" value="" isHeader />
<TableRow label="(-) Aquisição de Imobilizado" value={formatCurrency(0)} indent={1} />
<TableRow label="(=) Caixa Líquido das Atividades de Investimento" value={formatCurrency(0)} isTotal indent={1} />
<TableRow label="ATIVIDADES DE FINANCIAMENTO" value="" isHeader />
<TableRow label="(+) Novos Empréstimos" value={formatCurrency(0)} indent={1} />
<TableRow label="(=) Caixa Líquido das Atividades de Financiamento" value={formatCurrency(0)} isTotal indent={1} />
<div className={`p-4 mt-4 flex justify-between font-bold rounded-b-2xl ${reportData.dfc.netCashOperating >= 0 ? 'bg-green-50 text-green-800' : 'bg-red-50 text-red-800'}`}>
<span>AUMENTO/REDUÇÃO LÍQUIDA DE CAIXA</span>
<span>{formatCurrency(reportData.dfc.netCashOperating)}</span>
</div>
</div>
);
case 'DLPA':
return (
<div className="bg-white rounded-2xl border border-slate-100 p-0 overflow-hidden animate-fade-in max-w-4xl mx-auto">
<div className="p-6 border-b border-slate-100">
<h3 className="text-lg font-bold text-slate-800">Demonstração de Lucros ou Prejuízos Acumulados (DLPA)</h3>
</div>
<TableRow label="Saldo Inicial" value={formatCurrency(reportData.bp.retainedEarnings - reportData.dre.netIncome)} />
<TableRow label="(+) Ajustes de Exercícios Anteriores" value={formatCurrency(0)} />
<TableRow label="(+) Lucro Líquido do Exercício" value={formatCurrency(reportData.dre.netIncome)} isTotal />
<TableRow label="(-) Transferências para Reservas" value={formatCurrency(0)} />
<TableRow label="(-) Dividendos Distribuídos" value={formatCurrency(0)} />
<div className="p-4 bg-primary-50 mt-4 flex justify-between font-bold text-primary-700">
<span>SALDO FINAL</span>
<span>{formatCurrency(reportData.bp.retainedEarnings)}</span>
</div>
</div>
);
case 'DMPL':
return (
<div className="bg-white rounded-2xl border border-slate-100 p-0 overflow-hidden animate-fade-in max-w-5xl mx-auto overflow-x-auto">
<div className="p-6 border-b border-slate-100">
<h3 className="text-lg font-bold text-slate-800">Demonstração das Mutações do Patrimônio Líquido (DMPL)</h3>
</div>
<table className="w-full text-left text-sm">
<thead className="bg-slate-50 text-slate-700 font-bold">
<tr>
<th className="p-4">Histórico</th>
<th className="p-4 text-right">Capital Social</th>
<th className="p-4 text-right">Reservas de Lucro</th>
<th className="p-4 text-right">Lucros Acumulados</th>
<th className="p-4 text-right">Total</th>
</tr>
</thead>
<tbody className="divide-y divide-slate-100">
<tr>
<td className="p-4 font-medium text-slate-700">Saldo Inicial</td>
<td className="p-4 text-right">{formatCurrency(reportData.bp.shareCapital)}</td>
<td className="p-4 text-right">R$ 0,00</td>
<td className="p-4 text-right">{formatCurrency(reportData.bp.retainedEarnings - reportData.dre.netIncome)}</td>
<td className="p-4 text-right font-bold">{formatCurrency(reportData.bp.shareCapital + (reportData.bp.retainedEarnings - reportData.dre.netIncome))}</td>
</tr>
<tr>
<td className="p-4 font-medium text-slate-700">Lucro Líquido do Período</td>
<td className="p-4 text-right">-</td>
<td className="p-4 text-right">-</td>
<td className="p-4 text-right text-green-600">{formatCurrency(reportData.dre.netIncome)}</td>
<td className="p-4 text-right font-bold text-green-600">{formatCurrency(reportData.dre.netIncome)}</td>
</tr>
</tbody>
<tfoot className="bg-slate-50 font-bold text-slate-800">
<tr>
<td className="p-4">Saldo Final</td>
<td className="p-4 text-right">{formatCurrency(reportData.bp.shareCapital)}</td>
<td className="p-4 text-right">R$ 0,00</td>
<td className="p-4 text-right">{formatCurrency(reportData.bp.retainedEarnings)}</td>
<td className="p-4 text-right text-primary-600">{formatCurrency(reportData.bp.shareCapital + reportData.bp.retainedEarnings)}</td>
</tr>
</tfoot>
</table>
</div>
);
case 'DRA':
return (
<div className="bg-white rounded-2xl border border-slate-100 p-0 overflow-hidden animate-fade-in max-w-4xl mx-auto">
<div className="p-6 border-b border-slate-100">
<h3 className="text-lg font-bold text-slate-800">Demonstração do Resultado Abrangente (DRA)</h3>
</div>
<TableRow label="Lucro Líquido do Exercício" value={formatCurrency(reportData.dre.netIncome)} isTotal />
<TableRow label="Outros Resultados Abrangentes" value="" isHeader />
<TableRow label="(+/-) Ajustes de Avaliação Patrimonial" value={formatCurrency(0)} indent={1} />
<TableRow label="(+/-) Variação Cambial de Investimentos" value={formatCurrency(0)} indent={1} />
<div className="p-4 bg-primary-50 mt-4 flex justify-between font-bold text-primary-700">
<span>RESULTADO ABRANGENTE TOTAL</span>
<span>{formatCurrency(reportData.dre.netIncome)}</span>
</div>
</div>
);
case 'DVA':
return (
<div className="bg-white rounded-2xl border border-slate-100 p-0 overflow-hidden animate-fade-in max-w-4xl mx-auto">
<div className="p-6 border-b border-slate-100">
<h3 className="text-lg font-bold text-slate-800">Demonstração do Valor Adicionado (DVA)</h3>
</div>
<TableRow label="1. RECEITAS" value={formatCurrency(reportData.dva.grossRevenue)} isHeader />
<TableRow label="Vendas de Mercadorias, Produtos e Serviços" value={formatCurrency(reportData.dva.grossRevenue)} indent={1} />
<TableRow label="2. INSUMOS ADQUIRIDOS DE TERCEIROS" value={formatNegative(reportData.dva.inputs)} isHeader />
<TableRow label="Custos Operacionais e Materiais" value={formatNegative(reportData.dva.inputs)} indent={1} />
<TableRow label="3. VALOR ADICIONADO BRUTO (1-2)" value={formatCurrency(reportData.dva.grossValueAdded)} isTotal />
<TableRow label="4. RETENÇÕES" value={formatCurrency(0)} isHeader />
<TableRow label="Depreciação, Amortização e Exaustão" value={formatCurrency(0)} indent={1} />
<TableRow label="5. VALOR ADICIONADO LÍQUIDO (3-4)" value={formatCurrency(reportData.dva.grossValueAdded)} isTotal />
<div className="bg-slate-50 p-4 border-b border-slate-100 border-t font-bold text-slate-800 mt-4">6. DISTRIBUIÇÃO DO VALOR ADICIONADO</div>
<TableRow label="Pessoal (Salários e Benefícios)" value={formatCurrency(reportData.dva.personnelExpenses)} indent={1} />
<TableRow label="Impostos, Taxas e Contribuições" value={formatCurrency(reportData.dva.taxExpenses)} indent={1} />
<TableRow label="Remuneração de Capitais de Terceiros (Aluguéis/Juros)" value={formatCurrency(reportData.dva.rentals)} indent={1} />
<TableRow label="Remuneração de Capitais Próprios (Lucros)" value={formatCurrency(reportData.dva.equityRemuneration)} indent={1} />
<div className="p-4 bg-primary-50 mt-4 flex justify-between font-bold text-primary-700">
<span>TOTAL DISTRIBUÍDO</span>
<span>{formatCurrency(reportData.dva.personnelExpenses + reportData.dva.taxExpenses + reportData.dva.rentals + reportData.dva.equityRemuneration)}</span>
</div>
</div>
);
default:
return null;
}
};
return (
<div className="space-y-6">
<div className="flex flex-col md:flex-row justify-between items-start md:items-center gap-4">
<div>
<h1 className="text-2xl font-bold text-slate-800">Demonstrações Contábeis</h1>
<p className="text-slate-500">Relatórios gerados em tempo real com base nos lançamentos.</p>
</div>
<div className="flex gap-2">
<button
onClick={() => setShowFilters(!showFilters)}
className={`flex items-center gap-2 px-4 py-2 border rounded-xl transition-colors ${showFilters ? 'bg-slate-100 border-slate-300 text-slate-800' : 'bg-white border-slate-200 text-slate-600 hover:bg-slate-50'}`}
>
<Filter size={16} />
{showFilters ? 'Ocultar Filtros' : 'Filtros'}
</button>
<button onClick={handleExport} className="flex items-center gap-2 px-4 py-2 bg-primary-500 text-white rounded-xl hover:bg-primary-600 shadow-lg shadow-primary-200/50">
<Download size={16} /> Exportar
</button>
</div>
</div>
{/* Filter Panel */}
{showFilters && (
<div className="bg-white p-6 rounded-2xl border border-slate-100 shadow-sm grid grid-cols-1 md:grid-cols-3 gap-6 animate-slide-down">
<div>
<label className="block text-xs font-semibold text-slate-500 mb-2 uppercase flex items-center gap-2">
<Calendar size={14} /> Período
</label>
<div className="relative">
<CustomSelect
value={filters.period}
onChange={(val) => setFilters({...filters, period: val})}
options={[
{ value: 'mensal', label: 'Mensal (Mês Atual)' },
{ value: 'trimestral', label: 'Trimestral' },
{ value: 'semestral', label: 'Semestral' },
{ value: 'anual', label: 'Anual (Acumulado)' }
]}
/>
</div>
</div>
<div>
<label className="block text-xs font-semibold text-slate-500 mb-2 uppercase flex items-center gap-2">
<Building2 size={14} /> Centro de Custo
</label>
<div className="relative">
<CustomSelect
value={filters.costCenter}
onChange={(val) => setFilters({...filters, costCenter: val})}
options={[
{ value: 'Todos', label: 'Todos' },
{ value: 'Administrativo', label: 'Administrativo' },
{ value: 'Comercial', label: 'Comercial / Vendas' },
{ value: 'Operacional', label: 'Operacional' },
{ value: 'TI', label: 'Tecnologia (TI)' }
]}
/>
</div>
</div>
<div className="flex items-end">
<button className="w-full py-2.5 bg-slate-800 text-white rounded-xl hover:bg-slate-900 transition-colors font-medium flex items-center justify-center gap-2">
<CheckCircle2 size={16}/> Aplicar Filtros
</button>
</div>
</div>
)}
{/* Tabs */}
<div className="flex flex-wrap gap-2 pb-2">
<ReportTab active={activeTab === 'DRE'} label="DRE" onClick={() => setActiveTab('DRE')} />
<ReportTab active={activeTab === 'BP'} label="Balanço (BP)" onClick={() => setActiveTab('BP')} />
<ReportTab active={activeTab === 'DFC'} label="Fluxo de Caixa (DFC)" onClick={() => setActiveTab('DFC')} />
<ReportTab active={activeTab === 'DLPA'} label="DLPA" onClick={() => setActiveTab('DLPA')} />
<ReportTab active={activeTab === 'DMPL'} label="DMPL" onClick={() => setActiveTab('DMPL')} />
<ReportTab active={activeTab === 'DRA'} label="DRA" onClick={() => setActiveTab('DRA')} />
<ReportTab active={activeTab === 'DVA'} label="DVA" onClick={() => setActiveTab('DVA')} />
</div>
{renderContent()}
</div>
);
};