All files / src/components/ui ratings-row.tsx

0% Statements 0/55
0% Branches 0/1
0% Functions 0/1
0% Lines 0/55

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76                                                                                                                                                       
import { Star } from "lucide-react";
import type { OmdbData, WhatsonData } from "@/lib/types";
 
interface RatingsRowProps {
	omdbData?: OmdbData | null;
	whatsonData?: WhatsonData | null;
}
 
const formatVotes = (n: number): string => {
	if (n >= 1_000_000) return `${(n / 1_000_000).toFixed(1)}M`;
	if (n >= 1_000) return `${(n / 1_000).toFixed(0)}K`;
	return n.toString();
};
 
export const RatingsRow = ({ omdbData, whatsonData }: RatingsRowProps) => {
	// Priority: use Whatson data when available, fall back to OMDB
	const rawOmdbRating = omdbData?.imdbRating;
	const omdbRatingClean = rawOmdbRating && rawOmdbRating !== "N/A" ? rawOmdbRating : null;
	const imdbRating =
		whatsonData?.imdbRating != null ? whatsonData.imdbRating.toFixed(1) : omdbRatingClean;
	const imdbVotes = whatsonData?.imdbVotes ?? null;
	const rtCritic = whatsonData?.rtCriticsRating ?? null;
	// When Whatson has no RT score, fall back to OMDB's rottenTomatoes string
	const rtCriticFallback =
		rtCritic === null && omdbData?.rottenTomatoes && omdbData.rottenTomatoes !== "N/A"
			? omdbData.rottenTomatoes
			: null;
	const rtAudience = whatsonData?.rtAudienceRating ?? null;
	const rtAudienceCount = whatsonData?.rtAudienceCount ?? null;
	const rtCriticCount = whatsonData?.rtCriticsCount ?? null;
 
	const hasAny = imdbRating || rtCritic !== null || rtCriticFallback || rtAudience !== null;
	if (!hasAny) return null;
 
	return (
		<div className="flex items-center gap-1.5 flex-wrap">
			{imdbRating && (
				<span className="flex items-center gap-1 text-[11px] font-semibold bg-yellow-500/15 text-yellow-600 dark:text-yellow-400 px-2 py-0.5 rounded-full">
					<Star className="h-2.5 w-2.5" />
					{imdbRating}
					{imdbVotes && (
						<span className="font-normal opacity-70">ยท {formatVotes(imdbVotes)}</span>
					)}
				</span>
			)}
			{rtCritic !== null && (
				<span className="text-[11px] font-semibold bg-red-500/15 text-red-500 px-2 py-0.5 rounded-full">
					๐Ÿ… {rtCritic}%
					{rtCriticCount && (
						<span className="font-normal opacity-70">
							{" "}
							ยท {formatVotes(rtCriticCount)}
						</span>
					)}
				</span>
			)}
			{rtCriticFallback && (
				<span className="text-[11px] font-semibold bg-red-500/15 text-red-500 px-2 py-0.5 rounded-full">
					๐Ÿ… {rtCriticFallback}
				</span>
			)}
			{rtAudience !== null && (
				<span className="text-[11px] font-semibold bg-orange-500/15 text-orange-500 px-2 py-0.5 rounded-full">
					๐Ÿฟ {rtAudience}%
					{rtAudienceCount && (
						<span className="font-normal opacity-70">
							{" "}
							ยท {formatVotes(rtAudienceCount)}
						</span>
					)}
				</span>
			)}
		</div>
	);
};