/** * SponsorSlot - Invisible placeholder for future sponsors * * This component renders nothing when no sponsors are provided, * but can be "activated" by passing sponsor data. * * Sizes: * - banner: Full-width horizontal banner (homepage, tour pages) * - card: Square/rectangular card (sidebar, grid layouts) * - inline: Small inline mention (challenge cards, footer) * * Usage: * // Invisible placeholder * */ import { cn } from '@/lib/utils'; export interface Sponsor { name: string; logo?: string; url?: string; tier?: 'title' | 'gold' | 'silver' | 'challenge' | 'partner'; } interface SponsorSlotProps { size: 'banner' | 'card' | 'inline'; sponsors?: Sponsor[]; title?: string; // e.g., "Powered by", "Sponsored by", "Partners" className?: string; // For challenge sponsors challengeId?: string; } export function SponsorSlot({ size, sponsors, title = 'Partners', className, }: SponsorSlotProps) { // If no sponsors, render nothing (invisible placeholder) if (!sponsors || sponsors.length === 0) { return null; } // Banner style - full width, horizontal layout if (size === 'banner') { return (

{title}

{sponsors.map((sponsor) => ( ))}
); } // Card style - for sidebar or grid layouts if (size === 'card') { return (

{title}

{sponsors.map((sponsor) => ( ))}
); } // Inline style - small, compact if (size === 'inline') { return (
{title}: {sponsors.map((sponsor, idx) => ( {idx < sponsors.length - 1 && ', '} ))}
); } return null; } // Individual sponsor display function SponsorItem({ sponsor, size }: { sponsor: Sponsor; size: 'banner' | 'card' | 'inline' }) { const content = (
{sponsor.logo && ( {sponsor.name} )} {sponsor.name} {sponsor.tier === 'title' && size !== 'inline' && ( Title Sponsor )}
); if (sponsor.url) { return ( {content} ); } return content; } // Export types for use in tour schema export type { Sponsor as TourSponsor };