Add watch status indicators to title cards on Explore page

Title cards now show the user's existing watch status (watchlist,
watching, completed) with a color-coded badge on the poster and a
status-aware quick-add button that prevents re-adding tracked titles.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-05 10:17:29 -05:00
co-authored by Claude Opus 4.6
parent fa01a0d4a0
commit 843bf35513
7 changed files with 184 additions and 5 deletions
+16
View File
@@ -1,5 +1,8 @@
import { atom } from "jotai";
import { loadable } from "jotai/utils";
import { fetchUserStatuses } from "@/lib/actions/watchlist";
type TitleStatus = "watchlist" | "in_progress" | "completed";
interface TitleRowItem {
tmdbId: number;
@@ -13,6 +16,7 @@ interface TitleRowItem {
export const selectedGenreAtom = atom<number | null>(null);
export const mediaTypeAtom = atom<"movie" | "tv">("movie");
export const defaultItemsAtom = atom<TitleRowItem[]>([]);
export const initialUserStatusesAtom = atom<Record<string, TitleStatus>>({});
const genreResultsAsyncAtom = atom(async (get) => {
const genre = get(selectedGenreAtom);
@@ -26,3 +30,15 @@ const genreResultsAsyncAtom = atom(async (get) => {
});
export const genreResultsLoadable = loadable(genreResultsAsyncAtom);
const genreUserStatusesAsyncAtom = atom(async (get) => {
const genre = get(selectedGenreAtom);
if (genre === null) return null;
const genreResults = await get(genreResultsAsyncAtom);
if (!genreResults || genreResults.length === 0) return {};
return fetchUserStatuses(
genreResults.map((r) => ({ tmdbId: r.tmdbId, type: r.type })),
);
});
export const genreUserStatusesLoadable = loadable(genreUserStatusesAsyncAtom);