'use client'; import { Button } from '@/components/ui/button'; import { ArrowDown, ArrowUp, ArrowUpDown, Download } from 'lucide-react'; import { useCallback, useEffect, useState } from 'react'; import * as XLSX from 'xlsx'; interface AnaliticoItem { codigo_grupo: string; codigo_subgrupo: string; codigo_fornecedor: string; nome_fornecedor: string; id: number; codfilial: string; recnum: number; data_competencia: string; data_vencimento: string; data_pagamento: string; data_caixa: string; codigo_conta: string; conta: string; codigo_centrocusto: string; valor: number; historico: string; historico2: string; created_at: string; updated_at: string; } type SortField = 'nome_fornecedor' | 'data_competencia' | 'valor' | 'conta'; type SortDirection = 'asc' | 'desc'; interface SortConfig { field: SortField; direction: SortDirection; } interface AnaliticoProps { filtros: { dataInicio: string; dataFim: string; centroCusto?: string; codigoGrupo?: string; codigoSubgrupo?: string; codigoConta?: string; }; } export default function AnaliticoComponent({ filtros }: AnaliticoProps) { const [data, setData] = useState([]); const [loading, setLoading] = useState(false); const [sortConfig, setSortConfig] = useState({ field: 'data_competencia', direction: 'desc', }); const fetchData = useCallback(async () => { // Só faz a requisição se tiver dataInicio e dataFim if (!filtros.dataInicio || !filtros.dataFim) { setData([]); return; } setLoading(true); try { const params = new URLSearchParams({ dataInicio: filtros.dataInicio, dataFim: filtros.dataFim, ...(filtros.centroCusto && { centroCusto: filtros.centroCusto }), ...(filtros.codigoGrupo && { codigoGrupo: filtros.codigoGrupo }), ...(filtros.codigoSubgrupo && { codigoSubgrupo: filtros.codigoSubgrupo, }), ...(filtros.codigoConta && { codigoConta: filtros.codigoConta }), }); const response = await fetch(`/api/analitico?${params}`); if (response.ok) { const result = await response.json(); setData(result as AnaliticoItem[]); } else { console.error('Erro ao buscar dados:', await response.text()); } } catch (error) { console.error('Erro ao buscar dados:', error); } finally { setLoading(false); } }, [filtros]); useEffect(() => { fetchData(); }, [fetchData]); const handleSort = (field: SortField) => { setSortConfig((prev) => ({ field, direction: prev.field === field && prev.direction === 'asc' ? 'desc' : 'asc', })); }; const getSortIcon = (field: SortField) => { if (sortConfig.field !== field) { return ; } return sortConfig.direction === 'asc' ? ( ) : ( ); }; const sortedData = [...data].sort((a, b) => { const aValue = a[sortConfig.field]; const bValue = b[sortConfig.field]; if (typeof aValue === 'string' && typeof bValue === 'string') { return sortConfig.direction === 'asc' ? aValue.localeCompare(bValue) : bValue.localeCompare(aValue); } if (typeof aValue === 'number' && typeof bValue === 'number') { return sortConfig.direction === 'asc' ? aValue - bValue : bValue - aValue; } return 0; }); const formatCurrency = (value: number) => { return new Intl.NumberFormat('pt-BR', { style: 'currency', currency: 'BRL', }).format(value); }; const formatDate = (dateString: string) => { return new Date(dateString).toLocaleDateString('pt-BR'); }; const totalValor = data.reduce((sum, item) => { const valor = typeof item.valor === 'string' ? parseFloat(item.valor) : item.valor; return sum + (isNaN(valor) ? 0 : valor); }, 0); const exportToExcel = () => { if (data.length === 0) return; // Preparar dados para exportação const exportData = data.map((item) => ({ 'Código Fornecedor': item.codigo_fornecedor, 'Nome Fornecedor': item.nome_fornecedor, 'Data Competência': new Date(item.data_competencia).toLocaleDateString( 'pt-BR' ), 'Data Vencimento': new Date(item.data_vencimento).toLocaleDateString( 'pt-BR' ), 'Data Pagamento': item.data_pagamento ? new Date(item.data_pagamento).toLocaleDateString('pt-BR') : '', 'Data Caixa': new Date(item.data_caixa).toLocaleDateString('pt-BR'), 'Código Conta': item.codigo_conta, Conta: item.conta, 'Centro de Custo': item.codigo_centrocusto, Valor: typeof item.valor === 'string' ? parseFloat(item.valor) : item.valor, Histórico: item.historico, 'Histórico 2': item.historico2, })); // Criar workbook const wb = XLSX.utils.book_new(); const ws = XLSX.utils.json_to_sheet(exportData); // Adicionar resumo na segunda aba const resumoData = [ { 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'); // Gerar nome do arquivo com data e hora const now = new Date(); const timestamp = now.toISOString().slice(0, 19).replace(/:/g, '-'); const fileName = `analitico_${timestamp}.xlsx`; // Fazer download XLSX.writeFile(wb, fileName); }; return (

Análise Analítica

{data.length > 0 && ( )}
{/* Filtros aplicados */} {/*
Filtros aplicados:
{filtros.centroCusto && ( Centro: {filtros.centroCusto} )} {filtros.codigoGrupo && ( Grupo: {filtros.codigoGrupo} )} {filtros.codigoSubgrupo && ( Subgrupo: {filtros.codigoSubgrupo} )} {filtros.codigoConta && ( Conta: {filtros.codigoConta} )}
*/} {/* Resumo */} {/* Tabela */}
{/* Header fixo */}
Histórico
{loading ? (
Carregando dados analíticos...
) : sortedData.length === 0 ? (
Nenhum dado analítico encontrado para os filtros aplicados.
) : ( sortedData.map((row, index) => (
{row.nome_fornecedor || '-'}
{formatDate(row.data_competencia)}
{row.conta}
{formatCurrency( typeof row.valor === 'string' ? parseFloat(row.valor) : row.valor )}
{row.historico || '-'}
)) )}
{data.length > 0 && (

Total de Registros: {data.length}

Valor Total: {formatCurrency(totalValor)}

)}
); }