website refactor

This commit is contained in:
2026-01-12 16:12:01 +01:00
parent a735a51a11
commit 1f0c4f7fa6
7 changed files with 168 additions and 0 deletions

View File

@@ -0,0 +1,70 @@
/**
* Dashboard 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 DashboardViewData {
currentDriver: {
name: string;
avatarUrl: string;
country: string;
rating: string;
rank: string;
totalRaces: string;
wins: string;
podiums: string;
consistency: string;
};
nextRace: {
id: string;
track: string;
car: string;
scheduledAt: string; // ISO string
formattedDate: string;
formattedTime: string;
timeUntil: string;
isMyLeague: boolean;
} | null;
upcomingRaces: Array<{
id: string;
track: string;
car: string;
scheduledAt: string; // ISO string
formattedDate: string;
formattedTime: string;
timeUntil: string;
isMyLeague: boolean;
}>;
leagueStandings: Array<{
leagueId: string;
leagueName: string;
position: string;
points: string;
totalDrivers: string;
}>;
feedItems: Array<{
id: string;
type: string;
headline: string;
body?: string;
timestamp: string; // ISO string
formattedTime: string;
ctaHref?: string;
ctaLabel?: string;
}>;
friends: Array<{
id: string;
name: string;
avatarUrl: string;
country: string;
}>;
activeLeaguesCount: string;
friendCount: string;
hasUpcomingRaces: boolean;
hasLeagueStandings: boolean;
hasFeedItems: boolean;
hasFriends: boolean;
}

View File

@@ -0,0 +1,46 @@
/**
* 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;
}
export interface DriverRankingsViewData {
drivers: DriverRankingItem[];
podium: PodiumDriver[];
searchQuery: string;
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,83 @@
/**
* LeagueDetailViewData - Pure ViewData for LeagueDetailTemplate
* Contains only raw serializable data, no methods or computed properties
*/
export interface LeagueInfoData {
name: string;
description?: string;
membersCount: number;
racesCount: number;
avgSOF: number | null;
structure: string;
scoring: string;
createdAt: string;
discordUrl?: string;
youtubeUrl?: string;
websiteUrl?: string;
}
export interface SponsorInfo {
id: string;
name: string;
tier: 'main' | 'secondary';
logoUrl?: string;
websiteUrl?: string;
tagline?: string;
}
export interface LiveRaceData {
id: string;
name: string;
date: string;
registeredCount?: number;
strengthOfField?: number;
}
export interface DriverSummaryData {
driverId: string;
driverName: string;
avatarUrl: string | null;
rating: number | null;
rank: number | null;
roleBadgeText: string;
roleBadgeClasses: string;
profileUrl: string;
}
export interface LeagueDetailViewData {
// Basic info
leagueId: string;
name: string;
description: string;
// Info card data
info: LeagueInfoData;
// Live races
runningRaces: LiveRaceData[];
// Sponsors
sponsors: SponsorInfo[];
// Management
ownerSummary: DriverSummaryData | null;
adminSummaries: DriverSummaryData[];
stewardSummaries: DriverSummaryData[];
// Sponsor insights (for sponsor mode)
sponsorInsights: {
avgViewsPerRace: number;
engagementRate: string;
estimatedReach: number;
tier: 'premium' | 'standard' | 'starter';
trustScore: number;
discordMembers: number;
monthlyActivity: number;
mainSponsorAvailable: boolean;
secondarySlotsAvailable: number;
mainSponsorPrice: number;
secondaryPrice: number;
totalImpressions: number;
} | null;
}

View File

@@ -0,0 +1,39 @@
/**
* LeagueStandingsViewData - Pure ViewData for LeagueStandingsTemplate
* Contains only raw serializable data, no methods or computed properties
*/
export interface StandingEntryData {
driverId: string;
position: number;
points: number;
wins: number;
podiums: number;
races: number;
}
export interface DriverData {
id: string;
name: string;
avatarUrl: string | null;
iracingId?: string;
rating?: number;
country?: string;
}
export interface LeagueMembershipData {
driverId: string;
leagueId: string;
role: 'owner' | 'admin' | 'steward' | 'member';
joinedAt: string;
status: 'active' | 'pending' | 'banned';
}
export interface LeagueStandingsViewData {
standings: StandingEntryData[];
drivers: DriverData[];
memberships: LeagueMembershipData[];
leagueId: string;
currentDriverId: string | null;
isAdmin: boolean;
}

View File

@@ -0,0 +1,16 @@
/**
* ViewData for Profile Leagues page
* Pure, JSON-serializable data structure for Template rendering
*/
export interface ProfileLeaguesLeagueViewData {
leagueId: string;
name: string;
description: string;
membershipRole: 'owner' | 'admin' | 'steward' | 'member';
}
export interface ProfileLeaguesViewData {
ownedLeagues: ProfileLeaguesLeagueViewData[];
memberLeagues: ProfileLeaguesLeagueViewData[];
}

View File

@@ -0,0 +1,40 @@
/**
* TeamDetailViewData - Pure ViewData for TeamDetailTemplate
* Contains only raw serializable data, no methods or computed properties
*/
export interface TeamDetailData {
id: string;
name: string;
tag: string;
description?: string;
ownerId: string;
leagues: string[];
createdAt?: string;
specialization?: string;
region?: string;
languages?: string[];
category?: string;
membership?: {
role: string;
joinedAt: string;
isActive: boolean;
} | null;
canManage: boolean;
}
export interface TeamMemberData {
driverId: string;
driverName: string;
role: 'owner' | 'manager' | 'member';
joinedAt: string;
isActive: boolean;
avatarUrl: string;
}
export interface TeamDetailViewData {
team: TeamDetailData;
memberships: TeamMemberData[];
currentDriverId: string;
isAdmin: boolean;
}

View File

@@ -0,0 +1,16 @@
/**
* TeamsViewData - Pure ViewData for TeamsTemplate
* Contains only raw serializable data, no methods or computed properties
*/
export interface TeamSummaryData {
teamId: string;
teamName: string;
leagueName: string;
memberCount: number;
logoUrl?: string;
}
export interface TeamsViewData {
teams: TeamSummaryData[];
}