feat(admin-dashboard): add usage dashboard and improve admin insights#48
Merged
KerwinTsaiii merged 9 commits intodevelopfrom Apr 1, 2026
Merged
feat(admin-dashboard): add usage dashboard and improve admin insights#48KerwinTsaiii merged 9 commits intodevelopfrom
KerwinTsaiii merged 9 commits intodevelopfrom
Conversation
- Add Dashboard page to Admin UI with Recharts line/pie charts and Bootstrap table showing daily usage, resource distribution, and top users ranking - Add Tailwind v4 with tw: prefix to Admin UI for modern card layouts without conflicting with Bootstrap 5 - Add NavBar component shared across Users/Groups/Dashboard pages - Add shared TypeScript types and API helpers for stats endpoints - Add three stats API handlers: overview, usage time series, distribution breakdown - Decouple UsageSession writes from quota system: sessions are now always recorded regardless of quota_enabled, so all deployments get dashboard data by default
- New Dashboard page: date range picker, usage trend chart (daily/weekly), course usage ranking with avg session duration, top users table - Active Now panel: SSE-based live feed of running sessions (5s refresh) - NavBar: unified tab navigation across Users/Groups/Dashboard pages; removed redundant 'Manage Groups' / 'Back to Users' buttons - stats_handlers: add StatsActiveSSEHandler, avg_minutes in distribution, ActiveSession type; remove redundant REST active endpoint - spawner stop(): fallback session recovery when usage_session_id lost after Hub restart (finds active DB session by username) - dark mode: use Bootstrap semantic classes instead of Tailwind dark variant
…dless of quota_enabled
…ion times - Backend StatsHourlyHandler accepts tz_offset (minutes ahead of UTC) and applies SQLite datetime offset before extracting hour, so the distribution reflects the viewer's local time instead of server UTC - Frontend getHourlyDistribution sends tz_offset derived from new Date().getTimezoneOffset() (negated to get offset from UTC) - Active session start_time is now parsed as UTC and displayed in the browser's local timezone using toLocaleString()
- store accelerator display labels alongside session data so stats APIs surface both course and accelerator names - extend shared stats types to expose `accelerator_display` - update admin dashboard tables and user detail modal to render friendly course + accelerator labels with fallbacks The change ensures admins always see which course and accelerator a user is consuming, even while quota tracking still keys sessions by accelerator.
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.
Summary
Add an Admin Usage Dashboard to provide visibility into platform activity, sessions, and course usage.
The dashboard aggregates real-time and historical metrics to help administrators monitor system usage and identify potential issues.
Key capabilities include:
Features
Improvements
QuotaManagerso session tracking works even when quotas are disabledTest plan
Jira: AUPPM-16