import { ActivityLevelFormatter } from "@/lib/formatters/ActivityLevelFormatter"; import type { DashboardStatsViewData } from '@/lib/view-data/DashboardStatsViewData'; import { ViewModel } from "../contracts/view-models/ViewModel"; /** * 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 = ActivityLevelFormatter.levelLabel(engagementRate); this.activityLevelValue = ActivityLevelFormatter.levelValue(engagementRate); } }