website refactor

This commit is contained in:
2026-01-14 02:02:24 +01:00
parent 8d7c709e0c
commit 4522d41aef
291 changed files with 12763 additions and 9309 deletions

View File

@@ -0,0 +1,27 @@
/**
* AdminUsersViewData
*
* ViewData for AdminUsersTemplate.
* Template-ready data structure with only primitives.
*/
export interface AdminUsersViewData {
users: Array<{
id: string;
email: string;
displayName: string;
roles: string[];
status: string;
isSystemAdmin: boolean;
createdAt: string;
updatedAt: string;
lastLoginAt?: string;
primaryDriverId?: string;
}>;
total: number;
page: number;
limit: number;
totalPages: number;
// Pre-computed derived values for template
activeUserCount: number;
adminCount: number;
}

View File

@@ -0,0 +1,15 @@
export interface DriverRankingItem {
id: string;
name: string;
rating: number;
skillLevel: string;
nationality: string;
racesCompleted: number;
wins: number;
podiums: number;
rank: number;
avatarUrl: string;
winRate: string;
medalBg: string;
medalColor: string;
}

View File

@@ -1,33 +1,5 @@
/**
* DriverRankingsViewData - Pure ViewData for DriverRankingsTemplate
* Contains only raw serializable data, no methods or computed properties
*/
export interface DriverRankingItem {
id: string;
name: string;
rating: number;
skillLevel: string;
nationality: string;
racesCompleted: number;
wins: number;
podiums: number;
rank: number;
avatarUrl: string;
winRate: string;
medalBg: string;
medalColor: string;
}
export interface PodiumDriver {
id: string;
name: string;
rating: number;
wins: number;
podiums: number;
avatarUrl: string;
position: 1 | 2 | 3;
}
import type { DriverRankingItem } from './DriverRankingItem';
import type { PodiumDriver } from './PodiumDriver';
export interface DriverRankingsViewData {
drivers: DriverRankingItem[];
@@ -36,11 +8,4 @@ export interface DriverRankingsViewData {
selectedSkill: 'all' | 'pro' | 'advanced' | 'intermediate' | 'beginner';
sortBy: 'rank' | 'rating' | 'wins' | 'podiums' | 'winRate';
showFilters: boolean;
onSearchChange: (query: string) => void;
onSkillChange: (skill: 'all' | 'pro' | 'advanced' | 'intermediate' | 'beginner') => void;
onSortChange: (sort: 'rank' | 'rating' | 'wins' | 'podiums' | 'winRate') => void;
onToggleFilters: () => void;
onDriverClick: (id: string) => void;
onBackToLeaderboards: () => void;
onClearFilters: () => void;
}

View File

@@ -0,0 +1,11 @@
export interface LeaderboardDriverItem {
id: string;
name: string;
rating: number;
skillLevel: string;
nationality: string;
wins: number;
rank: number;
avatarUrl: string;
position: number;
}

View File

@@ -0,0 +1,10 @@
export interface LeaderboardTeamItem {
id: string;
name: string;
tag: string;
memberCount: number;
category?: string;
totalWins: number;
logoUrl: string;
position: number;
}

View File

@@ -0,0 +1,7 @@
import type { LeaderboardDriverItem } from './LeaderboardDriverItem';
import type { LeaderboardTeamItem } from './LeaderboardTeamItem';
export interface LeaderboardsViewData {
drivers: LeaderboardDriverItem[];
teams: LeaderboardTeamItem[];
}

View File

@@ -0,0 +1,34 @@
/**
* Leagues ViewData
*
* SSR-safe data structure that can be built directly from DTO
* without ViewModel instantiation. Contains formatted values
* for display and ISO string timestamps for JSON serialization.
*/
export interface LeaguesViewData {
leagues: Array<{
id: string;
name: string;
description: string | null;
logoUrl: string | null;
ownerId: string;
createdAt: string; // ISO string
maxDrivers: number;
usedDriverSlots: number;
maxTeams: number | undefined;
usedTeamSlots: number | undefined;
structureSummary: string;
timingSummary: string;
category: string | null;
scoring: {
gameId: string;
gameName: string;
primaryChampionshipType: string;
scoringPresetId: string;
scoringPresetName: string;
dropPolicySummary: string;
scoringPatternSummary: string;
} | undefined;
}>;
}

View File

@@ -0,0 +1,3 @@
export interface OnboardingPageViewData {
isAlreadyOnboarded: boolean;
}

View File

@@ -0,0 +1,9 @@
export interface PodiumDriver {
id: string;
name: string;
rating: number;
wins: number;
podiums: number;
avatarUrl: string;
position: 1 | 2 | 3;
}

View File

@@ -0,0 +1,63 @@
export interface ProfileViewData {
driver: {
id: string;
name: string;
countryCode: string;
countryFlag: string;
avatarUrl: string;
bio: string | null;
iracingId: string | null;
joinedAtLabel: string;
};
stats: {
ratingLabel: string;
globalRankLabel: string;
totalRacesLabel: string;
winsLabel: string;
podiumsLabel: string;
dnfsLabel: string;
bestFinishLabel: string;
worstFinishLabel: string;
avgFinishLabel: string;
consistencyLabel: string;
percentileLabel: string;
} | null;
teamMemberships: Array<{
teamId: string;
teamName: string;
teamTag: string | null;
roleLabel: string;
joinedAtLabel: string;
href: string;
}>;
extendedProfile: {
timezone: string;
racingStyle: string;
favoriteTrack: string;
favoriteCar: string;
availableHours: string;
lookingForTeamLabel: string;
openToRequestsLabel: string;
socialHandles: Array<{
platformLabel: string;
handle: string;
url: string;
}>;
achievements: Array<{
id: string;
title: string;
description: string;
earnedAtLabel: string;
icon: 'trophy' | 'medal' | 'star' | 'crown' | 'target' | 'zap';
rarityLabel: string;
}>;
friends: Array<{
id: string;
name: string;
countryFlag: string;
avatarUrl: string;
href: string;
}>;
friendsCountLabel: string;
} | null;
}

View File

@@ -0,0 +1,17 @@
import type { ViewData } from '@/lib/contracts/view-data/ViewData';
export type SponsorshipRequestsViewData = ViewData & {
sections: Array<{
entityType: 'driver' | 'team' | 'season';
entityId: string;
entityName: string;
requests: Array<{
id: string;
sponsorId: string;
sponsorName: string;
sponsorLogoUrl: string | null;
message: string | null;
createdAtIso: string;
}>;
}>;
};