feat: Add admin vehicle management and profile vehicles display (refs #11)
All checks were successful
Deploy to Staging / Build Images (pull_request) Successful in 4m34s
Deploy to Staging / Deploy to Staging (pull_request) Successful in 37s
Deploy to Staging / Verify Staging (pull_request) Successful in 6s
Deploy to Staging / Notify Staging Ready (pull_request) Successful in 6s
Deploy to Staging / Notify Staging Failure (pull_request) Has been skipped

- Add GET /api/admin/stats endpoint for Total Vehicles widget
- Add GET /api/admin/users/:auth0Sub/vehicles endpoint for user vehicle list
- Update AdminUsersPage with Total Vehicles stat and expandable vehicle rows
- Add My Vehicles section to SettingsPage (desktop) and MobileSettingsScreen
- Update AdminUsersMobileScreen with stats header and vehicle expansion
- Add defense-in-depth admin checks and error handling
- Update admin README documentation

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Eric Gullickson
2026-01-04 13:18:38 -06:00
parent 2ec208e25a
commit 4fc5b391e1
10 changed files with 639 additions and 67 deletions

View File

@@ -56,6 +56,23 @@ export interface AuditLogsResponse {
total: number;
}
// Admin stats response
export interface AdminStatsResponse {
totalVehicles: number;
totalUsers: number;
}
// User vehicle (admin view)
export interface AdminUserVehicle {
year: number;
make: string;
model: string;
}
export interface AdminUserVehiclesResponse {
vehicles: AdminUserVehicle[];
}
// Admin access verification
export const adminApi = {
// Verify admin access
@@ -64,6 +81,12 @@ export const adminApi = {
return response.data;
},
// Admin dashboard stats
getStats: async (): Promise<AdminStatsResponse> => {
const response = await apiClient.get<AdminStatsResponse>('/admin/stats');
return response.data;
},
// Admin management
listAdmins: async (): Promise<AdminUser[]> => {
const response = await apiClient.get<AdminUser[]>('/admin/admins');
@@ -309,6 +332,13 @@ export const adminApi = {
return response.data;
},
getVehicles: async (auth0Sub: string): Promise<AdminUserVehiclesResponse> => {
const response = await apiClient.get<AdminUserVehiclesResponse>(
`/admin/users/${encodeURIComponent(auth0Sub)}/vehicles`
);
return response.data;
},
updateTier: async (auth0Sub: string, data: UpdateUserTierRequest): Promise<ManagedUser> => {
const response = await apiClient.patch<ManagedUser>(
`/admin/users/${encodeURIComponent(auth0Sub)}/tier`,