/** * Component: Series Page * Documentation: documentation/frontend/components.md */ 'use client'; import { Suspense, useState, useEffect, useCallback } from 'react'; import { useSearchParams, useRouter } from 'next/navigation'; import { Header } from '@/components/layout/Header'; import { SeriesGrid } from '@/components/series/SeriesGrid'; import { useSeriesSearch } from '@/lib/hooks/useSeries'; import { ProtectedRoute } from '@/components/auth/ProtectedRoute'; import { CardSizeControls } from '@/components/ui/CardSizeControls'; import { SquareCoversToggle } from '@/components/ui/SquareCoversToggle'; import { usePreferences } from '@/contexts/PreferencesContext'; function SeriesPageContent() { const searchParams = useSearchParams(); const router = useRouter(); const initialQuery = searchParams.get('q') || ''; const [query, setQuery] = useState(initialQuery); const [debouncedQuery, setDebouncedQuery] = useState(initialQuery); const { cardSize, setCardSize, squareCovers, setSquareCovers } = usePreferences(); // Debounce search query and sync to URL useEffect(() => { const timer = setTimeout(() => { setDebouncedQuery(query); // Update URL without adding history entries const trimmed = query.trim(); if (trimmed) { router.replace(`/series?q=${encodeURIComponent(trimmed)}`, { scroll: false }); } else { router.replace('/series', { scroll: false }); } }, 500); return () => clearTimeout(timer); }, [query, router]); const { series, isLoading } = useSeriesSearch(debouncedQuery); const handleSearch = useCallback((e: React.FormEvent) => { e.preventDefault(); }, []); return (
{/* Page Header */}

Browse Series

Search for your favorite audiobook series

{/* Search Form */}
setQuery(e.target.value)} placeholder="Search by series name..." className="w-full pl-12 pr-12 py-4 text-lg border-2 border-gray-300 dark:border-gray-600 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 placeholder-gray-400" autoFocus /> {query && ( )}
{/* Results */} {debouncedQuery ? (
{/* Sticky Results Header */}

Series

{!isLoading && series.length > 0 && ( ({series.length} result{series.length !== 1 ? 's' : ''}) )}
{/* Series Grid */}
) : ( /* Empty State */

Start typing to search for series

Search by series name to discover audiobook collections

)}
); } export default function SeriesPage() { return ( ); }