Full admin console revamp#1
Merged
Merged
Conversation
- Overview: 6 KPIs, 30-day activity area chart, most-active leaderboard, recent activity feed, quick actions - Members: search + filter (all/active/pending) + sort (recent/name/onboarding/volume), onboarding progress bars, rich member detail modal (weekly volume, body weight, big-three charts, assigned plans, PRs, recent sessions, per-member actions) - Plans: card grid with focus + exercise/warm-up summary, structured create/edit, duplicate, and assign-to-members modal (select or all) - Insights: member comparison (big-three bars + weekly volume trend lines) - Backend: enriched admin stats (sessions/volume/active/onboarding/plans), new /admin/activity endpoint, richer user detail (weekly totals, body weight, assigned plans)
There was a problem hiding this comment.
Pull request overview
This PR replaces the existing admin panel with a more full-featured “Admin Console”, adding org-level KPIs/activity visualizations, richer member drill-down, improved plan management, and an insights comparison view, backed by new/enriched admin API responses.
Changes:
- Adds a new admin activity endpoint (
GET /admin/activity) and enriches admin stats/users payloads to support new UI surfaces. - Reworks the admin page into new tabs (Overview/Members/Plans/Insights) with charts, leaderboards, filtering/sorting, and modal-based workflows.
- Introduces new admin modals for per-member detail drill-down and plan assignment to selected members.
Reviewed changes
Copilot reviewed 7 out of 8 changed files in this pull request and generated 9 comments.
Show a summary per file
| File | Description |
|---|---|
| frontend/src/lib/api.ts | Adds adminApi.getActivity() to call the new backend endpoint. |
| frontend/src/components/admin/member-detail-modal.tsx | New member detail modal (KPIs, charts, assigned plans, member actions). |
| frontend/src/components/admin/assign-plan-modal.tsx | New modal to assign a plan to all or selected members. |
| frontend/src/app/admin/page.tsx | Major UI revamp of admin console tabs, activity views, filtering/sorting, and modals. |
| frontend/public/sw.js | Updates generated service worker precache manifest/assets. |
| backend/src/admin/admin.service.ts | Enriches admin endpoints and adds org-wide activity aggregation logic. |
| backend/src/admin/admin.module.ts | Wires in Exercises/BodyWeight modules for new admin data needs. |
| backend/src/admin/admin.controller.ts | Adds GET /admin/activity route under existing admin guards. |
Files not reviewed (1)
- frontend/public/sw.js: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| const act = async (key: string, fn: () => Promise<any>, reload = false) => { | ||
| setBusy(key); | ||
| try { await fn(); if (reload) await load(); onChanged(); } | ||
| catch (e) { console.error(e); } |
Comment on lines
+49
to
+50
| await act('delete', () => adminApi.deleteUser(userId)); | ||
| onClose(); |
|
|
||
| const assign = async () => { | ||
| if (!assignPlanId) return; | ||
| await act('assign', () => adminApi.assignPlan(parseInt(assignPlanId), userId), true); |
| onClose(); | ||
| }; | ||
|
|
||
| const weekly = (d?.weeklyTotals || []).map((v: number, i: number, a: number[]) => ({ week: `W${i - a.length + 1 === 0 ? '' : ''}${i + 1}`, volume: Math.round(v) })); |
| {users.length === 0 && <p className="text-sm text-muted-foreground text-center py-6">No members to assign.</p>} | ||
| </div> | ||
|
|
||
| {done && <p className="text-sm text-success text-center">{done}</p>} |
Comment on lines
+154
to
+157
| return Array.from({ length: len }, (_, i) => { | ||
| const row: any = { week: `W${i + 1}` }; | ||
| compareData.forEach((u) => { row[u.name] = Math.round(u.weeklyTotals?.[i] || 0); }); | ||
| return row; |
Comment on lines
+42
to
+45
| const sessions = await this.workoutsService.getUserSessions(u.id); // sorted DESC | ||
| const completed = sessions.filter((s) => s.completedAt); | ||
| const totalVolume = completed.reduce((sum, s) => sum + volumeOf(s.sets), 0); | ||
| return { |
Comment on lines
+147
to
+151
| for (const u of users) { | ||
| onboardingSum += await this.usersService.computeOnboardingPercent(u.id); | ||
| const sessions = await this.workoutsService.getUserSessions(u.id); | ||
| const completed = sessions.filter((s) => s.completedAt); | ||
| totalSessions += completed.length; |
Comment on lines
+184
to
+196
| for (const u of users) { | ||
| const sessions = await this.workoutsService.getUserSessions(u.id); | ||
| for (const s of sessions.filter((x) => x.completedAt)) { | ||
| all.push({ | ||
| userId: u.id, | ||
| name: u.name || u.email, | ||
| workoutType: s.workoutType, | ||
| startedAt: s.startedAt, | ||
| volume: Math.round(volumeOf(s.sets)), | ||
| sets: (s.sets || []).length, | ||
| }); | ||
| } | ||
| } |
Owner
Author
|
@ Added: Estimation tab + suggestion data collectionPer request — the estimation algorithm is unchanged; this adds evaluation + data collection so tuning can be decided from real data later.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
@
Overview
A complete re-imagining of the admin panel — from a basic 4-tab CRUD screen into a proper Admin Console with org-wide insight, per-member drill-down, and richer plan management. Admins remain confined to admin-only surfaces (unchanged).
Frontend
Overview tab
Members tab
Plans tab
Insights tab
Backend
GET /admin/stats: sessions, volume (week + all-time), active-this-week, avg onboarding, plan countGET /admin/activity: per-day session counts, recent feed, most-active leaderboardGET /admin/users(session count, total volume, last active) andGET /admin/users/:id(weekly totals, body weight, assigned plans)AdminModulenow wires inExercisesModule+BodyWeightModuleTesting
tsc --noEmitclean (frontend + backend)next buildandnest buildboth succeed🤖 Generated with Claude Code
@