map search
This commit is contained in:
@@ -1,14 +1,17 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import { useSearchParams } from "react-router-dom";
|
||||
import { useSearchParams, useNavigate } from "react-router-dom";
|
||||
import { Item } from "../types";
|
||||
import { itemAPI } from "../services/api";
|
||||
import ItemCard from "../components/ItemCard";
|
||||
import SearchResultsMap from "../components/SearchResultsMap";
|
||||
|
||||
const ItemList: React.FC = () => {
|
||||
const [searchParams] = useSearchParams();
|
||||
const navigate = useNavigate();
|
||||
const [items, setItems] = useState<Item[]>([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
const [viewMode, setViewMode] = useState<'list' | 'map'>('list');
|
||||
const [filters, setFilters] = useState({
|
||||
search: searchParams.get("search") || "",
|
||||
city: searchParams.get("city") || "",
|
||||
@@ -58,6 +61,16 @@ const ItemList: React.FC = () => {
|
||||
}
|
||||
};
|
||||
|
||||
const handleItemSelect = (item: Item) => {
|
||||
navigate(`/items/${item.id}`);
|
||||
};
|
||||
|
||||
const getSearchLocationString = () => {
|
||||
if (filters.city) return filters.city;
|
||||
if (filters.zipCode) return filters.zipCode;
|
||||
return '';
|
||||
};
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
<div className="container mt-5">
|
||||
@@ -81,23 +94,63 @@ const ItemList: React.FC = () => {
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="container mt-4">
|
||||
<h1>Browse Items</h1>
|
||||
|
||||
<div className="mb-4">
|
||||
<span className="text-muted">{items.length} items found</span>
|
||||
<div className="container-fluid mt-4" style={{ maxWidth: '1800px' }}>
|
||||
<div className="d-flex flex-column flex-md-row justify-content-between align-items-start align-items-md-center mb-4 gap-3">
|
||||
<div>
|
||||
<h1 className="mb-1">Browse Items</h1>
|
||||
<span className="text-muted">{items.length} items found</span>
|
||||
</div>
|
||||
|
||||
{items.length > 0 && (
|
||||
<div className="btn-group" role="group" aria-label="View toggle">
|
||||
<button
|
||||
type="button"
|
||||
className={`btn btn-outline-secondary ${viewMode === 'list' ? 'active' : ''}`}
|
||||
onClick={() => setViewMode('list')}
|
||||
>
|
||||
<i className="bi bi-list-ul me-1 me-md-2"></i>
|
||||
<span className="d-none d-md-inline">List</span>
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
className={`btn btn-outline-secondary ${viewMode === 'map' ? 'active' : ''}`}
|
||||
onClick={() => setViewMode('map')}
|
||||
>
|
||||
<i className="bi bi-geo-alt-fill me-1 me-md-2"></i>
|
||||
<span className="d-none d-md-inline">Map</span>
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{items.length === 0 ? (
|
||||
<p className="text-center text-muted">No items available for rent.</p>
|
||||
) : (
|
||||
<div className="text-center py-5">
|
||||
<i className="bi bi-search text-muted mb-3" style={{ fontSize: '4rem' }}></i>
|
||||
<h3 className="text-muted">No items found</h3>
|
||||
<p className="text-muted">
|
||||
Try adjusting your search criteria or browse all available items.
|
||||
</p>
|
||||
</div>
|
||||
) : viewMode === 'list' ? (
|
||||
<div className="row">
|
||||
{items.map((item) => (
|
||||
<div key={item.id} className="col-md-6 col-lg-4 mb-4">
|
||||
<div key={item.id} className="col-md-6 col-lg-4 col-xl-3 mb-4">
|
||||
<ItemCard item={item} variant="standard" />
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
) : (
|
||||
<div className="mb-4">
|
||||
<SearchResultsMap
|
||||
items={items}
|
||||
searchLocation={getSearchLocationString()}
|
||||
onItemSelect={handleItemSelect}
|
||||
style={{
|
||||
height: window.innerWidth < 768 ? '60vh' : '70vh',
|
||||
minHeight: window.innerWidth < 768 ? '400px' : '500px'
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user