From de69b989618ff746fadbad0ffaa3fd79aa10a240 Mon Sep 17 00:00:00 2001 From: KhooLy <73142442+KhooLy@users.noreply.github.com> Date: Wed, 29 Jul 2026 03:33:27 +0300 Subject: [PATCH] feat: color Metacritic badges by score, matching Metacritic's own convention Critic score (0-100): green >=61, yellow 40-60, red <40. User score (0-10): green >=7.5, yellow >=5.0, red below that. --- src/components/detail/RatingBadge.tsx | 5 +++-- src/components/detail/ratingSources.ts | 21 +++++++++++++++++++-- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/src/components/detail/RatingBadge.tsx b/src/components/detail/RatingBadge.tsx index 87f74c2..242f772 100644 --- a/src/components/detail/RatingBadge.tsx +++ b/src/components/detail/RatingBadge.tsx @@ -9,18 +9,19 @@ interface RatingBadgeProps { export function RatingBadge({ source, value }: RatingBadgeProps) { const info = RATING_SOURCES[source]; if (!info) return null; + const maskColor = info.colorForValue ? info.colorForValue(value) : info.maskColor; return ( {info.lucideIcon === 'popcorn' ? ( - ) : info.maskColor ? ( + ) : maskColor ? ( string; maskColor?: string; + colorForValue?: (value: number) => string; lucideIcon?: 'popcorn'; iconColor?: string; } @@ -11,6 +12,22 @@ const percent = (value: number) => `${Math.round(value)}%`; const outOfTen = (value: number) => value.toFixed(1); const bareScore = (value: number) => `${Math.round(value)}`; +const METACRITIC_GREEN = '#6C3'; +const METACRITIC_YELLOW = '#FC3'; +const METACRITIC_RED = '#F33'; + +const metacriticCriticColor = (value: number) => { + if (value >= 61) return METACRITIC_GREEN; + if (value >= 40) return METACRITIC_YELLOW; + return METACRITIC_RED; +}; + +const metacriticUserColor = (value: number) => { + if (value >= 7.5) return METACRITIC_GREEN; + if (value >= 5.0) return METACRITIC_YELLOW; + return METACRITIC_RED; +}; + export const RATING_SOURCES: Record = { imdb: { icon: '/imdb.svg', label: 'IMDb', format: outOfTen }, tmdb: { icon: '/tmdb.svg', label: 'TMDB', format: percent }, @@ -18,8 +35,8 @@ export const RATING_SOURCES: Record = { letterboxd: { icon: '/letterboxd.svg', label: 'Letterboxd', format: outOfTen }, tomatoes: { icon: '/rottentomatoes.svg', label: 'Rotten Tomatoes (Critics)', format: percent, maskColor: '#FA320A' }, popcorn: { label: 'Rotten Tomatoes (Audience)', format: percent, lucideIcon: 'popcorn', iconColor: '#FA320A' }, - metacritic: { icon: '/metacritic.svg', label: 'Metacritic', format: bareScore, maskColor: '#66CC33' }, - metacriticuser: { icon: '/metacritic.svg', label: 'Metacritic Users', format: outOfTen, maskColor: '#FFCC33' }, + metacritic: { icon: '/metacritic.svg', label: 'Metacritic', format: bareScore, maskColor: METACRITIC_GREEN, colorForValue: metacriticCriticColor }, + metacriticuser: { icon: '/metacritic.svg', label: 'Metacritic Users', format: outOfTen, maskColor: METACRITIC_GREEN, colorForValue: metacriticUserColor }, myanimelist: { icon: '/mal.svg', label: 'MyAnimeList', format: outOfTen }, };