diff --git a/src/app/portfolio/[slug]/(portfolio)/reporting/ReportingClientArea.tsx b/src/app/portfolio/[slug]/(portfolio)/reporting/ReportingClientArea.tsx index ae2154ce..7eda7231 100644 --- a/src/app/portfolio/[slug]/(portfolio)/reporting/ReportingClientArea.tsx +++ b/src/app/portfolio/[slug]/(portfolio)/reporting/ReportingClientArea.tsx @@ -97,6 +97,19 @@ export function ReportingClientArea({ function openDrill(t: DrillTarget) { setDrill(t); setDrillPage(1); + // Bring the shelf into view so a click below the fold doesn't look inert. + // Done in the handler (not an effect) per project convention. + if (typeof window !== "undefined") { + const reduce = window.matchMedia( + "(prefers-reduced-motion: reduce)", + ).matches; + requestAnimationFrame(() => + document.getElementById("reporting-drill-shelf")?.scrollIntoView({ + behavior: reduce ? "auto" : "smooth", + block: "nearest", + }), + ); + } } // ── KPI band ─────────────────────────────────────────────────────────── diff --git a/src/app/portfolio/[slug]/(portfolio)/reporting/compare/CompareClientArea.tsx b/src/app/portfolio/[slug]/(portfolio)/reporting/compare/CompareClientArea.tsx index 03b2f41e..8890ba7e 100644 --- a/src/app/portfolio/[slug]/(portfolio)/reporting/compare/CompareClientArea.tsx +++ b/src/app/portfolio/[slug]/(portfolio)/reporting/compare/CompareClientArea.tsx @@ -2,6 +2,12 @@ import { useState } from "react"; import { useQueries } from "@tanstack/react-query"; +import { X } from "lucide-react"; +import { + Popover, + PopoverContent, + PopoverTrigger, +} from "@/app/shadcn_components/ui/popover"; import { sapToEpc } from "@/app/utils"; import { pickBestIndex, countBelowBand } from "@/lib/reporting/model"; import { EpcChip, moneyFull } from "../components/primitives"; @@ -138,9 +144,24 @@ export function CompareClientArea({ scenarios: ScenarioMeta[]; baseline: Baseline; }) { - // Up to four columns stay readable at desk widths. - const [selected] = useState(() => scenarios.slice(0, 4).map((s) => s.id)); - const columns = scenarios.filter((s) => selected.includes(s.id)); + // Up to four columns stay readable at desk widths; the user picks which. + const MAX_COLUMNS = 4; + const [selected, setSelected] = useState(() => + scenarios.slice(0, MAX_COLUMNS).map((s) => s.id), + ); + // Column order follows selection order, not the scenario list order. + const columns = selected + .map((id) => scenarios.find((s) => s.id === id)) + .filter((s): s is ScenarioMeta => Boolean(s)); + const available = scenarios.filter((s) => !selected.includes(s.id)); + const canAdd = selected.length < MAX_COLUMNS && available.length > 0; + + const addColumn = (id: number) => + setSelected((ids) => + ids.length < MAX_COLUMNS && !ids.includes(id) ? [...ids, id] : ids, + ); + const removeColumn = (id: number) => + setSelected((ids) => (ids.length > 1 ? ids.filter((x) => x !== id) : ids)); const results = useQueries({ queries: columns.map((s) => ({ @@ -171,12 +192,54 @@ export function CompareClientArea({ Compare scenarios - - ← Back to reporting - +
+ All scenarios are already shown. +
+ )} +