website refactor
This commit is contained in:
104
apps/website/components/sponsors/PricingTableShell.tsx
Normal file
104
apps/website/components/sponsors/PricingTableShell.tsx
Normal file
@@ -0,0 +1,104 @@
|
||||
import React from 'react';
|
||||
import { Box } from '@/ui/Box';
|
||||
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';
|
||||
|
||||
export interface PricingTier {
|
||||
id: string;
|
||||
name: string;
|
||||
price: number;
|
||||
period: string;
|
||||
description: string;
|
||||
features: string[];
|
||||
isPopular?: boolean;
|
||||
available?: boolean;
|
||||
}
|
||||
|
||||
interface PricingTableShellProps {
|
||||
title: string;
|
||||
tiers: PricingTier[];
|
||||
onSelect?: (id: string) => void;
|
||||
selectedId?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* PricingTableShell
|
||||
*
|
||||
* A semantic component for displaying sponsorship pricing tiers.
|
||||
* Clean, comparison-focused layout.
|
||||
*/
|
||||
export function PricingTableShell({ title, tiers, onSelect, selectedId }: PricingTableShellProps) {
|
||||
return (
|
||||
<Box 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}>
|
||||
{tiers.map((tier) => (
|
||||
<Box
|
||||
key={tier.id}
|
||||
p={6}
|
||||
rounded="xl"
|
||||
border
|
||||
borderColor={selectedId === tier.id ? 'border-primary-blue' : 'border-charcoal-outline/50'}
|
||||
bg={selectedId === tier.id ? 'bg-primary-blue/5' : 'bg-iron-gray/10'}
|
||||
position="relative"
|
||||
cursor="pointer"
|
||||
onClick={() => onSelect?.(tier.id)}
|
||||
transition-all
|
||||
hoverBorderColor={selectedId === tier.id ? 'border-primary-blue' : 'border-charcoal-outline'}
|
||||
>
|
||||
{tier.isPopular && (
|
||||
<Box
|
||||
position="absolute"
|
||||
top={0}
|
||||
right={6}
|
||||
transform="-translate-y-1/2"
|
||||
bg="bg-primary-blue"
|
||||
px={3}
|
||||
py={1}
|
||||
rounded="full"
|
||||
>
|
||||
<Text size="xs" weight="bold" color="text-white" uppercase letterSpacing="wider">Popular</Text>
|
||||
</Box>
|
||||
)}
|
||||
|
||||
<Box mb={6}>
|
||||
<Text size="sm" weight="bold" color="text-primary-blue" uppercase letterSpacing="wider" block mb={2}>
|
||||
{tier.name}
|
||||
</Text>
|
||||
<Stack direction="row" align="baseline" gap={1}>
|
||||
<Text size="3xl" weight="bold" color="text-white">${tier.price}</Text>
|
||||
<Text size="sm" color="text-gray-500">/{tier.period}</Text>
|
||||
</Stack>
|
||||
<Text size="sm" color="text-gray-400" block mt={2}>
|
||||
{tier.description}
|
||||
</Text>
|
||||
</Box>
|
||||
|
||||
<Stack gap={3} mb={8}>
|
||||
{tier.features.map((feature, i) => (
|
||||
<Stack key={i} direction="row" align="start" gap={3}>
|
||||
<Box mt={0.5}>
|
||||
<Icon icon={Check} size={3.5} color="text-performance-green" />
|
||||
</Box>
|
||||
<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">
|
||||
<Icon icon={Info} size={4} color="text-racing-red" />
|
||||
<Text size="xs" weight="medium" color="text-racing-red">Currently Unavailable</Text>
|
||||
</Box>
|
||||
)}
|
||||
</Box>
|
||||
))}
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user