wip
This commit is contained in:
@@ -32,57 +32,73 @@ interface Sponsorship {
|
||||
drivers: number;
|
||||
}
|
||||
|
||||
// Mock data - in production would come from repository
|
||||
const MOCK_SPONSORSHIPS: Sponsorship[] = [
|
||||
{
|
||||
id: 'sp-1',
|
||||
leagueId: 'league-1',
|
||||
leagueName: 'GT3 Pro Championship',
|
||||
tier: 'main',
|
||||
status: 'active',
|
||||
startDate: new Date('2025-01-01'),
|
||||
endDate: new Date('2025-06-30'),
|
||||
price: 1200,
|
||||
impressions: 45200,
|
||||
drivers: 32,
|
||||
},
|
||||
{
|
||||
id: 'sp-2',
|
||||
leagueId: 'league-2',
|
||||
leagueName: 'Endurance Masters',
|
||||
tier: 'main',
|
||||
status: 'active',
|
||||
startDate: new Date('2025-02-01'),
|
||||
endDate: new Date('2025-07-31'),
|
||||
price: 1000,
|
||||
impressions: 38100,
|
||||
drivers: 48,
|
||||
},
|
||||
{
|
||||
id: 'sp-3',
|
||||
leagueId: 'league-3',
|
||||
leagueName: 'Formula Sim Series',
|
||||
tier: 'secondary',
|
||||
status: 'active',
|
||||
startDate: new Date('2025-03-01'),
|
||||
endDate: new Date('2025-08-31'),
|
||||
price: 400,
|
||||
impressions: 22800,
|
||||
drivers: 24,
|
||||
},
|
||||
{
|
||||
id: 'sp-4',
|
||||
leagueId: 'league-4',
|
||||
leagueName: 'Touring Car Cup',
|
||||
tier: 'secondary',
|
||||
status: 'pending',
|
||||
startDate: new Date('2025-04-01'),
|
||||
endDate: new Date('2025-09-30'),
|
||||
price: 350,
|
||||
impressions: 0,
|
||||
drivers: 28,
|
||||
},
|
||||
];
|
||||
interface SponsorshipDetailApi {
|
||||
id: string;
|
||||
leagueId: string;
|
||||
leagueName: string;
|
||||
seasonId: string;
|
||||
seasonName: string;
|
||||
seasonStartDate?: string;
|
||||
seasonEndDate?: string;
|
||||
tier: 'main' | 'secondary';
|
||||
status: string;
|
||||
pricing: {
|
||||
amount: number;
|
||||
currency: string;
|
||||
};
|
||||
metrics: {
|
||||
drivers: number;
|
||||
races: number;
|
||||
completedRaces: number;
|
||||
impressions: number;
|
||||
};
|
||||
createdAt: string;
|
||||
activatedAt?: string;
|
||||
}
|
||||
|
||||
interface SponsorSponsorshipsResponse {
|
||||
sponsorId: string;
|
||||
sponsorName: string;
|
||||
sponsorships: SponsorshipDetailApi[];
|
||||
summary: {
|
||||
totalSponsorships: number;
|
||||
activeSponsorships: number;
|
||||
totalInvestment: number;
|
||||
totalPlatformFees: number;
|
||||
currency: string;
|
||||
};
|
||||
}
|
||||
|
||||
function mapSponsorshipStatus(status: string): 'active' | 'pending' | 'expired' {
|
||||
switch (status) {
|
||||
case 'active':
|
||||
return 'active';
|
||||
case 'pending':
|
||||
return 'pending';
|
||||
default:
|
||||
return 'expired';
|
||||
}
|
||||
}
|
||||
|
||||
function mapApiToSponsorships(response: SponsorSponsorshipsResponse): Sponsorship[] {
|
||||
return response.sponsorships.map((s) => {
|
||||
const start = s.seasonStartDate ? new Date(s.seasonStartDate) : new Date(s.createdAt);
|
||||
const end = s.seasonEndDate ? new Date(s.seasonEndDate) : start;
|
||||
|
||||
return {
|
||||
id: s.id,
|
||||
leagueId: s.leagueId,
|
||||
leagueName: s.leagueName,
|
||||
tier: s.tier,
|
||||
status: mapSponsorshipStatus(s.status),
|
||||
startDate: start,
|
||||
endDate: end,
|
||||
price: s.pricing.amount,
|
||||
impressions: s.metrics.impressions,
|
||||
drivers: s.metrics.drivers,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
function SponsorshipCard({ sponsorship }: { sponsorship: Sponsorship }) {
|
||||
const router = useRouter();
|
||||
@@ -179,18 +195,59 @@ function SponsorshipCard({ sponsorship }: { sponsorship: Sponsorship }) {
|
||||
export default function SponsorCampaignsPage() {
|
||||
const router = useRouter();
|
||||
const [filter, setFilter] = useState<'all' | 'active' | 'pending' | 'expired'>('all');
|
||||
|
||||
const filteredSponsorships = filter === 'all'
|
||||
? MOCK_SPONSORSHIPS
|
||||
: MOCK_SPONSORSHIPS.filter(s => s.status === filter);
|
||||
const [sponsorships, setSponsorships] = useState<Sponsorship[]>([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
useEffect(() => {
|
||||
let isMounted = true;
|
||||
|
||||
async function fetchSponsorships() {
|
||||
try {
|
||||
const response = await fetch('/api/sponsors/sponsorships');
|
||||
if (!response.ok) {
|
||||
if (!isMounted) return;
|
||||
setSponsorships([]);
|
||||
return;
|
||||
}
|
||||
const json: SponsorSponsorshipsResponse = await response.json();
|
||||
if (!isMounted) return;
|
||||
setSponsorships(mapApiToSponsorships(json));
|
||||
} catch {
|
||||
if (!isMounted) return;
|
||||
setSponsorships([]);
|
||||
} finally {
|
||||
if (isMounted) {
|
||||
setLoading(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fetchSponsorships();
|
||||
|
||||
return () => {
|
||||
isMounted = false;
|
||||
};
|
||||
}, []);
|
||||
|
||||
const filteredSponsorships = filter === 'all'
|
||||
? sponsorships
|
||||
: sponsorships.filter(s => s.status === filter);
|
||||
|
||||
const stats = {
|
||||
total: MOCK_SPONSORSHIPS.length,
|
||||
active: MOCK_SPONSORSHIPS.filter(s => s.status === 'active').length,
|
||||
pending: MOCK_SPONSORSHIPS.filter(s => s.status === 'pending').length,
|
||||
totalInvestment: MOCK_SPONSORSHIPS.reduce((sum, s) => sum + s.price, 0),
|
||||
total: sponsorships.length,
|
||||
active: sponsorships.filter(s => s.status === 'active').length,
|
||||
pending: sponsorships.filter(s => s.status === 'pending').length,
|
||||
totalInvestment: sponsorships.reduce((sum, s) => sum + s.price, 0),
|
||||
};
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
<div className="max-w-6xl mx-auto py-8 px-4">
|
||||
<p className="text-gray-400">Loading sponsorships…</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="max-w-6xl mx-auto py-8 px-4">
|
||||
{/* Header */}
|
||||
|
||||
Reference in New Issue
Block a user