Show top apps and most-active users on the admin dashboard (Task #21)

Added two leaderboard panels to the admin dashboard that surface which
apps are most popular and which users drive the most activity in the
selected time range.

Backend (artifacts/api-server/src/routes/stats.ts):
- Extended GET /api/stats/admin to also return:
  - topApps: top 5 apps by app_opens count, with id, slug, names,
    iconName, color, count
  - mostActiveUsers: top 5 users by app_opens count, with id, username,
    displayNames, avatarUrl, count
- Both lists honor the existing `range` query param (7d/30d/90d) so
  they stay in sync with the trend charts. Task wording said "last 7
  days" because 7d is the default; using the selected range is a small
  intentional improvement that matches the rest of the dashboard.

API spec (lib/api-spec/openapi.yaml):
- Added TopAppItem and TopUserItem schemas.
- Added topApps and mostActiveUsers to AdminStats and made them
  required. Regenerated api-client-react and api-zod via codegen.

Frontend (artifacts/teaboy-os/src/pages/admin.tsx):
- Added two new panels to DashboardSection rendered in a 2-column grid
  between the trend charts and the recent activity card.
- Each row shows rank, color/initial, name (i18n), count, and a
  proportional progress bar. Empty state when no activity yet.

i18n (artifacts/teaboy-os/src/locales/{ar,en}.json):
- Added admin.dashboard.topApps, mostActiveUsers, *Subtitle,
  leaderboardEmpty, openCount keys.

Verified with end-to-end test: admin login, dashboard renders both
panels with seeded data, range switch updates subtitles to "Last 30
days".

Replit-Task-Id: c7b6aa4b-9242-443b-9802-a39ab0bc9547
This commit is contained in:
riyadhafraa
2026-04-21 06:11:28 +00:00
parent 284cb751ed
commit 94a361032e
8 changed files with 301 additions and 2 deletions
+56
View File
@@ -1607,6 +1607,14 @@ components:
- count
servicesCreatedInRange:
type: integer
topApps:
type: array
items:
$ref: "#/components/schemas/TopAppItem"
mostActiveUsers:
type: array
items:
$ref: "#/components/schemas/TopUserItem"
required:
- range
- rangeDays
@@ -1620,3 +1628,51 @@ components:
- appOpensPrevRange
- servicesCreatedByDay
- servicesCreatedInRange
- topApps
- mostActiveUsers
TopAppItem:
type: object
properties:
appId:
type: integer
slug:
type: string
nameAr:
type: string
nameEn:
type: string
iconName:
type: string
color:
type: string
count:
type: integer
required:
- appId
- slug
- nameAr
- nameEn
- iconName
- color
- count
TopUserItem:
type: object
properties:
userId:
type: integer
username:
type: string
displayNameAr:
type: ["string", "null"]
displayNameEn:
type: ["string", "null"]
avatarUrl:
type: ["string", "null"]
count:
type: integer
required:
- userId
- username
- count