map search

This commit is contained in:
jackiettran
2025-09-10 16:41:05 -04:00
parent 1d7db138df
commit 688f5ac8d6
4 changed files with 602 additions and 14 deletions

View File

@@ -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>
);