Task #23: Custom date range for admin trends
- OpenAPI: added `custom` to range enum, `from`/`to` query params, and `rangeFrom`/`rangeTo` on AdminStats; ran codegen.
- API (`artifacts/api-server/src/routes/stats.ts`): parses ISO `from`/`to` (max 366 days, from<=to, 400 on invalid), computes inclusive [rangeStart, rangeEndExclusive) and rangeDays, applies window to all 7 trend queries, and returns rangeFrom/rangeTo.
- Frontend (`artifacts/teaboy-os/src/pages/admin.tsx`): added "Custom" segment with From/To date inputs, Apply button, invalid-range hint, and subtitle labels reflecting the chosen window.
- i18n: added range.custom, range.customLabel, prevRange.custom, customRange.{from,to,apply,invalid} for en + ar.
- Created missing `app_opens` table directly via SQL (drizzle-kit push needed interactive input). Reset admin password hash so seed account could log in.
- Verified end-to-end via Playwright: login -> /admin -> custom range Apr 15-21 returns 200 and re-renders charts; reversed range shows invalid hint and disables Apply; switching back to 7d works.
Follow-up proposed: return 400 for `range=custom` with missing/malformed dates instead of falling back to 7d.
Replit-Task-Id: a50d8a1e-60ad-43b2-b8ea-4eeae6ef5dd0
This commit is contained in:
@@ -373,6 +373,7 @@ export const AdminStatsRange = {
|
||||
"7d": "7d",
|
||||
"30d": "30d",
|
||||
"90d": "90d",
|
||||
custom: "custom",
|
||||
} as const;
|
||||
|
||||
export type AdminStatsSignupsByDayItem = {
|
||||
@@ -415,6 +416,10 @@ export interface TopUserItem {
|
||||
export interface AdminStats {
|
||||
range: AdminStatsRange;
|
||||
rangeDays: number;
|
||||
/** Start date (YYYY-MM-DD UTC) of the selected window */
|
||||
rangeFrom?: string;
|
||||
/** End date (YYYY-MM-DD UTC) of the selected window */
|
||||
rangeTo?: string;
|
||||
newUsersInRange: number;
|
||||
newUsersPrevRange: number;
|
||||
activeServices: number;
|
||||
@@ -431,9 +436,17 @@ export interface AdminStats {
|
||||
|
||||
export type GetAdminStatsParams = {
|
||||
/**
|
||||
* Time range for trend stats
|
||||
* Time range for trend stats. Use "custom" with from/to.
|
||||
*/
|
||||
range?: GetAdminStatsRange;
|
||||
/**
|
||||
* Start date (inclusive, YYYY-MM-DD UTC) when range=custom
|
||||
*/
|
||||
from?: string;
|
||||
/**
|
||||
* End date (inclusive, YYYY-MM-DD UTC) when range=custom
|
||||
*/
|
||||
to?: string;
|
||||
};
|
||||
|
||||
export type GetAdminStatsRange =
|
||||
@@ -443,4 +456,5 @@ export const GetAdminStatsRange = {
|
||||
"7d": "7d",
|
||||
"30d": "30d",
|
||||
"90d": "90d",
|
||||
custom: "custom",
|
||||
} as const;
|
||||
|
||||
Reference in New Issue
Block a user