429 lines
15 KiB
TypeScript
429 lines
15 KiB
TypeScript
'use client';
|
|
|
|
import { useState } from 'react';
|
|
import { useRouter } from 'next/navigation';
|
|
import Card from '@/components/ui/Card';
|
|
import Button from '@/components/ui/Button';
|
|
import Input from '@/components/ui/Input';
|
|
import { Building2, Mail, Globe, Upload, Zap, Eye, TrendingUp, Users, ArrowRight } from 'lucide-react';
|
|
|
|
export default function SponsorSignupPage() {
|
|
const router = useRouter();
|
|
const [mode, setMode] = useState<'landing' | 'signup' | 'login'>('landing');
|
|
const [formData, setFormData] = useState({
|
|
name: '',
|
|
contactEmail: '',
|
|
websiteUrl: '',
|
|
logoFile: null as File | null,
|
|
password: '',
|
|
});
|
|
const [errors, setErrors] = useState<Record<string, string>>({});
|
|
const [submitting, setSubmitting] = useState(false);
|
|
|
|
const handleDemoLogin = async () => {
|
|
setSubmitting(true);
|
|
try {
|
|
// Demo: Set cookie to indicate sponsor mode
|
|
document.cookie = 'gridpilot_demo_mode=sponsor; path=/; max-age=86400';
|
|
document.cookie = 'gridpilot_sponsor_id=demo-sponsor-1; path=/; max-age=86400';
|
|
|
|
await new Promise(resolve => setTimeout(resolve, 500));
|
|
router.push('/leagues');
|
|
} finally {
|
|
setSubmitting(false);
|
|
}
|
|
};
|
|
|
|
const handleSubmit = async (e: React.FormEvent) => {
|
|
e.preventDefault();
|
|
|
|
const newErrors: Record<string, string> = {};
|
|
|
|
if (!formData.name.trim()) {
|
|
newErrors.name = 'Company name required';
|
|
}
|
|
|
|
if (!formData.contactEmail.trim()) {
|
|
newErrors.contactEmail = 'Contact email required';
|
|
} else if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(formData.contactEmail)) {
|
|
newErrors.contactEmail = 'Invalid email format';
|
|
}
|
|
|
|
if (mode === 'signup' && !formData.password.trim()) {
|
|
newErrors.password = 'Password required';
|
|
}
|
|
|
|
if (Object.keys(newErrors).length > 0) {
|
|
setErrors(newErrors);
|
|
return;
|
|
}
|
|
|
|
setSubmitting(true);
|
|
|
|
try {
|
|
// Alpha: In-memory only, set demo sponsor cookie
|
|
console.log('Sponsor signup:', formData);
|
|
|
|
document.cookie = 'gridpilot_demo_mode=sponsor; path=/; max-age=86400';
|
|
document.cookie = `gridpilot_sponsor_name=${encodeURIComponent(formData.name)}; path=/; max-age=86400`;
|
|
|
|
await new Promise(resolve => setTimeout(resolve, 800));
|
|
|
|
router.push('/leagues');
|
|
} catch (err) {
|
|
console.error('Sponsor signup failed:', err);
|
|
alert('Registration failed. Try again.');
|
|
} finally {
|
|
setSubmitting(false);
|
|
}
|
|
};
|
|
|
|
// Landing page for sponsors
|
|
if (mode === 'landing') {
|
|
return (
|
|
<div className="max-w-4xl mx-auto py-12">
|
|
{/* Hero */}
|
|
<div className="text-center mb-12">
|
|
<div className="flex justify-center mb-6">
|
|
<div className="flex h-16 w-16 items-center justify-center rounded-2xl bg-primary-blue/10">
|
|
<Building2 className="w-8 h-8 text-primary-blue" />
|
|
</div>
|
|
</div>
|
|
<h1 className="text-4xl font-bold text-white mb-4">Sponsor Sim Racing Leagues</h1>
|
|
<p className="text-lg text-gray-400 max-w-2xl mx-auto">
|
|
Connect your brand with passionate sim racing communities. Get exposure through liveries, league branding, and engaged audiences.
|
|
</p>
|
|
</div>
|
|
|
|
{/* Benefits */}
|
|
<div className="grid grid-cols-1 md:grid-cols-3 gap-6 mb-12">
|
|
<Card>
|
|
<div className="flex flex-col items-center text-center">
|
|
<div className="flex h-12 w-12 items-center justify-center rounded-xl bg-primary-blue/10 mb-4">
|
|
<Eye className="w-6 h-6 text-primary-blue" />
|
|
</div>
|
|
<h3 className="text-lg font-semibold text-white mb-2">Brand Exposure</h3>
|
|
<p className="text-sm text-gray-400">
|
|
Your logo on liveries, league pages, and race broadcasts. Reach thousands of dedicated sim racers.
|
|
</p>
|
|
</div>
|
|
</Card>
|
|
|
|
<Card>
|
|
<div className="flex flex-col items-center text-center">
|
|
<div className="flex h-12 w-12 items-center justify-center rounded-xl bg-performance-green/10 mb-4">
|
|
<TrendingUp className="w-6 h-6 text-performance-green" />
|
|
</div>
|
|
<h3 className="text-lg font-semibold text-white mb-2">Analytics Dashboard</h3>
|
|
<p className="text-sm text-gray-400">
|
|
Track impressions, clicks, and engagement. See exactly how your sponsorship performs.
|
|
</p>
|
|
</div>
|
|
</Card>
|
|
|
|
<Card>
|
|
<div className="flex flex-col items-center text-center">
|
|
<div className="flex h-12 w-12 items-center justify-center rounded-xl bg-warning-amber/10 mb-4">
|
|
<Users className="w-6 h-6 text-warning-amber" />
|
|
</div>
|
|
<h3 className="text-lg font-semibold text-white mb-2">Engaged Audience</h3>
|
|
<p className="text-sm text-gray-400">
|
|
Connect with a passionate, tech-savvy community that values authentic partnerships.
|
|
</p>
|
|
</div>
|
|
</Card>
|
|
</div>
|
|
|
|
{/* CTA Buttons */}
|
|
<div className="flex flex-col sm:flex-row gap-4 justify-center mb-8">
|
|
<Button
|
|
variant="primary"
|
|
onClick={() => setMode('signup')}
|
|
className="px-8 py-3"
|
|
>
|
|
<Building2 className="w-5 h-5 mr-2" />
|
|
Create Sponsor Account
|
|
</Button>
|
|
<Button
|
|
variant="secondary"
|
|
onClick={() => setMode('login')}
|
|
className="px-8 py-3"
|
|
>
|
|
Sign In
|
|
<ArrowRight className="w-5 h-5 ml-2" />
|
|
</Button>
|
|
</div>
|
|
|
|
{/* Demo Login */}
|
|
<div className="text-center">
|
|
<div className="inline-flex items-center gap-2 px-4 py-2 rounded-full bg-iron-gray/50 border border-charcoal-outline">
|
|
<Zap className="w-4 h-4 text-warning-amber" />
|
|
<span className="text-sm text-gray-400">Try it now:</span>
|
|
<button
|
|
onClick={handleDemoLogin}
|
|
disabled={submitting}
|
|
className="text-sm font-medium text-primary-blue hover:text-primary-blue/80 transition-colors disabled:opacity-50"
|
|
>
|
|
{submitting ? 'Loading...' : 'Demo Sponsor Login'}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Alpha Notice */}
|
|
<div className="mt-12 rounded-lg bg-warning-amber/10 border border-warning-amber/30 p-4">
|
|
<p className="text-xs text-gray-400 text-center">
|
|
<strong className="text-warning-amber">Alpha Preview:</strong> Sponsorship features are demonstration-only.
|
|
In production, you'll have access to payment processing, detailed analytics, and automated livery placement.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
// Login form
|
|
if (mode === 'login') {
|
|
return (
|
|
<div className="max-w-md mx-auto py-12">
|
|
<div className="mb-8">
|
|
<button
|
|
onClick={() => setMode('landing')}
|
|
className="text-sm text-gray-400 hover:text-white mb-4"
|
|
>
|
|
← Back
|
|
</button>
|
|
<div className="flex items-center gap-3 mb-4">
|
|
<div className="flex h-12 w-12 items-center justify-center rounded-xl bg-primary-blue/10">
|
|
<Building2 className="w-6 h-6 text-primary-blue" />
|
|
</div>
|
|
<div>
|
|
<h1 className="text-2xl font-bold text-white">Sponsor Sign In</h1>
|
|
<p className="text-sm text-gray-400">Access your sponsor dashboard</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<Card>
|
|
<form onSubmit={handleSubmit} className="space-y-6">
|
|
<div>
|
|
<label className="block text-sm font-medium text-gray-300 mb-2">
|
|
<div className="flex items-center gap-2">
|
|
<Mail className="w-4 h-4 text-gray-500" />
|
|
Email
|
|
</div>
|
|
</label>
|
|
<Input
|
|
type="email"
|
|
value={formData.contactEmail}
|
|
onChange={(e) => setFormData({ ...formData, contactEmail: e.target.value })}
|
|
placeholder="sponsor@company.com"
|
|
error={!!errors.contactEmail}
|
|
errorMessage={errors.contactEmail}
|
|
/>
|
|
</div>
|
|
|
|
<div>
|
|
<label className="block text-sm font-medium text-gray-300 mb-2">
|
|
Password
|
|
</label>
|
|
<Input
|
|
type="password"
|
|
value={formData.password}
|
|
onChange={(e) => setFormData({ ...formData, password: e.target.value })}
|
|
placeholder="••••••••"
|
|
error={!!errors.password}
|
|
errorMessage={errors.password}
|
|
/>
|
|
</div>
|
|
|
|
<Button
|
|
type="submit"
|
|
variant="primary"
|
|
disabled={submitting}
|
|
className="w-full"
|
|
>
|
|
{submitting ? 'Signing in...' : 'Sign In'}
|
|
</Button>
|
|
</form>
|
|
|
|
<div className="mt-6 pt-6 border-t border-charcoal-outline text-center">
|
|
<p className="text-sm text-gray-400">
|
|
Don't have an account?{' '}
|
|
<button
|
|
onClick={() => setMode('signup')}
|
|
className="text-primary-blue hover:text-primary-blue/80"
|
|
>
|
|
Create one
|
|
</button>
|
|
</p>
|
|
</div>
|
|
|
|
<div className="mt-4 text-center">
|
|
<button
|
|
onClick={handleDemoLogin}
|
|
disabled={submitting}
|
|
className="text-sm text-gray-500 hover:text-gray-400"
|
|
>
|
|
Or use demo login
|
|
</button>
|
|
</div>
|
|
</Card>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
// Signup form
|
|
return (
|
|
<div className="max-w-2xl mx-auto py-12">
|
|
{/* Header */}
|
|
<div className="mb-8">
|
|
<button
|
|
onClick={() => setMode('landing')}
|
|
className="text-sm text-gray-400 hover:text-white mb-4"
|
|
>
|
|
← Back
|
|
</button>
|
|
<div className="flex items-center gap-3 mb-4">
|
|
<div className="flex h-12 w-12 items-center justify-center rounded-xl bg-primary-blue/10">
|
|
<Building2 className="w-6 h-6 text-primary-blue" />
|
|
</div>
|
|
<div>
|
|
<h1 className="text-2xl font-bold text-white">Create Sponsor Account</h1>
|
|
<p className="text-sm text-gray-400">Register your company to sponsor leagues</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<Card>
|
|
<form onSubmit={handleSubmit} className="space-y-6">
|
|
{/* Company Name */}
|
|
<div>
|
|
<label className="block text-sm font-medium text-gray-300 mb-2">
|
|
Company Name
|
|
</label>
|
|
<Input
|
|
type="text"
|
|
value={formData.name}
|
|
onChange={(e) => setFormData({ ...formData, name: e.target.value })}
|
|
placeholder="Your company name"
|
|
error={!!errors.name}
|
|
errorMessage={errors.name}
|
|
/>
|
|
</div>
|
|
|
|
{/* Contact Email */}
|
|
<div>
|
|
<label className="block text-sm font-medium text-gray-300 mb-2">
|
|
<div className="flex items-center gap-2">
|
|
<Mail className="w-4 h-4 text-gray-500" />
|
|
Contact Email
|
|
</div>
|
|
</label>
|
|
<Input
|
|
type="email"
|
|
value={formData.contactEmail}
|
|
onChange={(e) => setFormData({ ...formData, contactEmail: e.target.value })}
|
|
placeholder="sponsor@company.com"
|
|
error={!!errors.contactEmail}
|
|
errorMessage={errors.contactEmail}
|
|
/>
|
|
</div>
|
|
|
|
{/* Website URL */}
|
|
<div>
|
|
<label className="block text-sm font-medium text-gray-300 mb-2">
|
|
<div className="flex items-center gap-2">
|
|
<Globe className="w-4 h-4 text-gray-500" />
|
|
Website URL (optional)
|
|
</div>
|
|
</label>
|
|
<Input
|
|
type="url"
|
|
value={formData.websiteUrl}
|
|
onChange={(e) => setFormData({ ...formData, websiteUrl: e.target.value })}
|
|
placeholder="https://company.com"
|
|
/>
|
|
</div>
|
|
|
|
{/* Logo Upload */}
|
|
<div>
|
|
<label className="block text-sm font-medium text-gray-300 mb-2">
|
|
<div className="flex items-center gap-2">
|
|
<Upload className="w-4 h-4 text-gray-500" />
|
|
Company Logo (optional)
|
|
</div>
|
|
</label>
|
|
<div className="flex items-center gap-3">
|
|
<input
|
|
type="file"
|
|
accept="image/png,image/jpeg,image/svg+xml"
|
|
onChange={(e) => {
|
|
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"
|
|
/>
|
|
</div>
|
|
<p className="text-xs text-gray-500 mt-1">
|
|
PNG, JPEG, or SVG. Recommended: 500x500px transparent background.
|
|
</p>
|
|
</div>
|
|
|
|
{/* Password */}
|
|
<div>
|
|
<label className="block text-sm font-medium text-gray-300 mb-2">
|
|
Password
|
|
</label>
|
|
<Input
|
|
type="password"
|
|
value={formData.password}
|
|
onChange={(e) => setFormData({ ...formData, password: e.target.value })}
|
|
placeholder="Create a password"
|
|
error={!!errors.password}
|
|
errorMessage={errors.password}
|
|
/>
|
|
</div>
|
|
|
|
{/* Alpha Notice */}
|
|
<div className="rounded-lg bg-warning-amber/10 border border-warning-amber/30 p-4">
|
|
<p className="text-xs text-gray-400">
|
|
<strong className="text-warning-amber">Alpha Note:</strong> Sponsor registration is demonstration-only.
|
|
In production, you'll have access to full payment processing and analytics.
|
|
</p>
|
|
</div>
|
|
|
|
{/* Actions */}
|
|
<div className="flex gap-3 pt-4">
|
|
<Button
|
|
type="submit"
|
|
variant="primary"
|
|
disabled={submitting}
|
|
className="flex-1"
|
|
>
|
|
{submitting ? 'Creating Account...' : 'Create Account'}
|
|
</Button>
|
|
<Button
|
|
type="button"
|
|
variant="secondary"
|
|
onClick={() => setMode('landing')}
|
|
disabled={submitting}
|
|
>
|
|
Cancel
|
|
</Button>
|
|
</div>
|
|
</form>
|
|
|
|
<div className="mt-6 pt-6 border-t border-charcoal-outline text-center">
|
|
<p className="text-sm text-gray-400">
|
|
Already have an account?{' '}
|
|
<button
|
|
onClick={() => setMode('login')}
|
|
className="text-primary-blue hover:text-primary-blue/80"
|
|
>
|
|
Sign in
|
|
</button>
|
|
</p>
|
|
</div>
|
|
</Card>
|
|
</div>
|
|
);
|
|
} |