website refactor
This commit is contained in:
@@ -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>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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'll receive the payment minus 10% platform fee.
|
||||
</Text>
|
||||
</Box>
|
||||
</Stack>
|
||||
</Stack>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user