novas atualizações na exportacao planilha, tela de listar fechamento, filtros

This commit is contained in:
Vitex Tecnologia
2026-05-07 11:34:55 -03:00
parent 1c1e62c7db
commit 343aae602f
13 changed files with 228 additions and 88 deletions
+10 -4
View File
@@ -11,13 +11,18 @@ import React from "react";
import IntelligenceIAApp from "./modules/intelligence-ia/App";
import FechamentoHgtxApp from "./modules/fechamento-hgtx/App";
const INTELLIGENCE_SCORE_PREFIX = "/intelligence-score";
const FECHAMENTO_LEGACY_PREFIX = "/fechamento-hgtx";
const FECHAMENTO_PREFIX = "/fechamento";
/** Redireciona URLs antigas `/fechamento-hgtx/...` para `/fechamento/...` (mesmo sufixo, query e hash). */
/** Redireciona URLs antigas para `/intelligence-score/...` (mesmo sufixo, query e hash). */
function FechamentoLegacyRedirect() {
const location = useLocation();
const tail = location.pathname.slice(FECHAMENTO_LEGACY_PREFIX.length);
const to = `/fechamento${tail}`;
const fromPrefix = location.pathname.startsWith(FECHAMENTO_LEGACY_PREFIX)
? FECHAMENTO_LEGACY_PREFIX
: FECHAMENTO_PREFIX;
const tail = location.pathname.slice(fromPrefix.length);
const to = `${INTELLIGENCE_SCORE_PREFIX}${tail}`;
return <Navigate to={`${to}${location.search}${location.hash}`} replace />;
}
@@ -44,7 +49,8 @@ const App = () => (
/>
<Route path="/intelligence-ia/*" element={<IntelligenceIAApp />} />
<Route path="/fechamento/*" element={<FechamentoHgtxApp />} />
<Route path="/intelligence-score/*" element={<FechamentoHgtxApp />} />
<Route path="/fechamento/*" element={<FechamentoLegacyRedirect />} />
<Route path="/fechamento-hgtx/*" element={<FechamentoLegacyRedirect />} />
<Route path="/*" element={<Index />} />
+2 -2
View File
@@ -105,7 +105,7 @@ export function UnidadeGate({ children }: UnidadeGateProps) {
<CardContent className="space-y-4 text-center text-muted-foreground">
<p>
O código do estabelecimento não foi enviado pelo ambiente (TransferArea). Abra o módulo
Fechamento HGTX a partir do Codex com o estabelecimento carregado no transfer.
HGTX Intelligence Score a partir do Codex com o estabelecimento carregado no transfer.
</p>
</CardContent>
</Card>
@@ -134,7 +134,7 @@ export function UnidadeGate({ children }: UnidadeGateProps) {
Cadastre o nome da unidade em Configurações (integração com o código atual do transfer).
</p>
<Button asChild>
<Link to="/fechamento/configuracoes#unidade">Ir para Configurações</Link>
<Link to="/intelligence-score/configuracoes#unidade">Ir para Configurações</Link>
</Button>
</>
) : (
+2 -2
View File
@@ -23,7 +23,7 @@ function RequireAdminRoute({ children }: { children: JSX.Element }) {
return children;
}
return <Navigate to="/fechamento/meu-fechamento" replace />;
return <Navigate to="/intelligence-score/meu-fechamento" replace />;
}
function RequireFechamentoDetalheRoute({ children }: { children: JSX.Element }) {
@@ -39,7 +39,7 @@ function RequireFechamentoDetalheRoute({ children }: { children: JSX.Element })
return children;
}
return <Navigate to="/fechamento/meu-fechamento" replace />;
return <Navigate to="/intelligence-score/meu-fechamento" replace />;
}
const FechamentoHgtxApp = () => {
@@ -97,7 +97,7 @@ export function AppSidebar() {
<ClipboardList className="h-5 w-5 text-primary" />
</div>
<div className="min-w-0 animate-fade-in">
<h1 className="truncate text-lg font-semibold text-sidebar-foreground">Fechamento HGTX</h1>
<h1 className="truncate text-lg font-semibold text-sidebar-foreground">HGTX Intelligence Score</h1>
<p className="text-xs text-muted-foreground">{isAdmin ? "Painel Admin" : "Painel Parceiro"}</p>
</div>
</div>
@@ -213,7 +213,7 @@ export default function BancoPontos() {
variant="outline"
className="border-border bg-background text-foreground hover:bg-muted/50 hover:text-foreground"
onClick={() =>
navigate(`/fechamento/banco-pontos/${row.parceiroId}`, {
navigate(`/intelligence-score/banco-pontos/${row.parceiroId}`, {
state: { nomeExibicao: getDisplayNome(row) },
})
}
@@ -154,7 +154,7 @@ export default function BancoPontosExtrato() {
<div className="flex h-full flex-col bg-background pb-16 md:pb-0">
<div className="border-b border-border bg-muted/20 p-3 md:p-6">
<div className="mb-3">
<Button variant="ghost" size="sm" onClick={() => navigate("/fechamento/banco-pontos")}>
<Button variant="ghost" size="sm" onClick={() => navigate("/intelligence-score/banco-pontos")}>
<ArrowLeft className="mr-1 h-4 w-4" />
Voltar ao banco de pontos
</Button>
@@ -275,7 +275,7 @@ export default function BancoPontosExtrato() {
variant="ghost"
className="gap-1 text-foreground hover:bg-zinc-200 hover:text-foreground dark:hover:bg-zinc-700"
onClick={() =>
navigate(`/fechamento/fechamentos/${linha.fechamentoId}`, {
navigate(`/intelligence-score/fechamentos/${linha.fechamentoId}`, {
state: { competenciaId: undefined, status: undefined },
})
}
@@ -36,15 +36,6 @@ function getDisplayNome(row: FechamentoDaCompetenciaItem): string {
return row.parceiroNome;
}
function formatHoras(minutos: number | null): string {
if (!minutos || minutos <= 0) return "0h";
const horas = Math.floor(minutos / 60);
const mins = Math.round(minutos % 60);
if (horas === 0) return `${mins}min`;
if (mins === 0) return `${horas}h`;
return `${horas}h ${mins}min`;
}
function AsanaImportLoadingCard() {
return (
<div
@@ -258,7 +249,7 @@ export default function CompetenciaFechamentos() {
<div className="flex h-full flex-col bg-background pb-16 md:pb-0">
<div className="border-b border-border p-3 md:p-6">
<div className="mb-3 flex items-center gap-2">
<Button variant="ghost" size="sm" onClick={() => navigate("/fechamento")}>
<Button variant="ghost" size="sm" onClick={() => navigate("/intelligence-score")}>
<ArrowLeft className="mr-1 h-4 w-4" />
Voltar
</Button>
@@ -334,7 +325,6 @@ export default function CompetenciaFechamentos() {
<TableHead className="min-w-[100px]">Logo</TableHead>
<TableHead className="min-w-[280px]">Nome</TableHead>
<TableHead className="min-w-[140px]">Pontuação Total</TableHead>
<TableHead className="min-w-[120px]">Horas Total</TableHead>
<TableHead className="min-w-[120px]">Status</TableHead>
<TableHead className="text-center">Ações</TableHead>
</TableRow>
@@ -342,7 +332,7 @@ export default function CompetenciaFechamentos() {
<TableBody>
{loading ? (
<TableRow>
<TableCell colSpan={6} className="py-16">
<TableCell colSpan={5} className="py-16">
<div
className="flex flex-col items-center justify-center gap-4 text-center"
role="status"
@@ -372,7 +362,6 @@ export default function CompetenciaFechamentos() {
</TableCell>
<TableCell className="font-medium">{getDisplayNome(row)}</TableCell>
<TableCell>{row.pontuacaoTotalEntregue}</TableCell>
<TableCell>{formatHoras(row.horasTotal * 60)}</TableCell>
<TableCell>
<Badge
className={
@@ -402,7 +391,7 @@ export default function CompetenciaFechamentos() {
variant="outline"
className="transition-colors hover:bg-muted/50 hover:text-foreground"
onClick={() =>
navigate(`/fechamento/fechamentos/${row.id}`, {
navigate(`/intelligence-score/fechamentos/${row.id}`, {
state: { competenciaId, status: row.status },
})
}
@@ -211,7 +211,7 @@ export default function Configuracoes() {
await fechamentoUnidadesService.createUnidade({ nome, estabelecimentoId: codigo });
toast.success("Unidade cadastrada.");
clearCommanderUnidadeIdCache();
navigate("/fechamento", { replace: true });
navigate("/intelligence-score", { replace: true });
}
} catch (error) {
const message = error instanceof Error ? error.message : "Erro ao salvar unidade.";
@@ -1,9 +1,8 @@
import { useEffect, useMemo, useState } from "react";
import { useEffect, useMemo, useRef, useState } from "react";
import { useLocation, useNavigate, useParams } from "react-router-dom";
import {
ArrowLeft,
CheckCircle2,
Clock3,
ExternalLink,
ListChecks,
Loader2,
@@ -41,23 +40,6 @@ import { fechamentoBancoPontosService } from "@/services/fechamento/bancoPontos"
import { fechamentoCompetenciasService, type CompetenciaItem } from "@/services/fechamento/competencias";
import { fechamentoFechamentosService, type FechamentoTarefaItem } from "@/services/fechamento/fechamentos";
function formatHoras(minutos: number | null): string {
if (!minutos || minutos <= 0) return "0h";
const horas = Math.floor(minutos / 60);
const mins = Math.round(minutos % 60);
if (horas === 0) return `${mins}min`;
if (mins === 0) return `${horas}h`;
return `${horas}h ${mins}min`;
}
function formatHorasResumo(minutos: number): string {
const horas = Math.floor(minutos / 60);
const mins = Math.round(minutos % 60);
if (horas === 0) return `${mins}min`;
if (mins === 0) return `${horas}h`;
return `${horas}h ${mins}min`;
}
function formatPontos(valor: number): string {
return valor.toLocaleString("pt-BR", { minimumFractionDigits: 0, maximumFractionDigits: 4 });
}
@@ -146,10 +128,33 @@ function formatDateTime(value: string | null): string {
});
}
function normalizeTextFilter(value: string): string {
return value.trim().toLocaleLowerCase("pt-BR");
}
function toFilterDate(value: string | null): string {
if (!value) return "";
const isoMatch = value.match(/^\d{4}-\d{2}-\d{2}/);
if (isoMatch) return isoMatch[0];
const parsed = new Date(value);
if (Number.isNaN(parsed.getTime())) return "";
const year = parsed.getFullYear();
const month = String(parsed.getMonth() + 1).padStart(2, "0");
const day = String(parsed.getDate()).padStart(2, "0");
return `${year}-${month}-${day}`;
}
function formatCompetenciaMesAno(item: Pick<CompetenciaItem, "mes" | "ano">): string {
return `${String(item.mes).padStart(2, "0")}/${item.ano}`;
}
function getTipoLancamentoLabel(tipo: string): string {
if (tipo === "bonus") return "Bônus Comercial";
if (tipo === "desconto") return "Desconto Comercial";
return tipo;
}
type FechamentoDetalhesLocationState = {
competenciaId?: string;
status?: "em_aberto" | "fechado";
@@ -206,6 +211,15 @@ export default function FechamentoDetalhes() {
const [edicaoCliente, setEdicaoCliente] = useState("");
const [edicaoTempoMinutos, setEdicaoTempoMinutos] = useState("");
const [edicaoPontuacao, setEdicaoPontuacao] = useState("");
const tableScrollRef = useRef<HTMLDivElement | null>(null);
const stickyScrollRef = useRef<HTMLDivElement | null>(null);
const stickyScrollSpacerRef = useRef<HTMLDivElement | null>(null);
const [showStickyScrollbar, setShowStickyScrollbar] = useState(false);
const [showFilters, setShowFilters] = useState(false);
const [filtroDescricao, setFiltroDescricao] = useState("");
const [filtroTicket, setFiltroTicket] = useState("");
const [filtroCliente, setFiltroCliente] = useState("");
const [filtroDataConclusao, setFiltroDataConclusao] = useState("");
const [competenciaStatus, setCompetenciaStatus] = useState<"em_aberto" | "concluido">("em_aberto");
const isFechado = fechamentoStatus === "fechado";
const isCompetenciaConcluida = competenciaStatus === "concluido";
@@ -215,10 +229,8 @@ export default function FechamentoDetalhes() {
const totais = useMemo(() => {
const aprovadas = tarefas.filter((t) => t.estaRevisada);
const pontos = aprovadas.reduce((acc, t) => acc + Number(t.pontuacao || 0), 0);
const minutos = aprovadas.reduce((acc, t) => acc + Number(t.tempoMinutos || 0), 0);
return {
pontos,
horas: formatHorasResumo(minutos),
aprovadas: aprovadas.length,
};
}, [tarefas]);
@@ -244,6 +256,31 @@ export default function FechamentoDetalhes() {
() => competenciasAbertas.filter((item) => item.id !== competenciaId),
[competenciasAbertas, competenciaId],
);
const hasActiveFilters = Boolean(
filtroDescricao ||
filtroTicket ||
filtroCliente ||
filtroDataConclusao,
);
const tarefasFiltradas = useMemo(() => {
const descricaoFilter = normalizeTextFilter(filtroDescricao);
const ticketFilter = normalizeTextFilter(filtroTicket);
const clienteFilter = normalizeTextFilter(filtroCliente);
return tarefas.filter((tarefa) => {
if (descricaoFilter && !normalizeTextFilter(tarefa.descricao ?? "").includes(descricaoFilter)) return false;
if (ticketFilter && !normalizeTextFilter(tarefa.numeroTicket ?? "").includes(ticketFilter)) return false;
if (clienteFilter && !normalizeTextFilter(tarefa.cliente ?? "").includes(clienteFilter)) return false;
if (filtroDataConclusao && toFilterDate(tarefa.dataConclusao) !== filtroDataConclusao) return false;
return true;
});
}, [
tarefas,
filtroDescricao,
filtroTicket,
filtroCliente,
filtroDataConclusao,
]);
const loadTarefas = async () => {
try {
@@ -344,6 +381,51 @@ export default function FechamentoDetalhes() {
}
}, [isConcluirOpen, parceiroId]);
useEffect(() => {
const main = tableScrollRef.current;
const sticky = stickyScrollRef.current;
if (!main || !sticky) return;
let syncingFromMain = false;
let syncingFromSticky = false;
const syncMetricsAndVisibility = () => {
const spacer = stickyScrollSpacerRef.current;
const canScrollX = main.scrollWidth > main.clientWidth + 1;
if (spacer) spacer.style.width = `${main.scrollWidth}px`;
if (sticky.scrollLeft !== main.scrollLeft) sticky.scrollLeft = main.scrollLeft;
setShowStickyScrollbar(canScrollX);
};
const onMainScroll = () => {
if (syncingFromSticky) return;
syncingFromMain = true;
sticky.scrollLeft = main.scrollLeft;
syncingFromMain = false;
};
const onStickyScroll = () => {
if (syncingFromMain) return;
syncingFromSticky = true;
main.scrollLeft = sticky.scrollLeft;
syncingFromSticky = false;
};
syncMetricsAndVisibility();
main.addEventListener("scroll", onMainScroll, { passive: true });
sticky.addEventListener("scroll", onStickyScroll, { passive: true });
window.addEventListener("resize", syncMetricsAndVisibility);
const resizeObserver = new ResizeObserver(() => syncMetricsAndVisibility());
resizeObserver.observe(main);
return () => {
main.removeEventListener("scroll", onMainScroll);
sticky.removeEventListener("scroll", onStickyScroll);
window.removeEventListener("resize", syncMetricsAndVisibility);
resizeObserver.disconnect();
};
}, [tarefas.length, loading]);
const handleToggleAprovada = async (tarefa: FechamentoTarefaItem, approved: boolean) => {
if (isCompetenciaConcluida) {
toastBloqueioCompetenciaConcluida();
@@ -365,6 +447,13 @@ export default function FechamentoDetalhes() {
);
};
const handleLimparFiltros = () => {
setFiltroDescricao("");
setFiltroTicket("");
setFiltroCliente("");
setFiltroDataConclusao("");
};
const handleToggleTodasAprovadas = async () => {
if (isCompetenciaConcluida) {
toastBloqueioCompetenciaConcluida();
@@ -501,7 +590,7 @@ export default function FechamentoDetalhes() {
});
toast.success(`Fechamento concluído. Banco de pontos: ${formatPontosAte2Casas(data.pontuacaoBanco)}.`);
setFechamentoStatus("fechado");
navigate(`/fechamento/competencias/${data.competenciaId}`);
navigate(`/intelligence-score/competencias/${data.competenciaId}`);
} catch (error) {
const message = error instanceof Error ? error.message : "Erro ao concluir fechamento.";
toast.error(message);
@@ -824,7 +913,7 @@ export default function FechamentoDetalhes() {
</div>
{!loading ? (
<div className="mt-4 grid grid-cols-1 gap-3 sm:grid-cols-2 xl:grid-cols-4">
<div className="mt-4 grid grid-cols-1 gap-3 sm:grid-cols-2 xl:grid-cols-3">
{isCompetenciaConcluida ? (
<div className="sm:col-span-2 xl:col-span-4 rounded-lg border border-amber-300 bg-amber-50 p-3 text-sm text-amber-900">
Competência concluída. Reabra a competência para editar este fechamento.
@@ -857,15 +946,6 @@ export default function FechamentoDetalhes() {
<CardTitle className="text-3xl">{formatPontos(totais.pontos)}</CardTitle>
</CardHeader>
</Card>
<Card className="border-border/70 bg-card shadow-sm transition hover:shadow-md">
<CardHeader className="space-y-2 p-4">
<div className="flex items-start justify-between">
<CardDescription className="text-[11px] uppercase tracking-wide">Horas aprovadas</CardDescription>
<Clock3 className="h-4 w-4 text-muted-foreground" />
</div>
<CardTitle className="text-3xl">{totais.horas}</CardTitle>
</CardHeader>
</Card>
</div>
) : null}
</div>
@@ -881,7 +961,20 @@ export default function FechamentoDetalhes() {
) : (
<div className="space-y-3">
{!loading ? (
<div className="flex justify-end">
<div className="space-y-3">
<div className="flex flex-wrap items-center justify-end gap-2">
<Button type="button" size="sm" variant="outline" onClick={() => setShowFilters((prev) => !prev)}>
{showFilters ? "Ocultar filtros" : "Exibir filtros"}
</Button>
<Button
type="button"
size="sm"
variant="outline"
onClick={handleLimparFiltros}
disabled={!hasActiveFilters}
>
Limpar filtros
</Button>
<Button
type="button"
size="sm"
@@ -897,8 +990,49 @@ export default function FechamentoDetalhes() {
{todasTarefasRevisadas ? "Desmarcar todas" : "Marcar todas"}
</Button>
</div>
{showFilters ? (
<div className="grid grid-cols-1 gap-3 rounded-lg border bg-muted/20 p-3 md:grid-cols-2 xl:grid-cols-4">
<div className="space-y-1">
<Label htmlFor="filtro-descricao">Descrição</Label>
<Input
id="filtro-descricao"
value={filtroDescricao}
onChange={(e) => setFiltroDescricao(e.target.value)}
placeholder="Digite parte da descrição"
/>
</div>
<div className="space-y-1">
<Label htmlFor="filtro-ticket">Ticket</Label>
<Input
id="filtro-ticket"
value={filtroTicket}
onChange={(e) => setFiltroTicket(e.target.value)}
placeholder="Ex.: TKT-1234"
/>
</div>
<div className="space-y-1">
<Label htmlFor="filtro-cliente">Cliente</Label>
<Input
id="filtro-cliente"
value={filtroCliente}
onChange={(e) => setFiltroCliente(e.target.value)}
placeholder="Nome do cliente"
/>
</div>
<div className="space-y-1">
<Label htmlFor="filtro-data-conclusao">Data de conclusão</Label>
<Input
id="filtro-data-conclusao"
type="date"
value={filtroDataConclusao}
onChange={(e) => setFiltroDataConclusao(e.target.value)}
/>
</div>
</div>
) : null}
<div className="overflow-x-auto rounded-lg border">
</div>
) : null}
<div ref={tableScrollRef} className="overflow-x-auto rounded-lg border">
<Table>
<TableHeader>
<TableRow>
@@ -911,7 +1045,6 @@ export default function FechamentoDetalhes() {
<TableHead className="min-w-[140px]">Data vencimento</TableHead>
<TableHead className="min-w-[170px]">Data conclusão</TableHead>
<TableHead className="min-w-[240px]">Etiquetas</TableHead>
<TableHead className="min-w-[120px]">Horas</TableHead>
<TableHead className="min-w-[120px]">Pontuação</TableHead>
<TableHead className="min-w-[140px] text-right">Ações</TableHead>
</TableRow>
@@ -919,12 +1052,18 @@ export default function FechamentoDetalhes() {
<TableBody>
{loading ? (
<TableRow>
<TableCell colSpan={12} className="py-8 text-center text-muted-foreground">
<TableCell colSpan={11} className="py-8 text-center text-muted-foreground">
Carregando tarefas...
</TableCell>
</TableRow>
) : tarefasFiltradas.length === 0 ? (
<TableRow>
<TableCell colSpan={11} className="py-8 text-center text-muted-foreground">
Nenhuma tarefa encontrada com os filtros aplicados.
</TableCell>
</TableRow>
) : (
tarefas.map((tarefa) => (
tarefasFiltradas.map((tarefa) => (
<TableRow key={tarefa.id}>
<TableCell>
<div className="flex items-center gap-2">
@@ -938,7 +1077,7 @@ export default function FechamentoDetalhes() {
<TableCell>{tarefa.numeroTicket || "—"}</TableCell>
<TableCell className="font-medium">{tarefa.descricao}</TableCell>
<TableCell>{tarefa.cliente || "—"}</TableCell>
<TableCell>{tarefa.tipo}</TableCell>
<TableCell>{getTipoLancamentoLabel(tarefa.tipo)}</TableCell>
<TableCell>{formatDateOnly(tarefa.dataInicio)}</TableCell>
<TableCell>{formatDateOnly(tarefa.dataVencimento)}</TableCell>
<TableCell>{formatDateTime(tarefa.dataConclusao)}</TableCell>
@@ -955,7 +1094,6 @@ export default function FechamentoDetalhes() {
"—"
)}
</TableCell>
<TableCell>{formatHoras(tarefa.tempoMinutos)}</TableCell>
<TableCell>{Number(tarefa.pontuacao || 0)}</TableCell>
<TableCell className="text-right">
<div className="flex items-center justify-end gap-1">
@@ -1014,6 +1152,13 @@ export default function FechamentoDetalhes() {
</TableBody>
</Table>
</div>
{showStickyScrollbar ? (
<div className="fixed bottom-2 left-2 right-2 z-50 rounded-md border bg-background/95 shadow-md backdrop-blur supports-[backdrop-filter]:bg-background/80">
<div ref={stickyScrollRef} className="overflow-x-auto">
<div ref={stickyScrollSpacerRef} className="h-4 min-w-full" />
</div>
</div>
) : null}
</div>
)}
</div>
@@ -1038,8 +1183,8 @@ export default function FechamentoDetalhes() {
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectItem value="bonus">Bonificação</SelectItem>
<SelectItem value="desconto">Desconto</SelectItem>
<SelectItem value="bonus">{getTipoLancamentoLabel("bonus")}</SelectItem>
<SelectItem value="desconto">{getTipoLancamentoLabel("desconto")}</SelectItem>
</SelectContent>
</Select>
</div>
@@ -258,7 +258,7 @@ export default function Fechamentos() {
<Button
size="sm"
variant="outline"
onClick={() => navigate(`/fechamento/competencias/${competencia.id}`)}
onClick={() => navigate(`/intelligence-score/competencias/${competencia.id}`)}
>
<ExternalLink className="mr-2 h-4 w-4" />
Acessar
@@ -159,7 +159,7 @@ export default function MeuFechamento() {
<ListChecks className="h-5 w-5 md:h-6 md:w-6" />
Meu Fechamento
</h1>
<Button onClick={() => navigate("/fechamento/meu-fechamento/banco-pontos")} className="gap-2">
<Button onClick={() => navigate("/intelligence-score/meu-fechamento/banco-pontos")} className="gap-2">
<Landmark className="h-4 w-4" />
Banco de Pontos
</Button>
@@ -266,7 +266,7 @@ export default function MeuFechamento() {
variant="outline"
disabled={!item.fechamento || item.fechamento.status !== "fechado"}
onClick={() =>
navigate(`/fechamento/fechamentos/${item.fechamento?.id}`, {
navigate(`/intelligence-score/fechamentos/${item.fechamento?.id}`, {
state: {
competenciaId: item.competenciaId,
status: item.fechamento?.status,
@@ -114,7 +114,7 @@ export default function MeuFechamentoBancoPontos() {
if (semVinculo) {
return (
<div className="p-3 md:p-6">
<Button variant="ghost" size="sm" onClick={() => navigate("/fechamento/meu-fechamento")}>
<Button variant="ghost" size="sm" onClick={() => navigate("/intelligence-score/meu-fechamento")}>
<ArrowLeft className="mr-1 h-4 w-4" />
Voltar
</Button>
@@ -133,7 +133,7 @@ export default function MeuFechamentoBancoPontos() {
<div className="flex h-full flex-col bg-background pb-16 md:pb-0">
<div className="border-b border-border bg-muted/20 p-3 md:p-6">
<div className="mb-3">
<Button variant="ghost" size="sm" onClick={() => navigate("/fechamento/meu-fechamento")}>
<Button variant="ghost" size="sm" onClick={() => navigate("/intelligence-score/meu-fechamento")}>
<ArrowLeft className="mr-1 h-4 w-4" />
Voltar ao meu fechamento
</Button>
@@ -16,7 +16,7 @@ export default function NotFound() {
<div className="text-center">
<h1 className="mb-3 text-4xl font-bold">404</h1>
<p className="mb-4 text-muted-foreground">Rota não encontrada neste módulo.</p>
<Link to="/fechamento" className="text-primary underline hover:text-primary/90">
<Link to="/intelligence-score" className="text-primary underline hover:text-primary/90">
Voltar para Fechamentos
</Link>
</div>