"use client"; import Image from "next/image"; import { Popover, PopoverContent, PopoverTrigger, } from "@/components/ui/popover"; import { Tooltip, TooltipContent, TooltipTrigger, } from "@/components/ui/tooltip"; import type { AvailabilityOffer } from "@/lib/types/title"; const MAX_VISIBLE = 4; const offerLabels: Record = { flatrate: "Stream", rent: "Rent", buy: "Buy", free: "Free", ads: "With Ads", }; function ProviderBadge({ name, logoPath, watchUrl, }: { name: string; logoPath: string | null; watchUrl: string | null; }) { return ( ), } : {})} className={`flex h-10 w-10 items-center justify-center overflow-hidden rounded-lg border border-border/30 bg-card motion-safe:transition-transform motion-safe:hover:scale-105${watchUrl ? "" : " cursor-default"}`} > {logoPath ? ( {name} ) : ( {name.slice(0, 2)} )} {watchUrl ? `Watch on ${name}` : name} ); } function OverflowProviderIcon({ offer }: { offer: AvailabilityOffer }) { return (
{offer.logoPath ? ( {offer.providerName} ) : ( {offer.providerName.slice(0, 2)} )}
); } function OverflowBadge({ offers }: { offers: AvailabilityOffer[] }) { return ( +{offers.length} {offers.map((offer) => offer.watchUrl ? ( {offer.providerName} ) : (
{offer.providerName}
), )}
); } export function TitleAvailability({ availability, }: { availability: AvailabilityOffer[]; }) { const availByType: Record = {}; for (const offer of availability) { if (!availByType[offer.offerType]) availByType[offer.offerType] = []; availByType[offer.offerType].push(offer); } if (Object.keys(availByType).length === 0) return null; return (

Where to Watch

{Object.entries(availByType).map(([type, offers]) => { const visible = offers.slice(0, MAX_VISIBLE); const overflow = offers.slice(MAX_VISIBLE); return (
{offerLabels[type] ?? type}
{visible.map((offer) => ( ))} {overflow.length > 0 && }
); })}
); }