"use client"; import { useLibraryShows } from "@/hooks/use-library-shows"; import { useLibrarySeasons } from "@/hooks/use-library-seasons"; import { LibraryItemCard } from "./library-item-card"; import { ShowTile } from "./show-tile"; import { SeasonTile } from "./season-tile"; import { BreadcrumbNav } from "./breadcrumb-nav"; import { ScheduleFromLibraryDialog } from "./schedule-from-library-dialog"; import { AddToBlockDialog } from "./add-to-block-dialog"; import { Button } from "@/components/ui/button"; import type { LibraryItemFull, ShowSummary } from "@/lib/types"; import type { LibrarySearchParams } from "@/hooks/use-library-search"; type Drilldown = null | { series: string } | { series: string; season: number }; interface Props { items: LibraryItemFull[]; total: number; page: number; pageSize: number; isLoading: boolean; selected: Set; onToggleSelect: (id: string) => void; onPageChange: (page: number) => void; selectedItems: LibraryItemFull[]; viewMode: "grouped" | "flat"; drilldown: Drilldown; onDrilldown: (next: Drilldown) => void; filter: LibrarySearchParams; selectedShows: ShowSummary[]; selectedShowNames: Set; onToggleSelectShow: (show: ShowSummary) => void; } export function LibraryGrid({ items, total, page, pageSize, isLoading, selected, onToggleSelect, onPageChange, selectedItems, viewMode, drilldown, onDrilldown, filter, selectedShows, selectedShowNames, onToggleSelectShow, }: Props) { const totalPages = Math.ceil(total / pageSize); // Hooks for grouped mode (called unconditionally per React rules) const showsFilter = { q: filter.q, genres: filter.genres, provider: filter.provider, }; const { data: showsData, isLoading: showsLoading } = useLibraryShows(showsFilter); const seasonsSeries = (viewMode === "grouped" && drilldown !== null && !("season" in drilldown)) ? drilldown.series : null; const { data: seasonsData, isLoading: seasonsLoading } = useLibrarySeasons( seasonsSeries, filter.provider, ); const isGroupedTopLevel = viewMode === "grouped" && drilldown === null; const isSeasonLevel = viewMode === "grouped" && drilldown !== null && !("season" in drilldown); const isEpisodeLevel = viewMode === "flat" || (viewMode === "grouped" && drilldown !== null && "season" in drilldown); function renderContent() { if (isGroupedTopLevel) { // Only show TV show tiles when no type filter is active — "Movies"/"Shorts" should not include shows const shows = !filter.type ? (showsData ?? []) : []; const nonEpisodes = items.filter(i => i.content_type !== "episode"); const loading = showsLoading; if (loading && shows.length === 0 && nonEpisodes.length === 0) { return

Loading…

; } if (shows.length === 0 && nonEpisodes.length === 0) { return

No items found. Run a library sync to populate the library.

; } return (
{shows.map(show => ( onToggleSelectShow(show)} onClick={() => onDrilldown({ series: show.series_name })} /> ))} {nonEpisodes.map(item => ( onToggleSelect(item.id)} /> ))}
); } if (isSeasonLevel && drilldown) { const seasons = seasonsData ?? []; if (seasonsLoading && seasons.length === 0) { return

Loading…

; } if (seasons.length === 0) { return

No seasons found.

; } return (
{seasons.map(season => ( {}} onClick={() => onDrilldown({ series: drilldown.series, season: season.season_number })} /> ))}
); } // Flat mode or episode-level drilldown if (isLoading) { return

Loading…

; } if (items.length === 0) { return

No items found. Run a library sync to populate the library.

; } return (
{items.map(item => ( onToggleSelect(item.id)} /> ))}
); } const showPagination = isEpisodeLevel && totalPages > 1; const totalSelected = selected.size + selectedShows.length; return (
{drilldown && ( { if (target === "root") onDrilldown(null); else if (target === "series" && drilldown && "series" in drilldown) onDrilldown({ series: drilldown.series }); }} /> )} {renderContent()}
{showPagination && (

{total.toLocaleString()} items total

{page + 1} / {totalPages}
)} {totalSelected > 0 && (
{totalSelected} selected {selected.size > 0 && }
)}
); }