198 lines
8.2 KiB
Markdown
198 lines
8.2 KiB
Markdown
# 🔧 Ajustes Pendentes - Financeiro V2 - Cruzamentos
|
|
|
|
## 📊 Contexto
|
|
Os cruzamentos já estão usando corretamente a rota `/extrato/apresentar`:
|
|
- **Receitas**: `tipoOperacao === 'C'` ✅
|
|
- **Despesas**: `tipoOperacao === 'D'` ✅
|
|
|
|
## ✅ Implementado
|
|
|
|
### CruzamentoView (Receitas)
|
|
- Estados de filtros adicionados
|
|
- Lógica de filtragem implementada (`dadosFiltrados`)
|
|
- KPIs recalculados (`kpisFiltrados`)
|
|
- Gráficos atualizados para usar dados filtrados
|
|
|
|
## 🚧 Pendente
|
|
|
|
### 1. CruzamentoView (Receitas) - Finalizar UI
|
|
|
|
#### 1.1. Adicionar Import do Select
|
|
```javascript
|
|
// Linha 19, após Badge
|
|
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
|
|
```
|
|
|
|
#### 1.2. Substituir Barra de Filtros (linhas 223-253)
|
|
Substituir o conteúdo atual por:
|
|
|
|
```jsx
|
|
{/* Filter & Summary Bar */}
|
|
<div className="bg-[#0f172a]/60 backdrop-blur-xl p-3 sm:p-4 rounded-xl sm:rounded-2xl border border-slate-800/50 flex flex-col gap-3 shadow-2xl relative z-10">
|
|
{/* Primeira Linha: Filtros de Período */}
|
|
<div className="flex flex-col sm:flex-row items-stretch sm:items-center gap-2 flex-1 min-w-0">
|
|
<div className="flex items-center gap-2">
|
|
<div className="p-2 bg-slate-900 rounded-lg border border-slate-800 shrink-0">
|
|
<Filter className="w-3.5 h-3.5 sm:w-4 sm:h-4 text-emerald-400" />
|
|
</div>
|
|
<Select value={filtroTipo} onValueChange={setFiltroTipo}>
|
|
<SelectTrigger className="h-8 w-28 bg-slate-900/50 border-slate-800 text-[10px] sm:text-[11px] font-bold text-white">
|
|
<SelectValue />
|
|
</SelectTrigger>
|
|
<SelectContent>
|
|
<SelectItem value="mes">Por Mês</SelectItem>
|
|
<SelectItem value="ano">Por Ano</SelectItem>
|
|
<SelectItem value="todos">Todos</SelectItem>
|
|
</SelectContent>
|
|
</Select>
|
|
</div>
|
|
|
|
{filtroTipo === 'mes' && (
|
|
<div className="flex items-center gap-2">
|
|
<Select value={filtroMes} onValueChange={setFiltroMes}>
|
|
<SelectTrigger className="h-8 w-32 bg-slate-900/50 border-slate-800 text-[10px] sm:text-[11px] font-bold text-white">
|
|
<SelectValue placeholder="Selecione o mês" />
|
|
</SelectTrigger>
|
|
<SelectContent>
|
|
<SelectItem value="01">Janeiro</SelectItem>
|
|
<SelectItem value="02">Fevereiro</SelectItem>
|
|
<SelectItem value="03">Março</SelectItem>
|
|
<SelectItem value="04">Abril</SelectItem>
|
|
<SelectItem value="05">Maio</SelectItem>
|
|
<SelectItem value="06">Junho</SelectItem>
|
|
<SelectItem value="07">Julho</SelectItem>
|
|
<SelectItem value="08">Agosto</SelectItem>
|
|
<SelectItem value="09">Setembro</SelectItem>
|
|
<SelectItem value="10">Outubro</SelectItem>
|
|
<SelectItem value="11">Novembro</SelectItem>
|
|
<SelectItem value="12">Dezembro</SelectItem>
|
|
</SelectContent>
|
|
</Select>
|
|
</div>
|
|
)}
|
|
|
|
{(filtroTipo === 'mes' || filtroTipo === 'ano') && (
|
|
<div className="flex items-center gap-2">
|
|
<Select value={filtroAno} onValueChange={setFiltroAno}>
|
|
<SelectTrigger className="h-8 w-24 bg-slate-900/50 border-slate-800 text-[10px] sm:text-[11px] font-bold text-white">
|
|
<SelectValue />
|
|
</SelectTrigger>
|
|
<SelectContent>
|
|
<SelectItem value="2024">2024</SelectItem>
|
|
<SelectItem value="2025">2025</SelectItem>
|
|
<SelectItem value="2026">2026</SelectItem>
|
|
</SelectContent>
|
|
</Select>
|
|
</div>
|
|
)}
|
|
</div>
|
|
|
|
{/* Segunda Linha: Filtro de Caixa */}
|
|
<div className="flex items-center gap-2 flex-wrap">
|
|
<span className="text-[10px] font-bold text-slate-500 uppercase">Caixa:</span>
|
|
<Select value={filtroCaixa} onValueChange={setFiltroCaixa}>
|
|
<SelectTrigger className="h-8 w-40 bg-slate-900/50 border-slate-800 text-[10px] sm:text-[11px] font-bold text-white">
|
|
<SelectValue />
|
|
</SelectTrigger>
|
|
<SelectContent>
|
|
<SelectItem value="todos">Todas as Caixas</SelectItem>
|
|
<SelectItem value="1">Caixa 1</SelectItem>
|
|
<SelectItem value="2">Caixa 2</SelectItem>
|
|
<SelectItem value="3">Caixa 3</SelectItem>
|
|
<SelectItem value="4">Caixa 4</SelectItem>
|
|
<SelectItem value="5">Caixa 5</SelectItem>
|
|
</SelectContent>
|
|
</Select>
|
|
<Badge variant="outline" className="h-8 px-3 rounded-lg bg-emerald-500/10 border-emerald-500/20 text-emerald-400 text-[10px] font-bold">
|
|
{dadosFiltrados.length} registros
|
|
</Badge>
|
|
</div>
|
|
</div>
|
|
```
|
|
|
|
#### 1.3. Atualizar KPIs para usar kpisFiltrados (linhas 257-281)
|
|
Substituir:
|
|
- `kpis?.totalRecebido` por `kpisFiltrados?.totalRecebido`
|
|
- `kpis?.totalPendente` por `kpisFiltrados?.totalPendente`
|
|
- `kpis?.totalGeral` por `kpisFiltrados?.totalGeral`
|
|
|
|
### 2. CruzamentoDespesasView (Despesas)
|
|
|
|
Aplicar as mesmas mudanças no arquivo `contas-pagar/CruzamentoDespesasView.jsx`:
|
|
|
|
#### 2.1. Adicionar Estados de Filtros (após linha 84)
|
|
```javascript
|
|
// Estados para filtros
|
|
const [filtroMes, setFiltroMes] = React.useState('');
|
|
const [filtroAno, setFiltroAno] = React.useState(new Date().getFullYear().toString());
|
|
const [filtroCaixa, setFiltroCaixa] = React.useState('todos');
|
|
const [filtroTipo, setFiltroTipo] = React.useState('mes'); // 'mes' | 'ano' | 'todos'
|
|
```
|
|
|
|
#### 2.2. Adicionar Lógica de Filtragem
|
|
```javascript
|
|
// Dados filtrados baseados nos filtros ativos
|
|
const dadosExecutadosFiltrados = React.useMemo(() => {
|
|
if (!Array.isArray(despesasExecutadas)) return [];
|
|
|
|
return despesasExecutadas.filter(item => {
|
|
// Filtro por período
|
|
if (filtroTipo === 'mes' && filtroMes && filtroAno) {
|
|
const dataItem = item?.dataEntrada || item?.data || '';
|
|
const [ano, mes] = dataItem.split('-');
|
|
if (ano !== filtroAno || mes !== filtroMes) return false;
|
|
} else if (filtroTipo === 'ano' && filtroAno) {
|
|
const dataItem = item?.dataEntrada || item?.data || '';
|
|
const [ano] = dataItem.split('-');
|
|
if (ano !== filtroAno) return false;
|
|
}
|
|
|
|
// Filtro por caixa
|
|
if (filtroCaixa !== 'todos' && item?.caixinha) {
|
|
if (item.caixinha !== filtroCaixa) return false;
|
|
}
|
|
|
|
return true;
|
|
});
|
|
}, [despesasExecutadas, filtroMes, filtroAno, filtroCaixa, filtroTipo]);
|
|
|
|
// KPIs recalculados
|
|
const kpisFiltrados = React.useMemo(() => {
|
|
const totalExecutado = dadosExecutadosFiltrados.reduce((acc, item) => acc + (item.valor || 0), 0);
|
|
|
|
return {
|
|
totalPlanejado: 0,
|
|
totalExecutado,
|
|
variacao: totalExecutado,
|
|
percentualVariacao: 0
|
|
};
|
|
}, [dadosExecutadosFiltrados]);
|
|
```
|
|
|
|
#### 2.3. Atualizar useMemo para usar dados filtrados
|
|
Substituir todas as referências a `despesasExecutadas` por `dadosExecutadosFiltrados` nos cálculos de:
|
|
- `comparativoCategoria`
|
|
- `timelineData`
|
|
- `categoriaData`
|
|
|
|
#### 2.4. Adicionar mesma UI de filtros (linhas 172-207)
|
|
|
|
#### 2.5. Atualizar KPIs para usar kpisFiltrados
|
|
|
|
## 🎯 Resultado Esperado
|
|
|
|
Após implementar essas mudanças:
|
|
- ✅ Filtros de mês/ano funcionais
|
|
- ✅ Filtro de caixa funcional
|
|
- ✅ KPIs atualizados dinamicamente conforme filtros
|
|
- ✅ Gráficos refletindo apenas dados filtrados
|
|
- ✅ Contador de registros filtrados visível
|
|
- ✅ Dados sempre vindos de `/extrato/apresentar`
|
|
|
|
## 📌 Observações
|
|
|
|
1. O campo `caixinha` pode não estar presente em todos os registros do extrato. Ajustar conforme necessário.
|
|
2. Os filtros são client-side. Para grandes volumes de dados, considerar filtros server-side.
|
|
3. O estado inicial do filtro de mês está vazio - o usuário precisa selecionar.
|
|
4. Considerar adicionar um botão "Limpar Filtros" para melhor UX.
|