Files
gridpilot.gg/apps/website/lib/view-models/TeamMemberViewModel.ts
2026-01-24 01:07:43 +01:00

59 lines
2.0 KiB
TypeScript

import { ViewModel } from "../contracts/view-models/ViewModel";
import { DateFormatter } from "../formatters/DateFormatter";
import type { TeamMemberRole, TeamMemberViewData } from "../view-data/TeamMemberViewData";
function normalizeTeamRole(role: string): TeamMemberRole {
if (role === 'owner' || role === 'manager' || role === 'member') return role;
// Backwards compatibility
if (role === 'admin') return 'manager';
return 'member';
}
export class TeamMemberViewModel extends ViewModel {
private readonly data: TeamMemberViewData;
constructor(data: TeamMemberViewData) {
super();
this.data = data;
}
get driverId(): string { return this.data.driverId; }
get driverName(): string { return this.data.driverName; }
get role(): TeamMemberRole { return normalizeTeamRole(this.data.role); }
get joinedAt(): string { return this.data.joinedAt; }
get isActive(): boolean { return this.data.isActive; }
get avatarUrl(): string { return this.data.avatarUrl || ''; }
get currentUserId(): string { return this.data.currentUserId; }
get teamOwnerId(): string { return this.data.teamOwnerId; }
/** UI-specific: Role badge variant */
get roleBadgeVariant(): string {
switch (this.role) {
case 'owner': return 'primary';
case 'manager': return 'secondary';
case 'member': return 'default';
default: return 'default';
}
}
/** UI-specific: Whether this member is the owner */
get isOwner(): boolean {
return this.driverId === this.teamOwnerId;
}
/** UI-specific: Whether current user can manage this member */
get canManage(): boolean {
return this.currentUserId === this.teamOwnerId && this.driverId !== this.currentUserId;
}
/** UI-specific: Whether this is the current user */
get isCurrentUser(): boolean {
return this.driverId === this.currentUserId;
}
/** UI-specific: Formatted joined date */
get formattedJoinedAt(): string {
return DateFormatter.formatShort(this.joinedAt);
}
}