/** * Component: Series Detail Page * Documentation: documentation/frontend/components.md */ 'use client'; import { use, useCallback, useMemo } from 'react'; import { useRouter, useSearchParams } from 'next/navigation'; import { Header } from '@/components/layout/Header'; import { AudiobookGrid } from '@/components/audiobooks/AudiobookGrid'; import { LoadMoreBar } from '@/components/ui/LoadMoreBar'; import { SeriesDetailCard, SeriesDetailSkeleton } from '@/components/series/SeriesDetailCard'; import { SimilarSeriesRow, SimilarSeriesSkeleton } from '@/components/series/SimilarSeriesRow'; import { useSeriesDetail } from '@/lib/hooks/useSeries'; import { Audiobook } from '@/lib/hooks/useAudiobooks'; import { ProtectedRoute } from '@/components/auth/ProtectedRoute'; import { SectionToolbar } from '@/components/ui/SectionToolbar'; import { usePreferences } from '@/contexts/PreferencesContext'; export default function SeriesDetailPage({ params, }: { params: Promise<{ asin: string }>; }) { const { asin } = use(params); const router = useRouter(); const searchParams = useSearchParams(); const fromSeriesTitle = searchParams.get('from'); const { series, hasMore, isLoading: seriesLoading, isLoadingMore, loadMore } = useSeriesDetail(asin); const { cardSize, setCardSize, squareCovers, setSquareCovers, hideAvailable, setHideAvailable } = usePreferences(); const handleBack = useCallback(() => { // Use browser back if we came from within the app, otherwise fallback to /series if (window.history.length > 1) { router.back(); } else { router.push('/series'); } }, [router]); // Filter out available titles when hideAvailable is enabled const filteredBooks = useMemo( () => series && hideAvailable ? series.books.filter((b: Audiobook) => !b.isAvailable && b.requestStatus !== 'completed') : series?.books ?? [], [series, hideAvailable] ); // Header count text: reflects filtered counts const visibleCount = filteredBooks.length; const booksCountText = series ? hasMore && series.bookCount > series.books.length ? `${visibleCount.toLocaleString()} of ${series.bookCount.toLocaleString()} title${series.bookCount !== 1 ? 's' : ''}` : visibleCount > 0 ? `${visibleCount.toLocaleString()} title${visibleCount !== 1 ? 's' : ''}` : '' : ''; return (
{/* Back navigation */} {/* Series Detail Card */} {seriesLoading ? ( ) : series ? ( ) : (

Series not found

)} {/* Similar Series */} {seriesLoading ? ( ) : series && series.similarSeries.length > 0 ? ( ) : null} {/* Books Section */} {series && (
{/* Sticky Books Header */}

Books in Series

{booksCountText && ( ({booksCountText}) )}
{/* Books Grid */} {/* Load More Bar */} {filteredBooks.length > 0 && ( 0 ? series.bookCount : undefined} hasMore={hasMore} isLoading={isLoadingMore} onLoadMore={loadMore} /> )}
)}
); }