import { useQuery } from "@tanstack/react-query"; import { ChevronLeft, ChevronRight, Grid, List } from "lucide-react"; import { useEffect, useState } from "react"; import { useLocation } from "wouter"; import { SearchBar } from "@/components/common/SearchBar"; import { WorkCard } from "@/components/common/WorkCard"; import { FilterSidebar } from "@/components/explore/FilterSidebar"; import { PageLayout } from "@/components/layout/PageLayout"; import { Button } from "@/components/ui/button"; import type { WorkWithAuthor } from "@/lib/types"; 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}`], select: (data) => data.map((work) => ({ ...work, tags: work.tags?.map((tag) => typeof tag === "string" ? { name: tag } : tag, ), })), }); 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)); const 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 && (
)}
); }