169 lines
4.9 KiB
TypeScript
169 lines
4.9 KiB
TypeScript
import { BillingSummaryPanel } from '@/components/sponsors/BillingSummaryPanel';
|
|
import { SponsorContractCard } from '@/components/sponsors/SponsorContractCard';
|
|
import { SponsorDashboardHeader } from '@/components/sponsors/SponsorDashboardHeader';
|
|
import { Box } from '@/ui/Box';
|
|
import { Button } from '@/ui/Button';
|
|
import { Container } from '@/ui/Container';
|
|
import { Icon } from '@/ui/Icon';
|
|
import { Stack } from '@/ui/Stack';
|
|
import {
|
|
BarChart3,
|
|
Check,
|
|
Clock,
|
|
Eye,
|
|
LucideIcon,
|
|
Search
|
|
} from 'lucide-react';
|
|
import React from 'react';
|
|
|
|
export type SponsorshipType = 'all' | 'leagues' | 'teams' | 'drivers' | 'races' | 'platform';
|
|
export type SponsorshipStatus = 'all' | 'active' | 'pending_approval' | 'approved' | 'rejected' | 'expired';
|
|
|
|
export interface SponsorCampaignsViewData {
|
|
sponsorships: Array<{
|
|
id: string;
|
|
type: string;
|
|
status: string;
|
|
leagueName: string;
|
|
seasonName: string;
|
|
tier: string;
|
|
formattedInvestment: string;
|
|
formattedImpressions: string;
|
|
formattedStartDate?: string;
|
|
formattedEndDate?: string;
|
|
}>;
|
|
stats: {
|
|
total: number;
|
|
active: number;
|
|
pending: number;
|
|
approved: number;
|
|
rejected: number;
|
|
formattedTotalInvestment: string;
|
|
formattedTotalImpressions: string;
|
|
};
|
|
}
|
|
|
|
interface SponsorCampaignsTemplateProps {
|
|
viewData: SponsorCampaignsViewData;
|
|
filteredSponsorships: SponsorCampaignsViewData['sponsorships'];
|
|
typeFilter: SponsorshipType;
|
|
setTypeFilter: (type: SponsorshipType) => void;
|
|
searchQuery: string;
|
|
setSearchQuery: (query: string) => void;
|
|
}
|
|
|
|
export function SponsorCampaignsTemplate({
|
|
viewData,
|
|
filteredSponsorships,
|
|
typeFilter,
|
|
setTypeFilter,
|
|
searchQuery,
|
|
setSearchQuery
|
|
}: SponsorCampaignsTemplateProps) {
|
|
const billingStats: Array<{
|
|
label: string;
|
|
value: string | number;
|
|
icon: LucideIcon;
|
|
variant: 'success' | 'warning' | 'info' | 'default';
|
|
}> = [
|
|
{
|
|
label: 'Active Campaigns',
|
|
value: viewData.stats.active,
|
|
icon: Check,
|
|
variant: 'success',
|
|
},
|
|
{
|
|
label: 'Pending Approval',
|
|
value: viewData.stats.pending,
|
|
icon: Clock,
|
|
variant: viewData.stats.pending > 0 ? 'warning' : 'default',
|
|
},
|
|
{
|
|
label: 'Total Investment',
|
|
value: viewData.stats.formattedTotalInvestment,
|
|
icon: BarChart3,
|
|
variant: 'info',
|
|
},
|
|
{
|
|
label: 'Total Impressions',
|
|
value: viewData.stats.formattedTotalImpressions,
|
|
icon: Eye,
|
|
variant: 'default',
|
|
},
|
|
];
|
|
|
|
return (
|
|
<Container size="lg" py={8}>
|
|
<Stack gap={8}>
|
|
<SponsorDashboardHeader
|
|
sponsorName="Sponsor"
|
|
onRefresh={() => console.log('Refresh')}
|
|
/>
|
|
|
|
<BillingSummaryPanel stats={billingStats} />
|
|
|
|
<Box>
|
|
<Stack direction={{ base: 'col', lg: 'row' }} gap={4} mb={6}>
|
|
<Box position="relative" flexGrow={1}>
|
|
<Box position="absolute" left={3} top="1/2" transform="-translate-y-1/2">
|
|
<Icon icon={Search} size={4} color="text-gray-500" />
|
|
</Box>
|
|
<Box
|
|
as="input"
|
|
type="text"
|
|
placeholder="Search sponsorships..."
|
|
value={searchQuery}
|
|
onChange={(e: React.ChangeEvent<HTMLInputElement>) => setSearchQuery(e.target.value)}
|
|
w="full"
|
|
pl={10}
|
|
pr={4}
|
|
py={2}
|
|
rounded="lg"
|
|
border
|
|
borderColor="border-charcoal-outline"
|
|
bg="bg-iron-gray/50"
|
|
color="text-white"
|
|
outline="none"
|
|
focusBorderColor="border-primary-blue"
|
|
/>
|
|
</Box>
|
|
|
|
<Stack direction="row" gap={2} overflow="auto" pb={{ base: 2, lg: 0 }}>
|
|
{(['all', 'leagues', 'teams', 'drivers'] as const).map((type) => (
|
|
<Button
|
|
key={type}
|
|
variant={typeFilter === type ? 'primary' : 'secondary'}
|
|
size="sm"
|
|
onClick={() => setTypeFilter(type)}
|
|
>
|
|
{type.charAt(0).toUpperCase() + type.slice(1)}
|
|
</Button>
|
|
))}
|
|
</Stack>
|
|
</Stack>
|
|
|
|
<Box display="grid" gridCols={{ base: 1, lg: 2 }} gap={4}>
|
|
{filteredSponsorships.map((s) => {
|
|
return (
|
|
<SponsorContractCard
|
|
key={s.id}
|
|
id={s.id}
|
|
type="league"
|
|
status={s.status}
|
|
title={s.leagueName}
|
|
subtitle={s.seasonName}
|
|
tier={s.tier}
|
|
investment={s.formattedInvestment}
|
|
impressions={s.formattedImpressions}
|
|
startDate={s.formattedStartDate}
|
|
endDate={s.formattedEndDate}
|
|
/>
|
|
);
|
|
})}
|
|
</Box>
|
|
</Box>
|
|
</Stack>
|
|
</Container>
|
|
);
|
|
}
|