website refactor

This commit is contained in:
2026-01-14 10:51:05 +01:00
parent 4522d41aef
commit 0d89ad027e
291 changed files with 6887 additions and 3685 deletions

View File

@@ -1,12 +1,11 @@
'use client';
import { useState } from 'react';
import { useRouter, useSearchParams } from 'next/navigation';
import { useSearchParams } from 'next/navigation';
import { motion, useReducedMotion, AnimatePresence } from 'framer-motion';
import Link from 'next/link';
import Card from '@/components/ui/Card';
import Button from '@/components/ui/Button';
import StatusBadge from '@/components/ui/StatusBadge';
import InfoBanner from '@/components/ui/InfoBanner';
import { useSponsorSponsorships } from "@/lib/hooks/sponsor/useSponsorSponsorships";
import {
@@ -44,33 +43,6 @@ import {
type SponsorshipType = 'all' | 'leagues' | 'teams' | 'drivers' | 'races' | 'platform';
type SponsorshipStatus = 'all' | 'active' | 'pending_approval' | 'approved' | 'rejected' | 'expired';
interface Sponsorship {
id: string;
type: SponsorshipType;
entityId: string;
entityName: string;
tier?: 'main' | 'secondary';
status: 'active' | 'pending_approval' | 'approved' | 'rejected' | 'expired';
applicationDate?: Date;
approvalDate?: Date;
rejectionReason?: string;
startDate: Date;
endDate: Date;
price: number;
impressions: number;
impressionsChange?: number;
engagement?: number;
details?: string;
// For pending approvals
entityOwner?: string;
applicationMessage?: string;
}
// ============================================================================
// Mock Data - Updated to show application workflow
// ============================================================================
// ============================================================================
// Configuration
// ============================================================================
@@ -85,40 +57,40 @@ const TYPE_CONFIG = {
};
const STATUS_CONFIG = {
active: {
icon: Check,
color: 'text-performance-green',
bgColor: 'bg-performance-green/10',
active: {
icon: Check,
color: 'text-performance-green',
bgColor: 'bg-performance-green/10',
borderColor: 'border-performance-green/30',
label: 'Active'
label: 'Active'
},
pending_approval: {
icon: Clock,
color: 'text-warning-amber',
bgColor: 'bg-warning-amber/10',
pending_approval: {
icon: Clock,
color: 'text-warning-amber',
bgColor: 'bg-warning-amber/10',
borderColor: 'border-warning-amber/30',
label: 'Awaiting Approval'
label: 'Awaiting Approval'
},
approved: {
icon: ThumbsUp,
color: 'text-primary-blue',
bgColor: 'bg-primary-blue/10',
approved: {
icon: ThumbsUp,
color: 'text-primary-blue',
bgColor: 'bg-primary-blue/10',
borderColor: 'border-primary-blue/30',
label: 'Approved'
label: 'Approved'
},
rejected: {
icon: ThumbsDown,
color: 'text-racing-red',
bgColor: 'bg-racing-red/10',
rejected: {
icon: ThumbsDown,
color: 'text-racing-red',
bgColor: 'bg-racing-red/10',
borderColor: 'border-racing-red/30',
label: 'Declined'
label: 'Declined'
},
expired: {
icon: XCircle,
color: 'text-gray-400',
bgColor: 'bg-gray-400/10',
expired: {
icon: XCircle,
color: 'text-gray-400',
bgColor: 'bg-gray-400/10',
borderColor: 'border-gray-400/30',
label: 'Expired'
label: 'Expired'
},
};
@@ -127,7 +99,6 @@ const STATUS_CONFIG = {
// ============================================================================
function SponsorshipCard({ sponsorship }: { sponsorship: any }) {
const router = useRouter();
const shouldReduceMotion = useReducedMotion();
const typeConfig = TYPE_CONFIG[sponsorship.type as keyof typeof TYPE_CONFIG];
@@ -159,8 +130,8 @@ function SponsorshipCard({ sponsorship }: { sponsorship: any }) {
transition={{ duration: 0.2 }}
>
<Card className={`hover:border-primary-blue/30 transition-all duration-300 ${
isPending ? 'border-warning-amber/30' :
isRejected ? 'border-racing-red/20 opacity-75' :
isPending ? 'border-warning-amber/30' :
isRejected ? 'border-racing-red/20 opacity-75' :
isApproved ? 'border-primary-blue/30' : ''
}`}>
{/* Header */}
@@ -176,8 +147,8 @@ function SponsorshipCard({ sponsorship }: { sponsorship: any }) {
</span>
{sponsorship.tier && (
<span className={`text-xs font-medium px-2 py-0.5 rounded ${
sponsorship.tier === 'main'
? 'bg-primary-blue/20 text-primary-blue'
sponsorship.tier === 'main'
? 'bg-primary-blue/20 text-primary-blue'
: 'bg-purple-400/20 text-purple-400'
}`}>
{sponsorship.tier === 'main' ? 'Main Sponsor' : 'Secondary'}
@@ -360,7 +331,6 @@ function SponsorshipCard({ sponsorship }: { sponsorship: any }) {
// ============================================================================
export default function SponsorCampaignsPage() {
const router = useRouter();
const searchParams = useSearchParams();
const shouldReduceMotion = useReducedMotion();
@@ -400,7 +370,7 @@ export default function SponsorCampaignsPage() {
const data = sponsorshipsData;
// Filter sponsorships
const filteredSponsorships = data.sponsorships.filter(s => {
const filteredSponsorships = data.sponsorships.filter((s: any) => {
if (typeFilter !== 'all' && s.type !== typeFilter) return false;
if (statusFilter !== 'all' && s.status !== statusFilter) return false;
if (searchQuery && !s.entityName.toLowerCase().includes(searchQuery.toLowerCase())) return false;
@@ -410,21 +380,21 @@ export default function SponsorCampaignsPage() {
// Calculate stats
const stats = {
total: data.sponsorships.length,
active: data.sponsorships.filter(s => s.status === 'active').length,
pending: data.sponsorships.filter(s => s.status === 'pending_approval').length,
approved: data.sponsorships.filter(s => s.status === 'approved').length,
rejected: data.sponsorships.filter(s => s.status === 'rejected').length,
totalInvestment: data.sponsorships.filter(s => s.status === 'active').reduce((sum, s) => sum + s.price, 0),
totalImpressions: data.sponsorships.reduce((sum, s) => sum + s.impressions, 0),
active: data.sponsorships.filter((s: any) => s.status === 'active').length,
pending: data.sponsorships.filter((s: any) => s.status === 'pending_approval').length,
approved: data.sponsorships.filter((s: any) => s.status === 'approved').length,
rejected: data.sponsorships.filter((s: any) => s.status === 'rejected').length,
totalInvestment: data.sponsorships.filter((s: any) => s.status === 'active').reduce((sum: number, s: any) => sum + s.price, 0),
totalImpressions: data.sponsorships.reduce((sum: number, s: any) => sum + s.impressions, 0),
};
// Stats by type
const statsByType = {
leagues: data.sponsorships.filter(s => s.type === 'leagues').length,
teams: data.sponsorships.filter(s => s.type === 'teams').length,
drivers: data.sponsorships.filter(s => s.type === 'drivers').length,
races: data.sponsorships.filter(s => s.type === 'races').length,
platform: data.sponsorships.filter(s => s.type === 'platform').length,
leagues: data.sponsorships.filter((s: any) => s.type === 'leagues').length,
teams: data.sponsorships.filter((s: any) => s.type === 'teams').length,
drivers: data.sponsorships.filter((s: any) => s.type === 'drivers').length,
races: data.sponsorships.filter((s: any) => s.type === 'races').length,
platform: data.sponsorships.filter((s: any) => s.type === 'platform').length,
};
return (
@@ -457,7 +427,7 @@ export default function SponsorCampaignsPage() {
>
<InfoBanner type="info" title="Sponsorship Applications">
<p>
You have <strong className="text-white">{stats.pending} pending application{stats.pending !== 1 ? 's' : ''}</strong> waiting for approval.
You have <strong className="text-white">{stats.pending} pending application{stats.pending !== 1 ? 's' : ''}</strong> waiting for approval.
League admins, team owners, and drivers review applications before accepting sponsorships.
</p>
</InfoBanner>
@@ -540,7 +510,7 @@ export default function SponsorCampaignsPage() {
className="w-full pl-10 pr-4 py-2.5 rounded-lg border border-charcoal-outline bg-iron-gray text-white placeholder-gray-500 focus:border-primary-blue focus:outline-none"
/>
</div>
{/* Type Filter */}
<div className="flex items-center gap-2 overflow-x-auto pb-2 lg:pb-0">
{(['all', 'leagues', 'teams', 'drivers', 'races', 'platform'] as const).map((type) => {
@@ -572,12 +542,12 @@ export default function SponsorCampaignsPage() {
{/* Status Filter */}
<div className="flex items-center gap-2 overflow-x-auto">
{(['all', 'active', 'pending_approval', 'approved', 'rejected'] as const).map((status) => {
const config = status === 'all'
? { label: 'All', color: 'text-gray-400' }
const config = status === 'all'
? { label: 'All', color: 'text-gray-400' }
: STATUS_CONFIG[status];
const count = status === 'all'
? stats.total
: data.sponsorships.filter(s => s.status === status).length;
: data.sponsorships.filter((s: any) => s.status === status).length;
return (
<button
key={status}
@@ -635,7 +605,7 @@ export default function SponsorCampaignsPage() {
</Card>
) : (
<div className="grid grid-cols-1 lg:grid-cols-2 gap-4">
{filteredSponsorships.map((sponsorship) => (
{filteredSponsorships.map((sponsorship: any) => (
<SponsorshipCard key={sponsorship.id} sponsorship={sponsorship} />
))}
</div>