"use client"; import Link from "next/link"; import type { Movie } from "@/types/movie"; import { TMDB_GENRE_MAP, getTMDBImageUrl } from "@/types/tmdb"; /** * — in-place result card for the home-page cross-list * roll. Renders IN PLACE per PROJECT_SCOPE.md:222-223; the only navigation * is the user-initiated "Open list" link. * * Uses the DB `Movie` row shape (not the TMDB landing teaser shape). Titles, * genres, and group names are rendered as React text children only — no * `dangerouslySetInnerHTML`, no unescaped `title=` attributes. */ interface HomeRollTeaserCardProps { movie: Movie; groupId: string; groupName: string | null; onReroll: () => void; } function genreLabelsFromIds(ids: string[]): string[] { const labels: string[] = []; for (const raw of ids) { const id = Number.parseInt(raw, 10); if (Number.isNaN(id)) continue; const name = TMDB_GENRE_MAP[id]; if (name) labels.push(name); } return labels; } export function HomeRollTeaserCard({ movie, groupId, groupName, onReroll, }: HomeRollTeaserCardProps) { const posterUrl = getTMDBImageUrl(movie.poster_path, "panel"); const genreLabels = genreLabelsFromIds(movie.genres ?? []); return (
{posterUrl ? ( // eslint-disable-next-line @next/next/no-img-element {movie.title} ) : (
No poster
)}

{movie.title}

{movie.year}

{genreLabels.length > 0 && (
{genreLabels.map((label) => ( {label} ))}
)}

from {groupName ?? "a list"}

Open list
); }