'use client'; import { SponsorMetricCard } from '@/components/sponsors/SponsorMetricCard'; import { SponsorshipTierBadge } from '@/components/sponsors/SponsorshipTierBadge'; import { SponsorSlotCard } from '@/components/sponsors/SponsorSlotCard'; import { Button } from '@/ui/Button'; import { Card } from '@/ui/Card'; import { Heading } from '@/ui/Heading'; import { Icon } from '@/ui/Icon'; import { InfoBox } from '@/ui/InfoBox'; import { Stack } from '@/ui/Stack'; import { Text } from '@/ui/Text'; import { Activity, Calendar, Check, Loader2, LucideIcon, MessageCircle, Shield, Target, Users, Zap } from 'lucide-react'; import { useCallback, useState } from 'react'; import { getEntityLabel, getSponsorshipTagline, getTierStyles } from './SponsorInsightsCardHelpers'; import { SponsorMetric, SponsorshipSlot } from './SponsorInsightsCardTypes'; const ICON_MAP: Record = { users: Users, zap: Zap, calendar: Calendar, activity: Activity, shield: Shield, target: Target, message: MessageCircle, }; export type EntityType = 'league' | 'race' | 'driver' | 'team'; export interface SponsorInsightsProps { entityType: EntityType; entityId: string; entityName: string; tier: 'premium' | 'standard' | 'starter'; metrics: SponsorMetric[]; slots: SponsorshipSlot[]; additionalStats?: { label: string; items: Array<{ label: string; value: string }>; }; trustScoreLabel?: string; discordMembersLabel?: string; monthlyActivityLabel?: string; ctaLabel?: string; ctaHref?: string; currentSponsorId?: string; onSponsorshipRequested?: (tier: 'main' | 'secondary') => void; onNavigate: (href: string) => void; } export function SponsorInsightsCard({ entityType, entityId, entityName, tier, metrics, slots, additionalStats, trustScoreLabel, discordMembersLabel, monthlyActivityLabel, ctaLabel, ctaHref, currentSponsorId, onSponsorshipRequested, onNavigate, }: SponsorInsightsProps) { const tierStyles = getTierStyles(tier); const [applyingTier, setApplyingTier] = useState<'main' | 'secondary' | null>(null); const [appliedTiers, setAppliedTiers] = useState>(new Set()); const [error, setError] = useState(null); const mainSlot = slots.find(s => s.tier === 'main'); const secondarySlots = slots.filter(s => s.tier === 'secondary'); const availableSecondary = secondarySlots.filter(s => s.available).length; const getSponsorableEntityType = useCallback((type: EntityType): 'driver' | 'team' | 'race' | 'season' => { switch (type) { case 'league': return 'season'; case 'race': return 'race'; case 'driver': return 'driver'; case 'team': return 'team'; } }, []); const handleSponsorClick = useCallback(async (slotTier: 'main' | 'secondary') => { if (!currentSponsorId) { const href = ctaHref || `/sponsor/${entityType}s/${entityId}?tier=${slotTier}`; onNavigate(href); return; } if (appliedTiers.has(slotTier)) { onNavigate(`/sponsor/dashboard`); return; } setApplyingTier(slotTier); setError(null); try { // Note: In a real app, we would fetch the raw price from the API or a ViewModel // For now, we assume the parent handles the actual request logic onSponsorshipRequested?.(slotTier); setAppliedTiers(prev => new Set([...prev, slotTier])); } catch (err) { console.error('Failed to apply for sponsorship:', err); setError(err instanceof Error ? err.message : 'Failed to submit sponsorship request'); } finally { setApplyingTier(null); } }, [currentSponsorId, ctaHref, entityType, entityId, onNavigate, appliedTiers, onSponsorshipRequested]); return ( Sponsorship Opportunity {getSponsorshipTagline(entityType)} {metrics.slice(0, 4).map((metric, index) => { const IconComponent = typeof metric.icon === 'string' ? ICON_MAP[metric.icon] || Target : metric.icon; return ( ); })} {(trustScoreLabel || discordMembersLabel || monthlyActivityLabel) && ( {trustScoreLabel && ( Trust Score: {trustScoreLabel} )} {discordMembersLabel && ( Discord: {discordMembersLabel} )} {monthlyActivityLabel && ( Monthly Activity: {monthlyActivityLabel} )} )} {mainSlot && ( handleSponsorClick('main')} disabled={applyingTier === 'main'} size="sm" > {applyingTier === 'main' ? ( Applying... ) : appliedTiers.has('main') ? ( Applied ) : ( 'Apply to Sponsor' )} } /> )} {secondarySlots.length > 0 && ( 0 ? 'text-purple-400' : 'text-gray-500'} benefits={secondarySlots[0]?.benefits.join(' • ') || 'Logo placement on page'} available={availableSecondary > 0} price={secondarySlots[0]?.priceLabel} action={ } /> )} {additionalStats && ( {additionalStats.label} {additionalStats.items.map((item, index) => ( {item.label}: {item.value} ))} )} {error && ( )} 10% platform fee applies • Logos burned on all liveries • Sponsorships are attached to seasons {appliedTiers.size > 0 && ' • Application pending review'} ); }