143 lines
4.7 KiB
TypeScript
143 lines
4.7 KiB
TypeScript
'use client';
|
|
|
|
import { Button } from '@/ui/Button';
|
|
import { Card } from '@/ui/Card';
|
|
import { Heading } from '@/ui/Heading';
|
|
import { Icon } from '@/ui/Icon';
|
|
import { Stack } from '@/ui/Stack';
|
|
import { Text } from '@/ui/Text';
|
|
import {
|
|
BarChart3,
|
|
Calendar,
|
|
Car,
|
|
ChevronRight,
|
|
ExternalLink,
|
|
Flag,
|
|
Megaphone,
|
|
Trophy,
|
|
Users
|
|
} from 'lucide-react';
|
|
import { SponsorStatus, SponsorStatusChip } from './SponsorStatusChip';
|
|
|
|
export type SponsorshipType = 'league' | 'team' | 'driver' | 'race' | 'platform';
|
|
|
|
interface SponsorContractCardProps {
|
|
id: string;
|
|
type: SponsorshipType;
|
|
status: string; // Accept raw status string
|
|
title: string;
|
|
subtitle?: string;
|
|
tier: string;
|
|
investment: string;
|
|
impressions: string;
|
|
startDate?: string;
|
|
endDate?: string;
|
|
onViewDetails?: (id: string) => void;
|
|
}
|
|
|
|
const TYPE_CONFIG = {
|
|
league: { icon: Trophy, color: 'text-primary-blue', bgColor: 'bg-primary-blue/10', label: 'League' },
|
|
team: { icon: Users, color: 'text-purple-400', bgColor: 'bg-purple-400/10', label: 'Team' },
|
|
driver: { icon: Car, color: 'text-performance-green', bgColor: 'bg-performance-green/10', label: 'Driver' },
|
|
race: { icon: Flag, color: 'text-warning-amber', bgColor: 'bg-warning-amber/10', label: 'Race' },
|
|
platform: { icon: Megaphone, color: 'text-racing-red', bgColor: 'bg-racing-red/10', label: 'Platform' },
|
|
};
|
|
|
|
function mapStatus(status: string): SponsorStatus {
|
|
if (status === 'pending_approval' || status === 'pending') return 'pending';
|
|
if (status === 'rejected' || status === 'declined') return 'declined';
|
|
if (status === 'expired') return 'expired';
|
|
if (status === 'approved') return 'approved';
|
|
if (status === 'active') return 'active';
|
|
return 'pending';
|
|
}
|
|
|
|
/**
|
|
* SponsorContractCard
|
|
*
|
|
* Semantic component for displaying a sponsorship contract/campaign.
|
|
* Provides a high-density overview of the sponsorship status and performance.
|
|
*/
|
|
export function SponsorContractCard({
|
|
id,
|
|
type,
|
|
status,
|
|
title,
|
|
subtitle,
|
|
tier,
|
|
investment,
|
|
impressions,
|
|
startDate,
|
|
endDate,
|
|
onViewDetails
|
|
}: SponsorContractCardProps) {
|
|
const typeConfig = TYPE_CONFIG[type];
|
|
const mappedStatus = mapStatus(status);
|
|
|
|
return (
|
|
<Card p={5} hoverBorderColor="border-primary-blue/30">
|
|
<Stack direction="row" align="start" justify="between" mb={4}>
|
|
<Stack direction="row" align="center" gap={3}>
|
|
<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} />
|
|
</Stack>
|
|
<Stack>
|
|
<Text size="xs" weight="bold" uppercase letterSpacing="wider" color={typeConfig.color as string}>
|
|
{typeConfig.label} • {tier}
|
|
</Text>
|
|
<Heading level={4} fontSize="lg" weight="bold" color="text-white">
|
|
{title}
|
|
</Heading>
|
|
{subtitle && <Text size="xs" color="text-gray-500">{subtitle}</Text>}
|
|
</Stack>
|
|
</Stack>
|
|
<SponsorStatusChip status={mappedStatus} />
|
|
</Stack>
|
|
|
|
<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>
|
|
</Stack>
|
|
<Stack>
|
|
<Text size="xs" color="text-gray-500" block mb={1}>Investment</Text>
|
|
<Text weight="bold" color="text-white">{investment}</Text>
|
|
</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>
|
|
</Stack>
|
|
</Stack>
|
|
|
|
<Stack direction="row" align="center" justify="between" pt={4} borderTop borderColor="border-charcoal-outline/30">
|
|
<Text size="xs" color="text-gray-500">
|
|
{startDate ? `Started ${startDate}` : 'Contract pending'}
|
|
</Text>
|
|
<Stack direction="row" gap={2}>
|
|
<Button
|
|
variant="secondary"
|
|
size="sm"
|
|
icon={<Icon icon={ExternalLink} size={3} />}
|
|
onClick={() => onViewDetails?.(id)}
|
|
>
|
|
View
|
|
</Button>
|
|
<Button
|
|
variant="secondary"
|
|
size="sm"
|
|
icon={<Icon icon={ChevronRight} size={3} />}
|
|
>
|
|
Details
|
|
</Button>
|
|
</Stack>
|
|
</Stack>
|
|
</Card>
|
|
);
|
|
}
|