Files
gridpilot.gg/apps/website/lib/view-models/LeagueSummaryViewModel.ts
2025-12-18 00:08:47 +01:00

67 lines
1.8 KiB
TypeScript

import { LeagueSummaryDTO } from '../types/generated/LeagueSummaryDTO';
export class LeagueSummaryViewModel implements LeagueSummaryDTO {
id: string;
name: string;
constructor(dto: LeagueSummaryDTO) {
this.id = dto.id;
this.name = dto.name;
}
// Note: The generated DTO only has id and name
// These fields will need to be added when the OpenAPI spec is updated
description?: string;
logoUrl?: string;
coverImage?: string;
memberCount: number = 0;
maxMembers: number = 0;
isPublic: boolean = false;
ownerId: string = '';
ownerName?: string;
scoringType?: string;
status?: string;
/** UI-specific: Formatted capacity display */
get formattedCapacity(): string {
return `${this.memberCount}/${this.maxMembers}`;
}
/** UI-specific: Capacity bar percentage */
get capacityBarPercent(): number {
return (this.memberCount / this.maxMembers) * 100;
}
/** UI-specific: Label for join button */
get joinButtonLabel(): string {
if (this.isFull) return 'Full';
return this.isJoinable ? 'Join League' : 'Request to Join';
}
/** UI-specific: Whether the league is full */
get isFull(): boolean {
return this.memberCount >= this.maxMembers;
}
/** UI-specific: Whether the league is joinable */
get isJoinable(): boolean {
return this.isPublic && !this.isFull;
}
/** UI-specific: Color for member progress */
get memberProgressColor(): string {
const percent = this.capacityBarPercent;
if (percent < 50) return 'green';
if (percent < 80) return 'yellow';
return 'red';
}
/** UI-specific: Badge variant for status */
get statusBadgeVariant(): string {
switch (this.status) {
case 'active': return 'success';
case 'inactive': return 'secondary';
default: return 'default';
}
}
}