import { useState, useEffect } from 'react'; import Link from 'next/link'; import Head from 'next/head'; import { useRouter } from 'next/router'; interface Listing { id: string; title: string; description: string; price: number; currency: string; quantity: number; category: string; status: string; sellerName?: string; location?: { city?: string; region?: string }; tags: string[]; viewCount: number; createdAt: string; } interface SearchResult { listings: Listing[]; total: number; page: number; limit: number; hasMore: boolean; } const categoryLabels: Record = { seeds: 'Seeds', seedlings: 'Seedlings', mature_plants: 'Mature Plants', cuttings: 'Cuttings', produce: 'Produce', supplies: 'Supplies', }; const categoryIcons: Record = { seeds: '🌰', seedlings: 'ðŸŒą', mature_plants: 'ðŸŠī', cuttings: '✂ïļ', produce: 'ðŸĨŽ', supplies: '🧰', }; const sortOptions = [ { value: 'date_desc', label: 'Newest First' }, { value: 'date_asc', label: 'Oldest First' }, { value: 'price_asc', label: 'Price: Low to High' }, { value: 'price_desc', label: 'Price: High to Low' }, { value: 'relevance', label: 'Most Popular' }, ]; export default function ListingsSearchPage() { const router = useRouter(); const { q, category, tags, sort, minPrice, maxPrice, page: pageParam } = router.query; const [results, setResults] = useState(null); const [loading, setLoading] = useState(true); const [searchQuery, setSearchQuery] = useState((q as string) || ''); const [selectedCategory, setSelectedCategory] = useState((category as string) || ''); const [selectedSort, setSelectedSort] = useState((sort as string) || 'date_desc'); const [priceMin, setPriceMin] = useState((minPrice as string) || ''); const [priceMax, setPriceMax] = useState((maxPrice as string) || ''); useEffect(() => { if (router.isReady) { fetchListings(); } }, [router.isReady, router.query]); const fetchListings = async () => { setLoading(true); try { const params = new URLSearchParams(); if (q) params.set('query', q as string); if (category) params.set('category', category as string); if (tags) params.set('tags', tags as string); if (sort) params.set('sortBy', sort as string); if (minPrice) params.set('minPrice', minPrice as string); if (maxPrice) params.set('maxPrice', maxPrice as string); if (pageParam) params.set('page', pageParam as string); const response = await fetch(`/api/marketplace/listings?${params.toString()}`); const data = await response.json(); if (!response.ok) { throw new Error(data.error || 'Failed to fetch listings'); } setResults(data); } catch (error) { console.error('Error fetching listings:', error); } finally { setLoading(false); } }; const handleSearch = (e: React.FormEvent) => { e.preventDefault(); updateFilters({ q: searchQuery || undefined }); }; const updateFilters = (updates: Record) => { const currentQuery = { ...router.query, ...updates }; // Remove undefined/empty values Object.keys(currentQuery).forEach(key => { if (!currentQuery[key]) delete currentQuery[key]; }); router.push({ pathname: '/marketplace/listings', query: currentQuery, }); }; const handleApplyFilters = () => { updateFilters({ category: selectedCategory || undefined, sortBy: selectedSort || undefined, minPrice: priceMin || undefined, maxPrice: priceMax || undefined, }); }; const clearFilters = () => { setSearchQuery(''); setSelectedCategory(''); setSelectedSort('date_desc'); setPriceMin(''); setPriceMax(''); router.push('/marketplace/listings'); }; return (
Browse Listings - LocalGreenChain Marketplace {/* Header */}
{/* Main Content */}
{/* Sidebar Filters */} {/* Results */}
{/* Active Filters */} {(q || category || tags) && (
Active filters: {q && ( Search: "{q}" )} {category && ( {categoryLabels[category as string]} )} {tags && ( Tag: {tags} )}
)} {/* Results Header */}

{q ? `Results for "${q}"` : category ? categoryLabels[category as string] : 'All Listings'} {results && ({results.total} found)}

{/* Listings Grid */} {loading ? (

Loading listings...

) : !results || results.listings.length === 0 ? (
🔍

No Listings Found

Try adjusting your search or filters to find what you're looking for.

) : ( <>
{results.listings.map((listing) => ( ))}
{/* Pagination */} {results.hasMore && (
)} )}
); } function ListingCard({ listing }: { listing: Listing }) { return (
{categoryIcons[listing.category] || 'ðŸŒŋ'}

{listing.title}

${listing.price.toFixed(2)}

{listing.description}

{categoryLabels[listing.category]} {listing.quantity} available
{listing.location && (
📍 {[listing.location.city, listing.location.region].filter(Boolean).join(', ')}
)}
); }