website refactor
This commit is contained in:
@@ -1,138 +0,0 @@
|
||||
import type { SponsorDashboardDTO } from '../types/generated/SponsorDashboardDTO';
|
||||
import { SponsorshipViewModel } from './SponsorshipViewModel';
|
||||
import { ActivityItemViewModel } from './ActivityItemViewModel';
|
||||
import { RenewalAlertViewModel } from './RenewalAlertViewModel';
|
||||
|
||||
/**
|
||||
* Sponsor Dashboard View Model
|
||||
*
|
||||
* View model for sponsor dashboard data with UI-specific transformations.
|
||||
*/
|
||||
export class SponsorDashboardViewModel {
|
||||
sponsorId: string;
|
||||
sponsorName: string;
|
||||
metrics: any;
|
||||
sponsorships: {
|
||||
leagues: SponsorshipViewModel[];
|
||||
teams: SponsorshipViewModel[];
|
||||
drivers: SponsorshipViewModel[];
|
||||
races: SponsorshipViewModel[];
|
||||
platform: SponsorshipViewModel[];
|
||||
};
|
||||
recentActivity: ActivityItemViewModel[];
|
||||
upcomingRenewals: RenewalAlertViewModel[];
|
||||
|
||||
constructor(dto: SponsorDashboardDTO) {
|
||||
this.sponsorId = dto.sponsorId;
|
||||
this.sponsorName = dto.sponsorName;
|
||||
this.metrics = dto.metrics;
|
||||
|
||||
// Cast sponsorships to proper type
|
||||
const sponsorships = dto.sponsorships as any;
|
||||
this.sponsorships = {
|
||||
leagues: (sponsorships?.leagues || []).map((s: any) => new SponsorshipViewModel(s)),
|
||||
teams: (sponsorships?.teams || []).map((s: any) => new SponsorshipViewModel(s)),
|
||||
drivers: (sponsorships?.drivers || []).map((s: any) => new SponsorshipViewModel(s)),
|
||||
races: (sponsorships?.races || []).map((s: any) => new SponsorshipViewModel(s)),
|
||||
platform: (sponsorships?.platform || []).map((s: any) => new SponsorshipViewModel(s)),
|
||||
};
|
||||
this.recentActivity = (dto.recentActivity || []).map((a: any) => new ActivityItemViewModel(a));
|
||||
this.upcomingRenewals = (dto.upcomingRenewals || []).map((r: any) => new RenewalAlertViewModel(r));
|
||||
}
|
||||
|
||||
get totalSponsorships(): number {
|
||||
return this.sponsorships.leagues.length +
|
||||
this.sponsorships.teams.length +
|
||||
this.sponsorships.drivers.length +
|
||||
this.sponsorships.races.length +
|
||||
this.sponsorships.platform.length;
|
||||
}
|
||||
|
||||
get activeSponsorships(): number {
|
||||
const all = [
|
||||
...this.sponsorships.leagues,
|
||||
...this.sponsorships.teams,
|
||||
...this.sponsorships.drivers,
|
||||
...this.sponsorships.races,
|
||||
...this.sponsorships.platform,
|
||||
];
|
||||
return all.filter(s => s.status === 'active').length;
|
||||
}
|
||||
|
||||
get totalInvestment(): number {
|
||||
const all = [
|
||||
...this.sponsorships.leagues,
|
||||
...this.sponsorships.teams,
|
||||
...this.sponsorships.drivers,
|
||||
...this.sponsorships.races,
|
||||
...this.sponsorships.platform,
|
||||
];
|
||||
return all.filter(s => s.status === 'active').reduce((sum, s) => sum + s.price, 0);
|
||||
}
|
||||
|
||||
get totalImpressions(): number {
|
||||
const all = [
|
||||
...this.sponsorships.leagues,
|
||||
...this.sponsorships.teams,
|
||||
...this.sponsorships.drivers,
|
||||
...this.sponsorships.races,
|
||||
...this.sponsorships.platform,
|
||||
];
|
||||
return all.reduce((sum, s) => sum + s.impressions, 0);
|
||||
}
|
||||
|
||||
/** UI-specific: Formatted total investment */
|
||||
get formattedTotalInvestment(): string {
|
||||
return `$${this.totalInvestment.toLocaleString()}`;
|
||||
}
|
||||
|
||||
/** UI-specific: Active percentage */
|
||||
get activePercentage(): number {
|
||||
if (this.totalSponsorships === 0) return 0;
|
||||
return Math.round((this.activeSponsorships / this.totalSponsorships) * 100);
|
||||
}
|
||||
|
||||
/** UI-specific: Has sponsorships */
|
||||
get hasSponsorships(): boolean {
|
||||
return this.totalSponsorships > 0;
|
||||
}
|
||||
|
||||
/** UI-specific: Status text */
|
||||
get statusText(): string {
|
||||
if (this.activeSponsorships === 0) return 'No active sponsorships';
|
||||
if (this.activeSponsorships === this.totalSponsorships) return 'All sponsorships active';
|
||||
return `${this.activeSponsorships} of ${this.totalSponsorships} active`;
|
||||
}
|
||||
|
||||
/** UI-specific: Cost per 1K views */
|
||||
get costPerThousandViews(): string {
|
||||
if (this.totalImpressions === 0) return '$0.00';
|
||||
return `$${(this.totalInvestment / this.totalImpressions * 1000).toFixed(2)}`;
|
||||
}
|
||||
|
||||
/** UI-specific: Category data for charts */
|
||||
get categoryData() {
|
||||
return {
|
||||
leagues: {
|
||||
count: this.sponsorships.leagues.length,
|
||||
impressions: this.sponsorships.leagues.reduce((sum, l) => sum + l.impressions, 0),
|
||||
},
|
||||
teams: {
|
||||
count: this.sponsorships.teams.length,
|
||||
impressions: this.sponsorships.teams.reduce((sum, t) => sum + t.impressions, 0),
|
||||
},
|
||||
drivers: {
|
||||
count: this.sponsorships.drivers.length,
|
||||
impressions: this.sponsorships.drivers.reduce((sum, d) => sum + d.impressions, 0),
|
||||
},
|
||||
races: {
|
||||
count: this.sponsorships.races.length,
|
||||
impressions: this.sponsorships.races.reduce((sum, r) => sum + r.impressions, 0),
|
||||
},
|
||||
platform: {
|
||||
count: this.sponsorships.platform.length,
|
||||
impressions: this.sponsorships.platform.reduce((sum, p) => sum + p.impressions, 0),
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user