wip
This commit is contained in:
@@ -30,6 +30,63 @@ export interface DemoTeamDTO {
|
||||
memberCount: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Demo sponsor data for seeding
|
||||
*/
|
||||
export interface DemoSponsorDTO {
|
||||
id: string;
|
||||
name: string;
|
||||
contactEmail: string;
|
||||
logoUrl: string;
|
||||
websiteUrl: string;
|
||||
tagline: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Demo season sponsorship data
|
||||
*/
|
||||
export interface DemoSeasonSponsorshipDTO {
|
||||
id: string;
|
||||
seasonId: string;
|
||||
sponsorId: string;
|
||||
tier: 'main' | 'secondary';
|
||||
pricingAmount: number;
|
||||
pricingCurrency: 'USD' | 'EUR' | 'GBP';
|
||||
status: 'pending' | 'active' | 'cancelled';
|
||||
description?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Demo sponsorship request data for seeding pending requests
|
||||
*/
|
||||
export interface DemoSponsorshipRequestDTO {
|
||||
id: string;
|
||||
sponsorId: string;
|
||||
entityType: 'driver' | 'team' | 'race' | 'season';
|
||||
entityId: string;
|
||||
tier: 'main' | 'secondary';
|
||||
offeredAmount: number;
|
||||
currency: 'USD' | 'EUR' | 'GBP';
|
||||
message?: string;
|
||||
status: 'pending' | 'accepted' | 'rejected' | 'withdrawn';
|
||||
createdAt: Date;
|
||||
}
|
||||
|
||||
/**
|
||||
* Demo sponsorship pricing configuration for entities
|
||||
*/
|
||||
export interface DemoSponsorshipPricingDTO {
|
||||
entityType: 'driver' | 'team' | 'race' | 'season';
|
||||
entityId: string;
|
||||
mainSlotPrice: number;
|
||||
mainSlotBenefits: string[];
|
||||
secondarySlotPrice?: number;
|
||||
secondarySlotBenefits?: string[];
|
||||
secondaryMaxSlots?: number;
|
||||
acceptingApplications: boolean;
|
||||
customRequirements?: string;
|
||||
}
|
||||
|
||||
export type RacingSeedData = {
|
||||
drivers: Driver[];
|
||||
leagues: League[];
|
||||
@@ -40,6 +97,10 @@ export type RacingSeedData = {
|
||||
friendships: Friendship[];
|
||||
feedEvents: FeedItem[];
|
||||
teams: DemoTeamDTO[];
|
||||
sponsors: DemoSponsorDTO[];
|
||||
seasonSponsorships: DemoSeasonSponsorshipDTO[];
|
||||
sponsorshipRequests: DemoSponsorshipRequestDTO[];
|
||||
sponsorshipPricings: DemoSponsorshipPricingDTO[];
|
||||
};
|
||||
|
||||
const POINTS_TABLE: Record<number, number> = {
|
||||
@@ -519,6 +580,316 @@ function createFeedEvents(
|
||||
return sorted;
|
||||
}
|
||||
|
||||
/**
|
||||
* Demo sponsors data - realistic sim racing sponsors
|
||||
*/
|
||||
const DEMO_SPONSORS: DemoSponsorDTO[] = [
|
||||
{
|
||||
id: 'sponsor-fanatec',
|
||||
name: 'Fanatec',
|
||||
contactEmail: 'partnerships@fanatec.com',
|
||||
logoUrl: '/images/sponsors/fanatec.svg',
|
||||
websiteUrl: 'https://fanatec.com',
|
||||
tagline: 'The world\'s leading sim racing hardware',
|
||||
},
|
||||
{
|
||||
id: 'sponsor-simucube',
|
||||
name: 'Simucube',
|
||||
contactEmail: 'sponsors@simucube.com',
|
||||
logoUrl: '/images/sponsors/simucube.svg',
|
||||
websiteUrl: 'https://simucube.com',
|
||||
tagline: 'Professional Direct Drive Wheels',
|
||||
},
|
||||
{
|
||||
id: 'sponsor-heusinkveld',
|
||||
name: 'Heusinkveld',
|
||||
contactEmail: 'info@heusinkveld.com',
|
||||
logoUrl: '/images/sponsors/heusinkveld.svg',
|
||||
websiteUrl: 'https://heusinkveld.com',
|
||||
tagline: 'Sim Racing Pedals & Hardware',
|
||||
},
|
||||
{
|
||||
id: 'sponsor-trak-racer',
|
||||
name: 'Trak Racer',
|
||||
contactEmail: 'partnerships@trakracer.com',
|
||||
logoUrl: '/images/sponsors/trak-racer.svg',
|
||||
websiteUrl: 'https://trakracer.com',
|
||||
tagline: 'Premium Racing Simulators & Cockpits',
|
||||
},
|
||||
{
|
||||
id: 'sponsor-simlab',
|
||||
name: 'Sim-Lab',
|
||||
contactEmail: 'sponsor@sim-lab.eu',
|
||||
logoUrl: '/images/sponsors/simlab.svg',
|
||||
websiteUrl: 'https://sim-lab.eu',
|
||||
tagline: 'Aluminum Profile Sim Racing Rigs',
|
||||
},
|
||||
{
|
||||
id: 'sponsor-motionrig',
|
||||
name: 'MotionRig Pro',
|
||||
contactEmail: 'business@motionrigpro.com',
|
||||
logoUrl: '/images/sponsors/motionrig.svg',
|
||||
websiteUrl: 'https://motionrigpro.com',
|
||||
tagline: 'Feel every turn, every bump',
|
||||
},
|
||||
];
|
||||
|
||||
/**
|
||||
* Create season sponsorships linking sponsors to leagues
|
||||
*/
|
||||
function createSeasonSponsorships(
|
||||
leagues: League[],
|
||||
sponsors: DemoSponsorDTO[],
|
||||
): DemoSeasonSponsorshipDTO[] {
|
||||
const sponsorships: DemoSeasonSponsorshipDTO[] = [];
|
||||
|
||||
// GridPilot Sprint Series - sponsored by Fanatec (main) + Heusinkveld & Simucube (secondary)
|
||||
const sprintLeague = leagues.find(l => l.name === 'GridPilot Sprint Series');
|
||||
if (sprintLeague) {
|
||||
sponsorships.push({
|
||||
id: `sponsorship-${sprintLeague.id}-fanatec`,
|
||||
seasonId: `season-${sprintLeague.id}-demo`,
|
||||
sponsorId: 'sponsor-fanatec',
|
||||
tier: 'main',
|
||||
pricingAmount: 5000,
|
||||
pricingCurrency: 'USD',
|
||||
status: 'active',
|
||||
description: 'Main sponsor for the Sprint Series - premium wheel branding',
|
||||
});
|
||||
sponsorships.push({
|
||||
id: `sponsorship-${sprintLeague.id}-heusinkveld`,
|
||||
seasonId: `season-${sprintLeague.id}-demo`,
|
||||
sponsorId: 'sponsor-heusinkveld',
|
||||
tier: 'secondary',
|
||||
pricingAmount: 2000,
|
||||
pricingCurrency: 'USD',
|
||||
status: 'active',
|
||||
});
|
||||
sponsorships.push({
|
||||
id: `sponsorship-${sprintLeague.id}-simucube`,
|
||||
seasonId: `season-${sprintLeague.id}-demo`,
|
||||
sponsorId: 'sponsor-simucube',
|
||||
tier: 'secondary',
|
||||
pricingAmount: 2000,
|
||||
pricingCurrency: 'USD',
|
||||
status: 'active',
|
||||
});
|
||||
}
|
||||
|
||||
// GridPilot Endurance Cup - sponsored by Trak Racer (main) + Sim-Lab (secondary)
|
||||
const enduranceLeague = leagues.find(l => l.name === 'GridPilot Endurance Cup');
|
||||
if (enduranceLeague) {
|
||||
sponsorships.push({
|
||||
id: `sponsorship-${enduranceLeague.id}-trakracer`,
|
||||
seasonId: `season-${enduranceLeague.id}-demo`,
|
||||
sponsorId: 'sponsor-trak-racer',
|
||||
tier: 'main',
|
||||
pricingAmount: 7500,
|
||||
pricingCurrency: 'USD',
|
||||
status: 'active',
|
||||
description: 'Endurance series naming rights',
|
||||
});
|
||||
sponsorships.push({
|
||||
id: `sponsorship-${enduranceLeague.id}-simlab`,
|
||||
seasonId: `season-${enduranceLeague.id}-demo`,
|
||||
sponsorId: 'sponsor-simlab',
|
||||
tier: 'secondary',
|
||||
pricingAmount: 3000,
|
||||
pricingCurrency: 'USD',
|
||||
status: 'active',
|
||||
});
|
||||
}
|
||||
|
||||
// GridPilot Club Ladder - sponsored by MotionRig Pro (main)
|
||||
const clubLeague = leagues.find(l => l.name === 'GridPilot Club Ladder');
|
||||
if (clubLeague) {
|
||||
sponsorships.push({
|
||||
id: `sponsorship-${clubLeague.id}-motionrig`,
|
||||
seasonId: `season-${clubLeague.id}-demo`,
|
||||
sponsorId: 'sponsor-motionrig',
|
||||
tier: 'main',
|
||||
pricingAmount: 3500,
|
||||
pricingCurrency: 'USD',
|
||||
status: 'active',
|
||||
description: 'Club ladder motion platform showcase',
|
||||
});
|
||||
}
|
||||
|
||||
return sponsorships;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create sponsorship pricing configurations for demo entities
|
||||
*/
|
||||
function createSponsorshipPricings(
|
||||
leagues: League[],
|
||||
teams: DemoTeamDTO[],
|
||||
drivers: Driver[],
|
||||
races: Race[],
|
||||
): DemoSponsorshipPricingDTO[] {
|
||||
const pricings: DemoSponsorshipPricingDTO[] = [];
|
||||
|
||||
// League/Season pricing - all leagues can accept sponsorships
|
||||
leagues.forEach((league, index) => {
|
||||
const basePrice = 500 + (index * 100);
|
||||
pricings.push({
|
||||
entityType: 'season',
|
||||
entityId: `season-${league.id}-demo`,
|
||||
mainSlotPrice: basePrice * 10, // Main sponsor is more expensive
|
||||
mainSlotBenefits: ['Hood placement', 'League banner', 'Prominent logo', 'League page URL'],
|
||||
secondarySlotPrice: basePrice * 3,
|
||||
secondarySlotBenefits: ['Side logo placement', 'League page listing'],
|
||||
secondaryMaxSlots: 2,
|
||||
acceptingApplications: true,
|
||||
});
|
||||
});
|
||||
|
||||
// Team pricing - first 10 teams accept sponsorships
|
||||
teams.slice(0, 10).forEach((team, index) => {
|
||||
pricings.push({
|
||||
entityType: 'team',
|
||||
entityId: team.id,
|
||||
mainSlotPrice: 500 + (index * 50),
|
||||
mainSlotBenefits: ['Team name suffix', 'Car livery', 'All driver suits'],
|
||||
secondarySlotPrice: 250 + (index * 25),
|
||||
secondarySlotBenefits: ['Team page logo', 'Minor livery placement'],
|
||||
secondaryMaxSlots: 2,
|
||||
acceptingApplications: true,
|
||||
});
|
||||
});
|
||||
|
||||
// Driver pricing - first 20 drivers accept sponsorships
|
||||
drivers.slice(0, 20).forEach((driver, index) => {
|
||||
pricings.push({
|
||||
entityType: 'driver',
|
||||
entityId: driver.id,
|
||||
mainSlotPrice: 200 + (index * 20),
|
||||
mainSlotBenefits: ['Suit logo', 'Helmet branding', 'Social mentions'],
|
||||
acceptingApplications: index % 3 !== 0, // Some drivers not accepting
|
||||
});
|
||||
});
|
||||
|
||||
// Race pricing - upcoming races can have title sponsors
|
||||
const upcomingRaces = races.filter(r => r.status === 'scheduled').slice(0, 10);
|
||||
upcomingRaces.forEach((race, index) => {
|
||||
pricings.push({
|
||||
entityType: 'race',
|
||||
entityId: race.id,
|
||||
mainSlotPrice: 300 + (index * 30),
|
||||
mainSlotBenefits: ['Race title sponsor', 'Stream overlay', 'Results banner'],
|
||||
acceptingApplications: true,
|
||||
});
|
||||
});
|
||||
|
||||
return pricings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create demo sponsorship requests (some pending, some accepted/rejected)
|
||||
*/
|
||||
function createSponsorshipRequests(
|
||||
sponsors: DemoSponsorDTO[],
|
||||
leagues: League[],
|
||||
teams: DemoTeamDTO[],
|
||||
drivers: Driver[],
|
||||
races: Race[],
|
||||
): DemoSponsorshipRequestDTO[] {
|
||||
const requests: DemoSponsorshipRequestDTO[] = [];
|
||||
const now = new Date();
|
||||
|
||||
// Pending request: Simucube wants to sponsor a driver
|
||||
requests.push({
|
||||
id: 'req-simucube-driver-1',
|
||||
sponsorId: 'sponsor-simucube',
|
||||
entityType: 'driver',
|
||||
entityId: drivers[5].id,
|
||||
tier: 'main',
|
||||
offeredAmount: 25000, // $250.00 in cents
|
||||
currency: 'USD',
|
||||
message: 'We would love to sponsor your racing career! Simucube offers the best direct drive wheels in sim racing.',
|
||||
status: 'pending',
|
||||
createdAt: new Date(now.getTime() - 2 * 24 * 60 * 60 * 1000), // 2 days ago
|
||||
});
|
||||
|
||||
// Pending request: Heusinkveld wants to sponsor a team
|
||||
requests.push({
|
||||
id: 'req-heusinkveld-team-1',
|
||||
sponsorId: 'sponsor-heusinkveld',
|
||||
entityType: 'team',
|
||||
entityId: teams[2].id,
|
||||
tier: 'main',
|
||||
offeredAmount: 55000, // $550.00 in cents
|
||||
currency: 'USD',
|
||||
message: 'Heusinkveld pedals are known for their precision. We believe your team embodies the same values.',
|
||||
status: 'pending',
|
||||
createdAt: new Date(now.getTime() - 3 * 24 * 60 * 60 * 1000), // 3 days ago
|
||||
});
|
||||
|
||||
// Pending request: Trak Racer wants to sponsor a race
|
||||
const upcomingRace = races.find(r => r.status === 'scheduled');
|
||||
if (upcomingRace) {
|
||||
requests.push({
|
||||
id: 'req-trakracer-race-1',
|
||||
sponsorId: 'sponsor-trak-racer',
|
||||
entityType: 'race',
|
||||
entityId: upcomingRace.id,
|
||||
tier: 'main',
|
||||
offeredAmount: 35000, // $350.00 in cents
|
||||
currency: 'USD',
|
||||
message: 'We would like to be the title sponsor for this exciting race event!',
|
||||
status: 'pending',
|
||||
createdAt: new Date(now.getTime() - 1 * 24 * 60 * 60 * 1000), // 1 day ago
|
||||
});
|
||||
}
|
||||
|
||||
// Pending request: MotionRig Pro wants secondary spot on a league
|
||||
const clubLeague = leagues.find(l => l.name === 'Sprint Challenge League');
|
||||
if (clubLeague) {
|
||||
requests.push({
|
||||
id: 'req-motionrig-league-1',
|
||||
sponsorId: 'sponsor-motionrig',
|
||||
entityType: 'season',
|
||||
entityId: `season-${clubLeague.id}-demo`,
|
||||
tier: 'secondary',
|
||||
offeredAmount: 150000, // $1500.00 in cents
|
||||
currency: 'USD',
|
||||
message: 'MotionRig Pro would love to be a secondary sponsor. Our motion platforms are perfect for your competitive drivers.',
|
||||
status: 'pending',
|
||||
createdAt: new Date(now.getTime() - 5 * 24 * 60 * 60 * 1000), // 5 days ago
|
||||
});
|
||||
}
|
||||
|
||||
// Already accepted request (for history)
|
||||
requests.push({
|
||||
id: 'req-simlab-team-accepted',
|
||||
sponsorId: 'sponsor-simlab',
|
||||
entityType: 'team',
|
||||
entityId: teams[0].id,
|
||||
tier: 'secondary',
|
||||
offeredAmount: 30000,
|
||||
currency: 'USD',
|
||||
message: 'Sim-Lab rigs are the foundation of any competitive setup.',
|
||||
status: 'accepted',
|
||||
createdAt: new Date(now.getTime() - 30 * 24 * 60 * 60 * 1000), // 30 days ago
|
||||
});
|
||||
|
||||
// Already rejected request (for history)
|
||||
requests.push({
|
||||
id: 'req-motionrig-driver-rejected',
|
||||
sponsorId: 'sponsor-motionrig',
|
||||
entityType: 'driver',
|
||||
entityId: drivers[10].id,
|
||||
tier: 'main',
|
||||
offeredAmount: 15000,
|
||||
currency: 'USD',
|
||||
message: 'Would you like to represent MotionRig Pro?',
|
||||
status: 'rejected',
|
||||
createdAt: new Date(now.getTime() - 20 * 24 * 60 * 60 * 1000), // 20 days ago
|
||||
});
|
||||
|
||||
return requests;
|
||||
}
|
||||
|
||||
export function createStaticRacingSeed(seed: number): RacingSeedData {
|
||||
faker.seed(seed);
|
||||
|
||||
@@ -531,6 +902,10 @@ export function createStaticRacingSeed(seed: number): RacingSeedData {
|
||||
const friendships = createFriendships(drivers);
|
||||
const feedEvents = createFeedEvents(drivers, leagues, races, friendships);
|
||||
const standings = createStandings(leagues, results);
|
||||
const sponsors = DEMO_SPONSORS;
|
||||
const seasonSponsorships = createSeasonSponsorships(leagues, sponsors);
|
||||
const sponsorshipPricings = createSponsorshipPricings(leagues, teams, drivers, races);
|
||||
const sponsorshipRequests = createSponsorshipRequests(sponsors, leagues, teams, drivers, races);
|
||||
|
||||
return {
|
||||
drivers,
|
||||
@@ -542,6 +917,10 @@ export function createStaticRacingSeed(seed: number): RacingSeedData {
|
||||
friendships,
|
||||
feedEvents,
|
||||
teams,
|
||||
sponsors,
|
||||
seasonSponsorships,
|
||||
sponsorshipRequests,
|
||||
sponsorshipPricings,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -568,6 +947,10 @@ export const teams = staticSeed.teams;
|
||||
export const memberships = staticSeed.memberships;
|
||||
export const friendships = staticSeed.friendships;
|
||||
export const feedEvents = staticSeed.feedEvents;
|
||||
export const sponsors = staticSeed.sponsors;
|
||||
export const seasonSponsorships = staticSeed.seasonSponsorships;
|
||||
export const sponsorshipRequests = staticSeed.sponsorshipRequests;
|
||||
export const sponsorshipPricings = staticSeed.sponsorshipPricings;
|
||||
|
||||
/**
|
||||
* Derived friend DTOs for UI consumption.
|
||||
|
||||
Reference in New Issue
Block a user