Files
gridpilot.gg/apps/website/lib/services/leagues/ProfileLeaguesService.ts
2026-01-14 10:51:05 +01:00

98 lines
3.4 KiB
TypeScript

import { ApiClient } from '@/lib/api';
import { getWebsiteApiBaseUrl } from '@/lib/config/apiBaseUrl';
import { Result } from '@/lib/contracts/Result';
import type { Service } from '@/lib/contracts/services/Service';
type ProfileLeaguesServiceError = 'notFound' | 'redirect' | 'unknown';
interface ProfileLeaguesPageDto {
ownedLeagues: Array<{
leagueId: string;
name: string;
description: string;
membershipRole: 'owner' | 'admin' | 'steward' | 'member';
}>;
memberLeagues: Array<{
leagueId: string;
name: string;
description: string;
membershipRole: 'owner' | 'admin' | 'steward' | 'member';
}>;
}
interface MembershipDTO {
driverId: string;
role: string;
status?: 'active' | 'inactive';
}
export class ProfileLeaguesService implements Service {
async getProfileLeagues(driverId: string): Promise<Result<ProfileLeaguesPageDto, ProfileLeaguesServiceError>> {
try {
const baseUrl = getWebsiteApiBaseUrl();
const apiClient = new ApiClient(baseUrl);
const leaguesDto = await apiClient.leagues.getAllWithCapacity();
if (!leaguesDto?.leagues) {
return Result.err('notFound');
}
// Fetch all memberships in parallel
const leagueMemberships = await Promise.all(
leaguesDto.leagues.map(async (league) => {
try {
const membershipsDto = await apiClient.leagues.getMemberships(league.id);
let memberships: MembershipDTO[] = [];
if (membershipsDto && typeof membershipsDto === 'object') {
if ('members' in membershipsDto && Array.isArray((membershipsDto as { members?: unknown }).members)) {
memberships = (membershipsDto as { members: MembershipDTO[] }).members;
} else if ('memberships' in membershipsDto && Array.isArray((membershipsDto as { memberships?: unknown }).memberships)) {
memberships = (membershipsDto as { memberships: MembershipDTO[] }).memberships;
}
}
const currentMembership = memberships.find((m) => m.driverId === driverId);
if (currentMembership && currentMembership.status === 'active') {
return {
leagueId: league.id,
name: league.name,
description: league.description,
membershipRole: currentMembership.role as 'owner' | 'admin' | 'steward' | 'member',
};
}
return null;
} catch {
return null;
}
})
);
// Filter and categorize
const validLeagues = leagueMemberships.filter((l): l is NonNullable<typeof l> => l !== null);
const ownedLeagues = validLeagues.filter((l) => l.membershipRole === 'owner');
const memberLeagues = validLeagues.filter((l) => l.membershipRole !== 'owner');
return Result.ok({
ownedLeagues,
memberLeagues,
});
} catch (error) {
const errorAny = error as { statusCode?: number; message?: string };
if (errorAny.statusCode === 404 || errorAny.message?.toLowerCase().includes('not found')) {
return Result.err('notFound');
}
if (errorAny.statusCode === 302 || errorAny.message?.toLowerCase().includes('redirect')) {
return Result.err('redirect');
}
return Result.err('unknown');
}
}
}