Updated search bar to remove location. Will get or ask for user's location. Removed Start Earning button. Works on desktop and mobile
This commit is contained in:
@@ -1,23 +1,61 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import React, { useState, useEffect, useRef } from "react";
|
||||
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";
|
||||
import LocationPromptModal from "../components/LocationPromptModal";
|
||||
import { useAuth } from "../contexts/AuthContext";
|
||||
|
||||
const ItemList: React.FC = () => {
|
||||
const [searchParams] = useSearchParams();
|
||||
const navigate = useNavigate();
|
||||
const { user } = useAuth();
|
||||
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 [showLocationPrompt, setShowLocationPrompt] = useState(false);
|
||||
const locationCheckDone = useRef(false);
|
||||
const [filters, setFilters] = useState({
|
||||
search: searchParams.get("search") || "",
|
||||
city: searchParams.get("city") || "",
|
||||
zipCode: searchParams.get("zipCode") || "",
|
||||
lat: searchParams.get("lat") || "",
|
||||
lng: searchParams.get("lng") || "",
|
||||
radius: searchParams.get("radius") || "",
|
||||
});
|
||||
|
||||
// Check if location is needed and handle accordingly
|
||||
useEffect(() => {
|
||||
// Only run this check once per mount
|
||||
if (locationCheckDone.current) return;
|
||||
|
||||
const hasLocation = searchParams.has("lat") || searchParams.has("city") || searchParams.has("zipCode");
|
||||
|
||||
if (!hasLocation) {
|
||||
// Check user's saved address for lat/lng
|
||||
const userLat = user?.addresses?.[0]?.latitude;
|
||||
const userLng = user?.addresses?.[0]?.longitude;
|
||||
|
||||
if (userLat && userLng) {
|
||||
// Use saved address coordinates
|
||||
const params = new URLSearchParams(searchParams);
|
||||
params.set("lat", userLat.toString());
|
||||
params.set("lng", userLng.toString());
|
||||
params.set("radius", "25");
|
||||
locationCheckDone.current = true;
|
||||
navigate(`/items?${params.toString()}`, { replace: true });
|
||||
} else {
|
||||
// No saved address with coordinates - show location prompt
|
||||
locationCheckDone.current = true;
|
||||
setShowLocationPrompt(true);
|
||||
}
|
||||
} else {
|
||||
locationCheckDone.current = true;
|
||||
}
|
||||
}, [user, searchParams, navigate]);
|
||||
|
||||
useEffect(() => {
|
||||
fetchItems();
|
||||
}, [filters]);
|
||||
@@ -28,9 +66,37 @@ const ItemList: React.FC = () => {
|
||||
search: searchParams.get("search") || "",
|
||||
city: searchParams.get("city") || "",
|
||||
zipCode: searchParams.get("zipCode") || "",
|
||||
lat: searchParams.get("lat") || "",
|
||||
lng: searchParams.get("lng") || "",
|
||||
radius: searchParams.get("radius") || "",
|
||||
});
|
||||
}, [searchParams]);
|
||||
|
||||
const handleLocationSelect = (
|
||||
location: { lat: number; lng: number } | { city?: string; zipCode?: string }
|
||||
) => {
|
||||
const params = new URLSearchParams(searchParams);
|
||||
|
||||
if ("lat" in location) {
|
||||
params.set("lat", location.lat.toString());
|
||||
params.set("lng", location.lng.toString());
|
||||
params.set("radius", "25");
|
||||
// Remove city/zipCode if using coordinates
|
||||
params.delete("city");
|
||||
params.delete("zipCode");
|
||||
} else {
|
||||
if (location.city) params.set("city", location.city);
|
||||
if (location.zipCode) params.set("zipCode", location.zipCode);
|
||||
// Remove lat/lng if using city/zip
|
||||
params.delete("lat");
|
||||
params.delete("lng");
|
||||
params.delete("radius");
|
||||
}
|
||||
|
||||
navigate(`/items?${params.toString()}`, { replace: true });
|
||||
setShowLocationPrompt(false);
|
||||
};
|
||||
|
||||
const fetchItems = async () => {
|
||||
try {
|
||||
setLoading(true);
|
||||
@@ -66,6 +132,10 @@ const ItemList: React.FC = () => {
|
||||
};
|
||||
|
||||
const getSearchLocationString = () => {
|
||||
if (filters.lat && filters.lng) {
|
||||
// When using coordinates, return them as a string for the map
|
||||
return `${filters.lat},${filters.lng}`;
|
||||
}
|
||||
if (filters.city) return filters.city;
|
||||
if (filters.zipCode) return filters.zipCode;
|
||||
return '';
|
||||
@@ -145,13 +215,19 @@ const ItemList: React.FC = () => {
|
||||
items={items}
|
||||
searchLocation={getSearchLocationString()}
|
||||
onItemSelect={handleItemSelect}
|
||||
style={{
|
||||
height: window.innerWidth < 768 ? '60vh' : '70vh',
|
||||
minHeight: window.innerWidth < 768 ? '400px' : '500px'
|
||||
style={{
|
||||
height: window.innerWidth < 768 ? '60vh' : '70vh',
|
||||
minHeight: window.innerWidth < 768 ? '400px' : '500px'
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<LocationPromptModal
|
||||
show={showLocationPrompt}
|
||||
onClose={() => setShowLocationPrompt(false)}
|
||||
onLocationSelect={handleLocationSelect}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user