'use client';
import { useState } from 'react';
import { motion, useReducedMotion } from 'framer-motion';
import { Card } from '@/ui/Card';
import { Button } from '@/ui/Button';
import { StatCard } from '@/ui/StatCard';
import { SectionHeader } from '@/ui/SectionHeader';
import { StatusBadge } from '@/ui/StatusBadge';
import { InfoBanner } from '@/ui/InfoBanner';
import { PageHeader } from '@/ui/PageHeader';
import { siteConfig } from '@/lib/siteConfig';
import { useSponsorBilling } from "@/lib/hooks/sponsor/useSponsorBilling";
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
// ============================================================================
// ============================================================================
// Components
// ============================================================================
function PaymentMethodCard({
method,
onSetDefault,
onRemove
}: {
method: any;
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 (
{method.displayLabel}
{method.isDefault && (
Default
)}
{method.expiryDisplay && (
Expires {method.expiryDisplay}
)}
{method.type === 'sepa' && (
SEPA Direct Debit
)}
{!method.isDefault && (
)}
);
}
function InvoiceRow({ invoice, index }: { invoice: any; 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 as keyof typeof statusConfig];
const StatusIcon = status.icon;
return (
{invoice.description}
{typeLabels[invoice.sponsorshipType as keyof typeof typeLabels]}
{invoice.invoiceNumber}
•
{invoice.formattedDate}
{invoice.formattedTotalAmount}
incl. {invoice.formattedVatAmount} VAT
{status.label}
);
}
// ============================================================================
// Main Component
// ============================================================================
export default function SponsorBillingPage() {
const shouldReduceMotion = useReducedMotion();
const [showAllInvoices, setShowAllInvoices] = useState(false);
const { data: billingData, isLoading, error, retry } = useSponsorBilling('demo-sponsor-1');
if (isLoading) {
return (
);
}
if (error || !billingData) {
return (
{error?.getUserMessage() || 'No billing data available'}
{error && (
)}
);
}
const data = billingData;
const handleSetDefault = (methodId: string) => {
// In a real app, this would call an API
console.log('Setting default payment method:', methodId);
};
const handleRemoveMethod = (methodId: string) => {
if (confirm('Remove this payment method?')) {
// In a real app, this would call an API
console.log('Removing payment method:', methodId);
}
};
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
}
/>
{data.paymentMethods.map((method: { id: string; type: string; last4: string; brand: string; default: boolean }) => (
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
}
/>
{data.invoices.slice(0, showAllInvoices ? data.invoices.length : 4).map((invoice: { id: string; date: string; amount: number; status: string }, index: number) => (
))}
{data.invoices.length > 4 && (
)}
{/* Platform Fee & VAT Information */}
{/* Platform Fee */}
{siteConfig.fees.platformFeePercent}%
{siteConfig.fees.description}
• Applied to all sponsorship payments
• Covers platform maintenance and analytics
• Ensures quality sponsorship placements
{/* 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.
);
}