100 lines
3.8 KiB
TypeScript
100 lines
3.8 KiB
TypeScript
import { LeaguesApiClient } from '@/lib/api/leagues/LeaguesApiClient';
|
|
import { ConsoleLogger } from '@/lib/infrastructure/logging/ConsoleLogger';
|
|
import { ConsoleErrorReporter } from '@/lib/infrastructure/logging/ConsoleErrorReporter';
|
|
import { getWebsiteApiBaseUrl } from '@/lib/config/apiBaseUrl';
|
|
import { Result } from '@/lib/contracts/Result';
|
|
import { Service, type DomainError } from '@/lib/contracts/services/Service';
|
|
|
|
export 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, DomainError>> {
|
|
try {
|
|
const baseUrl = getWebsiteApiBaseUrl();
|
|
const logger = new ConsoleLogger();
|
|
const errorReporter = new ConsoleErrorReporter();
|
|
const leaguesApiClient = new LeaguesApiClient(baseUrl, errorReporter, logger);
|
|
|
|
const leaguesDto = await leaguesApiClient.getAllWithCapacity();
|
|
|
|
if (!leaguesDto?.leagues) {
|
|
return Result.err({ type: 'notFound', message: 'Leagues not found' });
|
|
}
|
|
|
|
// Fetch all memberships in parallel
|
|
const leagueMemberships = await Promise.all(
|
|
leaguesDto.leagues.map(async (league) => {
|
|
try {
|
|
const membershipsDto = await leaguesApiClient.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: any) {
|
|
const errorAny = error as { statusCode?: number; message?: string };
|
|
|
|
if (errorAny.statusCode === 404 || errorAny.message?.toLowerCase().includes('not found')) {
|
|
return Result.err({ type: 'notFound', message: 'Profile leagues not found' });
|
|
}
|
|
|
|
if (errorAny.statusCode === 302 || errorAny.message?.toLowerCase().includes('redirect')) {
|
|
return Result.err({ type: 'unauthorized', message: 'Unauthorized access' });
|
|
}
|
|
|
|
return Result.err({ type: 'unknown', message: error.message || 'Failed to fetch profile leagues' });
|
|
}
|
|
}
|
|
}
|