59 lines
2.0 KiB
TypeScript
59 lines
2.0 KiB
TypeScript
import { ViewModel } from "../contracts/view-models/ViewModel";
|
|
import { DateDisplay } from "../display-objects/DateDisplay";
|
|
import type { TeamMemberViewData, TeamMemberRole } 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 DateDisplay.formatShort(this.joinedAt);
|
|
}
|
|
}
|