/** * Profile Display Objects * * Deterministic formatting for profile data. * NO Intl.*, NO Date.toLocale*, NO dynamic formatting. */ // ============================================================================ // COUNTRY FLAG DISPLAY // ============================================================================ export interface CountryFlagDisplayData { flag: string; label: string; } export const countryFlagDisplay: Record = { // Common country codes - add as needed US: { flag: '🇺🇸', label: 'United States' }, GB: { flag: '🇬🇧', label: 'United Kingdom' }, DE: { flag: '🇩🇪', label: 'Germany' }, FR: { flag: '🇫🇷', label: 'France' }, IT: { flag: '🇮🇹', label: 'Italy' }, ES: { flag: '🇪🇸', label: 'Spain' }, JP: { flag: '🇯🇵', label: 'Japan' }, AU: { flag: '🇦🇺', label: 'Australia' }, CA: { flag: '🇨🇦', label: 'Canada' }, BR: { flag: '🇧🇷', label: 'Brazil' }, // Fallback for unknown codes DEFAULT: { flag: '🏁', label: 'Unknown' }, } as const; export function getCountryFlagDisplay(countryCode: string): CountryFlagDisplayData { const code = countryCode.toUpperCase(); return countryFlagDisplay[code] || countryFlagDisplay.DEFAULT; } // ============================================================================ // ACHIEVEMENT RARITY DISPLAY // ============================================================================ export interface AchievementRarityDisplayData { text: string; badgeClasses: string; borderClasses: string; } export const achievementRarityDisplay: Record = { common: { text: 'Common', badgeClasses: 'bg-gray-400/10 text-gray-400', borderClasses: 'border-gray-400/30', }, rare: { text: 'Rare', badgeClasses: 'bg-primary-blue/10 text-primary-blue', borderClasses: 'border-primary-blue/30', }, epic: { text: 'Epic', badgeClasses: 'bg-purple-400/10 text-purple-400', borderClasses: 'border-purple-400/30', }, legendary: { text: 'Legendary', badgeClasses: 'bg-yellow-400/10 text-yellow-400', borderClasses: 'border-yellow-400/30', }, } as const; export function getAchievementRarityDisplay(rarity: string): AchievementRarityDisplayData { return achievementRarityDisplay[rarity] || achievementRarityDisplay.common; } // ============================================================================ // ACHIEVEMENT ICON DISPLAY // ============================================================================ export type AchievementIconType = 'trophy' | 'medal' | 'star' | 'crown' | 'target' | 'zap'; export interface AchievementIconDisplayData { name: string; // Icon component will be resolved in UI layer } export const achievementIconDisplay: Record = { trophy: { name: 'Trophy' }, medal: { name: 'Medal' }, star: { name: 'Star' }, crown: { name: 'Crown' }, target: { name: 'Target' }, zap: { name: 'Zap' }, } as const; export function getAchievementIconDisplay(icon: string): AchievementIconDisplayData { return achievementIconDisplay[icon as AchievementIconType] || achievementIconDisplay.trophy; } // ============================================================================ // SOCIAL PLATFORM DISPLAY // ============================================================================ export interface SocialPlatformDisplayData { name: string; hoverClasses: string; } export const socialPlatformDisplay: Record = { twitter: { name: 'Twitter', hoverClasses: 'hover:text-sky-400 hover:bg-sky-400/10', }, youtube: { name: 'YouTube', hoverClasses: 'hover:text-red-500 hover:bg-red-500/10', }, twitch: { name: 'Twitch', hoverClasses: 'hover:text-purple-400 hover:bg-purple-400/10', }, discord: { name: 'Discord', hoverClasses: 'hover:text-indigo-400 hover:bg-indigo-400/10', }, } as const; export function getSocialPlatformDisplay(platform: string): SocialPlatformDisplayData { return socialPlatformDisplay[platform] || socialPlatformDisplay.discord; } // ============================================================================ // DATE FORMATTING (DETERMINISTIC) // ============================================================================ /** * Format date string to "Month Year" format * Input: ISO date string (e.g., "2024-01-15T10:30:00Z") * Output: "Jan 2024" */ export function formatMonthYear(dateString: string): string { const date = new Date(dateString); const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']; const month = months[date.getUTCMonth()]; const year = date.getUTCFullYear(); return `${month} ${year}`; } /** * Format date string to "Month Day, Year" format * Input: ISO date string * Output: "Jan 15, 2024" */ export function formatMonthDayYear(dateString: string): string { const date = new Date(dateString); const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']; const month = months[date.getUTCMonth()]; const day = date.getUTCDate(); const year = date.getUTCFullYear(); return `${month} ${day}, ${year}`; } // ============================================================================ // STATISTICS FORMATTING // ============================================================================ export interface StatDisplayData { value: string; label: string; } /** * Format percentage with 1 decimal place * Input: 0.1234 * Output: "12.3%" */ export function formatPercentage(value: number | null): string { if (value === null || value === undefined) return '0.0%'; return `${(value * 100).toFixed(1)}%`; } /** * Format finish position * Input: 1 * Output: "P1" */ export function formatFinishPosition(position: number | null): string { if (position === null || position === undefined) return 'P-'; return `P${position}`; } /** * Format average finish with 1 decimal place * Input: 3.456 * Output: "P3.5" */ export function formatAvgFinish(avg: number | null): string { if (avg === null || avg === undefined) return 'P-'; return `P${avg.toFixed(1)}`; } /** * Format rating (whole number) * Input: 1234.56 * Output: "1235" */ export function formatRating(rating: number | null): string { if (rating === null || rating === undefined) return '0'; return Math.round(rating).toString(); } /** * Format consistency percentage * Input: 87.5 * Output: "88%" */ export function formatConsistency(consistency: number | null): string { if (consistency === null || consistency === undefined) return '0%'; return `${Math.round(consistency)}%`; } /** * Format percentile * Input: 15.5 * Output: "Top 16%" */ export function formatPercentile(percentile: number | null): string { if (percentile === null || percentile === undefined) return 'Top -%'; return `Top ${Math.round(percentile)}%`; } // ============================================================================ // TEAM ROLE DISPLAY // ============================================================================ export interface TeamRoleDisplayData { text: string; badgeClasses: string; } export const teamRoleDisplay: Record = { owner: { text: 'Owner', badgeClasses: 'bg-yellow-500/10 text-yellow-500 border-yellow-500/30', }, admin: { text: 'Admin', badgeClasses: 'bg-purple-500/10 text-purple-400 border-purple-500/30', }, steward: { text: 'Steward', badgeClasses: 'bg-blue-500/10 text-blue-400 border-blue-500/30', }, member: { text: 'Member', badgeClasses: 'bg-primary-blue/10 text-primary-blue border-primary-blue/30', }, } as const; export function getTeamRoleDisplay(role: string): TeamRoleDisplayData { return teamRoleDisplay[role] || teamRoleDisplay.member; }