import { PageLayout } from "@/components/layout/PageLayout"; import { SearchBar } from "@/components/common/SearchBar"; import { WorkCard } from "@/components/common/WorkCard"; import { WorkWithAuthor } from "@/lib/types"; import { useQuery } from "@tanstack/react-query"; import { useState, useEffect } from "react"; import { useLocation } from "wouter"; import { FilterSidebar } from "@/components/explore/FilterSidebar"; import { Button } from "@/components/ui/button"; import { Grid, List, ChevronLeft, ChevronRight } from "lucide-react"; interface FilterState { language?: string; type?: string; yearStart?: number; yearEnd?: number; tags?: number[]; query?: string; sort?: string; page: number; } export default function Explore() { const [location] = useLocation(); const [filters, setFilters] = useState({ page: 1 }); const [viewMode, setViewMode] = useState<'list' | 'grid'>('list'); // Parse URL search params on initial load useEffect(() => { const searchParams = new URLSearchParams(location.split('?')[1]); const newFilters: FilterState = { page: 1 }; if (searchParams.has('q')) { newFilters.query = searchParams.get('q') || undefined; } if (searchParams.has('language')) { newFilters.language = searchParams.get('language') || undefined; } if (searchParams.has('type')) { newFilters.type = searchParams.get('type') || undefined; } if (searchParams.has('yearStart')) { newFilters.yearStart = parseInt(searchParams.get('yearStart') || '0', 10) || undefined; } if (searchParams.has('yearEnd')) { newFilters.yearEnd = parseInt(searchParams.get('yearEnd') || '0', 10) || undefined; } if (searchParams.has('tags')) { newFilters.tags = searchParams.get('tags')?.split(',').map(Number) || undefined; } if (searchParams.has('sort')) { newFilters.sort = searchParams.get('sort') || undefined; } if (searchParams.has('page')) { newFilters.page = parseInt(searchParams.get('page') || '1', 10); } setFilters(newFilters); }, [location]); // Build API query string based on filters const getQueryString = () => { const params = new URLSearchParams(); if (filters.query) { params.append('q', filters.query); } if (filters.language) { params.append('language', filters.language); } if (filters.type) { params.append('type', filters.type); } if (filters.yearStart) { params.append('yearStart', filters.yearStart.toString()); } if (filters.yearEnd) { params.append('yearEnd', filters.yearEnd.toString()); } if (filters.tags && filters.tags.length > 0) { params.append('tags', filters.tags.join(',')); } if (filters.sort) { params.append('sort', filters.sort); } // Pagination (we'll use limit/offset) const limit = 10; const offset = (filters.page - 1) * limit; params.append('limit', limit.toString()); params.append('offset', offset.toString()); return params.toString(); }; const queryString = getQueryString(); const { data: works, isLoading } = useQuery({ queryKey: [`/api/filter?${queryString}`], }); const { data: tags } = useQuery({ queryKey: ['/api/tags'], }); const handleFilterChange = (newFilters: Partial) => { setFilters(prev => ({ ...prev, ...newFilters, page: 1 })); }; const handlePageChange = (newPage: number) => { setFilters(prev => ({ ...prev, page: newPage })); window.scrollTo({ top: 0, behavior: 'smooth' }); }; // Generate page numbers for pagination const totalWorks = works?.length || 0; const workPerPage = 10; const totalPages = Math.ceil(totalWorks / workPerPage); const pageNumbers = []; const maxPageButtons = 5; let startPage = Math.max(1, filters.page - Math.floor(maxPageButtons / 2)); let endPage = Math.min(totalPages, startPage + maxPageButtons - 1); if (endPage - startPage + 1 < maxPageButtons) { startPage = Math.max(1, endPage - maxPageButtons + 1); } for (let i = startPage; i <= endPage; i++) { pageNumbers.push(i); } return (

Explore Literature

Discover works across languages, genres, and time periods

{/* Filters sidebar */} {/* Results */}
Showing {works?.length || 0} results {filters.query && for "{filters.query}"}
Display:
{isLoading ? (
{Array.from({ length: 5 }).map((_, i) => (
))}
) : viewMode === 'list' ? (
{works?.map(work => ( ))}
) : (
{works?.map(work => ( ))}
)} {/* Pagination */} {totalPages > 1 && (
)}
); }