di usage in website
This commit is contained in:
@@ -3,7 +3,10 @@
|
||||
import { useState } from 'react';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import { RacesTemplate, TimeFilter, RaceStatusFilter } from '@/templates/RacesTemplate';
|
||||
import { useRacesPageData, useRegisterForRace, useWithdrawFromRace, useCancelRace } from '@/hooks/useRaceService';
|
||||
import { useRacesPageData } from '@/hooks/race/useRacesPageData';
|
||||
import { useRegisterForRace } from '@/hooks/race/useRegisterForRace';
|
||||
import { useWithdrawFromRace } from '@/hooks/race/useWithdrawFromRace';
|
||||
import { useCancelRace } from '@/hooks/race/useCancelRace';
|
||||
import { LeagueMembershipUtility } from '@/lib/utilities/LeagueMembershipUtility';
|
||||
import { useEffectiveDriverId } from '@/hooks/useEffectiveDriverId';
|
||||
|
||||
|
||||
@@ -1,16 +1,19 @@
|
||||
import { RacesTemplate } from '@/templates/RacesTemplate';
|
||||
import { useServices } from '@/lib/services/ServiceProvider';
|
||||
import { ContainerManager } from '@/lib/di/container';
|
||||
import { RACE_SERVICE_TOKEN } from '@/lib/di/tokens';
|
||||
import type { RaceListItemViewModel } from '@/lib/view-models/RaceListItemViewModel';
|
||||
import type { RaceService } from '@/lib/services/races/RaceService';
|
||||
|
||||
// This is a server component that fetches data and passes it to the template
|
||||
export async function RacesStatic() {
|
||||
const { raceService } = useServices();
|
||||
const container = ContainerManager.getInstance().getContainer();
|
||||
const raceService = container.get<RaceService>(RACE_SERVICE_TOKEN);
|
||||
|
||||
// Fetch race data server-side
|
||||
const pageData = await raceService.getRacesPageData();
|
||||
|
||||
// Extract races from the response
|
||||
const races = pageData.races.map(race => ({
|
||||
const races = pageData.races.map((race: RaceListItemViewModel) => ({
|
||||
id: race.id,
|
||||
track: race.track,
|
||||
car: race.car,
|
||||
@@ -27,7 +30,7 @@ export async function RacesStatic() {
|
||||
|
||||
// Transform the categorized races as well
|
||||
const transformRaces = (raceList: RaceListItemViewModel[]) =>
|
||||
raceList.map(race => ({
|
||||
raceList.map((race: RaceListItemViewModel) => ({
|
||||
id: race.id,
|
||||
track: race.track,
|
||||
car: race.car,
|
||||
|
||||
@@ -3,21 +3,18 @@
|
||||
import { useState } from 'react';
|
||||
import { useParams, useRouter } from 'next/navigation';
|
||||
import { RaceDetailTemplate } from '@/templates/RaceDetailTemplate';
|
||||
import {
|
||||
useRegisterForRace,
|
||||
useWithdrawFromRace,
|
||||
useCancelRace,
|
||||
useCompleteRace,
|
||||
useReopenRace
|
||||
} from '@/hooks/useRaceService';
|
||||
import { useRegisterForRace } from '@/hooks/race/useRegisterForRace';
|
||||
import { useWithdrawFromRace } from '@/hooks/race/useWithdrawFromRace';
|
||||
import { useCancelRace } from '@/hooks/race/useCancelRace';
|
||||
import { useCompleteRace } from '@/hooks/race/useCompleteRace';
|
||||
import { useReopenRace } from '@/hooks/race/useReopenRace';
|
||||
import { useLeagueMembership } from '@/hooks/useLeagueMembershipService';
|
||||
import { useEffectiveDriverId } from '@/hooks/useEffectiveDriverId';
|
||||
import { LeagueMembershipUtility } from '@/lib/utilities/LeagueMembershipUtility';
|
||||
|
||||
// Shared state components
|
||||
import { useDataFetching } from '@/components/shared/hooks/useDataFetching';
|
||||
import { StateContainer } from '@/components/shared/state/StateContainer';
|
||||
import { useServices } from '@/lib/services/ServiceProvider';
|
||||
import { useRaceDetail } from '@/hooks/race/useRaceDetail';
|
||||
import { Flag } from 'lucide-react';
|
||||
|
||||
export function RaceDetailInteractive() {
|
||||
@@ -25,13 +22,9 @@ export function RaceDetailInteractive() {
|
||||
const params = useParams();
|
||||
const raceId = params.id as string;
|
||||
const currentDriverId = useEffectiveDriverId();
|
||||
const { raceService } = useServices();
|
||||
|
||||
// Fetch data using new hook
|
||||
const { data: viewModel, isLoading, error, retry } = useDataFetching({
|
||||
queryKey: ['raceDetail', raceId, currentDriverId],
|
||||
queryFn: () => raceService.getRaceDetail(raceId, currentDriverId),
|
||||
});
|
||||
// Fetch data using DI + React-Query
|
||||
const { data: viewModel, isLoading, error, retry } = useRaceDetail(raceId, currentDriverId);
|
||||
|
||||
// Fetch membership
|
||||
const { data: membership } = useLeagueMembership(viewModel?.league?.id || '', currentDriverId);
|
||||
|
||||
@@ -39,23 +39,66 @@ vi.mock('@/components/sponsors/SponsorInsightsCard', () => ({
|
||||
useSponsorMode: () => false,
|
||||
}));
|
||||
|
||||
// Mock services hook to provide raceService and leagueMembershipService
|
||||
// Mock the new DI hooks
|
||||
const mockGetRaceDetails = vi.fn();
|
||||
const mockReopenRace = vi.fn();
|
||||
const mockFetchLeagueMemberships = vi.fn();
|
||||
const mockGetMembership = vi.fn();
|
||||
|
||||
vi.mock('@/lib/services/ServiceProvider', () => ({
|
||||
useServices: () => ({
|
||||
raceService: {
|
||||
getRaceDetails: mockGetRaceDetails,
|
||||
reopenRace: mockReopenRace,
|
||||
// other methods are not used in this test
|
||||
},
|
||||
leagueMembershipService: {
|
||||
fetchLeagueMemberships: mockFetchLeagueMemberships,
|
||||
getMembership: mockGetMembership,
|
||||
},
|
||||
// Mock race detail hook
|
||||
vi.mock('@/hooks/race/useRaceDetail', () => ({
|
||||
useRaceDetail: (raceId: string, driverId: string) => ({
|
||||
data: mockGetRaceDetails.mock.results[0]?.value || null,
|
||||
isLoading: false,
|
||||
isError: false,
|
||||
isSuccess: !!mockGetRaceDetails.mock.results[0]?.value,
|
||||
refetch: vi.fn(),
|
||||
retry: vi.fn(),
|
||||
}),
|
||||
}));
|
||||
|
||||
// Mock reopen race hook
|
||||
vi.mock('@/hooks/race/useReopenRace', () => ({
|
||||
useReopenRace: () => ({
|
||||
mutateAsync: mockReopenRace,
|
||||
mutate: mockReopenRace,
|
||||
isPending: false,
|
||||
isLoading: false,
|
||||
}),
|
||||
}));
|
||||
|
||||
// Mock league membership service static method
|
||||
vi.mock('@/lib/services/leagues/LeagueMembershipService', () => ({
|
||||
LeagueMembershipService: {
|
||||
getMembership: mockGetMembership,
|
||||
fetchLeagueMemberships: mockFetchLeagueMemberships,
|
||||
setLeagueMemberships: vi.fn(),
|
||||
clearLeagueMemberships: vi.fn(),
|
||||
getCachedMembershipsIterator: vi.fn(() => [][Symbol.iterator]()),
|
||||
getAllMembershipsForDriver: vi.fn(() => []),
|
||||
getLeagueMembers: vi.fn(() => []),
|
||||
},
|
||||
}));
|
||||
|
||||
// Mock league membership hook (if used by component)
|
||||
vi.mock('@/hooks/league/useLeagueMemberships', () => ({
|
||||
useLeagueMemberships: (leagueId: string, currentUserId: string) => ({
|
||||
data: mockFetchLeagueMemberships.mock.results[0]?.value || null,
|
||||
isLoading: false,
|
||||
isError: false,
|
||||
isSuccess: !!mockFetchLeagueMemberships.mock.results[0]?.value,
|
||||
refetch: vi.fn(),
|
||||
}),
|
||||
}));
|
||||
|
||||
// Mock the useLeagueMembership hook that the component imports
|
||||
vi.mock('@/hooks/useLeagueMembershipService', () => ({
|
||||
useLeagueMembership: (leagueId: string, driverId: string) => ({
|
||||
data: mockGetMembership.mock.results[0]?.value || null,
|
||||
isLoading: false,
|
||||
isError: false,
|
||||
isSuccess: !!mockGetMembership.mock.results[0]?.value,
|
||||
refetch: vi.fn(),
|
||||
}),
|
||||
}));
|
||||
|
||||
@@ -122,7 +165,7 @@ describe('RaceDetailPage - Re-open Race behavior', () => {
|
||||
mockGetMembership.mockReset();
|
||||
mockIsOwnerOrAdmin.mockReset();
|
||||
|
||||
// Set up default mock implementations for services
|
||||
// Set up default mock implementations
|
||||
mockFetchLeagueMemberships.mockResolvedValue(undefined);
|
||||
mockGetMembership.mockReturnValue({ role: 'owner' }); // Return owner role by default
|
||||
});
|
||||
@@ -131,8 +174,9 @@ describe('RaceDetailPage - Re-open Race behavior', () => {
|
||||
mockIsOwnerOrAdmin.mockReturnValue(true);
|
||||
const viewModel = createViewModel('completed');
|
||||
|
||||
// Mock the service to return the right data
|
||||
mockGetRaceDetails.mockResolvedValue(viewModel);
|
||||
// Mock the hooks to return the right data
|
||||
mockGetRaceDetails.mockReturnValue(viewModel);
|
||||
mockGetMembership.mockReturnValue({ role: 'owner' });
|
||||
mockReopenRace.mockResolvedValue(undefined);
|
||||
|
||||
const confirmSpy = vi.spyOn(window, 'confirm').mockReturnValue(true);
|
||||
@@ -162,7 +206,8 @@ describe('RaceDetailPage - Re-open Race behavior', () => {
|
||||
mockIsOwnerOrAdmin.mockReturnValue(false);
|
||||
const viewModel = createViewModel('completed');
|
||||
|
||||
mockGetRaceDetails.mockResolvedValue(viewModel);
|
||||
mockGetRaceDetails.mockReturnValue(viewModel);
|
||||
mockGetMembership.mockReturnValue({ role: 'member' });
|
||||
|
||||
renderWithQueryClient(<RaceDetailInteractive />);
|
||||
|
||||
@@ -178,7 +223,8 @@ describe('RaceDetailPage - Re-open Race behavior', () => {
|
||||
mockIsOwnerOrAdmin.mockReturnValue(true);
|
||||
const viewModel = createViewModel('scheduled');
|
||||
|
||||
mockGetRaceDetails.mockResolvedValue(viewModel);
|
||||
mockGetRaceDetails.mockReturnValue(viewModel);
|
||||
mockGetMembership.mockReturnValue({ role: 'owner' });
|
||||
|
||||
renderWithQueryClient(<RaceDetailInteractive />);
|
||||
|
||||
|
||||
@@ -3,14 +3,14 @@
|
||||
import { useState } from 'react';
|
||||
import { useParams, useRouter } from 'next/navigation';
|
||||
import { RaceResultsTemplate } from '@/templates/RaceResultsTemplate';
|
||||
import { useLeagueMembership } from '@/hooks/useLeagueMembershipService';
|
||||
import { useLeagueMemberships } from '@/hooks/league/useLeagueMemberships';
|
||||
import { useEffectiveDriverId } from '@/hooks/useEffectiveDriverId';
|
||||
import { LeagueRoleUtility } from '@/lib/utilities/LeagueRoleUtility';
|
||||
|
||||
// Shared state components
|
||||
import { useDataFetching } from '@/components/shared/hooks/useDataFetching';
|
||||
import { StateContainer } from '@/components/shared/state/StateContainer';
|
||||
import { useServices } from '@/lib/services/ServiceProvider';
|
||||
import { useRaceResultsDetail } from '@/hooks/race/useRaceResultsDetail';
|
||||
import { useRaceWithSOF } from '@/hooks/race/useRaceWithSOF';
|
||||
import { Trophy } from 'lucide-react';
|
||||
|
||||
export function RaceResultsInteractive() {
|
||||
@@ -18,22 +18,13 @@ export function RaceResultsInteractive() {
|
||||
const params = useParams();
|
||||
const raceId = params.id as string;
|
||||
const currentDriverId = useEffectiveDriverId();
|
||||
const { raceResultsService, raceService } = useServices();
|
||||
|
||||
// Fetch data using new hook
|
||||
const { data: raceData, isLoading, error, retry } = useDataFetching({
|
||||
queryKey: ['raceResultsDetail', raceId, currentDriverId],
|
||||
queryFn: () => raceResultsService.getResultsDetail(raceId, currentDriverId),
|
||||
});
|
||||
|
||||
// Fetch SOF data
|
||||
const { data: sofData } = useDataFetching({
|
||||
queryKey: ['raceWithSOF', raceId],
|
||||
queryFn: () => raceResultsService.getWithSOF(raceId),
|
||||
});
|
||||
// Fetch data using existing hooks
|
||||
const { data: raceData, isLoading, error, retry } = useRaceResultsDetail(raceId, currentDriverId);
|
||||
const { data: sofData } = useRaceWithSOF(raceId);
|
||||
|
||||
// Fetch membership
|
||||
const { data: membership } = useLeagueMembership(raceData?.league?.id || '', currentDriverId);
|
||||
const { data: membershipsData } = useLeagueMemberships(raceData?.league?.id || '', currentDriverId || '');
|
||||
|
||||
// UI State
|
||||
const [importing, setImporting] = useState(false);
|
||||
@@ -42,7 +33,8 @@ export function RaceResultsInteractive() {
|
||||
const [showImportForm, setShowImportForm] = useState(false);
|
||||
|
||||
const raceSOF = sofData?.strengthOfField || null;
|
||||
const isAdmin = membership ? LeagueRoleUtility.isLeagueAdminOrHigherRole(membership.role) : false;
|
||||
const currentMembership = membershipsData?.memberships.find(m => m.driverId === currentDriverId);
|
||||
const isAdmin = currentMembership ? LeagueRoleUtility.isLeagueAdminOrHigherRole(currentMembership.role) : false;
|
||||
|
||||
// Transform data for template
|
||||
const results = raceData?.results.map(result => ({
|
||||
@@ -142,4 +134,4 @@ export function RaceResultsInteractive() {
|
||||
)}
|
||||
</StateContainer>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -3,14 +3,13 @@
|
||||
import { useState } from 'react';
|
||||
import { useParams, useRouter } from 'next/navigation';
|
||||
import { RaceStewardingTemplate, StewardingTab } from '@/templates/RaceStewardingTemplate';
|
||||
import { useLeagueMembership } from '@/hooks/useLeagueMembershipService';
|
||||
import { useLeagueMemberships } from '@/hooks/league/useLeagueMemberships';
|
||||
import { useEffectiveDriverId } from '@/hooks/useEffectiveDriverId';
|
||||
import { LeagueRoleUtility } from '@/lib/utilities/LeagueRoleUtility';
|
||||
|
||||
// Shared state components
|
||||
import { useDataFetching } from '@/components/shared/hooks/useDataFetching';
|
||||
import { StateContainer } from '@/components/shared/state/StateContainer';
|
||||
import { useServices } from '@/lib/services/ServiceProvider';
|
||||
import { useRaceStewardingData } from '@/hooks/race/useRaceStewardingData';
|
||||
import { Gavel } from 'lucide-react';
|
||||
|
||||
export function RaceStewardingInteractive() {
|
||||
@@ -18,21 +17,18 @@ export function RaceStewardingInteractive() {
|
||||
const params = useParams();
|
||||
const raceId = params.id as string;
|
||||
const currentDriverId = useEffectiveDriverId();
|
||||
const { raceStewardingService } = useServices();
|
||||
|
||||
// Fetch data using new hook
|
||||
const { data: stewardingData, isLoading, error, retry } = useDataFetching({
|
||||
queryKey: ['raceStewardingData', raceId, currentDriverId],
|
||||
queryFn: () => raceStewardingService.getRaceStewardingData(raceId, currentDriverId),
|
||||
});
|
||||
// Fetch data using existing hooks
|
||||
const { data: stewardingData, isLoading, error, retry } = useRaceStewardingData(raceId, currentDriverId);
|
||||
|
||||
// Fetch membership
|
||||
const { data: membership } = useLeagueMembership(stewardingData?.league?.id || '', currentDriverId);
|
||||
const { data: membershipsData } = useLeagueMemberships(stewardingData?.league?.id || '', currentDriverId || '');
|
||||
|
||||
// UI State
|
||||
const [activeTab, setActiveTab] = useState<StewardingTab>('pending');
|
||||
|
||||
const isAdmin = membership ? LeagueRoleUtility.isLeagueAdminOrHigherRole(membership.role) : false;
|
||||
const currentMembership = membershipsData?.memberships.find(m => m.driverId === currentDriverId);
|
||||
const isAdmin = currentMembership ? LeagueRoleUtility.isLeagueAdminOrHigherRole(currentMembership.role) : false;
|
||||
|
||||
// Actions
|
||||
const handleBack = () => {
|
||||
@@ -88,4 +84,4 @@ export function RaceStewardingInteractive() {
|
||||
)}
|
||||
</StateContainer>
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user