view data fixes
This commit is contained in:
74
apps/website/lib/view-models/DashboardStatsViewModel.ts
Normal file
74
apps/website/lib/view-models/DashboardStatsViewModel.ts
Normal file
@@ -0,0 +1,74 @@
|
||||
import { ViewModel } from "../contracts/view-models/ViewModel";
|
||||
import { ActivityLevelDisplay } from "@/lib/display-objects/ActivityLevelDisplay";
|
||||
import type { DashboardStatsViewData } from '@/lib/view-data/DashboardStatsViewData';
|
||||
|
||||
/**
|
||||
* DashboardStatsViewModel
|
||||
*
|
||||
* View Model for admin dashboard statistics.
|
||||
* Provides formatted statistics and derived metrics for UI.
|
||||
*/
|
||||
export class DashboardStatsViewModel extends ViewModel {
|
||||
totalUsers: number;
|
||||
activeUsers: number;
|
||||
suspendedUsers: number;
|
||||
deletedUsers: number;
|
||||
systemAdmins: number;
|
||||
recentLogins: number;
|
||||
newUsersToday: number;
|
||||
userGrowth: {
|
||||
label: string;
|
||||
value: number;
|
||||
color: string;
|
||||
}[];
|
||||
roleDistribution: {
|
||||
label: string;
|
||||
value: number;
|
||||
color: string;
|
||||
}[];
|
||||
statusDistribution: {
|
||||
active: number;
|
||||
suspended: number;
|
||||
deleted: number;
|
||||
};
|
||||
activityTimeline: {
|
||||
date: string;
|
||||
newUsers: number;
|
||||
logins: number;
|
||||
}[];
|
||||
|
||||
// UI-specific derived fields (primitive outputs only)
|
||||
readonly activeRate: number;
|
||||
readonly activeRateFormatted: string;
|
||||
readonly adminRatio: string;
|
||||
readonly activityLevelLabel: string;
|
||||
readonly activityLevelValue: 'low' | 'medium' | 'high';
|
||||
|
||||
constructor(viewData: DashboardStatsViewData) {
|
||||
super();
|
||||
this.totalUsers = viewData.totalUsers;
|
||||
this.activeUsers = viewData.activeUsers;
|
||||
this.suspendedUsers = viewData.suspendedUsers;
|
||||
this.deletedUsers = viewData.deletedUsers;
|
||||
this.systemAdmins = viewData.systemAdmins;
|
||||
this.recentLogins = viewData.recentLogins;
|
||||
this.newUsersToday = viewData.newUsersToday;
|
||||
this.userGrowth = viewData.userGrowth;
|
||||
this.roleDistribution = viewData.roleDistribution;
|
||||
this.statusDistribution = viewData.statusDistribution;
|
||||
this.activityTimeline = viewData.activityTimeline;
|
||||
|
||||
// Derive active rate
|
||||
this.activeRate = this.totalUsers > 0 ? (this.activeUsers / this.totalUsers) * 100 : 0;
|
||||
this.activeRateFormatted = `${Math.round(this.activeRate)}%`;
|
||||
|
||||
// Derive admin ratio
|
||||
const nonAdmins = Math.max(1, this.totalUsers - this.systemAdmins);
|
||||
this.adminRatio = `1:${Math.floor(nonAdmins / Math.max(1, this.systemAdmins))}`;
|
||||
|
||||
// Derive activity level using Display Object
|
||||
const engagementRate = this.totalUsers > 0 ? (this.recentLogins / this.totalUsers) * 100 : 0;
|
||||
this.activityLevelLabel = ActivityLevelDisplay.levelLabel(engagementRate);
|
||||
this.activityLevelValue = ActivityLevelDisplay.levelValue(engagementRate);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user