diff --git a/src/app/(app)/painel/page.tsx b/src/app/(app)/painel/page.tsx index e44d118..b2fcfd9 100644 --- a/src/app/(app)/painel/page.tsx +++ b/src/app/(app)/painel/page.tsx @@ -10,9 +10,10 @@ import { buildDayMatrix } from "@/lib/report-days"; import { toSearchParams } from "@/lib/schemas/report"; import { formatHms } from "@/lib/time"; import { getTenant } from "@/server/get-tenant"; +import { loadCatalog } from "../views"; import { ReportChartsSection } from "../relatorios/charts"; import { loadReport } from "../relatorios/load-report"; -import { PanelFilters } from "./panel-filters"; +import { ReportFilters } from "../relatorios/report-filters"; export const metadata: Metadata = { title: "Painel" }; @@ -26,15 +27,15 @@ export default function PanelPage({ searchParams }: PageProps<"/painel">) { async function Panel({ searchParams }: Pick, "searchParams">) { const { ctx, tenant } = await getTenant(); - const report = await loadReport(tenant, ctx, await searchParams); + const [catalog, report] = await Promise.all([loadCatalog(tenant), loadReport(tenant, ctx, await searchParams)]); const { query, period, isAdmin } = report; - const summary = summarize(report.rows, "descricao"); + const summary = summarize(report.rows, query.agrupar); const matrix = buildDayMatrix(report.rows, period, ctx.timezone, { includePeople: false }); const charts = buildCharts(summary, matrix); const h = buildHighlights(report.rows, summary, ctx.timezone); - // The same period and people, opened in the full report (filters by client/project live there). - const reportHref = `/relatorios?${toSearchParams({ ...query, cliente: undefined, projeto: undefined, tarefa: undefined, agrupar: undefined })}`; + // The same filters, opened in the full report. + const reportHref = `/relatorios?${toSearchParams(query)}`; return (
@@ -51,7 +52,7 @@ async function Panel({ searchParams }: Pick, "searchParams" - + {report.periodError && (

@@ -80,7 +81,7 @@ async function Panel({ searchParams }: Pick, "searchParams" /> - + )}

diff --git a/src/app/(app)/painel/panel-filters.tsx b/src/app/(app)/painel/panel-filters.tsx deleted file mode 100644 index cdf053d..0000000 --- a/src/app/(app)/painel/panel-filters.tsx +++ /dev/null @@ -1,92 +0,0 @@ -"use client"; - -import Link from "next/link"; -import { useState } from "react"; -import { Button } from "@/components/ui/button"; -import { Input } from "@/components/ui/input"; -import { PERIOD_LABELS, PERIOD_PRESETS, type PeriodPreset } from "@/lib/report-period"; -import type { ReportQuery } from "@/lib/schemas/report"; -import type { PersonOption } from "../relatorios/report-filters"; -import { selectClass } from "../project-task-fields"; - -/** - * Dashboard filters: period and (for admins) people only. A plain GET form like the report's, so the URL - * stays the source of truth. Choosing a preset applies at once; a custom range needs its dates, so it has a button. - */ -export function PanelFilters({ people, query }: { people: PersonOption[] | null; query: ReportQuery }) { - const [period, setPeriod] = useState(query.periodo); - const [selected, setSelected] = useState(query.pessoas); - - return ( -
- - - {period === "custom" && ( - <> - - - - )} - - {people && ( -
- - {selected.length === 0 ? "Todas as pessoas" : `${selected.length} ${selected.length === 1 ? "pessoa" : "pessoas"}`} - -
- Pessoas - {people.map((p) => ( - - ))} - {selected.length > 0 && ( - - )} -
-
- )} - - {(period === "custom" || people) && } - -
- ); -} diff --git a/src/app/(app)/relatorios/page.tsx b/src/app/(app)/relatorios/page.tsx index f4c231d..ef7495a 100644 --- a/src/app/(app)/relatorios/page.tsx +++ b/src/app/(app)/relatorios/page.tsx @@ -49,7 +49,7 @@ async function Reports({ searchParams }: Pick, "searchP for (const id of query.pessoas) params.append("pessoas", id); return `/relatorios?${params}`; })(); - const panelHref = `/painel?${toSearchParams({ ...query, cliente: undefined, projeto: undefined, tarefa: undefined, agrupar: undefined })}`; + const panelHref = `/painel?${toSearchParams(query)}`; const summary = summarize(result.rows, query.agrupar); const dayMatrix = buildDayMatrix(result.rows, period, tz, { includePeople: isAdmin }); const showPerson = isAdmin; diff --git a/src/app/(app)/relatorios/report-filters.tsx b/src/app/(app)/relatorios/report-filters.tsx index 82a2fe5..976647a 100644 --- a/src/app/(app)/relatorios/report-filters.tsx +++ b/src/app/(app)/relatorios/report-filters.tsx @@ -20,11 +20,16 @@ export function ReportFilters({ catalog, people, query, + action = "/relatorios", + submitLabel = "Gerar relatório", }: { catalog: CatalogView; /** Null for members: they only ever see their own hours, so there is nothing to pick. */ people: PersonOption[] | null; query: ReportQuery; + /** Page the form submits to; the dashboard reuses these filters. */ + action?: "/relatorios" | "/painel"; + submitLabel?: string; }) { const [period, setPeriod] = useState(query.periodo); const [clientId, setClientId] = useState(query.cliente ?? ""); @@ -37,7 +42,7 @@ export function ReportFilters({ const tasks = catalog.tasks.filter((t) => t.projectId === projectId); return ( -
+