From b5d90d3c26a68189985f6c63e5a907a39e7cb0c1 Mon Sep 17 00:00:00 2001 From: Matt Date: Wed, 11 Feb 2026 19:08:04 +0100 Subject: [PATCH] Add project reports section and fix mobile overflow issues - Add project-wide reporting table with scope selector (all rounds / per round) - Fix horizontal overflow on mobile (body, admin sidebar, logo truncation) - Make members header and reports tabs responsive with flex-wrap Co-Authored-By: Claude Opus 4.6 --- src/app/(admin)/admin/reports/page.tsx | 118 +++++++++++++++++++++-- src/app/globals.css | 2 +- src/components/admin/members-content.tsx | 6 +- src/components/layouts/admin-sidebar.tsx | 4 +- src/components/shared/logo.tsx | 4 +- 5 files changed, 116 insertions(+), 18 deletions(-) diff --git a/src/app/(admin)/admin/reports/page.tsx b/src/app/(admin)/admin/reports/page.tsx index fff6eb4..a2cb70f 100644 --- a/src/app/(admin)/admin/reports/page.tsx +++ b/src/app/(admin)/admin/reports/page.tsx @@ -65,6 +65,22 @@ function ReportsOverview() { // Flatten rounds from all programs const rounds = programs?.flatMap(p => p.rounds.map(r => ({ ...r, programId: p.id, programName: `${p.year} Edition` }))) || [] + // Project reporting scope (default: latest program, all rounds) + const [selectedValue, setSelectedValue] = useState(null) + + if (programs?.length && !selectedValue) { + setSelectedValue(`all:${programs[0].id}`) + } + + const scopeInput = parseSelection(selectedValue) + const hasScope = !!scopeInput.roundId || !!scopeInput.programId + + const { data: projectRankings, isLoading: projectsLoading } = + trpc.analytics.getProjectRankings.useQuery( + { ...scopeInput, limit: 5000 }, + { enabled: hasScope } + ) + if (isLoading || statsLoading) { return (
@@ -203,17 +219,101 @@ function ReportsOverview() { )} - {/* Rounds Table */} + {/* Project Reports (default: all projects, filterable by round) */}
- +
- Round Reports + Project Reports
- View progress and export data for each round + Project-wide reporting across all projects — optionally filter to a specific round + +
+ + {/* Scope selector */} +
+ Scope: + +
+ + {projectsLoading ? ( + + ) : projectRankings?.length ? ( +
+ + + + Project + Team + Avg + Evals + Status + + + + {projectRankings.map((p) => ( + + + + {p.title} + + + + {p.teamName || '-'} + + + {p.averageScore === null ? '-' : p.averageScore.toFixed(2)} + + {p.evaluationCount} + + {p.status} + + + ))} + +
+
+ ) : ( +
+ +

+ No project report data available for the selected scope yet. +

+
+ )} +
+
+ + {/* Round exports (still available) */} + + + +
+ +
+ Round Exports +
+ + Download round-level evaluations and results
@@ -221,7 +321,7 @@ function ReportsOverview() {

- No rounds created yet. Round-specific reports will appear here once rounds are set up. + No rounds created yet.

) : ( @@ -230,7 +330,6 @@ function ReportsOverview() { Round Program - Projects Status Export @@ -249,7 +348,6 @@ function ReportsOverview() {
{round.programName} - - -
+