website refactor

This commit is contained in:
2026-01-19 14:07:49 +01:00
parent 54f42bab9f
commit 6154d54435
88 changed files with 755 additions and 566 deletions

View File

@@ -75,12 +75,12 @@ export function DriverProfileTemplate({
const { currentDriver, stats, teamMemberships, socialSummary, extendedProfile } = viewData;
const careerStats = stats ? [
{ label: 'Rating', value: stats.rating || 0, color: 'text-primary-blue' },
{ label: 'Wins', value: stats.wins, color: 'text-performance-green' },
{ label: 'Podiums', value: stats.podiums, color: 'text-warning-amber' },
{ label: 'Total Races', value: stats.totalRaces },
{ label: 'Avg Finish', value: stats.avgFinish?.toFixed(1) || '-', subValue: 'POS' },
{ label: 'Consistency', value: stats.consistency ? `${stats.consistency}%` : '-' },
{ label: 'Rating', value: stats.ratingLabel, color: 'text-primary-blue' },
{ label: 'Wins', value: stats.winsLabel, color: 'text-performance-green' },
{ label: 'Podiums', value: stats.podiumsLabel, color: 'text-warning-amber' },
{ label: 'Total Races', value: stats.totalRacesLabel },
{ label: 'Avg Finish', value: stats.avgFinishLabel, subValue: 'POS' },
{ label: 'Consistency', value: stats.consistencyLabel, color: 'text-primary-blue' },
] : [];
return (
@@ -115,7 +115,9 @@ export function DriverProfileTemplate({
avatarUrl={currentDriver.avatarUrl}
nationality={currentDriver.country}
rating={stats?.rating || 0}
globalRank={currentDriver.globalRank ?? undefined}
ratingLabel={currentDriver.ratingLabel}
safetyRatingLabel="SR 92"
globalRankLabel={currentDriver.globalRankLabel}
bio={currentDriver.bio}
friendRequestSent={friendRequestSent}
onAddFriend={onAddFriend}
@@ -132,7 +134,7 @@ export function DriverProfileTemplate({
memberships={teamMemberships.map((m) => ({
team: { id: m.teamId, name: m.teamName },
role: m.role,
joinedAt: new Date(m.joinedAt)
joinedAtLabel: m.joinedAtLabel
}))}
/>
)}
@@ -172,7 +174,8 @@ export function DriverProfileTemplate({
<AchievementGrid
achievements={extendedProfile.achievements.map((a) => ({
...a,
earnedAt: new Date(a.earnedAt)
rarity: a.rarityLabel,
earnedAtLabel: a.earnedAtLabel
}))}
/>
)}

View File

@@ -36,10 +36,10 @@ export function DriversTemplate({
<Container size="lg" py={8}>
<Stack gap={10}>
<DriversDirectoryHeader
totalDrivers={drivers.length}
activeDrivers={activeCount}
totalWins={totalWins}
totalRaces={totalRaces}
totalDriversLabel={viewData?.totalDriversLabel || '0'}
activeDriversLabel={viewData?.activeCountLabel || '0'}
totalWinsLabel={viewData?.totalWinsLabel || '0'}
totalRacesLabel={viewData?.totalRacesLabel || '0'}
onViewLeaderboard={onViewLeaderboard}
/>
@@ -54,7 +54,8 @@ export function DriversTemplate({
avatarUrl={driver.avatarUrl}
nationality={driver.nationality}
rating={driver.rating}
wins={driver.wins}
ratingLabel={driver.ratingLabel}
winsLabel={String(driver.wins)}
onClick={() => onDriverClick(driver.id)}
/>
))}

View File

@@ -121,7 +121,7 @@ export function LeagueSponsorshipsTemplate({ viewData }: LeagueSponsorshipsTempl
key={request.id}
request={{
...request,
slotName: slot?.name || 'Unknown slot'
slotName: slot?.name || 'Unknown slot',
}}
/>
);

View File

@@ -40,9 +40,9 @@ export function LeagueWalletTemplate({ viewData, onExport, transactions }: Leagu
</SharedBox>
<WalletSummaryPanel
balance={viewData.balance}
formattedBalance={viewData.formattedBalance}
currency="USD"
transactions={transactions}
transactions={viewData.transactions}
onDeposit={() => {}} // Not implemented for leagues yet
onWithdraw={() => {}} // Not implemented for leagues yet
/>

View File

@@ -70,10 +70,9 @@ export function ProfileTemplate({
...viewData.driver,
country: viewData.driver.countryCode,
iracingId: Number(viewData.driver.iracingId) || 0,
joinedAt: new Date().toISOString(), // Placeholder
}}
stats={viewData.stats ? { rating: Number(viewData.stats.ratingLabel) || 0 } : null}
globalRank={Number(viewData.stats?.globalRankLabel) || 0}
stats={viewData.stats ? { ratingLabel: viewData.stats.ratingLabel } : null}
globalRankLabel={viewData.stats?.globalRankLabel || '—'}
onAddFriend={onFriendRequestSend}
friendRequestSent={friendRequestSent}
isOwnProfile={true}
@@ -99,7 +98,7 @@ export function ProfileTemplate({
memberships={viewData.teamMemberships.map(m => ({
team: { id: m.teamId, name: m.teamName },
role: m.roleLabel,
joinedAt: new Date() // Placeholder
joinedAtLabel: m.joinedAtLabel
}))}
/>
</Stack>
@@ -117,7 +116,7 @@ export function ProfileTemplate({
achievements={viewData.extendedProfile.achievements.map(a => ({
...a,
rarity: a.rarityLabel,
earnedAt: new Date() // Placeholder
earnedAtLabel: a.earnedAtLabel
}))}
/>
</Stack>

View File

@@ -62,7 +62,7 @@ export function RosterAdminTemplate({
<Stack direction={{ base: 'col', md: 'row' }} align="center" justify="between" gap={4}>
<Stack gap={1}>
<Text weight="bold" color="text-white">{req.driver.name}</Text>
<Text size="xs" color="text-gray-500">{new Date(req.requestedAt).toLocaleString()}</Text>
<Text size="xs" color="text-gray-500">{req.formattedRequestedAt}</Text>
{req.message && (
<Text size="sm" color="text-gray-400" mt={1}>&quot;{req.message}&quot;</Text>
)}
@@ -117,7 +117,7 @@ export function RosterAdminTemplate({
<Text weight="bold" color="text-white">{member.driver.name}</Text>
</TableCell>
<TableCell>
<Text size="sm" color="text-gray-400">{new Date(member.joinedAt).toLocaleDateString()}</Text>
<Text size="sm" color="text-gray-400">{member.formattedJoinedAt}</Text>
</TableCell>
<TableCell>
<Box

View File

@@ -27,10 +27,10 @@ export interface SponsorCampaignsViewData {
leagueName: string;
seasonName: string;
tier: string;
pricing: { amount: number; currency: string };
metrics: { impressions: number };
seasonStartDate?: Date;
seasonEndDate?: Date;
formattedInvestment: string;
formattedImpressions: string;
formattedStartDate?: string;
formattedEndDate?: string;
}>;
stats: {
total: number;
@@ -38,8 +38,8 @@ export interface SponsorCampaignsViewData {
pending: number;
approved: number;
rejected: number;
totalInvestment: number;
totalImpressions: number;
formattedTotalInvestment: string;
formattedTotalImpressions: string;
};
}
@@ -80,13 +80,13 @@ export function SponsorCampaignsTemplate({
},
{
label: 'Total Investment',
value: `$${viewData.stats.totalInvestment.toLocaleString()}`,
value: viewData.stats.formattedTotalInvestment,
icon: BarChart3,
variant: 'info',
},
{
label: 'Total Impressions',
value: `${(viewData.stats.totalImpressions / 1000).toFixed(0)}k`,
value: viewData.stats.formattedTotalImpressions,
icon: Eye,
variant: 'default',
},
@@ -153,10 +153,10 @@ export function SponsorCampaignsTemplate({
title={s.leagueName}
subtitle={s.seasonName}
tier={s.tier}
investment={`$${s.pricing.amount.toLocaleString()}`}
impressions={s.metrics.impressions.toLocaleString()}
startDate={s.seasonStartDate ? new Date(s.seasonStartDate).toLocaleDateString() : undefined}
endDate={s.seasonEndDate ? new Date(s.seasonEndDate).toLocaleDateString() : undefined}
investment={s.formattedInvestment}
impressions={s.formattedImpressions}
startDate={s.formattedStartDate}
endDate={s.formattedEndDate}
/>
);
})}

View File

@@ -148,40 +148,40 @@ export function SponsorDashboardTemplate({ viewData }: SponsorDashboardTemplateP
<SponsorshipCategoryCard
icon={Trophy}
title="Leagues"
count={categoryData.leagues.count}
impressions={categoryData.leagues.impressions}
countLabel={categoryData.leagues.countLabel}
impressionsLabel={categoryData.leagues.impressionsLabel}
color="#3b82f6"
href="/sponsor/campaigns?type=leagues"
/>
<SponsorshipCategoryCard
icon={Users}
title="Teams"
count={categoryData.teams.count}
impressions={categoryData.teams.impressions}
countLabel={categoryData.teams.countLabel}
impressionsLabel={categoryData.teams.impressionsLabel}
color="#a855f7"
href="/sponsor/campaigns?type=teams"
/>
<SponsorshipCategoryCard
icon={Car}
title="Drivers"
count={categoryData.drivers.count}
impressions={categoryData.drivers.impressions}
countLabel={categoryData.drivers.countLabel}
impressionsLabel={categoryData.drivers.impressionsLabel}
color="#10b981"
href="/sponsor/campaigns?type=drivers"
/>
<SponsorshipCategoryCard
icon={Flag}
title="Races"
count={categoryData.races.count}
impressions={categoryData.races.impressions}
countLabel={categoryData.races.countLabel}
impressionsLabel={categoryData.races.impressionsLabel}
color="#f59e0b"
href="/sponsor/campaigns?type=races"
/>
<SponsorshipCategoryCard
icon={Megaphone}
title="Platform Ads"
count={categoryData.platform.count}
impressions={categoryData.platform.impressions}
countLabel={categoryData.platform.countLabel}
impressionsLabel={categoryData.platform.impressionsLabel}
color="#ef4444"
href="/sponsor/campaigns?type=platform"
/>

View File

@@ -45,11 +45,16 @@ export interface SponsorLeagueDetailViewData extends ViewData {
description: string;
tier: 'premium' | 'standard' | 'starter';
rating: number;
formattedRating: string;
drivers: number;
formattedDrivers: string;
races: number;
formattedRaces: string;
completedRaces: number;
racesLeft: number;
formattedRacesLeft: string;
engagement: number;
formattedEngagement: string;
totalImpressions: number;
formattedTotalImpressions: string;
projectedTotal: number;
@@ -61,17 +66,20 @@ export interface SponsorLeagueDetailViewData extends ViewData {
nextRace?: {
name: string;
date: string;
formattedDate: string;
};
sponsorSlots: {
main: {
available: boolean;
price: number;
priceLabel: string;
benefits: string[];
};
secondary: {
available: number;
total: number;
price: number;
priceLabel: string;
benefits: string[];
};
};
@@ -84,10 +92,12 @@ export interface SponsorLeagueDetailViewData extends ViewData {
drivers: Array<{
id: string;
position: number;
positionLabel: string;
name: string;
team: string;
country: string;
races: number;
formattedRaces: string;
impressions: number;
formattedImpressions: string;
}>;
@@ -98,6 +108,7 @@ export interface SponsorLeagueDetailViewData extends ViewData {
formattedDate: string;
status: 'completed' | 'upcoming';
views: number;
formattedViews: string;
}>;
}
@@ -139,13 +150,13 @@ export function SponsorLeagueDetailTemplate({
},
{
label: 'Engagement',
value: `${league.engagement}%`,
value: league.formattedEngagement,
icon: BarChart3,
variant: 'warning',
},
{
label: 'Races Left',
value: league.racesLeft,
value: league.formattedRacesLeft,
icon: Calendar,
variant: 'default',
},
@@ -156,6 +167,7 @@ export function SponsorLeagueDetailTemplate({
id: 'main',
name: 'Main Sponsor',
price: league.sponsorSlots.main.price,
priceLabel: league.sponsorSlots.main.priceLabel,
period: 'Season',
description: 'Exclusive primary branding across all league assets.',
features: league.sponsorSlots.main.benefits,
@@ -166,6 +178,7 @@ export function SponsorLeagueDetailTemplate({
id: 'secondary',
name: 'Secondary Sponsor',
price: league.sponsorSlots.secondary.price,
priceLabel: league.sponsorSlots.secondary.priceLabel,
period: 'Season',
description: 'Supporting branding on cars and broadcast overlays.',
features: league.sponsorSlots.secondary.benefits,
@@ -238,8 +251,8 @@ export function SponsorLeagueDetailTemplate({
<InfoRow label="Platform" value={league.game} />
<InfoRow label="Season" value={league.season} />
<InfoRow label="Duration" value="Oct 2025 - Feb 2026" />
<InfoRow label="Drivers" value={league.drivers} />
<InfoRow label="Races" value={league.races} last />
<InfoRow label="Drivers" value={league.formattedDrivers} />
<InfoRow label="Races" value={league.formattedRaces} last />
</SharedStack>
</SharedCard>
@@ -253,8 +266,8 @@ export function SponsorLeagueDetailTemplate({
<InfoRow label="Total Season Views" value={league.formattedTotalImpressions} />
<InfoRow label="Projected Total" value={league.formattedProjectedTotal} />
<InfoRow label="Main Sponsor CPM" value={league.formattedMainSponsorCpm} color="text-performance-green" />
<InfoRow label="Engagement Rate" value={`${league.engagement}%`} />
<InfoRow label="League Rating" value={`${league.rating}/5.0`} last />
<InfoRow label="Engagement Rate" value={league.formattedEngagement} />
<InfoRow label="League Rating" value={league.formattedRating} last />
</SharedStack>
</SharedCard>
@@ -274,7 +287,7 @@ export function SponsorLeagueDetailTemplate({
</Surface>
<SharedBox>
<SharedText size="lg" weight="semibold" color="text-white" block>{league.nextRace.name}</SharedText>
<SharedText size="sm" color="text-gray-400" block mt={1}>{league.nextRace.date}</SharedText>
<SharedText size="sm" color="text-gray-400" block mt={1}>{league.nextRace.formattedDate}</SharedText>
</SharedBox>
</SharedStack>
<SharedButton variant="secondary">
@@ -300,7 +313,7 @@ export function SponsorLeagueDetailTemplate({
<SharedStack direction="row" align="center" justify="between">
<SharedStack direction="row" align="center" gap={4}>
<Surface variant="muted" rounded="full" padding={1} style={{ width: '2.5rem', height: '2.5rem', display: 'flex', alignItems: 'center', justifyContent: 'center', background: '#262626' }}>
<SharedText weight="bold" color="text-white">{driver.position}</SharedText>
<SharedText weight="bold" color="text-white">{driver.positionLabel}</SharedText>
</Surface>
<SharedBox>
<SharedText weight="medium" color="text-white" block>{driver.name}</SharedText>
@@ -309,7 +322,7 @@ export function SponsorLeagueDetailTemplate({
</SharedStack>
<SharedStack direction="row" align="center" gap={8}>
<SharedBox textAlign="right">
<SharedText weight="medium" color="text-white" block>{driver.races}</SharedText>
<SharedText weight="medium" color="text-white" block>{driver.formattedRaces}</SharedText>
<SharedText size="xs" color="text-gray-500">races</SharedText>
</SharedBox>
<SharedBox textAlign="right">
@@ -344,7 +357,7 @@ export function SponsorLeagueDetailTemplate({
<SharedBox>
{race.status === 'completed' ? (
<SharedBox textAlign="right">
<SharedText weight="semibold" color="text-white" block>{race.views.toLocaleString()}</SharedText>
<SharedText weight="semibold" color="text-white" block>{race.formattedViews}</SharedText>
<SharedText size="xs" color="text-gray-500">views</SharedText>
</SharedBox>
) : (
@@ -384,7 +397,7 @@ export function SponsorLeagueDetailTemplate({
<SharedStack gap={3} mb={6}>
<InfoRow label="Selected Tier" value={`${selectedTier.charAt(0).toUpperCase() + selectedTier.slice(1)} Sponsor`} />
<InfoRow label="Season Price" value={`$${selectedTier === 'main' ? league.sponsorSlots.main.price : league.sponsorSlots.secondary.price}`} />
<InfoRow label="Season Price" value={selectedTier === 'main' ? league.sponsorSlots.main.priceLabel : league.sponsorSlots.secondary.priceLabel} />
<InfoRow label={`Platform Fee (${siteConfig.fees.platformFeePercent}%)`} value={`$${((selectedTier === 'main' ? league.sponsorSlots.main.price : league.sponsorSlots.secondary.price) * siteConfig.fees.platformFeePercent / 100).toFixed(2)}`} />
<SharedBox pt={4} borderTop borderColor="border-neutral-800">
<SharedStack direction="row" align="center" justify="between">

View File

@@ -96,9 +96,9 @@ export function TeamDetailTemplate({
entityName={team.name}
tier="standard"
metrics={viewData.teamMetrics}
slots={SlotTemplates.team(true, true, 500, 250)}
trustScore={90}
monthlyActivity={85}
slots={SlotTemplates.team(true, true, '$500', '$250')}
trustScoreLabel="90/100"
monthlyActivityLabel="85%"
onNavigate={(href) => window.location.href = href}
/>
)}

View File

@@ -33,6 +33,9 @@ export function TeamsTemplate({ viewData, onTeamClick, onViewFullLeaderboard, on
name={team.teamName}
memberCount={team.memberCount}
logo={team.logoUrl}
ratingLabel={team.ratingLabel}
winsLabel={team.winsLabel}
racesLabel={team.racesLabel}
onClick={() => onTeamClick?.(team.teamId)}
/>
))}