'use client'; import { SponsorBenefitCard } from '@/components/sponsors/SponsorBenefitCard'; import { SponsorHero } from '@/components/sponsors/SponsorHero'; import { SponsorWorkflowMockup } from '@/components/sponsors/SponsorWorkflowMockup'; import { SponsorSignupCommandModel } from '@/lib/command-models/sponsors/SponsorSignupCommandModel'; import { siteConfig } from '@/lib/siteConfig'; import { Box } from '@/ui/Box'; import { Button } from '@/ui/Button'; import { Card } from '@/ui/Card'; import { Heading } from '@/ui/Heading'; import { Input } from '@/ui/Input'; import { Stack } from '@/ui/Stack'; import { Text } from '@/ui/Text'; import { motion, useReducedMotion } from 'framer-motion'; import { ArrowRight, BarChart3, Building2, Car, CheckCircle2, Eye, Flag, Globe, Mail, Megaphone, Shield, Target, TrendingUp, Trophy, Upload, Users } from 'lucide-react'; import { useState } from 'react'; // Sponsorship type definitions interface SponsorshipType { id: string; title: string; icon: typeof Trophy; description: string; benefits: string[]; priceRange: string; color: string; } const SPONSORSHIP_TYPES: SponsorshipType[] = [ { id: 'leagues', title: 'League Sponsorship', icon: Trophy, description: 'Sponsor entire racing leagues and get your brand in front of all participants and viewers.', benefits: [ 'Logo on all participant liveries', 'League page banner placement', 'Results page branding', 'Social media mentions' ], priceRange: '$200 - $2,000/season', color: 'text-primary-blue', }, { id: 'teams', title: 'Team Sponsorship', icon: Users, description: 'Partner with competitive racing teams to build long-term brand associations.', benefits: [ 'Team livery logo placement', 'Team profile visibility', 'Driver association', 'Event representation' ], priceRange: '$100 - $800/season', color: 'text-purple-400', }, { id: 'drivers', title: 'Driver Sponsorship', icon: Car, description: 'Support individual drivers and grow with rising sim racing talent.', benefits: [ 'Personal livery branding', 'Driver profile sponsor badge', 'Race results association', 'Direct driver partnership' ], priceRange: '$50 - $300/season', color: 'text-performance-green', }, { id: 'races', title: 'Race Sponsorship', icon: Flag, description: 'Sponsor individual race events for targeted, high-impact exposure.', benefits: [ 'Race title naming rights', 'Event page branding', 'Results page placement', 'Social media features' ], priceRange: '$50 - $500/race', color: 'text-warning-amber', }, { id: 'platform', title: 'Platform Advertising', icon: Megaphone, description: 'Reach the entire GridPilot audience with strategic platform placements.', benefits: [ 'Homepage banner ads', 'Sidebar placements', 'Newsletter inclusion', 'Cross-platform exposure' ], priceRange: '$100 - $1,000/month', color: 'text-racing-red', }, ]; // Stats for social proof const PLATFORM_STATS = [ { value: '50,000+', label: 'Monthly Race Views' }, { value: '12,000+', label: 'Active Drivers' }, { value: '500+', label: 'Racing Leagues' }, { value: '4.8%', label: 'Avg. Engagement Rate' }, ]; export default function SponsorSignupPage() { const shouldReduceMotion = useReducedMotion(); const [mode, setMode] = useState<'landing' | 'signup' | 'login'>('landing'); const [form, setForm] = useState(() => new SponsorSignupCommandModel()); const [formData, setFormData] = useState({ logoFile: null as File | null, password: '', confirmPassword: '', interests: [] as string[], acceptTerms: false, acceptVat: false, }); const [errors, setErrors] = useState>({}); const [submitting, setSubmitting] = useState(false); const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); const validationErrors = form.validate(); const newErrors: Record = { ...validationErrors }; if (mode === 'signup') { if (!formData.password.trim()) { newErrors.password = 'Password required'; } else if (formData.password.length < 8) { newErrors.password = 'Password must be at least 8 characters'; } if (formData.password !== formData.confirmPassword) { newErrors.confirmPassword = 'Passwords do not match'; } if (!formData.acceptTerms) { newErrors.acceptTerms = 'You must accept the terms and conditions'; } if (!formData.acceptVat) { newErrors.acceptVat = 'You must acknowledge the VAT policy'; } } if (Object.keys(newErrors).length > 0) { setErrors(newErrors); return; } setSubmitting(true); try { const command = form.toCommand(); // Note: Business logic for auth should be moved to a mutation // This is a temporary implementation for contract compliance const response = await fetch('/api/auth/signup', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ email: command.contactEmail, password: formData.password, displayName: command.companyName, sponsorData: { companyName: command.companyName, websiteUrl: command.websiteUrl, interests: formData.interests, }, }), }); if (!response.ok) { const errorData = await response.json().catch(() => ({})); throw new Error(errorData.message || 'Signup failed'); } const loginResponse = await fetch('/api/auth/login', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ email: command.contactEmail, password: formData.password, }), }); if (!loginResponse.ok) { throw new Error('Auto-login failed'); } // Navigate to dashboard window.location.href = '/sponsor/dashboard'; } catch (err) { console.error('Sponsor signup failed:', err); alert('Registration failed. ' + (err instanceof Error ? err.message : 'Try again.')); } finally { setSubmitting(false); } }; const toggleInterest = (id: string) => { setFormData(prev => ({ ...prev, interests: prev.interests.includes(id) ? prev.interests.filter(i => i !== id) : [...prev.interests, id] })); }; // Landing page for sponsors if (mode === 'landing') { return ( {/* Hero Section */} {/* Platform Stats */} {PLATFORM_STATS.map((stat, index) => ( {stat.value} {stat.label} ))} {/* Sponsorship Types Section */} Sponsorship Opportunities Choose how you want to connect with the sim racing community. Multiple sponsorship tiers and types to fit every budget and goal. {SPONSORSHIP_TYPES.map((type, index) => ( {type.title} {type.priceRange} {type.description} {type.benefits.map((benefit, i) => ( {benefit} ))} ))} {/* Workflow Mockup Section */} How It Works From discovery to results tracking — a seamless sponsorship experience. {/* Benefits Grid */} Why Sponsor on GridPilot? Professional tools and genuine community engagement make your sponsorship worthwhile. {/* CTA Section */} Ready to Grow Your Brand? Join sponsors connecting with sim racing communities worldwide. ); } // Login form if (mode === 'login') { return ( Sponsor Sign In Access your sponsor dashboard Email Address { form.contactEmail = e.target.value; setForm(new SponsorSignupCommandModel(form.toCommand())); }} placeholder="sponsor@company.com" variant={errors.contactEmail ? 'error' : 'default'} errorMessage={errors.contactEmail} /> Password setFormData({ ...formData, password: e.target.value })} placeholder="••••••••" variant={errors.password ? 'error' : 'default'} errorMessage={errors.password} /> Remember me Don't have an account?{' '} ); } // Signup form return ( {/* Header */} Create Sponsor Account Register your company to sponsor racing entities {/* Company Information */} }> Company Information Company Name * { form.companyName = e.target.value; setForm(new SponsorSignupCommandModel(form.toCommand())); }} placeholder="Your company name" variant={errors.companyName ? 'error' : 'default'} errorMessage={errors.companyName} /> Contact Email * { form.contactEmail = e.target.value; setForm(new SponsorSignupCommandModel(form.toCommand())); }} placeholder="sponsor@company.com" variant={errors.contactEmail ? 'error' : 'default'} errorMessage={errors.contactEmail} /> Website URL { form.websiteUrl = e.target.value; setForm(new SponsorSignupCommandModel(form.toCommand())); }} placeholder="https://company.com" variant={errors.websiteUrl ? 'error' : 'default'} errorMessage={errors.websiteUrl} /> {/* Sponsorship Interests */} }> Sponsorship Interests Select the types of sponsorships you're interested in (optional) {SPONSORSHIP_TYPES.map((type) => { const isSelected = formData.interests.includes(type.id); return ( ); })} {/* Company Logo */} Company Logo (optional) { const file = e.target.files?.[0] || null; setFormData({ ...formData, logoFile: file }); }} className="block w-full text-sm text-gray-400 file:mr-4 file:py-2 file:px-4 file:rounded-full file:border-0 file:text-sm file:font-semibold file:bg-primary-blue/10 file:text-primary-blue hover:file:bg-primary-blue/20" /> PNG, JPEG, or SVG. Recommended: 500x500px transparent background. {/* Account Security */} }> Account Security Password * setFormData({ ...formData, password: e.target.value })} placeholder="Min. 8 characters" variant={errors.password ? 'error' : 'default'} errorMessage={errors.password} /> Confirm Password * setFormData({ ...formData, confirmPassword: e.target.value })} placeholder="Confirm password" variant={errors.confirmPassword ? 'error' : 'default'} errorMessage={errors.confirmPassword} /> {/* Legal Agreements */} setFormData({ ...formData, acceptTerms: e.target.checked })} className="mt-1 rounded border-charcoal-outline bg-iron-gray text-primary-blue focus:ring-primary-blue" /> I accept the{' '} Terms of Service {' '}and{' '} Privacy Policy {' '}* {errors.acceptTerms && ( {errors.acceptTerms} )} setFormData({ ...formData, acceptVat: e.target.checked })} className="mt-1 rounded border-charcoal-outline bg-iron-gray text-primary-blue focus:ring-primary-blue" /> {siteConfig.vat.notice} A {siteConfig.fees.platformFeePercent}% platform fee applies to all sponsorships. * {errors.acceptVat && ( {errors.acceptVat} )} {/* Actions */} Already have an account?{' '} ); }