website refactor

This commit is contained in:
2026-01-18 16:18:18 +01:00
parent 0b301feb61
commit 13567d51af
329 changed files with 4701 additions and 4750 deletions

View File

@@ -1,9 +1,9 @@
import React from 'react';
import { Box, BoxProps } from '@/ui/Box';
import { Stack } from '@/ui/Stack';
import { Text } from '@/ui/Text';
import { Icon } from '@/ui/Icon';
import { LucideIcon } from 'lucide-react';
import { Grid } from '@/ui/Grid';
interface BillingStatProps {
label: string;
@@ -31,16 +31,16 @@ function BillingStat({ label, value, subValue, icon, variant = 'default' }: Bill
};
return (
<Box p={4} bg="bg-iron-gray/20" rounded="lg" border borderColor="border-charcoal-outline/50">
<Stack p={4} bg="bg-iron-gray/20" rounded="lg" border borderColor="border-charcoal-outline/50">
<Stack direction="row" align="center" gap={3} mb={2}>
<Box p={2} rounded="md" bg={bgMap[variant] as BoxProps<'div'>['bg']}>
<Stack p={2} rounded="md" bg={bgMap[variant]}>
<Icon icon={icon} size={4} color={colorMap[variant] as any} />
</Box>
</Stack>
<Text size="xs" weight="medium" color="text-gray-500" uppercase letterSpacing="wider">
{label}
</Text>
</Stack>
<Box>
<Stack>
<Text size="xl" weight="bold" color={colorMap[variant] as any}>
{value}
</Text>
@@ -49,8 +49,8 @@ function BillingStat({ label, value, subValue, icon, variant = 'default' }: Bill
{subValue}
</Text>
)}
</Box>
</Box>
</Stack>
</Stack>
);
}
@@ -66,10 +66,10 @@ interface BillingSummaryPanelProps {
*/
export function BillingSummaryPanel({ stats }: BillingSummaryPanelProps) {
return (
<Box display="grid" gridCols={{ base: 1, sm: 2, lg: 4 }} gap={4} mb={8}>
<Grid cols={1} mdCols={2} lgCols={4} gap={4} mb={8}>
{stats.map((stat, index) => (
<BillingStat key={index} {...stat} />
))}
</Box>
</Grid>
);
}

View File

@@ -2,10 +2,9 @@
import React, { useState } from 'react';
import { Building } from 'lucide-react';
import { Box } from '@/ui/Box';
import { Stack } from '@/ui/Stack';
import { Text } from '@/ui/Text';
import { Heading } from '@/ui/Heading';
import { Stack } from '@/ui/Stack';
import { Icon } from '@/ui/Icon';
import { Badge } from '@/ui/Badge';
import { SponsorshipRequestItem } from '@/components/sponsors/SponsorshipRequestItem';
@@ -68,34 +67,34 @@ export function PendingSponsorshipRequests({
if (isLoading) {
return (
<Box textAlign="center" py={8}>
<Stack textAlign="center" py={8}>
<Text color="text-gray-400" animate="pulse">Loading sponsorship requests...</Text>
</Box>
</Stack>
);
}
if (requests.length === 0) {
return (
<Box textAlign="center" py={8}>
<Box w="12" h="12" mx="auto" mb={3} rounded="full" bg="bg-iron-gray/50" display="flex" alignItems="center" justifyContent="center">
<Stack textAlign="center" py={8}>
<Stack w="12" h="12" mx="auto" mb={3} rounded="full" bg="bg-iron-gray/50" display="flex" alignItems="center" justifyContent="center">
<Icon icon={Building} size={6} color="rgb(115, 115, 115)" />
</Box>
</Stack>
<Text color="text-gray-400" size="sm" block>No pending sponsorship requests</Text>
<Text color="text-gray-500" size="xs" mt={1} block>
When sponsors apply to sponsor this {entityType}, their requests will appear here. Sponsorships are attached to seasons, so you can change partners from season to season.
</Text>
</Box>
</Stack>
);
}
return (
<Stack gap={4}>
<Box display="flex" alignItems="center" justifyContent="between">
<Stack display="flex" alignItems="center" justifyContent="between">
<Heading level={3}>Sponsorship Requests</Heading>
<Badge variant="primary">
{requests.length} pending
</Badge>
</Box>
</Stack>
<Stack gap={3}>
{requests.map((request) => (
@@ -123,12 +122,12 @@ export function PendingSponsorshipRequests({
))}
</Stack>
<Box mt={4}>
<Stack mt={4}>
<Text size="xs" color="text-gray-500" block>
<Text weight="bold" color="text-gray-400">Note:</Text> Accepting a request will activate the sponsorship.
The sponsor will be charged per season and you&apos;ll receive the payment minus 10% platform fee.
</Text>
</Box>
</Stack>
</Stack>
);
}

View File

@@ -1,8 +1,7 @@
import React from 'react';
import { Box } from '@/ui/Box';
import { Stack } from '@/ui/Stack';
import { Text } from '@/ui/Text';
import { Heading } from '@/ui/Heading';
import { Stack } from '@/ui/Stack';
import { Icon } from '@/ui/Icon';
import { Check, Info } from 'lucide-react';
@@ -32,13 +31,13 @@ interface PricingTableShellProps {
*/
export function PricingTableShell({ title, tiers, onSelect, selectedId }: PricingTableShellProps) {
return (
<Box mb={8}>
<Stack mb={8}>
<Heading level={3} fontSize="lg" weight="semibold" mb={4} color="text-white">
{title}
</Heading>
<Box display="grid" gridCols={{ base: 1, md: 3 }} gap={6}>
<Stack display="grid" gridCols={{ base: 1, md: 3 }} gap={6}>
{tiers.map((tier) => (
<Box
<Stack
key={tier.id}
p={6}
rounded="xl"
@@ -52,7 +51,7 @@ export function PricingTableShell({ title, tiers, onSelect, selectedId }: Pricin
hoverBorderColor={selectedId === tier.id ? 'border-primary-blue' : 'border-charcoal-outline'}
>
{tier.isPopular && (
<Box
<Stack
position="absolute"
top={0}
right={6}
@@ -63,10 +62,10 @@ export function PricingTableShell({ title, tiers, onSelect, selectedId }: Pricin
rounded="full"
>
<Text size="xs" weight="bold" color="text-white" uppercase letterSpacing="wider">Popular</Text>
</Box>
</Stack>
)}
<Box mb={6}>
<Stack mb={6}>
<Text size="sm" weight="bold" color="text-primary-blue" uppercase letterSpacing="wider" block mb={2}>
{tier.name}
</Text>
@@ -77,28 +76,28 @@ export function PricingTableShell({ title, tiers, onSelect, selectedId }: Pricin
<Text size="sm" color="text-gray-400" block mt={2}>
{tier.description}
</Text>
</Box>
</Stack>
<Stack gap={3} mb={8}>
{tier.features.map((feature, i) => (
<Stack key={i} direction="row" align="start" gap={3}>
<Box mt={0.5}>
<Stack mt={0.5}>
<Icon icon={Check} size={3.5} color="text-performance-green" />
</Box>
</Stack>
<Text size="sm" color="text-gray-300">{feature}</Text>
</Stack>
))}
</Stack>
{!tier.available && (
<Box display="flex" alignItems="center" gap={2} p={3} rounded="lg" bg="bg-racing-red/10" border borderColor="border-racing-red/20">
<Stack display="flex" alignItems="center" gap={2} p={3} rounded="lg" bg="bg-racing-red/10" border borderColor="border-racing-red/20">
<Icon icon={Info} size={4} color="text-racing-red" />
<Text size="xs" weight="medium" color="text-racing-red">Currently Unavailable</Text>
</Box>
</Stack>
)}
</Box>
</Stack>
))}
</Box>
</Box>
</Stack>
</Stack>
);
}

View File

@@ -1,10 +1,9 @@
import { LucideIcon } from 'lucide-react';
import { Box } from '@/ui/Box';
import { Stack } from '@/ui/Stack';
import { Button } from '@/ui/Button';
import { Icon } from '@/ui/Icon';
import { Stack } from '@/ui/Stack';
import { Text } from '@/ui/Text';
interface RenewalItemProps {
@@ -35,12 +34,12 @@ export function RenewalItem({
>
<Stack direction="row" align="center" gap={3}>
<Icon icon={icon} size={4} color="rgb(245, 158, 11)" />
<Box>
<Stack>
<Text size="sm" color="text-white" block>{name}</Text>
<Text size="xs" color="text-gray-400">Renews {renewDateLabel}</Text>
</Box>
</Stack>
</Stack>
<Box textAlign="right">
<Stack textAlign="right">
<Text size="sm" weight="semibold" color="text-white" block>{priceLabel}</Text>
<Button
variant="secondary"
@@ -51,7 +50,7 @@ export function RenewalItem({
>
Renew
</Button>
</Box>
</Stack>
</Stack>
);
}

View File

@@ -1,5 +1,4 @@
import React from 'react';
import { Box } from '@/ui/Box';
import { Stack } from '@/ui/Stack';
import { Text } from '@/ui/Text';
@@ -18,8 +17,8 @@ export function SponsorActivityItem({
}: SponsorActivityItemProps) {
return (
<Stack direction="row" align="start" gap={3} py={3} borderBottom={true} borderColor="border-charcoal-outline/50">
<Box width="2" height="2" rounded="full" mt={2} className={typeColor} flexShrink={0} />
<Box flexGrow={1} minWidth="0">
<Stack width="2" height="2" rounded="full" mt={2} className={typeColor} flexShrink={0} />
<Stack flexGrow={1} minWidth="0">
<Text size="sm" color="text-white" block truncate>{message}</Text>
<Stack direction="row" align="center" gap={2} mt={1}>
<Text size="xs" color="text-gray-500">{time}</Text>
@@ -30,7 +29,7 @@ export function SponsorActivityItem({
</>
)}
</Stack>
</Box>
</Stack>
</Stack>
);
}

View File

@@ -1,9 +1,9 @@
import React from 'react';
import { Box, BoxProps } from '@/ui/Box';
import { Text } from '@/ui/Text';
import { Heading } from '@/ui/Heading';
import { Icon } from '@/ui/Icon';
import { LucideIcon, Clock } from 'lucide-react';
import { Stack } from '@/ui/Stack';
export interface Activity {
id: string;
@@ -27,52 +27,50 @@ interface SponsorActivityPanelProps {
*/
export function SponsorActivityPanel({ activities }: SponsorActivityPanelProps) {
return (
<Box>
<Stack>
<Heading level={3} fontSize="lg" weight="semibold" mb={4} color="text-white">
Recent Activity
</Heading>
<Box border rounded="xl" borderColor="border-charcoal-outline/50" overflow="hidden" bg="bg-iron-gray/10">
<Stack border rounded="xl" borderColor="border-charcoal-outline/50" overflow="hidden" bg="bg-iron-gray/10">
{activities.length === 0 ? (
<Box p={8} textAlign="center">
<Stack p={8} align="center">
<Icon icon={Clock} size={8} color="text-gray-600" className="mx-auto mb-3" />
<Text color="text-gray-500">No recent activity to show.</Text>
</Box>
</Stack>
) : (
<Box>
<Stack>
{activities.map((activity, index) => (
<Box
<Stack
key={activity.id}
p={4}
display="flex"
direction="row"
gap={4}
borderBottom={index !== activities.length - 1}
borderColor="border-charcoal-outline/30"
hoverBg="bg-iron-gray/20"
transition-colors
className="transition-colors hover:bg-bg-iron-gray/20"
>
<Box
<Stack
w="10"
h="10"
rounded="lg"
display="flex"
alignItems="center"
justifyContent="center"
bg={activity.color.replace('text-', 'bg-').concat('/10') as BoxProps<'div'>['bg']}
align="center"
justify="center"
bg={activity.color.replace('text-', 'bg-').concat('/10')}
>
<Icon icon={activity.icon} size={5} color={activity.color as any} />
</Box>
<Box flexGrow={1}>
<Box display="flex" alignItems="center" justifyContent="between" mb={0.5}>
</Stack>
<Stack flexGrow={1}>
<Stack direction="row" align="center" justify="between" mb={0.5}>
<Text weight="medium" color="text-white">{activity.title}</Text>
<Text size="xs" color="text-gray-500">{activity.timestamp}</Text>
</Box>
</Stack>
<Text size="sm" color="text-gray-400">{activity.description}</Text>
</Box>
</Box>
</Stack>
</Stack>
))}
</Box>
</Stack>
)}
</Box>
</Box>
</Stack>
</Stack>
);
}

View File

@@ -1,11 +1,9 @@
'use client';
import React from 'react';
import { Card } from '@/ui/Card';
import { Box } from '@/ui/Box';
import { Card , Card as Surface } from '@/ui/Card';
import { Stack } from '@/ui/Stack';
import { Text } from '@/ui/Text';
import { Surface } from '@/ui/Surface';
import { SponsorLogo } from '@/components/sponsors/SponsorLogo';
interface SponsorBrandingPreviewProps {
@@ -28,13 +26,13 @@ export function SponsorBrandingPreview({
}: SponsorBrandingPreviewProps) {
return (
<Card p={0} overflow="hidden">
<Box p={4} borderBottom borderColor="border-charcoal-outline">
<Stack p={4} borderBottom borderColor="border-charcoal-outline">
<Text size="xs" weight="bold" uppercase letterSpacing="wider" color="text-gray-400">
Branding Preview
</Text>
</Box>
</Stack>
<Box p={6}>
<Stack p={6}>
<Stack gap={6}>
{/* Logo Preview */}
<Stack align="center" gap={4}>
@@ -56,21 +54,21 @@ export function SponsorBrandingPreview({
</Stack>
{/* Color Palette */}
<Box>
<Stack>
<Text size="xs" weight="bold" uppercase letterSpacing="wider" color="text-gray-500" block mb={3}>
Color Palette
</Text>
<Stack direction="row" gap={4}>
<Stack gap={2} flexGrow={1}>
<Box h={12} rounded="lg" backgroundColor={primaryColor} border borderColor="border-white/10" />
<Stack h={12} rounded="lg" backgroundColor={primaryColor} border borderColor="border-white/10" />
<Text size="xs" color="text-gray-400" textAlign="center">{primaryColor}</Text>
</Stack>
<Stack gap={2} flexGrow={1}>
<Box h={12} rounded="lg" backgroundColor={secondaryColor} border borderColor="border-white/10" />
<Stack h={12} rounded="lg" backgroundColor={secondaryColor} border borderColor="border-white/10" />
<Text size="xs" color="text-gray-400" textAlign="center">{secondaryColor}</Text>
</Stack>
</Stack>
</Box>
</Stack>
{/* Mockup Hint */}
<Surface variant="muted" rounded="lg" padding={3} bg="bg-primary-blue/5" border borderColor="border-primary-blue/20">
@@ -79,7 +77,7 @@ export function SponsorBrandingPreview({
</Text>
</Surface>
</Stack>
</Box>
</Stack>
</Card>
);
}

View File

@@ -2,7 +2,6 @@
import React from 'react';
import { Card } from '@/ui/Card';
import { Box } from '@/ui/Box';
import { Stack } from '@/ui/Stack';
import { Text } from '@/ui/Text';
import { Heading } from '@/ui/Heading';
@@ -80,10 +79,10 @@ export function SponsorContractCard({
<Card p={5} hoverBorderColor="border-primary-blue/30">
<Stack direction="row" align="start" justify="between" mb={4}>
<Stack direction="row" align="center" gap={3}>
<Box w="10" h="10" rounded="lg" bg={typeConfig.bgColor as string} display="flex" alignItems="center" justifyContent="center">
<Stack w="10" h="10" rounded="lg" bg={typeConfig.bgColor as string} display="flex" alignItems="center" justifyContent="center">
<Icon icon={typeConfig.icon} size={5} color={typeConfig.color as string} />
</Box>
<Box>
</Stack>
<Stack>
<Text size="xs" weight="bold" uppercase letterSpacing="wider" color={typeConfig.color as string}>
{typeConfig.label} {tier}
</Text>
@@ -91,31 +90,31 @@ export function SponsorContractCard({
{title}
</Heading>
{subtitle && <Text size="xs" color="text-gray-500">{subtitle}</Text>}
</Box>
</Stack>
</Stack>
<SponsorStatusChip status={mappedStatus} />
</Stack>
<Box display="grid" gridCols={3} gap={4} mb={4} p={3} rounded="lg" bg="bg-iron-gray/20">
<Box>
<Stack display="grid" gridCols={3} gap={4} mb={4} p={3} rounded="lg" bg="bg-iron-gray/20">
<Stack>
<Text size="xs" color="text-gray-500" block mb={1}>Impressions</Text>
<Stack direction="row" align="center" gap={1}>
<Icon icon={BarChart3} size={3} color="text-gray-400" />
<Text weight="bold" color="text-white">{impressions}</Text>
</Stack>
</Box>
<Box>
</Stack>
<Stack>
<Text size="xs" color="text-gray-500" block mb={1}>Investment</Text>
<Text weight="bold" color="text-white">{investment}</Text>
</Box>
<Box>
</Stack>
<Stack>
<Text size="xs" color="text-gray-500" block mb={1}>Term</Text>
<Stack direction="row" align="center" gap={1}>
<Icon icon={Calendar} size={3} color="text-gray-400" />
<Text weight="bold" color="text-white">{endDate || 'N/A'}</Text>
</Stack>
</Box>
</Box>
</Stack>
</Stack>
<Stack direction="row" align="center" justify="between" pt={4} borderTop borderColor="border-charcoal-outline/30">
<Text size="xs" color="text-gray-500">

View File

@@ -1,7 +1,6 @@
'use client';
import React from 'react';
import { Box } from '@/ui/Box';
import { Stack } from '@/ui/Stack';
import { Heading } from '@/ui/Heading';
import { Text } from '@/ui/Text';
@@ -30,7 +29,7 @@ interface SponsorDashboardHeaderProps {
*/
export function SponsorDashboardHeader({ sponsorName, onRefresh }: SponsorDashboardHeaderProps) {
return (
<Box mb={8}>
<Stack mb={8}>
<Stack direction={{ base: 'col', md: 'row' }} align="start" justify="between" gap={4}>
<Stack direction="row" align="center" gap={4}>
<Surface
@@ -43,14 +42,14 @@ export function SponsorDashboardHeader({ sponsorName, onRefresh }: SponsorDashbo
>
<Icon icon={LayoutDashboard} size={6} color="text-primary-blue" />
</Surface>
<Box>
<Stack>
<Heading level={1} fontSize="2xl" weight="bold" color="text-white">
Sponsor Dashboard
</Heading>
<Text color="text-gray-400" size="sm">
Welcome back, <Text color="text-white" weight="medium">{sponsorName}</Text>
</Text>
</Box>
</Stack>
</Stack>
<Stack direction="row" align="center" gap={3}>
@@ -81,7 +80,7 @@ export function SponsorDashboardHeader({ sponsorName, onRefresh }: SponsorDashbo
<Button variant="secondary" size="sm" position="relative">
<Icon icon={Bell} size={4} />
<Box
<Stack
position="absolute"
top={-1}
right={-1}
@@ -95,6 +94,6 @@ export function SponsorDashboardHeader({ sponsorName, onRefresh }: SponsorDashbo
</Button>
</Stack>
</Stack>
</Box>
</Stack>
);
}

View File

@@ -1,9 +1,8 @@
import React from 'react';
import { LucideIcon } from 'lucide-react';
import { Box } from '@/ui/Box';
import { Stack } from '@/ui/Stack';
import { Heading } from '@/ui/Heading';
import { Icon } from '@/ui/Icon';
import { Stack } from '@/ui/Stack';
import { Surface } from '@/ui/Surface';
import { Text } from '@/ui/Text';
@@ -29,7 +28,7 @@ export function SponsorHeaderPanel({
stats,
}: SponsorHeaderPanelProps) {
return (
<Box mb={8}>
<Stack mb={8}>
<Stack direction="row" align="start" justify="between" wrap gap={6}>
<Stack direction="row" align="center" gap={4}>
<Surface
@@ -42,23 +41,23 @@ export function SponsorHeaderPanel({
>
<Icon icon={icon} size={7} color="text-primary-blue" />
</Surface>
<Box>
<Stack>
<Heading level={1} fontSize="2xl" weight="bold">{title}</Heading>
{description && (
<Text color="text-gray-400" block mt={1} size="sm">{description}</Text>
)}
</Box>
</Stack>
</Stack>
<Stack direction="row" align="center" gap={4}>
{stats && (
<Box borderRight borderColor="border-charcoal-outline" pr={4} mr={2} display={{ base: 'none', md: 'block' }}>
<Stack borderRight borderColor="border-charcoal-outline" pr={4} mr={2} display={{ base: 'none', md: 'block' }}>
{stats}
</Box>
</Stack>
)}
{actions && <Box>{actions}</Box>}
{actions && <Stack>{actions}</Stack>}
</Stack>
</Stack>
</Box>
</Stack>
);
}

View File

@@ -25,7 +25,6 @@ const ICON_MAP: Record<string, LucideIcon> = {
};
import { Button } from '@/ui/Button';
import { Card } from '@/ui/Card';
import { Box } from '@/ui/Box';
import { Stack } from '@/ui/Stack';
import { Text } from '@/ui/Text';
import { Heading } from '@/ui/Heading';
@@ -143,8 +142,8 @@ export function SponsorInsightsCard({
borderColor="border-primary-blue/30"
bg={`linear-gradient(to right, ${tierStyles.gradient.split(' ')[1]}, ${tierStyles.gradient.split(' ')[2]})`}
>
<Box display="flex" alignItems="start" justifyContent="between" mb={4}>
<Box>
<Stack display="flex" alignItems="start" justifyContent="between" mb={4}>
<Stack>
<Stack direction="row" align="center" gap={2} mb={1}>
<Icon icon={Target} size={5} color="rgb(59, 130, 246)" />
<Heading level={3}>Sponsorship Opportunity</Heading>
@@ -152,11 +151,11 @@ export function SponsorInsightsCard({
<Text size="sm" color="text-gray-400">
{getSponsorshipTagline(entityType)}
</Text>
</Box>
</Stack>
<SponsorshipTierBadge tier={tier} entityLabel={getEntityLabel(entityType)} />
</Box>
</Stack>
<Box display="grid" gridCols={{ base: 2, md: 4 }} gap={3} mb={4}>
<Stack display="grid" gridCols={{ base: 2, md: 4 }} gap={3} mb={4}>
{metrics.slice(0, 4).map((metric, index) => {
const IconComponent = typeof metric.icon === 'string' ? ICON_MAP[metric.icon] || Target : metric.icon;
return (
@@ -170,10 +169,10 @@ export function SponsorInsightsCard({
/>
);
})}
</Box>
</Stack>
{(trustScore !== undefined || discordMembers !== undefined || monthlyActivity !== undefined) && (
<Box display="flex" flexWrap="wrap" gap={4} mb={4} pb={4} borderBottom borderColor="border-charcoal-outline/50">
<Stack display="flex" flexWrap="wrap" gap={4} mb={4} pb={4} borderBottom borderColor="border-charcoal-outline/50">
{trustScore !== undefined && (
<Stack direction="row" align="center" gap={2}>
<Icon icon={Shield} size={4} color="rgb(16, 185, 129)" />
@@ -195,10 +194,10 @@ export function SponsorInsightsCard({
<Text size="sm" weight="semibold" color="text-white">{monthlyActivity}%</Text>
</Stack>
)}
</Box>
</Stack>
)}
<Box display="grid" gridCols={{ base: 1, md: 2 }} gap={3} mb={4}>
<Stack display="grid" gridCols={{ base: 1, md: 2 }} gap={3} mb={4}>
{mainSlot && (
<SponsorSlotCard
variant="main"
@@ -266,12 +265,12 @@ export function SponsorInsightsCard({
}
/>
)}
</Box>
</Stack>
{additionalStats && (
<Box mb={4} pb={4} borderBottom borderColor="border-charcoal-outline/50">
<Stack mb={4} pb={4} borderBottom borderColor="border-charcoal-outline/50">
<Heading level={4} mb={2} color="text-gray-400">{additionalStats.label}</Heading>
<Box display="flex" flexWrap="wrap" gap={4}>
<Stack display="flex" flexWrap="wrap" gap={4}>
{additionalStats.items.map((item, index) => (
<Stack key={index} direction="row" align="center" gap={2}>
<Text size="sm" color="text-gray-500">{item.label}:</Text>
@@ -280,8 +279,8 @@ export function SponsorInsightsCard({
</Text>
</Stack>
))}
</Box>
</Box>
</Stack>
</Stack>
)}
{error && (
@@ -293,7 +292,7 @@ export function SponsorInsightsCard({
/>
)}
<Box display="flex" alignItems="center" justifyContent="between" pt={3} borderTop borderColor="border-charcoal-outline/50">
<Stack display="flex" alignItems="center" justifyContent="between" pt={3} borderTop borderColor="border-charcoal-outline/50">
<Text size="xs" color="text-gray-500">
10% platform fee applies Logos burned on all liveries Sponsorships are attached to seasons
{appliedTiers.size > 0 && ' • Application pending review'}
@@ -305,7 +304,7 @@ export function SponsorInsightsCard({
>
{ctaLabel || 'View Full Details'}
</Button>
</Box>
</Stack>
</Card>
);
}

View File

@@ -2,11 +2,10 @@
import React from 'react';
import { Table, TableHead, TableBody, TableRow, TableHeader, TableCell } from '@/ui/Table';
import { Box } from '@/ui/Box';
import { Stack } from '@/ui/Stack';
import { Text } from '@/ui/Text';
import { Icon } from '@/ui/Icon';
import { Badge } from '@/ui/Badge';
import { Stack } from '@/ui/Stack';
import {
Clock,
CheckCircle2,
@@ -73,14 +72,14 @@ export function SponsorPayoutQueueTable({ payouts }: SponsorPayoutQueueTableProp
</Stack>
</TableCell>
<TableCell>
<Box display="flex" justifyContent="center">
<Stack display="flex" justifyContent="center">
<Badge variant={payout.status === 'completed' ? 'success' : payout.status === 'failed' ? 'danger' : 'warning'}>
<Stack direction="row" align="center" gap={1.5}>
<Icon icon={status.icon} size={3} />
<Text size="xs" weight="bold" uppercase letterSpacing="wider">{status.label}</Text>
</Stack>
</Badge>
</Box>
</Stack>
</TableCell>
</TableRow>
);

View File

@@ -1,7 +1,6 @@
'use client';
import React from 'react';
import { Box } from '@/ui/Box';
import { Stack } from '@/ui/Stack';
import { Text } from '@/ui/Text';
import { Icon } from '@/ui/Icon';
@@ -40,7 +39,7 @@ export function SponsorStatusChip({ status, label }: SponsorStatusChipProps) {
const config = STATUS_CONFIG[status];
return (
<Box
<Stack
px={2.5}
py={1}
rounded="full"
@@ -61,6 +60,6 @@ export function SponsorStatusChip({ status, label }: SponsorStatusChipProps) {
{label || config.label}
</Text>
</Stack>
</Box>
</Stack>
);
}

View File

@@ -2,10 +2,9 @@
import { CheckCircle2, LucideIcon } from 'lucide-react';
import { Badge } from '@/ui/Badge';
import { Box } from '@/ui/Box';
import { Stack } from '@/ui/Stack';
import { Heading } from '@/ui/Heading';
import { Icon } from '@/ui/Icon';
import { Stack } from '@/ui/Stack';
import { Surface } from '@/ui/Surface';
import { Text } from '@/ui/Text';
@@ -47,7 +46,7 @@ export function SponsorTierCard({
position="relative"
>
<Stack direction="row" align="start" justify="between" mb={4}>
<Box>
<Stack>
<Stack direction="row" align="center" gap={2} mb={1}>
<Icon icon={icon} size={5} className={iconColor} />
<Heading level={3}>{isMain ? 'Main Sponsor' : 'Secondary Sponsor'}</Heading>
@@ -55,7 +54,7 @@ export function SponsorTierCard({
<Text size="sm" color="text-gray-400">
{isMain ? 'Primary branding position' : 'Supporting branding position'}
</Text>
</Box>
</Stack>
<Badge variant={available ? 'success' : 'default'}>
{isMain
? (available ? 'Available' : 'Filled')
@@ -64,12 +63,12 @@ export function SponsorTierCard({
</Badge>
</Stack>
<Box mb={4}>
<Stack mb={4}>
<Text size="3xl" weight="bold" color="text-white">
${price}
<Text size="sm" weight="normal" color="text-gray-500">/season</Text>
</Text>
</Box>
</Stack>
<Stack gap={2} mb={4}>
{benefits.map((benefit, i) => (
@@ -81,8 +80,8 @@ export function SponsorTierCard({
</Stack>
{isSelected && available && (
<Box position="absolute" top="4" right="4">
<Box
<Stack position="absolute" top="4" right="4">
<Stack
width="4"
height="4"
rounded="full"
@@ -91,8 +90,8 @@ export function SponsorTierCard({
center
>
<Icon icon={CheckCircle2} size={3} color="text-white" />
</Box>
</Box>
</Stack>
</Stack>
)}
</Surface>
);

View File

@@ -2,7 +2,6 @@ import React from 'react';
import { LucideIcon } from 'lucide-react';
import { Link } from '@/ui/Link';
import { Card } from '@/ui/Card';
import { Box } from '@/ui/Box';
import { Stack } from '@/ui/Stack';
import { Text } from '@/ui/Text';
import { Icon } from '@/ui/Icon';
@@ -29,7 +28,7 @@ export function SponsorshipCategoryCard({
<Card p={4} className="hover:border-charcoal-outline/60 transition-all cursor-pointer">
<Stack direction="row" align="center" justify="between">
<Stack direction="row" align="center" gap={3}>
<Box
<Stack
width="10"
height="10"
rounded="lg"
@@ -38,16 +37,16 @@ export function SponsorshipCategoryCard({
center
>
<Icon icon={icon} size={5} className={color} />
</Box>
<Box>
</Stack>
<Stack>
<Text weight="medium" color="text-white" block>{title}</Text>
<Text size="sm" color="text-gray-500">{count} active</Text>
</Box>
</Stack>
</Stack>
<Box textAlign="right">
<Stack textAlign="right">
<Text weight="semibold" color="text-white" block>{impressions.toLocaleString()}</Text>
<Text size="xs" color="text-gray-500">impressions</Text>
</Box>
</Stack>
</Stack>
</Card>
</Link>

View File

@@ -1,9 +1,10 @@
import React from 'react';
import { Box, BoxProps } from '@/ui/Box';
import { Text } from '@/ui/Text';
import { Icon } from '@/ui/Icon';
import { Button } from '@/ui/Button';
import { Download, Receipt, Clock, Check, AlertTriangle } from 'lucide-react';
import { Grid } from '@/ui/Grid';
import { Stack } from '@/ui/Stack';
export interface Transaction {
id: string;
@@ -59,67 +60,66 @@ const STATUS_CONFIG = {
*/
export function TransactionTable({ transactions, onDownload }: TransactionTableProps) {
return (
<Box border rounded="xl" borderColor="border-charcoal-outline/50" overflow="hidden" bg="bg-iron-gray/10">
<Box display={{ base: 'none', md: 'grid' }} gridCols={12} gap={4} p={4} bg="bg-iron-gray/30" borderBottom borderColor="border-charcoal-outline/50">
<Box colSpan={5}>
<Stack border rounded="xl" borderColor="border-charcoal-outline/50" overflow="hidden" bg="bg-iron-gray/10">
<Grid className="hidden md:grid" cols={12} gap={4} p={4} bg="bg-iron-gray/30" borderBottom borderColor="border-charcoal-outline/50">
<Stack colSpan={5}>
<Text size="xs" weight="bold" color="text-gray-500" uppercase letterSpacing="wider">Description</Text>
</Box>
<Box colSpan={2}>
</Stack>
<Stack colSpan={2}>
<Text size="xs" weight="bold" color="text-gray-500" uppercase letterSpacing="wider">Date</Text>
</Box>
<Box colSpan={2}>
</Stack>
<Stack colSpan={2}>
<Text size="xs" weight="bold" color="text-gray-500" uppercase letterSpacing="wider">Amount</Text>
</Box>
<Box colSpan={2}>
</Stack>
<Stack colSpan={2}>
<Text size="xs" weight="bold" color="text-gray-500" uppercase letterSpacing="wider">Status</Text>
</Box>
<Box colSpan={1} textAlign="right">
</Stack>
<Stack colSpan={1} textAlign="right">
<Text size="xs" weight="bold" color="text-gray-500" uppercase letterSpacing="wider">Action</Text>
</Box>
</Box>
</Stack>
</Grid>
<Box>
<Stack>
{transactions.map((tx, index) => {
const status = STATUS_CONFIG[tx.status];
return (
<Box
<Grid
key={tx.id}
display="grid"
gridCols={{ base: 1, md: 12 }}
cols={1}
mdCols={12}
gap={4}
p={4}
alignItems="center"
borderBottom={index !== transactions.length - 1}
borderColor="border-charcoal-outline/30"
hoverBg="bg-iron-gray/20"
transition-colors
className="transition-colors hover:bg-bg-iron-gray/20"
>
<Box colSpan={{ base: 1, md: 5 }} display="flex" alignItems="center" gap={3}>
<Box w="8" h="8" rounded="lg" bg="bg-iron-gray/50" display="flex" alignItems="center" justifyContent="center">
<Stack colSpan={{ base: 1, md: 5 } as any} direction="row" align="center" gap={3}>
<Stack w="8" h="8" rounded="lg" bg="bg-iron-gray/50" align="center" justify="center">
<Icon icon={Receipt} size={4} color="text-gray-400" />
</Box>
<Box>
</Stack>
<Stack>
<Text weight="medium" color="text-white" block>{tx.description}</Text>
<Text size="xs" color="text-gray-500">{tx.invoiceNumber} {tx.type}</Text>
</Box>
</Box>
</Stack>
</Stack>
<Box colSpan={{ base: 1, md: 2 }}>
<Stack colSpan={{ base: 1, md: 2 } as any}>
<Text size="sm" color="text-gray-400">{new Date(tx.date).toLocaleDateString()}</Text>
</Box>
</Stack>
<Box colSpan={{ base: 1, md: 2 }}>
<Stack colSpan={{ base: 1, md: 2 } as any}>
<Text weight="semibold" color="text-white">${tx.amount.toFixed(2)}</Text>
</Box>
</Stack>
<Box colSpan={{ base: 1, md: 2 }}>
<Box display="inline-flex" alignItems="center" gap={1.5} px={2} py={0.5} rounded="full" bg={status.bg as BoxProps<'div'>['bg']} border borderColor={status.border as BoxProps<'div'>['borderColor']}>
<Stack colSpan={{ base: 1, md: 2 } as any}>
<Stack direction="row" align="center" gap={1.5} px={2} py={0.5} rounded="full" bg={status.bg} border borderColor={status.border}>
<Icon icon={status.icon} size={3} color={status.color as any} />
<Text size="xs" weight="medium" color={status.color as any}>{status.label}</Text>
</Box>
</Box>
</Stack>
</Stack>
<Box colSpan={{ base: 1, md: 1 }} textAlign="right">
<Stack colSpan={{ base: 1, md: 1 } as any} textAlign="right">
<Button
variant="ghost"
size="sm"
@@ -128,11 +128,11 @@ export function TransactionTable({ transactions, onDownload }: TransactionTableP
>
PDF
</Button>
</Box>
</Box>
</Stack>
</Grid>
);
})}
</Box>
</Box>
</Stack>
</Stack>
);
}