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:
jackiettran
2025-12-23 18:09:12 -05:00
parent 07e5a2a320
commit 347f709f72
5 changed files with 531 additions and 214 deletions

View File

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