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,21 @@
export class CountryFlagDisplay {
private constructor(private readonly value: string) {}
static fromCountryCode(countryCode: string | null | undefined): CountryFlagDisplay {
if (!countryCode) {
return new CountryFlagDisplay('🏁');
}
const code = countryCode.toUpperCase();
if (code.length !== 2) {
return new CountryFlagDisplay('🏁');
}
const codePoints = [...code].map((char) => 127397 + char.charCodeAt(0));
return new CountryFlagDisplay(String.fromCodePoint(...codePoints));
}
toString(): string {
return this.value;
}
}

View File

@@ -0,0 +1,11 @@
/**
* DashboardConsistencyDisplay
*
* Deterministic consistency formatting for dashboard display.
*/
export class DashboardConsistencyDisplay {
static format(consistency: number): string {
return `${consistency}%`;
}
}

View File

@@ -0,0 +1,11 @@
/**
* DashboardCountDisplay
*
* Deterministic count formatting for dashboard display.
*/
export class DashboardCountDisplay {
static format(count: number): string {
return count.toString();
}
}

View File

@@ -0,0 +1,53 @@
/**
* DashboardDateDisplay
*
* Deterministic date formatting for dashboard display.
* No Intl.* or toLocale* methods.
*/
export interface DashboardDateDisplayData {
date: string;
time: string;
relative: string;
}
/**
* Format date for display (deterministic, no Intl)
*/
export class DashboardDateDisplay {
static format(date: Date): DashboardDateDisplayData {
const days = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
const dayName = days[date.getDay()];
const month = months[date.getMonth()];
const day = date.getDate();
const year = date.getFullYear();
const hours = date.getHours().toString().padStart(2, '0');
const minutes = date.getMinutes().toString().padStart(2, '0');
// Calculate relative time (deterministic)
const now = new Date();
const diffMs = date.getTime() - now.getTime();
const diffHours = Math.floor(diffMs / (1000 * 60 * 60));
const diffDays = Math.floor(diffHours / 24);
let relative: string;
if (diffHours < 0) {
relative = 'Past';
} else if (diffHours === 0) {
relative = 'Now';
} else if (diffHours < 24) {
relative = `${diffHours}h`;
} else {
relative = `${diffDays}d`;
}
return {
date: `${dayName}, ${month} ${day}, ${year}`,
time: `${hours}:${minutes}`,
relative,
};
}
}

View File

@@ -1,138 +0,0 @@
/**
* Dashboard Display Objects
*
* Deterministic formatting for dashboard data without Intl.* or toLocale*
*/
export interface DashboardStatDisplayData {
icon: string;
color: string;
label: string;
}
export interface DashboardDateDisplayData {
date: string;
time: string;
relative: string;
}
/**
* Stat card display configurations
*/
export const dashboardStatDisplay = {
wins: {
icon: 'Trophy',
color: 'bg-performance-green/20 text-performance-green',
label: 'Wins',
},
podiums: {
icon: 'Medal',
color: 'bg-warning-amber/20 text-warning-amber',
label: 'Podiums',
},
consistency: {
icon: 'Target',
color: 'bg-primary-blue/20 text-primary-blue',
label: 'Consistency',
},
activeLeagues: {
icon: 'Users',
color: 'bg-purple-500/20 text-purple-400',
label: 'Active Leagues',
},
} as const;
/**
* Format date for display (deterministic, no Intl)
*/
export function formatDashboardDate(date: Date): DashboardDateDisplayData {
const days = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
const dayName = days[date.getDay()];
const month = months[date.getMonth()];
const day = date.getDate();
const year = date.getFullYear();
const hours = date.getHours().toString().padStart(2, '0');
const minutes = date.getMinutes().toString().padStart(2, '0');
// Calculate relative time (deterministic)
const now = new Date();
const diffMs = date.getTime() - now.getTime();
const diffHours = Math.floor(diffMs / (1000 * 60 * 60));
const diffDays = Math.floor(diffHours / 24);
let relative: string;
if (diffHours < 0) {
relative = 'Past';
} else if (diffHours === 0) {
relative = 'Now';
} else if (diffHours < 24) {
relative = `${diffHours}h`;
} else {
relative = `${diffDays}d`;
}
return {
date: `${dayName}, ${month} ${day}, ${year}`,
time: `${hours}:${minutes}`,
relative,
};
}
/**
* Format rating for display
*/
export function formatRating(rating: number): string {
return rating.toFixed(1);
}
/**
* Format rank for display
*/
export function formatRank(rank: number): string {
return rank.toString();
}
/**
* Format consistency percentage
*/
export function formatConsistency(consistency: number): string {
return `${consistency}%`;
}
/**
* Format race count
*/
export function formatRaceCount(count: number): string {
return count.toString();
}
/**
* Format friend count
*/
export function formatFriendCount(count: number): string {
return count.toString();
}
/**
* Format league position
*/
export function formatLeaguePosition(position: number): string {
return `#${position}`;
}
/**
* Format points
*/
export function formatPoints(points: number): string {
return points.toString();
}
/**
* Format total drivers
*/
export function formatTotalDrivers(total: number): string {
return total.toString();
}

View File

@@ -0,0 +1,11 @@
/**
* DashboardLeaguePositionDisplay
*
* Deterministic league position formatting for dashboard display.
*/
export class DashboardLeaguePositionDisplay {
static format(position: number): string {
return `#${position}`;
}
}

View File

@@ -0,0 +1,11 @@
/**
* DashboardRankDisplay
*
* Deterministic rank formatting for dashboard display.
*/
export class DashboardRankDisplay {
static format(rank: number): string {
return rank.toString();
}
}

View File

@@ -0,0 +1,11 @@
/**
* RatingDisplay
*
* Deterministic rating formatting for display.
*/
export class RatingDisplay {
static format(rating: number): string {
return rating.toFixed(1);
}
}