'use client'; import * as React from 'react'; import { useRouter, useSearchParams } from 'next/navigation'; import { Button } from '@/components/ui/button'; import { FilterBar, type SearchFilters } from '@/components/search/filter-bar'; import { SearchResults } from '@/components/search/search-results'; import { ListingMap } from '@/components/map/listing-map'; import { listingsApi, type ListingDetail, type PaginatedResult } from '@/lib/listings-api'; type ViewMode = 'list' | 'map' | 'split'; const defaultFilters: SearchFilters = { transactionType: '', propertyType: '', city: '', district: '', minPrice: '', maxPrice: '', minArea: '', maxArea: '', bedrooms: '', sort: '', }; function SearchContent() { const router = useRouter(); const searchParams = useSearchParams(); const [filters, setFilters] = React.useState(() => ({ ...defaultFilters, transactionType: searchParams.get('transactionType') || '', propertyType: searchParams.get('propertyType') || '', city: searchParams.get('city') || '', district: searchParams.get('district') || '', minPrice: searchParams.get('minPrice') || '', maxPrice: searchParams.get('maxPrice') || '', bedrooms: searchParams.get('bedrooms') || '', sort: searchParams.get('sort') || '', })); const [page, setPage] = React.useState(Number(searchParams.get('page')) || 1); const [result, setResult] = React.useState | null>(null); const [loading, setLoading] = React.useState(true); const [viewMode, setViewMode] = React.useState('list'); const [showMobileFilters, setShowMobileFilters] = React.useState(false); const fetchListings = React.useCallback(() => { setLoading(true); const params: Record = { page, limit: 12, status: 'ACTIVE', }; if (filters.transactionType) params['transactionType'] = filters.transactionType; if (filters.propertyType) params['propertyType'] = filters.propertyType; if (filters.city) params['city'] = filters.city; if (filters.district) params['district'] = filters.district; if (filters.minPrice) params['minPrice'] = filters.minPrice; if (filters.maxPrice) params['maxPrice'] = filters.maxPrice; if (filters.minArea) params['minArea'] = Number(filters.minArea); if (filters.maxArea) params['maxArea'] = Number(filters.maxArea); if (filters.bedrooms) params['bedrooms'] = Number(filters.bedrooms); listingsApi .search(params) .then(setResult) .catch(() => setResult(null)) .finally(() => setLoading(false)); }, [filters, page]); React.useEffect(() => { fetchListings(); }, [fetchListings]); // Sync filters to URL React.useEffect(() => { const params = new URLSearchParams(); Object.entries(filters).forEach(([key, value]) => { if (value) params.set(key, value); }); if (page > 1) params.set('page', String(page)); const qs = params.toString(); router.replace(`/search${qs ? `?${qs}` : ''}`, { scroll: false }); }, [filters, page, router]); const handleFilterChange = (newFilters: SearchFilters) => { setFilters(newFilters); setPage(1); }; const handleSearch = () => { setPage(1); fetchListings(); }; const activeFilterCount = Object.entries(filters).filter( ([key, value]) => value && key !== 'sort', ).length; return (
{/* Header */}

Tìm kiếm bất động sản

Tìm bất động sản phù hợp với nhu cầu của bạn

{/* View Mode Toggle + Mobile Filter Button */}
{/* Desktop horizontal filter bar */}
{/* Mobile filter panel */} {showMobileFilters && (
{ handleSearch(); setShowMobileFilters(false); }} layout="sidebar" />
)} {/* Content Area */}
{/* Sidebar filters (desktop, split/list mode) */} {viewMode !== 'map' && ( )} {/* Main content */}
{viewMode === 'list' && ( handleFilterChange({ ...filters, sort })} /> )} {viewMode === 'map' && ( )} {viewMode === 'split' && (
handleFilterChange({ ...filters, sort })} />
)}
); } export default function SearchPage() { return (
} >
); }