Files
gridpilot.gg/apps/website/hooks/driver/useDriverProfile.ts
2026-01-26 17:47:37 +01:00

99 lines
4.1 KiB
TypeScript

import { useInject } from '@/lib/di/hooks/useInject';
import { enhanceQueryResult } from '@/lib/di/hooks/useReactQueryWithApiError';
import { DRIVER_SERVICE_TOKEN } from '@/lib/di/tokens';
import { ApiError } from '@/lib/gateways/api/base/ApiError';
import type { ProfileViewData } from '@/lib/view-data/ProfileViewData';
import { DriverProfileViewModel, type DriverProfileViewModelData } from '@/lib/view-models/DriverProfileViewModel';
import { useQuery, UseQueryOptions } from '@tanstack/react-query';
export function useDriverProfile(
driverId: string,
options?: Omit<UseQueryOptions<DriverProfileViewModel, ApiError>, 'queryKey' | 'queryFn'>
) {
const driverService = useInject(DRIVER_SERVICE_TOKEN);
const queryResult = useQuery({
queryKey: ['driverProfile', driverId],
queryFn: async () => {
const result = await driverService.getDriverProfile(driverId);
if (result.isErr()) {
const error = result.getError();
throw new ApiError(error.message, 'SERVER_ERROR', { timestamp: new globalThis.Date().toISOString() });
}
const dto = result.unwrap();
// Convert GetDriverProfileOutputDTO to ProfileViewData
const viewData: ProfileViewData = {
driver: dto.currentDriver ? {
id: dto.currentDriver.id,
name: dto.currentDriver.name,
countryCode: dto.currentDriver.country || '',
countryFlag: '',
avatarUrl: dto.currentDriver.avatarUrl || '',
bio: dto.currentDriver.bio || null,
iracingId: dto.currentDriver.iracingId || null,
joinedAtLabel: dto.currentDriver.joinedAt || '',
globalRankLabel: dto.currentDriver.globalRank?.toString() || '',
} : {
id: '',
name: '',
countryCode: '',
countryFlag: '',
avatarUrl: '',
bio: null,
iracingId: null,
joinedAtLabel: '',
globalRankLabel: '',
},
stats: dto.stats ? {
ratingLabel: dto.stats.rating?.toString() || '',
globalRankLabel: dto.stats.overallRank?.toString() || '',
totalRacesLabel: dto.stats.totalRaces?.toString() || '',
winsLabel: dto.stats.wins?.toString() || '',
podiumsLabel: dto.stats.podiums?.toString() || '',
dnfsLabel: dto.stats.dnfs?.toString() || '',
bestFinishLabel: dto.stats.bestFinish?.toString() || '',
worstFinishLabel: dto.stats.worstFinish?.toString() || '',
avgFinishLabel: dto.stats.avgFinish?.toString() || '',
consistencyLabel: dto.stats.consistency?.toString() || '',
percentileLabel: dto.stats.percentile?.toString() || '',
} : null,
teamMemberships: dto.teamMemberships.map(m => ({
teamId: m.teamId,
teamName: m.teamName,
teamTag: m.teamTag || null,
roleLabel: m.role || '',
joinedAtLabel: m.joinedAt || '',
href: `/teams/${m.teamId}`,
})),
extendedProfile: dto.extendedProfile ? {
timezone: dto.extendedProfile.timezone || '',
racingStyle: dto.extendedProfile.racingStyle || '',
favoriteTrack: dto.extendedProfile.favoriteTrack || '',
favoriteCar: dto.extendedProfile.favoriteCar || '',
availableHours: dto.extendedProfile.availableHours || '',
lookingForTeamLabel: dto.extendedProfile.lookingForTeam ? 'Yes' : 'No',
openToRequestsLabel: dto.extendedProfile.openToRequests ? 'Yes' : 'No',
socialHandles: dto.extendedProfile.socialHandles?.map(h => ({
platformLabel: h.platform || '',
handle: h.handle || '',
url: h.url || '',
})) || [],
achievements: dto.extendedProfile.achievements?.map(a => ({
id: a.id,
title: a.title,
description: a.description,
earnedAtLabel: a.earnedAt || '',
icon: a.icon as any,
rarityLabel: a.rarity || '',
})) || [],
} : null,
};
return new DriverProfileViewModel(viewData);
},
enabled: !!driverId,
...options,
});
return enhanceQueryResult(queryResult);
}