import { ProviderInfo, CalendarData, ModelData, OrgCandidate, CandidateSummary, } from "../types/heatmap"; import { generateCalendarData } from "./calendar"; import { fetchAllProvidersData, fetchAllAuthorsData } from "./authors"; import { assignColor } from "../constants/colors"; import { LEADERBOARD_SIZE } from "../constants/organizations"; export interface RankingBadge { className: string; icon: string | null; } export const getRankingBadge = (rank: number): RankingBadge => { if (rank === 1) { return { className: "absolute -top-4 -left-4 w-12 h-12 bg-gradient-to-br from-yellow-400 via-yellow-500 to-yellow-600 text-white rounded-full flex items-center justify-center text-lg font-bold shadow-2xl border-4 border-yellow-300", icon: "👑", }; } else if (rank === 2) { return { className: "absolute -top-4 -left-4 w-10 h-10 bg-gradient-to-br from-gray-300 via-gray-400 to-gray-500 text-white rounded-full flex items-center justify-center text-base font-bold shadow-xl border-3 border-gray-200", icon: "🥈", }; } else if (rank === 3) { return { className: "absolute -top-4 -left-4 w-10 h-10 bg-gradient-to-br from-amber-600 via-amber-700 to-amber-800 text-white rounded-full flex items-center justify-center text-base font-bold shadow-xl border-3 border-amber-400", icon: "🥉", }; } else { return { className: "absolute -top-3 -left-3 w-8 h-8 bg-gradient-to-br from-blue-500 to-blue-600 text-white rounded-full flex items-center justify-center text-sm font-bold shadow-lg", icon: null, }; } }; export const extractUniqueAuthors = (providers: ProviderInfo[]): string[] => { const allAuthors = providers.flatMap(({ authors }) => authors); return Array.from(new Set(allAuthors)); }; export const sortProvidersByActivity = ( providers: ProviderInfo[], calendarData: CalendarData ): ProviderInfo[] => { return [...providers].sort((a, b) => { const aCount = (calendarData[a.authors[0]] || []).reduce( (sum, day) => sum + day.count, 0 ); const bCount = (calendarData[b.authors[0]] || []).reduce( (sum, day) => sum + day.count, 0 ); return bCount - aCount; }); }; const candidatesToProviders = (candidates: OrgCandidate[]): ProviderInfo[] => candidates.map((c) => ({ color: c.color || "", authors: c.authors, })); export const getProviders = async (candidates: OrgCandidate[]) => { const allProviders = candidatesToProviders(candidates); const uniqueAuthors = extractUniqueAuthors(allProviders); const [authorModelsData, providersWithMetadata] = await Promise.all([ fetchAllAuthorsData(uniqueAuthors), fetchAllProvidersData(allProviders), ]); const calendarData = generateCalendarData( authorModelsData, providersWithMetadata ); const sorted = sortProvidersByActivity(providersWithMetadata, calendarData); const topN = sorted.slice(0, LEADERBOARD_SIZE); const coloredProviders = topN.map((provider, index) => ({ ...provider, color: provider.color || assignColor(index), })); const topKeys = new Set(coloredProviders.map((p) => p.authors[0])); const filteredCalendar: CalendarData = {}; for (const key of Object.keys(calendarData)) { if (topKeys.has(key)) { filteredCalendar[key] = calendarData[key]; } } const lastProvider = coloredProviders[coloredProviders.length - 1]; const lastKey = lastProvider?.authors[0]; const minActivityCount = lastKey ? (filteredCalendar[lastKey] || []).reduce((s, d) => s + d.count, 0) : 0; const allCandidates: CandidateSummary[] = sorted.map((p) => ({ author: p.authors[0], fullName: p.fullName || p.authors[0], avatarUrl: p.avatarUrl || null, })); return { calendarData: filteredCalendar, providers: coloredProviders, allCandidates, minActivityCount, }; };