From 70a2a9f28d946c2edba64db84c4af13c1f8c1bde Mon Sep 17 00:00:00 2001 From: Jake Jarvis Date: Thu, 5 Mar 2026 20:24:17 -0500 Subject: [PATCH] Fix missing userStatus on title cards across dashboard, recommendations, and filmography Co-Authored-By: Claude Opus 4.6 --- .../dashboard/_components/library-section.tsx | 1 + .../dashboard/_components/title-grid.tsx | 2 ++ .../[id]/_components/filmography-grid.tsx | 7 ++++- app/(pages)/people/[id]/page.tsx | 10 ++++++- .../[id]/_components/recommendations-grid.tsx | 3 ++ .../_components/title-recommendations.tsx | 17 ++++++++++- lib/services/discovery.ts | 1 + lib/services/tracking.ts | 30 +++++++++++++++++++ 8 files changed, 68 insertions(+), 3 deletions(-) diff --git a/app/(pages)/dashboard/_components/library-section.tsx b/app/(pages)/dashboard/_components/library-section.tsx index f8f4c31..7d70a56 100644 --- a/app/(pages)/dashboard/_components/library-section.tsx +++ b/app/(pages)/dashboard/_components/library-section.tsx @@ -16,6 +16,7 @@ export async function LibrarySection({ userId }: { userId: string }) { posterPath: tmdbImageUrl(t.posterPath, "w500"), releaseDate: t.releaseDate ?? t.firstAirDate, voteAverage: t.voteAverage, + userStatus: t.userStatus as "watchlist" | "in_progress" | "completed", })); return ( diff --git a/app/(pages)/dashboard/_components/title-grid.tsx b/app/(pages)/dashboard/_components/title-grid.tsx index 9f74f3e..1637d28 100644 --- a/app/(pages)/dashboard/_components/title-grid.tsx +++ b/app/(pages)/dashboard/_components/title-grid.tsx @@ -10,6 +10,7 @@ interface TitleGridItem { posterPath: string | null; releaseDate?: string | null; voteAverage?: number | null; + userStatus?: "watchlist" | "in_progress" | "completed" | null; } export function TitleGrid({ items }: { items: TitleGridItem[] }) { @@ -29,6 +30,7 @@ export function TitleGrid({ items }: { items: TitleGridItem[] }) { posterPath={t.posterPath} releaseDate={t.releaseDate} voteAverage={t.voteAverage} + userStatus={t.userStatus} /> ))} diff --git a/app/(pages)/people/[id]/_components/filmography-grid.tsx b/app/(pages)/people/[id]/_components/filmography-grid.tsx index 2806565..8086026 100644 --- a/app/(pages)/people/[id]/_components/filmography-grid.tsx +++ b/app/(pages)/people/[id]/_components/filmography-grid.tsx @@ -18,9 +18,13 @@ type Sort = "newest" | "rating"; interface FilmographyGridProps { credits: PersonCredit[]; + userStatuses?: Record; } -export function FilmographyGrid({ credits }: FilmographyGridProps) { +export function FilmographyGrid({ + credits, + userStatuses, +}: FilmographyGridProps) { const [filter, setFilter] = useState("all"); const [sort, setSort] = useState("newest"); @@ -128,6 +132,7 @@ export function FilmographyGrid({ credits }: FilmographyGridProps) { posterPath={credit.posterPath} releaseDate={credit.releaseDate ?? credit.firstAirDate} voteAverage={credit.voteAverage} + userStatus={userStatuses?.[credit.titleId]} /> ))} diff --git a/app/(pages)/people/[id]/page.tsx b/app/(pages)/people/[id]/page.tsx index 48274c3..5f9c00d 100644 --- a/app/(pages)/people/[id]/page.tsx +++ b/app/(pages)/people/[id]/page.tsx @@ -9,6 +9,7 @@ import { getOrFetchPerson, getOrFetchPersonByTmdbId, } from "@/lib/services/person"; +import { getUserStatusesByTitleIds } from "@/lib/services/tracking"; import { FilmographyGrid } from "./_components/filmography-grid"; import { PersonHero } from "./_components/person-hero"; @@ -47,11 +48,18 @@ export default async function PersonDetailPage({ if (!person) notFound(); const filmography = getLocalFilmography(person.id); + const session = await getSession(); + const userStatuses = session + ? getUserStatusesByTitleIds( + session.user.id, + filmography.map((c) => c.titleId), + ) + : {}; return (
- +
); } diff --git a/app/(pages)/titles/[id]/_components/recommendations-grid.tsx b/app/(pages)/titles/[id]/_components/recommendations-grid.tsx index aaa8f46..17bceef 100644 --- a/app/(pages)/titles/[id]/_components/recommendations-grid.tsx +++ b/app/(pages)/titles/[id]/_components/recommendations-grid.tsx @@ -6,8 +6,10 @@ import type { RecommendedTitle } from "@/lib/types/title"; export function RecommendationsGrid({ recommendations, + userStatuses, }: { recommendations: RecommendedTitle[]; + userStatuses?: Record; }) { return (
@@ -30,6 +32,7 @@ export function RecommendationsGrid({ posterPath={rec.posterPath} releaseDate={rec.releaseDate ?? rec.firstAirDate} voteAverage={rec.voteAverage} + userStatus={userStatuses?.[rec.id]} />
))} diff --git a/app/(pages)/titles/[id]/_components/title-recommendations.tsx b/app/(pages)/titles/[id]/_components/title-recommendations.tsx index 95358fc..a232929 100644 --- a/app/(pages)/titles/[id]/_components/title-recommendations.tsx +++ b/app/(pages)/titles/[id]/_components/title-recommendations.tsx @@ -1,4 +1,6 @@ +import { getSession } from "@/lib/auth/session"; import { getRecommendationsForTitle } from "@/lib/services/discovery"; +import { getUserStatusesByTitleIds } from "@/lib/services/tracking"; import type { RecommendedTitle } from "@/lib/types/title"; import { RecommendationsGrid } from "./recommendations-grid"; @@ -17,5 +19,18 @@ export async function TitleRecommendations({ titleId }: { titleId: string }) { voteAverage: r.voteAverage, })); - return ; + const session = await getSession(); + const userStatuses = session + ? getUserStatusesByTitleIds( + session.user.id, + recommendations.map((r) => r.id), + ) + : {}; + + return ( + + ); } diff --git a/lib/services/discovery.ts b/lib/services/discovery.ts index 0b05e77..46f395a 100644 --- a/lib/services/discovery.ts +++ b/lib/services/discovery.ts @@ -370,6 +370,7 @@ export function getNewAvailableFeed(userId: string, days = 14) { firstAirDate: titles.firstAirDate, voteAverage: titles.voteAverage, popularity: titles.popularity, + userStatus: userTitleStatus.status, }) .from(titles) .innerJoin( diff --git a/lib/services/tracking.ts b/lib/services/tracking.ts index ddf7944..6067def 100644 --- a/lib/services/tracking.ts +++ b/lib/services/tracking.ts @@ -451,6 +451,36 @@ export function getUserStatusesByTmdbIds( return result; } +export function getUserStatusesByTitleIds( + userId: string, + titleIds: string[], +): Record { + if (titleIds.length === 0) return {}; + + const rows = db + .select({ + titleId: userTitleStatus.titleId, + status: userTitleStatus.status, + }) + .from(userTitleStatus) + .where( + and( + eq(userTitleStatus.userId, userId), + inArray(userTitleStatus.titleId, titleIds), + ), + ) + .all(); + + const result: Record = {}; + for (const row of rows) { + result[row.titleId] = row.status as + | "watchlist" + | "in_progress" + | "completed"; + } + return result; +} + export function getEpisodeProgressByTmdbIds( userId: string, tmdbIds: { tmdbId: number; type: string }[],