'use client'; import { useState } from 'react'; import { motion, useReducedMotion } from 'framer-motion'; import Card from '@/components/ui/Card'; import Button from '@/components/ui/Button'; import StatCard from '@/components/ui/StatCard'; import SectionHeader from '@/components/ui/SectionHeader'; import StatusBadge from '@/components/ui/StatusBadge'; import InfoBanner from '@/components/ui/InfoBanner'; import PageHeader from '@/components/ui/PageHeader'; import { siteConfig } from '@/lib/siteConfig'; import { CreditCard, DollarSign, Calendar, Download, Plus, Check, AlertTriangle, FileText, ArrowRight, TrendingUp, Receipt, Building2, Wallet, Clock, ChevronRight, Info, ExternalLink, Percent } from 'lucide-react'; // ============================================================================ // Types // ============================================================================ interface PaymentMethod { id: string; type: 'card' | 'bank' | 'sepa'; last4: string; brand?: string; isDefault: boolean; expiryMonth?: number; expiryYear?: number; bankName?: string; } interface Invoice { id: string; invoiceNumber: string; date: Date; dueDate: Date; amount: number; vatAmount: number; totalAmount: number; status: 'paid' | 'pending' | 'overdue' | 'failed'; description: string; sponsorshipType: 'league' | 'team' | 'driver' | 'race' | 'platform'; pdfUrl: string; } interface BillingStats { totalSpent: number; pendingAmount: number; nextPaymentDate: Date; nextPaymentAmount: number; activeSponsorships: number; averageMonthlySpend: number; } // ============================================================================ // Mock Data // ============================================================================ const MOCK_PAYMENT_METHODS: PaymentMethod[] = [ { id: 'pm-1', type: 'card', last4: '4242', brand: 'Visa', isDefault: true, expiryMonth: 12, expiryYear: 2027, }, { id: 'pm-2', type: 'card', last4: '5555', brand: 'Mastercard', isDefault: false, expiryMonth: 6, expiryYear: 2026, }, { id: 'pm-3', type: 'sepa', last4: '8901', bankName: 'Deutsche Bank', isDefault: false, }, ]; const MOCK_INVOICES: Invoice[] = [ { id: 'inv-1', invoiceNumber: 'GP-2025-001234', date: new Date('2025-11-01'), dueDate: new Date('2025-11-15'), amount: 1090.91, vatAmount: 207.27, totalAmount: 1298.18, status: 'paid', description: 'GT3 Pro Championship - Primary Sponsor (Q4 2025)', sponsorshipType: 'league', pdfUrl: '#', }, { id: 'inv-2', invoiceNumber: 'GP-2025-001235', date: new Date('2025-10-01'), dueDate: new Date('2025-10-15'), amount: 363.64, vatAmount: 69.09, totalAmount: 432.73, status: 'paid', description: 'Team Velocity - Gear Sponsor (Q4 2025)', sponsorshipType: 'team', pdfUrl: '#', }, { id: 'inv-3', invoiceNumber: 'GP-2025-001236', date: new Date('2025-12-01'), dueDate: new Date('2025-12-15'), amount: 318.18, vatAmount: 60.45, totalAmount: 378.63, status: 'pending', description: 'Alex Thompson - Driver Sponsorship (Dec 2025)', sponsorshipType: 'driver', pdfUrl: '#', }, { id: 'inv-4', invoiceNumber: 'GP-2025-001237', date: new Date('2025-11-15'), dueDate: new Date('2025-11-29'), amount: 454.55, vatAmount: 86.36, totalAmount: 540.91, status: 'overdue', description: 'Touring Car Cup - Secondary Sponsor (Q1 2026)', sponsorshipType: 'league', pdfUrl: '#', }, ]; const MOCK_STATS: BillingStats = { totalSpent: 12450, pendingAmount: 919.54, nextPaymentDate: new Date('2025-12-15'), nextPaymentAmount: 378.63, activeSponsorships: 6, averageMonthlySpend: 2075, }; // ============================================================================ // Components // ============================================================================ function PaymentMethodCard({ method, onSetDefault, onRemove }: { method: PaymentMethod; onSetDefault: () => void; onRemove: () => void; }) { const shouldReduceMotion = useReducedMotion(); const getIcon = () => { if (method.type === 'sepa') return Building2; return CreditCard; }; const Icon = getIcon(); const getLabel = () => { if (method.type === 'sepa' && method.bankName) { return `${method.bankName} •••• ${method.last4}`; } return `${method.brand} •••• ${method.last4}`; }; return (
{getLabel()} {method.isDefault && ( Default )}
{method.expiryMonth && method.expiryYear && ( Expires {String(method.expiryMonth).padStart(2, '0')}/{method.expiryYear} )} {method.type === 'sepa' && ( SEPA Direct Debit )}
{!method.isDefault && ( )}
); } function InvoiceRow({ invoice, index }: { invoice: Invoice; index: number }) { const shouldReduceMotion = useReducedMotion(); const statusConfig = { paid: { icon: Check, label: 'Paid', color: 'text-performance-green', bg: 'bg-performance-green/10', border: 'border-performance-green/30' }, pending: { icon: Clock, label: 'Pending', color: 'text-warning-amber', bg: 'bg-warning-amber/10', border: 'border-warning-amber/30' }, overdue: { icon: AlertTriangle, label: 'Overdue', color: 'text-racing-red', bg: 'bg-racing-red/10', border: 'border-racing-red/30' }, failed: { icon: AlertTriangle, label: 'Failed', color: 'text-racing-red', bg: 'bg-racing-red/10', border: 'border-racing-red/30' }, }; const typeLabels = { league: 'League', team: 'Team', driver: 'Driver', race: 'Race', platform: 'Platform', }; const status = statusConfig[invoice.status]; const StatusIcon = status.icon; return (
{invoice.description} {typeLabels[invoice.sponsorshipType]}
{invoice.invoiceNumber} {invoice.date.toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' })}
€{invoice.totalAmount.toLocaleString('de-DE', { minimumFractionDigits: 2 })}
incl. €{invoice.vatAmount.toLocaleString('de-DE', { minimumFractionDigits: 2 })} VAT
{status.label}
); } // ============================================================================ // Main Component // ============================================================================ export default function SponsorBillingPage() { const shouldReduceMotion = useReducedMotion(); const [paymentMethods, setPaymentMethods] = useState(MOCK_PAYMENT_METHODS); const [showAllInvoices, setShowAllInvoices] = useState(false); const handleSetDefault = (methodId: string) => { setPaymentMethods(methods => methods.map(m => ({ ...m, isDefault: m.id === methodId })) ); }; const handleRemoveMethod = (methodId: string) => { if (confirm('Remove this payment method?')) { setPaymentMethods(methods => methods.filter(m => m.id !== methodId)); } }; const displayedInvoices = showAllInvoices ? MOCK_INVOICES : MOCK_INVOICES.slice(0, 4); const containerVariants = { hidden: { opacity: 0 }, visible: { opacity: 1, transition: { staggerChildren: shouldReduceMotion ? 0 : 0.1, }, }, }; const itemVariants = { hidden: { opacity: 0, y: 20 }, visible: { opacity: 1, y: 0 }, }; return ( {/* Header */} {/* Stats Grid */} i.status === 'pending' || i.status === 'overdue').length} invoices`} color="text-warning-amber" bgColor="bg-warning-amber/10" /> {/* Payment Methods */} Add Payment Method } />
{paymentMethods.map((method) => ( handleSetDefault(method.id)} onRemove={() => handleRemoveMethod(method.id)} /> ))}

We support Visa, Mastercard, American Express, and SEPA Direct Debit.

All payment information is securely processed and stored by our payment provider.

{/* Billing History */} Export All } />
{displayedInvoices.map((invoice, index) => ( ))}
{MOCK_INVOICES.length > 4 && (
)}
{/* Platform Fee & VAT Information */} {/* Platform Fee */}

Platform Fee

{siteConfig.fees.platformFeePercent}%

{siteConfig.fees.description}

• Applied to all sponsorship payments

• Covers platform maintenance and analytics

• Ensures quality sponsorship placements

{/* VAT Information */}

VAT Information

{siteConfig.vat.notice}

Standard VAT Rate {siteConfig.vat.standardRate}%
B2B Reverse Charge Available

Enter your VAT ID in Settings to enable reverse charge for B2B transactions.

{/* Billing Support */}

Need help with billing?

Contact our billing support for questions about invoices, payments, or refunds.

); }