From 35aca238eaacc4cab657ce7badfa027d660190a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alessandro=20Gon=C3=A7aalves?= Date: Mon, 20 Oct 2025 17:35:24 -0300 Subject: [PATCH] =?UTF-8?q?fix:=20remo=C3=A7=C3=A3o=20dos=20icones?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/DRE/analitico.tsx | 550 +++++++++++++++++++++++--------------- src/app/DRE/teste.tsx | 303 ++++++++++++++------- 2 files changed, 543 insertions(+), 310 deletions(-) diff --git a/src/app/DRE/analitico.tsx b/src/app/DRE/analitico.tsx index ddfd3fe..bc8bb10 100644 --- a/src/app/DRE/analitico.tsx +++ b/src/app/DRE/analitico.tsx @@ -1,4 +1,4 @@ -'use client'; +"use client"; import * as React from "react"; import { @@ -25,7 +25,7 @@ import { SelectItem, } from "@/components/ui/select"; import { Download, Filter, X } from "lucide-react"; -import * as XLSX from 'xlsx'; +import * as XLSX from "xlsx"; interface AnaliticoItem { codigo_grupo: string; @@ -66,7 +66,9 @@ export default function AnaliticoComponent({ filtros }: AnaliticoProps) { const [globalFilter, setGlobalFilter] = React.useState(""); const [columnFilters, setColumnFilters] = React.useState([]); const [open, setOpen] = React.useState(false); - const [conditions, setConditions] = React.useState([{ column: "", operator: "contains", value: "" }]); + const [conditions, setConditions] = React.useState([ + { column: "", operator: "contains", value: "" }, + ]); const fetchData = React.useCallback(async () => { // Só faz a requisição se tiver dataInicio e dataFim @@ -93,10 +95,10 @@ export default function AnaliticoComponent({ filtros }: AnaliticoProps) { const result = await response.json(); setData(result as AnaliticoItem[]); } else { - console.error('Erro ao buscar dados:', await response.text()); + console.error("Erro ao buscar dados:", await response.text()); } } catch (error) { - console.error('Erro ao buscar dados:', error); + console.error("Erro ao buscar dados:", error); } finally { setLoading(false); } @@ -108,58 +110,82 @@ export default function AnaliticoComponent({ filtros }: AnaliticoProps) { const columns = React.useMemo( () => [ - { - accessorKey: "data_competencia", - header: "Data Comp.", + { + accessorKey: "data_competencia", + header: "Data Comp.", filterFn: "advancedText", cell: ({ getValue }: { getValue: () => string }) => { const value = getValue(); - return new Date(value).toLocaleDateString('pt-BR'); - } + return new Date(value).toLocaleDateString("pt-BR"); + }, }, - { - accessorKey: "data_vencimento", - header: "Data Venc.", + { + accessorKey: "data_vencimento", + header: "Data Venc.", filterFn: "advancedText", cell: ({ getValue }: { getValue: () => string }) => { const value = getValue(); - return new Date(value).toLocaleDateString('pt-BR'); - } + return new Date(value).toLocaleDateString("pt-BR"); + }, }, - { - accessorKey: "data_caixa", - header: "Data Caixa", + { + accessorKey: "data_caixa", + header: "Data Caixa", filterFn: "advancedText", cell: ({ getValue }: { getValue: () => string }) => { const value = getValue(); - return new Date(value).toLocaleDateString('pt-BR'); - } + return new Date(value).toLocaleDateString("pt-BR"); + }, + }, + { + accessorKey: "codigo_fornecedor", + header: "Cód. Fornec.", + filterFn: "advancedText", + }, + { + accessorKey: "nome_fornecedor", + header: "Fornecedor", + filterFn: "advancedText", + }, + { + accessorKey: "codigo_centrocusto", + header: "Cód. Centro", + filterFn: "advancedText", + }, + { + accessorKey: "codigo_conta", + header: "Cód. Conta", + filterFn: "advancedText", }, - { accessorKey: "codigo_fornecedor", header: "Cód. Fornec.", filterFn: "advancedText" }, - { accessorKey: "nome_fornecedor", header: "Fornecedor", filterFn: "advancedText" }, - { accessorKey: "codigo_centrocusto", header: "Cód. Centro", filterFn: "advancedText" }, - { accessorKey: "codigo_conta", header: "Cód. Conta", filterFn: "advancedText" }, { accessorKey: "conta", header: "Conta", filterFn: "advancedText" }, - { - accessorKey: "valor", - header: "Valor", + { + accessorKey: "valor", + header: "Valor", filterFn: "advancedText", cell: ({ getValue }: { getValue: () => number }) => { const value = getValue(); - const formatted = new Intl.NumberFormat('pt-BR', { - style: 'currency', - currency: 'BRL', + const formatted = new Intl.NumberFormat("pt-BR", { + style: "currency", + currency: "BRL", }).format(value); const isNegative = value < 0; return ( - + {formatted} ); - } + }, + }, + { + accessorKey: "historico", + header: "Histórico", + filterFn: "advancedText", + }, + { + accessorKey: "historico2", + header: "Histórico 2", + filterFn: "advancedText", }, - { accessorKey: "historico", header: "Histórico", filterFn: "advancedText" }, - { accessorKey: "historico2", header: "Histórico 2", filterFn: "advancedText" }, { accessorKey: "recnum", header: "Recnum", filterFn: "advancedText" }, ], [] @@ -169,10 +195,10 @@ export default function AnaliticoComponent({ filtros }: AnaliticoProps) { () => ({ advancedText: (row: any, columnId: string, filters: any[]) => { if (!filters || filters.length === 0) return true; - + // Se veio um único filtro (objeto), transforma em array const conds = Array.isArray(filters) ? filters : [filters]; - + // A coluna deve atender a todas as condições aplicáveis a ela return conds.every((filter) => { const raw = row.getValue(columnId); @@ -181,7 +207,7 @@ export default function AnaliticoComponent({ filtros }: AnaliticoProps) { const q = (filter.value ?? "").toString(); const a = v.toLowerCase(); const b = q.toLowerCase(); - + switch (op) { case "contains": return a.includes(b); @@ -203,7 +229,6 @@ export default function AnaliticoComponent({ filtros }: AnaliticoProps) { }), [] ); - const table = useReactTable({ data, @@ -227,27 +252,28 @@ export default function AnaliticoComponent({ filtros }: AnaliticoProps) { const virtualRows = rowVirtualizer.getVirtualItems(); - const applyFilters = () => { // Agrupar múltiplas condições por coluna const grouped: Record = {}; - + conditions.forEach((c) => { if ( c.column && - (c.operator === "empty" || c.operator === "notEmpty" || (c.value ?? "") !== "") + (c.operator === "empty" || + c.operator === "notEmpty" || + (c.value ?? "") !== "") ) { if (!grouped[c.column]) grouped[c.column] = []; grouped[c.column].push({ operator: c.operator, value: c.value }); } }); - + // Converte em formato aceito pelo TanStack const filters = Object.keys(grouped).map((col) => ({ id: col, value: grouped[col], })); - + setColumnFilters(filters); setOpen(false); }; @@ -260,7 +286,7 @@ export default function AnaliticoComponent({ filtros }: AnaliticoProps) { const totalValor = data.reduce((sum, item) => { const valor = - typeof item.valor === 'string' ? parseFloat(item.valor) : item.valor; + typeof item.valor === "string" ? parseFloat(item.valor) : item.valor; return sum + (isNaN(valor) ? 0 : valor); }, 0); @@ -269,23 +295,23 @@ export default function AnaliticoComponent({ filtros }: AnaliticoProps) { // Preparar dados para exportação const exportData = data.map((item) => ({ - 'Data Competência': new Date(item.data_competencia).toLocaleDateString( - 'pt-BR' + "Data Competência": new Date(item.data_competencia).toLocaleDateString( + "pt-BR" ), - 'Data Vencimento': new Date(item.data_vencimento).toLocaleDateString( - 'pt-BR' + "Data Vencimento": new Date(item.data_vencimento).toLocaleDateString( + "pt-BR" ), - 'Data Caixa': new Date(item.data_caixa).toLocaleDateString('pt-BR'), - 'Código Fornecedor': item.codigo_fornecedor, + "Data Caixa": new Date(item.data_caixa).toLocaleDateString("pt-BR"), + "Código Fornecedor": item.codigo_fornecedor, Fornecedor: item.nome_fornecedor, - 'Código Centro Custo': item.codigo_centrocusto, - 'Centro Custo': item.codigo_centrocusto, // Assumindo que é o mesmo valor - 'Código Conta': item.codigo_conta, + "Código Centro Custo": item.codigo_centrocusto, + "Centro Custo": item.codigo_centrocusto, // Assumindo que é o mesmo valor + "Código Conta": item.codigo_conta, Conta: item.conta, Valor: - typeof item.valor === 'string' ? parseFloat(item.valor) : item.valor, + typeof item.valor === "string" ? parseFloat(item.valor) : item.valor, Histórico: item.historico, - 'Histórico 2': item.historico2, + "Histórico 2": item.historico2, Recnum: item.recnum, })); @@ -295,18 +321,18 @@ export default function AnaliticoComponent({ filtros }: AnaliticoProps) { // Adicionar resumo na segunda aba const resumoData = [ - { Métrica: 'Total de Registros', Valor: data.length }, - { Métrica: 'Valor Total', Valor: totalValor }, + { Métrica: "Total de Registros", Valor: data.length }, + { Métrica: "Valor Total", Valor: totalValor }, ]; const wsResumo = XLSX.utils.json_to_sheet(resumoData); // Adicionar abas ao workbook - XLSX.utils.book_append_sheet(wb, ws, 'Dados Analíticos'); - XLSX.utils.book_append_sheet(wb, wsResumo, 'Resumo'); + XLSX.utils.book_append_sheet(wb, ws, "Dados Analíticos"); + XLSX.utils.book_append_sheet(wb, wsResumo, "Resumo"); // Gerar nome do arquivo com data e hora const now = new Date(); - const timestamp = now.toISOString().slice(0, 19).replace(/:/g, '-'); + const timestamp = now.toISOString().slice(0, 19).replace(/:/g, "-"); const fileName = `analitico_${timestamp}.xlsx`; // Fazer download @@ -318,163 +344,258 @@ export default function AnaliticoComponent({ filtros }: AnaliticoProps) { {/* Header Section */}
-
- - + {/*
+ + -
+
*/}
-

Análise Analítica

-

Relatório detalhado de transações

+

+ Análise Analítica +

+

+ Relatório detalhado de transações +

- - {/* Controls */} -
- ) => setGlobalFilter(e.target.value)} - className="w-64 bg-white border-gray-300 focus:border-blue-500 focus:ring-blue-500" - /> - - {(columnFilters.length > 0 || globalFilter) && ( - - )} - {data.length > 0 && ( - - )} -
+ + {/* Controls */} +
+ ) => + setGlobalFilter(e.target.value) + } + className="w-64 bg-white border-gray-300 focus:border-blue-500 focus:ring-blue-500" + /> + + {(columnFilters.length > 0 || globalFilter) && ( + + )} + {data.length > 0 && ( + + )} +
{/* Table Container */}
- {/* Table Header */} -
-
-
Data Comp.
-
Data Venc.
-
Data Caixa
-
Cód. Fornec.
-
Fornecedor
-
Cód. Centro
-
Cód. Conta
-
Conta
-
Valor
-
Recnum
+ {/* Table Header */} +
+
+
Data Comp.
+
Data Venc.
+
Data Caixa
+
Cód. Fornec.
+
Fornecedor
+
Cód. Centro
+
Cód. Conta
+
Conta
+
Valor
+
Recnum
+
-
- {/* Table Body */} -
- {loading ? ( -
-
-
-

Carregando dados...

-
-
- ) : virtualRows.length === 0 ? ( -
-
-
- - - + {/* Table Body */} +
+ {loading ? ( +
+
+
+

Carregando dados...

-

Nenhum dado encontrado

-
- ) : ( -
- {virtualRows.map((virtualRow) => { - const row = table.getRowModel().rows[virtualRow.index]; - return ( -
-
{new Date(row.original.data_competencia).toLocaleDateString('pt-BR')}
-
{new Date(row.original.data_vencimento).toLocaleDateString('pt-BR')}
-
{new Date(row.original.data_caixa).toLocaleDateString('pt-BR')}
-
{row.original.codigo_fornecedor}
-
{row.original.nome_fornecedor}
-
{row.original.codigo_centrocusto}
-
{row.original.codigo_conta}
-
{row.original.conta}
-
- {new Intl.NumberFormat('pt-BR', { style: 'currency', currency: 'BRL' }).format(row.original.valor)} + ) : virtualRows.length === 0 ? ( +
+
+
+ + + +
+

Nenhum dado encontrado

-
{row.original.recnum}
-
- ); - })}
- )} -
+ ) : ( +
+ {virtualRows.map((virtualRow) => { + const row = table.getRowModel().rows[virtualRow.index]; + return ( +
+
+ {new Date( + row.original.data_competencia + ).toLocaleDateString("pt-BR")} +
+
+ {new Date( + row.original.data_vencimento + ).toLocaleDateString("pt-BR")} +
+
+ {new Date(row.original.data_caixa).toLocaleDateString( + "pt-BR" + )} +
+
+ {row.original.codigo_fornecedor} +
+
+ {row.original.nome_fornecedor} +
+
+ {row.original.codigo_centrocusto} +
+
+ {row.original.codigo_conta} +
+
+ {row.original.conta} +
+
+ {new Intl.NumberFormat("pt-BR", { + style: "currency", + currency: "BRL", + }).format(row.original.valor)} +
+
+ {row.original.recnum} +
+
+ ); + })} +
+ )} +
- {/* Summary Footer - Integrado */} - {data.length > 0 && ( -
-
-
-
- - - + {/* Summary Footer - Integrado */} + {data.length > 0 && ( +
+
+
+ {/*
+ + + +
*/} +
+

+ Total de Registros:{" "} + + {table.getRowModel().rows.length} + +

+

+ Transações encontradas +

+
-
-

- Total de Registros: {table.getRowModel().rows.length} +
+

+ + Valor Total:{" "} + {new Intl.NumberFormat("pt-BR", { + style: "currency", + currency: "BRL", + }).format(totalValor)} +

-

Transações encontradas

+

+ Soma de todos os valores +

-
-

- - Valor Total: {new Intl.NumberFormat('pt-BR', { - style: 'currency', - currency: 'BRL', - }).format(totalValor)} - -

-

Soma de todos os valores

-
-
- )} + )}
@@ -482,12 +603,17 @@ export default function AnaliticoComponent({ filtros }: AnaliticoProps) { - Filtros Avançados + + Filtros Avançados +
{conditions.map((cond, idx) => ( -
+
@@ -522,7 +651,8 @@ export default function AnaliticoComponent({ filtros }: AnaliticoProps) { onValueChange={(v: string) => { const next = [...conditions]; next[idx].operator = v; - if (v === "empty" || v === "notEmpty") next[idx].value = ""; + if (v === "empty" || v === "notEmpty") + next[idx].value = ""; setConditions(next); }} > @@ -540,7 +670,9 @@ export default function AnaliticoComponent({ filtros }: AnaliticoProps) {
- {!(cond.operator === "empty" || cond.operator === "notEmpty") && ( + {!( + cond.operator === "empty" || cond.operator === "notEmpty" + ) && (
- -
); -} \ No newline at end of file +} diff --git a/src/app/DRE/teste.tsx b/src/app/DRE/teste.tsx index 272032c..77fb086 100644 --- a/src/app/DRE/teste.tsx +++ b/src/app/DRE/teste.tsx @@ -1,8 +1,8 @@ -'use client'; +"use client"; -import { LoaderPinwheel } from 'lucide-react'; -import { useEffect, useState } from 'react'; -import AnaliticoComponent from './analitico'; +import { LoaderPinwheel } from "lucide-react"; +import { useEffect, useState } from "react"; +import AnaliticoComponent from "./analitico"; interface DREItem { codfilial: string; @@ -17,7 +17,7 @@ interface DREItem { } interface HierarchicalRow { - type: 'grupo' | 'subgrupo' | 'centro_custo' | 'conta'; + type: "grupo" | "subgrupo" | "centro_custo" | "conta"; level: number; grupo?: string; subgrupo?: string; @@ -30,7 +30,6 @@ interface HierarchicalRow { percentuaisPorMes?: Record; } - export default function Teste() { const [data, setData] = useState([]); const [loading, setLoading] = useState(true); @@ -46,12 +45,12 @@ export default function Teste() { // Estados para analítico const [analiticoFiltros, setAnaliticoFiltros] = useState({ - dataInicio: '', - dataFim: '', - centroCusto: '', - codigoGrupo: '', - codigoSubgrupo: '', - codigoConta: '', + dataInicio: "", + dataFim: "", + centroCusto: "", + codigoGrupo: "", + codigoSubgrupo: "", + codigoConta: "", }); const [linhaSelecionada, setLinhaSelecionada] = useState(null); @@ -63,7 +62,7 @@ export default function Teste() { try { setLoading(true); setError(null); - const response = await fetch('/api/dre'); + const response = await fetch("/api/dre"); if (!response.ok) { throw new Error(`Erro ao carregar dados: ${response.status}`); @@ -79,29 +78,29 @@ export default function Teste() { const dataCompetencia = new Date(item.data_competencia); return `${dataCompetencia.getFullYear()}-${String( dataCompetencia.getMonth() + 1 - ).padStart(2, '0')}`; + ).padStart(2, "0")}`; }) ), ].sort() as string[]; setMesesDisponiveis(meses); } catch (err) { - setError(err instanceof Error ? err.message : 'Erro desconhecido'); + setError(err instanceof Error ? err.message : "Erro desconhecido"); } finally { setLoading(false); } }; const formatCurrency = (value: string | number) => { - const numValue = typeof value === 'string' ? parseFloat(value) : value; - return numValue.toLocaleString('pt-BR', { - style: 'currency', - currency: 'BRL', + const numValue = typeof value === "string" ? parseFloat(value) : value; + return numValue.toLocaleString("pt-BR", { + style: "currency", + currency: "BRL", }); }; const formatCurrencyWithColor = (value: string | number) => { - const numValue = typeof value === 'string' ? parseFloat(value) : value; + const numValue = typeof value === "string" ? parseFloat(value) : value; const formatted = formatCurrency(value); const isNegative = numValue < 0; return { formatted, isNegative }; @@ -110,9 +109,9 @@ export default function Teste() { // Função para extrair códigos dos grupos e subgrupos const extractCodes = (grupo: string, subgrupo?: string) => { const grupoMatch = grupo.match(/^(\d+)/); - const codigoGrupo = grupoMatch ? grupoMatch[1] : ''; + const codigoGrupo = grupoMatch ? grupoMatch[1] : ""; - let codigoSubgrupo = ''; + let codigoSubgrupo = ""; if (subgrupo) { // Primeiro tenta extrair código numérico (ex: "001.008 - LOJA 8" -> "001.008") const subgrupoMatch = subgrupo.match(/^(\d+(?:\.\d+)+)/); @@ -140,14 +139,14 @@ export default function Teste() { const dataFimStr = new Date(dataFim).toISOString().substring(0, 7); // YYYY-MM const { codigoGrupo, codigoSubgrupo } = extractCodes( - row.grupo || '', + row.grupo || "", row.subgrupo ); // Criar um identificador único para a linha - const linhaId = `${row.type}-${row.grupo || ''}-${row.subgrupo || ''}-${ - row.centro_custo || '' - }-${row.codigo_conta || ''}`; + const linhaId = `${row.type}-${row.grupo || ""}-${row.subgrupo || ""}-${ + row.centro_custo || "" + }-${row.codigo_conta || ""}`; setLinhaSelecionada(linhaId); // Se um mês específico foi selecionado, usar apenas esse mês @@ -157,10 +156,10 @@ export default function Teste() { setAnaliticoFiltros({ dataInicio: dataInicioFiltro, dataFim: dataFimFiltro, - centroCusto: row.centro_custo || '', + centroCusto: row.centro_custo || "", codigoGrupo, codigoSubgrupo, - codigoConta: row.codigo_conta?.toString() || '', + codigoConta: row.codigo_conta?.toString() || "", }); }; @@ -194,7 +193,6 @@ export default function Teste() { setExpandedCentros(newExpanded); }; - const calcularValoresPorMes = (items: DREItem[]): Record => { const valoresPorMes: Record = {}; @@ -202,7 +200,7 @@ export default function Teste() { const dataCompetencia = new Date(item.data_competencia); const anoMes = `${dataCompetencia.getFullYear()}-${String( dataCompetencia.getMonth() + 1 - ).padStart(2, '0')}`; + ).padStart(2, "0")}`; if (!valoresPorMes[anoMes]) { valoresPorMes[anoMes] = 0; @@ -221,7 +219,7 @@ export default function Teste() { const percentuais: Record = {}; // Se for o grupo 03, retorna 100% para todos os meses - if (grupo.includes('03')) { + if (grupo.includes("03")) { Object.keys(valoresPorMes).forEach((mes) => { percentuais[mes] = 100; }); @@ -237,8 +235,8 @@ export default function Teste() { const dataCompetencia = new Date(item.data_competencia); const anoMes = `${dataCompetencia.getFullYear()}-${String( dataCompetencia.getMonth() + 1 - ).padStart(2, '0')}`; - return anoMes === mes && item.grupo.includes('03'); + ).padStart(2, "0")}`; + return anoMes === mes && item.grupo.includes("03"); }); const valorGrupo03 = grupo03Items.reduce( @@ -262,16 +260,16 @@ export default function Teste() { // Agrupar por grupo, mas tratar grupo 05 como subgrupo do grupo 04 const grupos = data.reduce((acc, item) => { // Se for grupo 05, adicionar ao grupo 04 como subgrupo - if (item.grupo.includes('05')) { + if (item.grupo.includes("05")) { // Encontrar grupo 04 existente ou criar um - const grupo04Key = Object.keys(acc).find((key) => key.includes('04')); + const grupo04Key = Object.keys(acc).find((key) => key.includes("04")); if (grupo04Key) { acc[grupo04Key].push(item); } else { // Se não existe grupo 04, criar um grupo especial const grupo04Nome = - Object.keys(acc).find((key) => key.includes('04')) || - '04 - GRUPO 04'; + Object.keys(acc).find((key) => key.includes("04")) || + "04 - GRUPO 04"; if (!acc[grupo04Nome]) { acc[grupo04Nome] = []; } @@ -288,7 +286,9 @@ export default function Teste() { }, {} as Record); // Ordenar grupos - const sortedGrupos = Object.entries(grupos).sort(([a], [b]) => a.localeCompare(b)); + const sortedGrupos = Object.entries(grupos).sort(([a], [b]) => + a.localeCompare(b) + ); sortedGrupos.forEach(([grupo, items]) => { const totalGrupo = items.reduce( @@ -299,7 +299,7 @@ export default function Teste() { // Linha do grupo const valoresPorMes = calcularValoresPorMes(items); rows.push({ - type: 'grupo', + type: "grupo", level: 0, grupo, total: totalGrupo, @@ -312,7 +312,7 @@ export default function Teste() { // Agrupar por subgrupo dentro do grupo const subgrupos = items.reduce((acc, item) => { // Se o item originalmente era do grupo 05, agrupar tudo sob o nome do grupo 05 - if (item.grupo.includes('05')) { + if (item.grupo.includes("05")) { const subgrupoKey = item.grupo; // Usar o nome completo do grupo 05 if (!acc[subgrupoKey]) { acc[subgrupoKey] = []; @@ -329,7 +329,9 @@ export default function Teste() { }, {} as Record); // Ordenar subgrupos - const sortedSubgrupos = Object.entries(subgrupos).sort(([a], [b]) => a.localeCompare(b)); + const sortedSubgrupos = Object.entries(subgrupos).sort(([a], [b]) => + a.localeCompare(b) + ); sortedSubgrupos.forEach(([subgrupo, subgrupoItems]) => { const totalSubgrupo = subgrupoItems.reduce( @@ -340,7 +342,7 @@ export default function Teste() { // Linha do subgrupo const valoresSubgrupoPorMes = calcularValoresPorMes(subgrupoItems); rows.push({ - type: 'subgrupo', + type: "subgrupo", level: 1, grupo, subgrupo, @@ -364,7 +366,9 @@ export default function Teste() { }, {} as Record); // Ordenar centros de custo - const sortedCentros = Object.entries(centros).sort(([a], [b]) => a.localeCompare(b)); + const sortedCentros = Object.entries(centros).sort(([a], [b]) => + a.localeCompare(b) + ); sortedCentros.forEach(([centro, centroItems]) => { const totalCentro = centroItems.reduce( @@ -375,7 +379,7 @@ export default function Teste() { // Linha do centro de custo const valoresCentroPorMes = calcularValoresPorMes(centroItems); rows.push({ - type: 'centro_custo', + type: "centro_custo", level: 2, grupo, subgrupo, @@ -402,7 +406,9 @@ export default function Teste() { }, {} as Record); // Ordenar contas - const sortedContas = Object.entries(contas).sort(([a], [b]) => a.localeCompare(b)); + const sortedContas = Object.entries(contas).sort(([a], [b]) => + a.localeCompare(b) + ); sortedContas.forEach(([conta, contaItems]) => { const totalConta = contaItems.reduce( @@ -413,7 +419,7 @@ export default function Teste() { // Linha da conta (sem ano/mês no nome) const valoresContaPorMes = calcularValoresPorMes(contaItems); rows.push({ - type: 'conta', + type: "conta", level: 3, grupo, subgrupo, @@ -439,28 +445,30 @@ export default function Teste() { }; const getRowStyle = (row: HierarchicalRow) => { - const baseStyle = 'transition-all duration-200 hover:bg-gradient-to-r hover:from-blue-50/30 hover:to-indigo-50/30'; + const baseStyle = + "transition-all duration-200 hover:bg-gradient-to-r hover:from-blue-50/30 hover:to-indigo-50/30"; // Criar identificador único para a linha - const linhaId = `${row.type}-${row.grupo || ''}-${row.subgrupo || ''}-${ - row.centro_custo || '' - }-${row.codigo_conta || ''}`; + const linhaId = `${row.type}-${row.grupo || ""}-${row.subgrupo || ""}-${ + row.centro_custo || "" + }-${row.codigo_conta || ""}`; const isSelected = linhaSelecionada === linhaId; let style = baseStyle; if (isSelected) { - style += ' bg-gradient-to-r from-blue-100 to-indigo-100 border-l-4 border-blue-500 shadow-lg'; + style += + " bg-gradient-to-r from-blue-100 to-indigo-100 border-l-4 border-blue-500 shadow-lg"; } switch (row.type) { - case 'grupo': + case "grupo": return `${style} bg-gradient-to-r from-blue-50/20 to-indigo-50/20 font-bold text-gray-900 border-b-2 border-blue-200`; - case 'subgrupo': + case "subgrupo": return `${style} bg-gradient-to-r from-gray-50/30 to-blue-50/20 font-semibold text-gray-800`; - case 'centro_custo': + case "centro_custo": return `${style} bg-gradient-to-r from-gray-50/20 to-gray-100/10 font-medium text-gray-700`; - case 'conta': + case "conta": return `${style} bg-white font-normal text-gray-600`; default: return style; @@ -473,7 +481,7 @@ export default function Teste() { const renderCellContent = (row: HierarchicalRow) => { switch (row.type) { - case 'grupo': + case "grupo": return (
); - case 'subgrupo': + case "subgrupo": return (
); - case 'centro_custo': + case "centro_custo": return (
); - case 'conta': + case "conta": return (
@@ -556,25 +568,43 @@ export default function Teste() {
-
- - + {/*
+ + -
+
*/}
-

DRE Gerencial

-

Demonstração do Resultado do Exercício

+

+ DRE Gerencial +

+

+ Demonstração do Resultado do Exercício +

- +
-

Carregando dados...

-

Aguarde enquanto processamos as informações

+

+ Carregando dados... +

+

+ Aguarde enquanto processamos as informações +

@@ -586,26 +616,52 @@ export default function Teste() {
-
- - + {/*
+ + -
+
*/}
-

DRE Gerencial

-

Demonstração do Resultado do Exercício

+

+ DRE Gerencial +

+

+ Demonstração do Resultado do Exercício +

- +
- - + +
-

Erro ao carregar DRE Gerencial

+

+ Erro ao carregar DRE Gerencial +

{error}

@@ -622,14 +678,26 @@ export default function Teste() { {/* Header Section */}
-
- - + {/*
+ + -
+
*/}

DRE Gerencial

-

Demonstração do Resultado do Exercício

+

+ Demonstração do Resultado do Exercício +

@@ -643,7 +711,9 @@ export default function Teste() { {mesesDisponiveis.map((mes) => (
{mes}
-
%
+
+ % +
))}
Total
@@ -653,8 +723,16 @@ export default function Teste() { {/* Table Body */}
{hierarchicalData.map((row, index) => ( -
-
+
+
{renderCellContent(row)}
{mesesDisponiveis.map((mes) => ( @@ -662,39 +740,62 @@ export default function Teste() {
handleRowClick(row, mes)} - title={row.valoresPorMes && row.valoresPorMes[mes] ? formatCurrency(row.valoresPorMes[mes]) : '-'} + title={ + row.valoresPorMes && row.valoresPorMes[mes] + ? formatCurrency(row.valoresPorMes[mes]) + : "-" + } > {row.valoresPorMes && row.valoresPorMes[mes] ? (() => { - const { formatted, isNegative } = formatCurrencyWithColor(row.valoresPorMes[mes]); + const { formatted, isNegative } = + formatCurrencyWithColor(row.valoresPorMes[mes]); return ( - + {formatted} ); })() - : '-'} + : "-"}
handleRowClick(row, mes)} - title={row.percentuaisPorMes && row.percentuaisPorMes[mes] !== undefined ? `${row.percentuaisPorMes[mes].toFixed(1)}%` : '-'} + title={ + row.percentuaisPorMes && + row.percentuaisPorMes[mes] !== undefined + ? `${row.percentuaisPorMes[mes].toFixed(1)}%` + : "-" + } > - {row.percentuaisPorMes && row.percentuaisPorMes[mes] !== undefined + {row.percentuaisPorMes && + row.percentuaisPorMes[mes] !== undefined ? `${row.percentuaisPorMes[mes].toFixed(1)}%` - : '-'} + : "-"}
))}
handleRowClick(row)} - title={row.total ? formatCurrency(row.total) : '-'} + title={row.total ? formatCurrency(row.total) : "-"} > {(() => { - const { formatted, isNegative } = formatCurrencyWithColor(row.total!); + const { formatted, isNegative } = formatCurrencyWithColor( + row.total! + ); return ( - + {formatted} );