website refactor
This commit is contained in:
@@ -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
|
||||
}))}
|
||||
/>
|
||||
)}
|
||||
|
||||
@@ -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)}
|
||||
/>
|
||||
))}
|
||||
|
||||
@@ -121,7 +121,7 @@ export function LeagueSponsorshipsTemplate({ viewData }: LeagueSponsorshipsTempl
|
||||
key={request.id}
|
||||
request={{
|
||||
...request,
|
||||
slotName: slot?.name || 'Unknown slot'
|
||||
slotName: slot?.name || 'Unknown slot',
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -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
|
||||
/>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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}>"{req.message}"</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
|
||||
|
||||
@@ -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}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
|
||||
@@ -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"
|
||||
/>
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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}
|
||||
/>
|
||||
)}
|
||||
|
||||
@@ -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)}
|
||||
/>
|
||||
))}
|
||||
|
||||
Reference in New Issue
Block a user