website refactor
This commit is contained in:
@@ -15,7 +15,9 @@ describe('LeagueDetailPageViewModel', () => {
|
||||
description: 'Top tier competition',
|
||||
ownerId: 'owner-1',
|
||||
createdAt: '2025-01-01T00:00:00Z',
|
||||
maxDrivers: 40,
|
||||
settings: {
|
||||
maxDrivers: 40,
|
||||
},
|
||||
socialLinks: {
|
||||
discordUrl: 'https://discord.gg/example',
|
||||
youtubeUrl: 'https://youtube.com/example',
|
||||
@@ -43,7 +45,7 @@ describe('LeagueDetailPageViewModel', () => {
|
||||
];
|
||||
|
||||
const memberships: LeagueMembershipsDTO = {
|
||||
memberships: [
|
||||
members: [
|
||||
{
|
||||
driverId: 'owner-1',
|
||||
role: 'owner',
|
||||
@@ -104,14 +106,14 @@ describe('LeagueDetailPageViewModel', () => {
|
||||
expect(vm.name).toBe(league.name);
|
||||
expect(vm.description).toBe(league.description);
|
||||
expect(vm.ownerId).toBe(league.ownerId);
|
||||
expect(vm.settings.maxDrivers).toBe(league.maxDrivers);
|
||||
expect(vm.socialLinks?.discordUrl).toBe(league.socialLinks?.discordUrl);
|
||||
expect(vm.settings.maxDrivers).toBe((league.settings as any).maxDrivers);
|
||||
expect(vm.socialLinks?.discordUrl).toBe((league.socialLinks as any).discordUrl);
|
||||
|
||||
expect(vm.owner).toEqual(owner);
|
||||
expect(vm.scoringConfig).toBeNull();
|
||||
|
||||
expect(vm.drivers).toHaveLength(drivers.length);
|
||||
expect(vm.memberships).toHaveLength(memberships.memberships.length);
|
||||
expect(vm.memberships).toHaveLength(memberships.members.length);
|
||||
|
||||
expect(vm.allRaces).toHaveLength(allRaces.length);
|
||||
expect(vm.runningRaces.every(r => r.status === 'running')).toBe(true);
|
||||
@@ -129,7 +131,7 @@ describe('LeagueDetailPageViewModel', () => {
|
||||
sponsors,
|
||||
);
|
||||
|
||||
const memberCount = memberships.memberships.length;
|
||||
const memberCount = memberships.members.length;
|
||||
const mainSponsorTaken = sponsors.some(s => s.tier === 'main');
|
||||
const secondaryTaken = sponsors.filter(s => s.tier === 'secondary').length;
|
||||
|
||||
@@ -189,7 +191,7 @@ describe('LeagueDetailPageViewModel', () => {
|
||||
expect(vmLow.sponsorInsights.tier).toBe('starter');
|
||||
|
||||
expect(vmHigh.sponsorInsights.trustScore).toBe(
|
||||
Math.min(100, 60 + memberships.memberships.length + (leagueStats as any).completedRaces),
|
||||
Math.min(100, 60 + memberships.members.length + (leagueStats as any).completedRaces),
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
@@ -1,309 +0,0 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import type { RaceDetailLeagueDTO } from '@/lib/types/generated/RaceDetailLeagueDTO';
|
||||
import type { RaceDetailRaceDTO } from '@/lib/types/generated/RaceDetailRaceDTO';
|
||||
import type { RaceDetailRegistrationDTO } from '@/lib/types/generated/RaceDetailRegistrationDTO';
|
||||
import type { RaceDetailUserResultDTO } from '@/lib/types/generated/RaceDetailUserResultDTO';
|
||||
import type { RaceDetailEntryDTO } from '@/lib/types/RaceDetailEntryDTO';
|
||||
import { RaceDetailViewModel } from './RaceDetailViewModel';
|
||||
|
||||
describe('RaceDetailViewModel', () => {
|
||||
const createMockRace = (overrides?: Partial<RaceDetailRaceDTO>): RaceDetailRaceDTO => ({
|
||||
id: 'race-123',
|
||||
title: 'Test Race',
|
||||
scheduledAt: '2023-12-31T20:00:00Z',
|
||||
status: 'upcoming',
|
||||
...overrides,
|
||||
});
|
||||
|
||||
const createMockLeague = (): RaceDetailLeagueDTO => ({
|
||||
id: 'league-123',
|
||||
name: 'Test League',
|
||||
});
|
||||
|
||||
const createMockRegistration = (
|
||||
overrides?: Partial<RaceDetailRegistrationDTO>
|
||||
): RaceDetailRegistrationDTO => ({
|
||||
isRegistered: false,
|
||||
canRegister: true,
|
||||
...overrides,
|
||||
});
|
||||
|
||||
it('should create instance with all properties', () => {
|
||||
const race = createMockRace();
|
||||
const league = createMockLeague();
|
||||
const entries: RaceDetailEntryDTO[] = [];
|
||||
const registration = createMockRegistration();
|
||||
const userResult: RaceDetailUserResultDTO | null = null;
|
||||
|
||||
const viewModel = new RaceDetailViewModel({
|
||||
race,
|
||||
league,
|
||||
entryList: entries,
|
||||
registration,
|
||||
userResult,
|
||||
}, 'current-driver');
|
||||
|
||||
expect(viewModel.race).toBe(race);
|
||||
expect(viewModel.league).toBe(league);
|
||||
expect(viewModel.entryList).toHaveLength(0);
|
||||
expect(viewModel.registration).toBe(registration);
|
||||
expect(viewModel.userResult).toBe(userResult);
|
||||
});
|
||||
|
||||
it('should handle null race and league', () => {
|
||||
const viewModel = new RaceDetailViewModel({
|
||||
race: null,
|
||||
league: null,
|
||||
entryList: [],
|
||||
registration: createMockRegistration(),
|
||||
userResult: null,
|
||||
});
|
||||
|
||||
expect(viewModel.race).toBeNull();
|
||||
expect(viewModel.league).toBeNull();
|
||||
});
|
||||
|
||||
it('should return correct isRegistered value', () => {
|
||||
const registeredVm = new RaceDetailViewModel({
|
||||
race: createMockRace(),
|
||||
league: createMockLeague(),
|
||||
entryList: [],
|
||||
registration: createMockRegistration({ isRegistered: true }),
|
||||
userResult: null,
|
||||
});
|
||||
|
||||
const notRegisteredVm = new RaceDetailViewModel({
|
||||
race: createMockRace(),
|
||||
league: createMockLeague(),
|
||||
entryList: [],
|
||||
registration: createMockRegistration({ isRegistered: false }),
|
||||
userResult: null,
|
||||
});
|
||||
|
||||
expect(registeredVm.isRegistered).toBe(true);
|
||||
expect(notRegisteredVm.isRegistered).toBe(false);
|
||||
});
|
||||
|
||||
it('should return correct canRegister value', () => {
|
||||
const canRegisterVm = new RaceDetailViewModel({
|
||||
race: createMockRace(),
|
||||
league: createMockLeague(),
|
||||
entryList: [],
|
||||
registration: createMockRegistration({ canRegister: true }),
|
||||
userResult: null,
|
||||
});
|
||||
|
||||
const cannotRegisterVm = new RaceDetailViewModel({
|
||||
race: createMockRace(),
|
||||
league: createMockLeague(),
|
||||
entryList: [],
|
||||
registration: createMockRegistration({ canRegister: false }),
|
||||
userResult: null,
|
||||
});
|
||||
|
||||
expect(canRegisterVm.canRegister).toBe(true);
|
||||
expect(cannotRegisterVm.canRegister).toBe(false);
|
||||
});
|
||||
|
||||
it('should format race status correctly', () => {
|
||||
const upcomingVm = new RaceDetailViewModel({
|
||||
race: createMockRace({ status: 'upcoming' }),
|
||||
league: createMockLeague(),
|
||||
entryList: [],
|
||||
registration: createMockRegistration(),
|
||||
userResult: null,
|
||||
});
|
||||
|
||||
const liveVm = new RaceDetailViewModel({
|
||||
race: createMockRace({ status: 'live' }),
|
||||
league: createMockLeague(),
|
||||
entryList: [],
|
||||
registration: createMockRegistration(),
|
||||
userResult: null,
|
||||
});
|
||||
|
||||
const finishedVm = new RaceDetailViewModel({
|
||||
race: createMockRace({ status: 'finished' }),
|
||||
league: createMockLeague(),
|
||||
entryList: [],
|
||||
registration: createMockRegistration(),
|
||||
userResult: null,
|
||||
});
|
||||
|
||||
expect(upcomingVm.raceStatusDisplay).toBe('Upcoming');
|
||||
expect(liveVm.raceStatusDisplay).toBe('Live');
|
||||
expect(finishedVm.raceStatusDisplay).toBe('Finished');
|
||||
});
|
||||
|
||||
it('should return Unknown for status when race is null', () => {
|
||||
const viewModel = new RaceDetailViewModel({
|
||||
race: null,
|
||||
league: createMockLeague(),
|
||||
entryList: [],
|
||||
registration: createMockRegistration(),
|
||||
userResult: null,
|
||||
});
|
||||
|
||||
expect(viewModel.raceStatusDisplay).toBe('Unknown');
|
||||
});
|
||||
|
||||
it('should format scheduled time correctly', () => {
|
||||
const viewModel = new RaceDetailViewModel({
|
||||
race: createMockRace({ scheduledAt: '2023-12-31T20:00:00Z' }),
|
||||
league: createMockLeague(),
|
||||
entryList: [],
|
||||
registration: createMockRegistration(),
|
||||
userResult: null,
|
||||
});
|
||||
|
||||
const formatted = viewModel.formattedScheduledTime;
|
||||
|
||||
expect(formatted).toContain('2023');
|
||||
expect(formatted).toContain('12/31');
|
||||
});
|
||||
|
||||
it('should return empty string for formatted time when race is null', () => {
|
||||
const viewModel = new RaceDetailViewModel({
|
||||
race: null,
|
||||
league: createMockLeague(),
|
||||
entryList: [],
|
||||
registration: createMockRegistration(),
|
||||
userResult: null,
|
||||
});
|
||||
|
||||
expect(viewModel.formattedScheduledTime).toBe('');
|
||||
});
|
||||
|
||||
it('should return correct entry count', () => {
|
||||
const entries: RaceDetailEntryDTO[] = [
|
||||
{ driverId: 'driver-1', carId: 'car-1' },
|
||||
{ driverId: 'driver-2', carId: 'car-2' },
|
||||
{ driverId: 'driver-3', carId: 'car-3' },
|
||||
] as RaceDetailEntryDTO[];
|
||||
|
||||
const viewModel = new RaceDetailViewModel({
|
||||
race: createMockRace(),
|
||||
league: createMockLeague(),
|
||||
entryList: entries,
|
||||
registration: createMockRegistration(),
|
||||
userResult: null,
|
||||
});
|
||||
|
||||
expect(viewModel.entryCount).toBe(3);
|
||||
});
|
||||
|
||||
it('should return true for hasResults when userResult exists', () => {
|
||||
const viewModel = new RaceDetailViewModel({
|
||||
race: createMockRace(),
|
||||
league: createMockLeague(),
|
||||
entryList: [],
|
||||
registration: createMockRegistration(),
|
||||
userResult: { position: 1, lapTime: 90.5 } as RaceDetailUserResultDTO,
|
||||
});
|
||||
|
||||
expect(viewModel.hasResults).toBe(true);
|
||||
});
|
||||
|
||||
it('should return false for hasResults when userResult is null', () => {
|
||||
const viewModel = new RaceDetailViewModel({
|
||||
race: createMockRace(),
|
||||
league: createMockLeague(),
|
||||
entryList: [],
|
||||
registration: createMockRegistration(),
|
||||
userResult: null,
|
||||
});
|
||||
|
||||
expect(viewModel.hasResults).toBe(false);
|
||||
});
|
||||
|
||||
it('should return correct registration status message when registered', () => {
|
||||
const viewModel = new RaceDetailViewModel({
|
||||
race: createMockRace(),
|
||||
league: createMockLeague(),
|
||||
entryList: [],
|
||||
registration: createMockRegistration({ isRegistered: true }),
|
||||
userResult: null,
|
||||
});
|
||||
|
||||
expect(viewModel.registrationStatusMessage).toBe('You are registered for this race');
|
||||
});
|
||||
|
||||
it('should return correct registration status message when can register', () => {
|
||||
const viewModel = new RaceDetailViewModel({
|
||||
race: createMockRace(),
|
||||
league: createMockLeague(),
|
||||
entryList: [],
|
||||
registration: createMockRegistration({ isRegistered: false, canRegister: true }),
|
||||
userResult: null,
|
||||
});
|
||||
|
||||
expect(viewModel.registrationStatusMessage).toBe('You can register for this race');
|
||||
});
|
||||
|
||||
it('should return correct registration status message when cannot register', () => {
|
||||
const viewModel = new RaceDetailViewModel({
|
||||
race: createMockRace(),
|
||||
league: createMockLeague(),
|
||||
entryList: [],
|
||||
registration: createMockRegistration({ isRegistered: false, canRegister: false }),
|
||||
userResult: null,
|
||||
});
|
||||
|
||||
expect(viewModel.registrationStatusMessage).toBe('Registration not available');
|
||||
});
|
||||
|
||||
it('should expose canReopenRace for completed and cancelled statuses', () => {
|
||||
const completedVm = new RaceDetailViewModel({
|
||||
race: createMockRace({ status: 'completed' }),
|
||||
league: createMockLeague(),
|
||||
entryList: [],
|
||||
registration: createMockRegistration(),
|
||||
userResult: null,
|
||||
});
|
||||
|
||||
const cancelledVm = new RaceDetailViewModel({
|
||||
race: createMockRace({ status: 'cancelled' }),
|
||||
league: createMockLeague(),
|
||||
entryList: [],
|
||||
registration: createMockRegistration(),
|
||||
userResult: null,
|
||||
});
|
||||
|
||||
const upcomingVm = new RaceDetailViewModel({
|
||||
race: createMockRace({ status: 'upcoming' }),
|
||||
league: createMockLeague(),
|
||||
entryList: [],
|
||||
registration: createMockRegistration(),
|
||||
userResult: null,
|
||||
});
|
||||
|
||||
expect(completedVm.canReopenRace).toBe(true);
|
||||
expect(cancelledVm.canReopenRace).toBe(true);
|
||||
expect(upcomingVm.canReopenRace).toBe(false);
|
||||
});
|
||||
|
||||
it('should handle error property', () => {
|
||||
const viewModel = new RaceDetailViewModel({
|
||||
race: createMockRace(),
|
||||
league: createMockLeague(),
|
||||
entryList: [],
|
||||
registration: createMockRegistration(),
|
||||
userResult: null,
|
||||
error: 'Failed to load race details',
|
||||
});
|
||||
|
||||
expect(viewModel.error).toBe('Failed to load race details');
|
||||
});
|
||||
|
||||
it('should handle custom race status', () => {
|
||||
const viewModel = new RaceDetailViewModel({
|
||||
race: createMockRace({ status: 'cancelled' }),
|
||||
league: createMockLeague(),
|
||||
entryList: [],
|
||||
registration: createMockRegistration(),
|
||||
userResult: null,
|
||||
});
|
||||
|
||||
expect(viewModel.raceStatusDisplay).toBe('cancelled');
|
||||
});
|
||||
});
|
||||
@@ -5,8 +5,7 @@ import { RaceResultViewModel } from './RaceResultViewModel';
|
||||
export class RaceResultsDetailViewModel {
|
||||
raceId: string;
|
||||
track: string;
|
||||
|
||||
private currentUserId: string;
|
||||
currentUserId: string;
|
||||
|
||||
constructor(dto: RaceResultsDetailDTO & { results?: RaceResultDTO[] }, currentUserId: string) {
|
||||
this.raceId = dto.raceId;
|
||||
|
||||
@@ -1,165 +0,0 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { SponsorDashboardViewModel } from './SponsorDashboardViewModel';
|
||||
import { SponsorshipViewModel } from './SponsorshipViewModel';
|
||||
import { ActivityItemViewModel } from './ActivityItemViewModel';
|
||||
import { RenewalAlertViewModel } from './RenewalAlertViewModel';
|
||||
|
||||
function makeSponsorship(overrides: Partial<any> = {}) {
|
||||
return {
|
||||
id: 's-1',
|
||||
type: 'leagues',
|
||||
entityId: 'league-1',
|
||||
entityName: 'Pro League',
|
||||
status: 'active',
|
||||
startDate: '2025-01-01',
|
||||
endDate: '2025-12-31',
|
||||
price: 5_000,
|
||||
impressions: 50_000,
|
||||
...overrides,
|
||||
};
|
||||
}
|
||||
|
||||
describe('SponsorDashboardViewModel', () => {
|
||||
const baseDto = {
|
||||
sponsorId: 'sp-1',
|
||||
sponsorName: 'Acme Corp',
|
||||
metrics: { totalSpend: 10_000, totalImpressions: 100_000 },
|
||||
sponsorships: {
|
||||
leagues: [makeSponsorship()],
|
||||
teams: [makeSponsorship({ id: 's-2', type: 'teams', price: 2_000, impressions: 20_000 })],
|
||||
drivers: [],
|
||||
races: [],
|
||||
platform: [],
|
||||
},
|
||||
recentActivity: [
|
||||
{ id: 'a-1', type: 'impression', timestamp: '2025-01-01T00:00:00Z', metadata: {} },
|
||||
],
|
||||
upcomingRenewals: [
|
||||
{ id: 'r-1', sponsorshipId: 's-1', leagueName: 'Pro League', daysUntilRenewal: 10 },
|
||||
],
|
||||
} as any;
|
||||
|
||||
it('maps nested DTOs into view models', () => {
|
||||
const vm = new SponsorDashboardViewModel(baseDto);
|
||||
|
||||
expect(vm.sponsorId).toBe(baseDto.sponsorId);
|
||||
expect(vm.sponsorName).toBe(baseDto.sponsorName);
|
||||
expect(vm.metrics).toBe(baseDto.metrics);
|
||||
|
||||
expect(vm.sponsorships.leagues[0]).toBeInstanceOf(SponsorshipViewModel);
|
||||
expect(vm.sponsorships.teams[0]).toBeInstanceOf(SponsorshipViewModel);
|
||||
expect(vm.recentActivity[0]).toBeInstanceOf(ActivityItemViewModel);
|
||||
expect(vm.upcomingRenewals[0]).toBeInstanceOf(RenewalAlertViewModel);
|
||||
});
|
||||
|
||||
it('computes total, active counts and investment from sponsorship buckets', () => {
|
||||
const vm = new SponsorDashboardViewModel(baseDto);
|
||||
|
||||
const all = [
|
||||
...baseDto.sponsorships.leagues,
|
||||
...baseDto.sponsorships.teams,
|
||||
];
|
||||
|
||||
expect(vm.totalSponsorships).toBe(all.length);
|
||||
expect(vm.activeSponsorships).toBe(all.filter(s => s.status === 'active').length);
|
||||
const expectedInvestment = all
|
||||
.filter(s => s.status === 'active')
|
||||
.reduce((sum, s) => sum + s.price, 0);
|
||||
expect(vm.totalInvestment).toBe(expectedInvestment);
|
||||
});
|
||||
|
||||
it('aggregates total impressions across all sponsorships', () => {
|
||||
const vm = new SponsorDashboardViewModel(baseDto);
|
||||
|
||||
const all = [
|
||||
...baseDto.sponsorships.leagues,
|
||||
...baseDto.sponsorships.teams,
|
||||
];
|
||||
|
||||
const expectedImpressions = all.reduce((sum, s) => sum + s.impressions, 0);
|
||||
expect(vm.totalImpressions).toBe(expectedImpressions);
|
||||
});
|
||||
|
||||
it('derives formatted investment, active percentage, status text and CPM', () => {
|
||||
const vm = new SponsorDashboardViewModel(baseDto);
|
||||
|
||||
expect(vm.formattedTotalInvestment).toBe(`$${vm.totalInvestment.toLocaleString()}`);
|
||||
|
||||
const expectedActivePercentage = Math.round((vm.activeSponsorships / vm.totalSponsorships) * 100);
|
||||
expect(vm.activePercentage).toBe(expectedActivePercentage);
|
||||
expect(vm.hasSponsorships).toBe(true);
|
||||
|
||||
// statusText variants
|
||||
const noActive = new SponsorDashboardViewModel({
|
||||
...baseDto,
|
||||
sponsorships: {
|
||||
leagues: [makeSponsorship({ status: 'expired' })],
|
||||
teams: [],
|
||||
drivers: [],
|
||||
races: [],
|
||||
platform: [],
|
||||
},
|
||||
} as any);
|
||||
expect(noActive.statusText).toBe('No active sponsorships');
|
||||
|
||||
const allActive = new SponsorDashboardViewModel({
|
||||
...baseDto,
|
||||
sponsorships: {
|
||||
leagues: [makeSponsorship()],
|
||||
teams: [],
|
||||
drivers: [],
|
||||
races: [],
|
||||
platform: [],
|
||||
},
|
||||
} as any);
|
||||
expect(allActive.statusText).toBe('All sponsorships active');
|
||||
|
||||
// cost per thousand views
|
||||
expect(vm.costPerThousandViews).toBe(`$${(vm.totalInvestment / vm.totalImpressions * 1000).toFixed(2)}`);
|
||||
|
||||
const zeroImpressions = new SponsorDashboardViewModel({
|
||||
...baseDto,
|
||||
sponsorships: {
|
||||
leagues: [makeSponsorship({ impressions: 0 })],
|
||||
teams: [],
|
||||
drivers: [],
|
||||
races: [],
|
||||
platform: [],
|
||||
},
|
||||
} as any);
|
||||
expect(zeroImpressions.costPerThousandViews).toBe('$0.00');
|
||||
});
|
||||
|
||||
it('exposes category data per sponsorship bucket', () => {
|
||||
const vm = new SponsorDashboardViewModel(baseDto);
|
||||
|
||||
expect(vm.categoryData.leagues.count).toBe(baseDto.sponsorships.leagues.length);
|
||||
expect(vm.categoryData.leagues.impressions).toBe(
|
||||
baseDto.sponsorships.leagues.reduce((sum: number, s: any) => sum + s.impressions, 0),
|
||||
);
|
||||
|
||||
expect(vm.categoryData.teams.count).toBe(baseDto.sponsorships.teams.length);
|
||||
expect(vm.categoryData.teams.impressions).toBe(
|
||||
baseDto.sponsorships.teams.reduce((sum: number, s: any) => sum + s.impressions, 0),
|
||||
);
|
||||
});
|
||||
|
||||
it('handles missing sponsorship buckets gracefully', () => {
|
||||
const vm = new SponsorDashboardViewModel({
|
||||
...baseDto,
|
||||
sponsorships: undefined,
|
||||
recentActivity: undefined,
|
||||
upcomingRenewals: undefined,
|
||||
} as any);
|
||||
|
||||
expect(vm.totalSponsorships).toBe(0);
|
||||
expect(vm.activeSponsorships).toBe(0);
|
||||
expect(vm.totalInvestment).toBe(0);
|
||||
expect(vm.totalImpressions).toBe(0);
|
||||
expect(vm.activePercentage).toBe(0);
|
||||
expect(vm.hasSponsorships).toBe(false);
|
||||
expect(vm.costPerThousandViews).toBe('$0.00');
|
||||
expect(vm.recentActivity).toEqual([]);
|
||||
expect(vm.upcomingRenewals).toEqual([]);
|
||||
});
|
||||
});
|
||||
21
apps/website/lib/view-models/SponsorDashboardViewModel.ts
Normal file
21
apps/website/lib/view-models/SponsorDashboardViewModel.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
import { SponsorDashboardDTO } from '@/lib/types/generated/SponsorDashboardDTO';
|
||||
|
||||
/**
|
||||
* Sponsor Dashboard View Model
|
||||
*
|
||||
* Represents dashboard data for a sponsor with UI-specific transformations.
|
||||
*/
|
||||
export class SponsorDashboardViewModel {
|
||||
sponsorId: string;
|
||||
sponsorName: string;
|
||||
|
||||
constructor(dto: SponsorDashboardDTO) {
|
||||
this.sponsorId = dto.sponsorId;
|
||||
this.sponsorName = dto.sponsorName;
|
||||
}
|
||||
|
||||
/** UI-specific: Welcome message */
|
||||
get welcomeMessage(): string {
|
||||
return `Welcome back, ${this.sponsorName}!`;
|
||||
}
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
|
||||
describe('view-models index', () => {
|
||||
it('should export view models', async () => {
|
||||
const module = await import('./index');
|
||||
expect(Object.keys(module).length).toBeGreaterThan(0);
|
||||
});
|
||||
});
|
||||
97
apps/website/lib/view-models/index.ts
Normal file
97
apps/website/lib/view-models/index.ts
Normal file
@@ -0,0 +1,97 @@
|
||||
export * from "./ActivityItemViewModel";
|
||||
export * from "./AdminUserViewModel";
|
||||
export * from "./AnalyticsDashboardViewModel";
|
||||
export * from "./AnalyticsMetricsViewModel";
|
||||
export * from "./AvailableLeaguesViewModel";
|
||||
export * from "./AvatarGenerationViewModel";
|
||||
export * from "./AvatarViewModel";
|
||||
export * from "./BillingViewModel";
|
||||
export * from "./CompleteOnboardingViewModel";
|
||||
export * from "./CreateLeagueViewModel";
|
||||
export * from "./CreateTeamViewModel";
|
||||
export * from "./DeleteMediaViewModel";
|
||||
export * from "./DriverLeaderboardItemViewModel";
|
||||
export * from "./DriverLeaderboardViewModel";
|
||||
export * from "./DriverProfileDriverSummaryViewModel";
|
||||
export * from "./DriverProfileViewModel";
|
||||
export * from "./DriverRegistrationStatusViewModel";
|
||||
export * from "./DriverSummaryViewModel";
|
||||
export * from "./DriverTeamViewModel";
|
||||
export * from "./DriverViewModel";
|
||||
export * from "./EmailSignupViewModel";
|
||||
export * from "./HomeDiscoveryViewModel";
|
||||
export * from "./ImportRaceResultsSummaryViewModel";
|
||||
export * from "./LeagueAdminRosterJoinRequestViewModel";
|
||||
export * from "./LeagueAdminRosterMemberViewModel";
|
||||
export * from "./LeagueAdminScheduleViewModel";
|
||||
export * from "./LeagueAdminViewModel";
|
||||
export * from "./LeagueCardViewModel";
|
||||
export * from "./LeagueDetailPageViewModel";
|
||||
export * from "./LeagueDetailViewModel";
|
||||
export * from "./LeagueJoinRequestViewModel";
|
||||
export * from "./LeagueMembershipsViewModel";
|
||||
export * from "./LeagueMemberViewModel";
|
||||
export * from "./LeaguePageDetailViewModel";
|
||||
export * from "./LeagueScheduleViewModel";
|
||||
export * from "./LeagueScoringChampionshipViewModel";
|
||||
export * from "./LeagueScoringConfigViewModel";
|
||||
export * from "./LeagueScoringPresetsViewModel";
|
||||
export * from "./LeagueScoringPresetViewModel";
|
||||
export * from "./LeagueScoringSectionViewModel";
|
||||
export * from "./LeagueSeasonSummaryViewModel";
|
||||
export * from "./LeagueSettingsViewModel";
|
||||
export * from "./LeagueStandingsViewModel";
|
||||
export * from "./LeagueStatsViewModel";
|
||||
export * from "./LeagueStewardingViewModel";
|
||||
export * from "./LeagueSummaryViewModel";
|
||||
export * from "./LeagueWalletViewModel";
|
||||
export * from "./MediaViewModel";
|
||||
export * from "./MembershipFeeViewModel";
|
||||
export * from "./OnboardingViewModel";
|
||||
export * from "./PaymentViewModel";
|
||||
export * from "./PrizeViewModel";
|
||||
export * from "./ProfileOverviewViewModel";
|
||||
export * from "./ProtestDetailViewModel";
|
||||
export * from "./ProtestDriverViewModel";
|
||||
export * from "./ProtestViewModel";
|
||||
export * from "./RaceDetailEntryViewModel";
|
||||
export * from "./RaceDetailsViewModel";
|
||||
export * from "./RaceDetailUserResultViewModel";
|
||||
export * from "./RaceListItemViewModel";
|
||||
export * from "./RaceResultsDetailViewModel";
|
||||
export * from "./RaceResultViewModel";
|
||||
export * from "./RacesPageViewModel";
|
||||
export * from "./RaceStatsViewModel";
|
||||
export * from "./RaceStewardingViewModel";
|
||||
export * from "./RaceViewModel";
|
||||
export * from "./RaceWithSOFViewModel";
|
||||
export * from "./RecordEngagementInputViewModel";
|
||||
export * from "./RecordEngagementOutputViewModel";
|
||||
export * from "./RecordPageViewInputViewModel";
|
||||
export * from "./RecordPageViewOutputViewModel";
|
||||
export * from "./RemoveMemberViewModel";
|
||||
export * from "./RenewalAlertViewModel";
|
||||
export * from "./RequestAvatarGenerationViewModel";
|
||||
export * from "./ScoringConfigurationViewModel";
|
||||
export * from "./SessionViewModel";
|
||||
export * from "./SponsorDashboardViewModel";
|
||||
export * from "./SponsorSettingsViewModel";
|
||||
export * from "./SponsorshipDetailViewModel";
|
||||
export * from "./SponsorshipPricingViewModel";
|
||||
export * from "./SponsorshipRequestViewModel";
|
||||
export * from "./SponsorshipViewModel";
|
||||
export * from "./SponsorSponsorshipsViewModel";
|
||||
export * from "./SponsorViewModel";
|
||||
export * from "./StandingEntryViewModel";
|
||||
export * from "./TeamCardViewModel";
|
||||
export * from "./TeamDetailsViewModel";
|
||||
export * from "./TeamJoinRequestViewModel";
|
||||
export * from "./TeamMemberViewModel";
|
||||
export * from "./TeamSummaryViewModel";
|
||||
export * from "./UpcomingRaceCardViewModel";
|
||||
export * from "./UpdateAvatarViewModel";
|
||||
export * from "./UpdateTeamViewModel";
|
||||
export * from "./UploadMediaViewModel";
|
||||
export * from "./UserProfileViewModel";
|
||||
export * from "./WalletTransactionViewModel";
|
||||
export * from "./WalletViewModel";
|
||||
Reference in New Issue
Block a user