import { useCallback, useEffect, useMemo, useRef, useState } from "react"; import { LayoutDashboard, Loader2, RefreshCw } from "lucide-react"; import { toast } from "sonner"; import { Button } from "@/components/ui/button"; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"; import { useAuthAccess } from "@/contexts/AuthAccessContext"; import { dashboardPontosPorClienteService, type DashboardPontosPorParceiro, } from "@/services/fechamento/dashboardPontosPorCliente"; import { fechamentoParceirosService, type ParceiroItem } from "@/services/fechamento/parceiros"; function formatPontos(valor: number): string { return valor.toLocaleString("pt-BR", { minimumFractionDigits: 0, maximumFractionDigits: 4 }); } function primeiroDiaMesAtual(): string { const d = new Date(); const y = d.getFullYear(); const m = String(d.getMonth() + 1).padStart(2, "0"); return `${y}-${m}-01`; } function hojeIsoDate(): string { const d = new Date(); const y = d.getFullYear(); const m = String(d.getMonth() + 1).padStart(2, "0"); const day = String(d.getDate()).padStart(2, "0"); return `${y}-${m}-${day}`; } export default function DashboardPontos() { const { papel, me } = useAuthAccess(); const [parceiros, setParceiros] = useState([]); const [dataInicio, setDataInicio] = useState(primeiroDiaMesAtual); const [dataFim, setDataFim] = useState(hojeIsoDate); const [parceiroId, setParceiroId] = useState("all"); const [cliente, setCliente] = useState(""); const [loading, setLoading] = useState(true); const [dados, setDados] = useState([]); const clienteRef = useRef(cliente); clienteRef.current = cliente; const parceiroFixoSupervisor = papel === "supervisor" && me?.parceiroId; const loadParceiros = useCallback(async () => { if (parceiroFixoSupervisor && me?.parceiroId) { try { const res = await fechamentoParceirosService.listarParceiros({ estaAtivo: "all", page: 1, perPage: 200, }); const um = res.data.find((p) => p.id === me.parceiroId); setParceiros(um ? [um] : []); setParceiroId(me.parceiroId); } catch (e) { const message = e instanceof Error ? e.message : "Erro ao carregar parceiros."; toast.error(message); setParceiros([]); setParceiroId(me.parceiroId); } return; } try { const lista = await fechamentoParceirosService.listarParceirosAtivos(); setParceiros(lista); } catch (e) { const message = e instanceof Error ? e.message : "Erro ao carregar parceiros."; toast.error(message); setParceiros([]); } }, [me?.parceiroId, parceiroFixoSupervisor]); const loadRelatorio = useCallback(async () => { try { setLoading(true); const pid = parceiroFixoSupervisor && me?.parceiroId ? me.parceiroId : parceiroId === "all" ? undefined : parceiroId; const res = await dashboardPontosPorClienteService.relatorioPontosPorCliente({ dataInicio: dataInicio.trim() || undefined, dataFim: dataFim.trim() || undefined, parceiroId: pid, cliente: clienteRef.current.trim() || undefined, }); setDados(res); } catch (e) { const message = e instanceof Error ? e.message : "Erro ao carregar dashboard."; toast.error(message); setDados([]); } finally { setLoading(false); } }, [dataFim, dataInicio, me?.parceiroId, parceiroFixoSupervisor, parceiroId]); useEffect(() => { void loadParceiros(); }, [loadParceiros]); useEffect(() => { void loadRelatorio(); }, [dataFim, dataInicio, loadRelatorio, parceiroId, me?.parceiroId, papel]); const totalGeral = useMemo( () => dados.reduce((acc, p) => acc + p.totalParceiro, 0), [dados], ); return (

Dashboard

Pontos alocados por cliente (tarefas revisadas), por parceiro.

Filtros Período por data de conclusão da tarefa, ou data de criação se ainda não concluída.
setDataInicio(e.target.value)} />
setDataFim(e.target.value)} />
setCliente(e.target.value)} />
Resumo Soma dos pontos no período e filtros atuais.
{loading ? ( ) : ( {formatPontos(totalGeral)} pts )}
{loading && dados.length === 0 ? (
) : dados.length === 0 ? ( Nenhum dado para os filtros selecionados. ) : (
{dados.map((bloco) => (
{bloco.parceiroNome} Total: {formatPontos(bloco.totalParceiro)} pts
Cliente Pontos {bloco.linhas.map((linha) => ( {linha.cliente} {formatPontos(linha.pontos)} ))}
))}
)}
); }