website refactor
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
import { LeaguesApiClient } from '@/lib/api/leagues/LeaguesApiClient';
|
||||
import { DriversApiClient } from '@/lib/api/drivers/DriversApiClient';
|
||||
import { Result } from '@/lib/contracts/Result';
|
||||
import { DomainError } from '@/lib/contracts/services/Service';
|
||||
|
||||
/**
|
||||
* League Settings Service - DTO Only
|
||||
@@ -25,4 +27,20 @@ export class LeagueSettingsService {
|
||||
async transferOwnership(leagueId: string, currentOwnerId: string, newOwnerId: string): Promise<{ success: boolean }> {
|
||||
return this.leagueApiClient.transferOwnership(leagueId, currentOwnerId, newOwnerId);
|
||||
}
|
||||
|
||||
async selectScoringPreset(leagueId: string, preset: string): Promise<Result<void, DomainError>> {
|
||||
return Result.err({ type: 'notImplemented', message: 'selectScoringPreset' });
|
||||
}
|
||||
|
||||
async toggleCustomScoring(leagueId: string, enabled: boolean): Promise<Result<void, DomainError>> {
|
||||
return Result.err({ type: 'notImplemented', message: 'toggleCustomScoring' });
|
||||
}
|
||||
|
||||
getPresetEmoji(preset: string): string {
|
||||
return '🏆';
|
||||
}
|
||||
|
||||
getPresetDescription(preset: string): string {
|
||||
return `Scoring preset: ${preset}`;
|
||||
}
|
||||
}
|
||||
97
apps/website/lib/services/leagues/ProfileLeaguesService.ts
Normal file
97
apps/website/lib/services/leagues/ProfileLeaguesService.ts
Normal file
@@ -0,0 +1,97 @@
|
||||
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');
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user