Skip to content

Commit 41ef64d

Browse files
committed
restored findme option to include Auto, GPS, searchCenter
1 parent 239fe07 commit 41ef64d

File tree

4 files changed

+173
-69
lines changed

4 files changed

+173
-69
lines changed

src/app/[locale]/page.tsx

Lines changed: 52 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
'use client';
22

33
import L from 'leaflet';
4-
54
import { useTranslations } from 'next-intl';
65
import dynamic from 'next/dynamic';
76
import Image from 'next/image';
@@ -16,6 +15,7 @@ import { DeviceLocationType, IUserSettings } from '@/constants/types';
1615

1716
import { AppContext } from '../../../context/AppContextProvider';
1817
import logger from '../../../logger.config.mjs';
18+
import { userLocation } from '@/utils/resolveUserLocation';
1919

2020
export default function Index() {
2121
const t = useTranslations();
@@ -24,14 +24,9 @@ export default function Index() {
2424
});
2525
const mapRef = useRef<L.Map | null>(null);
2626

27-
const [mapCenter, setMapCenter] = useState<{ lat: number; lng: number }>({
28-
lat: 0,
29-
lng: 0,
30-
});
31-
const [searchCenter, setSetSearchCenter] = useState<{ lat: number; lng: number }>({
32-
lat: 0,
33-
lng: 0,
34-
});
27+
// State management with proper typing
28+
const [mapCenter, setMapCenter] = useState<{ lat: number; lng: number } | null>(null);
29+
const [searchCenter, setSearchCenter] = useState<{ lat: number; lng: number } | null>(null);
3530
const [findme, setFindme] = useState<DeviceLocationType>(DeviceLocationType.SearchCenter);
3631
const [dbUserSettings, setDbUserSettings] = useState<IUserSettings | null>(null);
3732
const [zoomLevel, setZoomLevel] = useState(2);
@@ -40,12 +35,13 @@ export default function Index() {
4035
const [isSearchClicked, setSearchClicked] = useState(false);
4136
const [searchResults, setSearchResults] = useState<any[]>([]);
4237

43-
const { isSigningInUser, currentUser, autoLoginUser } = useContext(AppContext);
38+
const { isSigningInUser, currentUser, autoLoginUser, reload, setReload } = useContext(AppContext);
4439

4540
// Default map center (example: New York City)
4641
const defaultMapCenter = { lat: 20, lng: -74.006 };
4742

4843
useEffect(() => {
44+
setReload(false)
4945
if (!currentUser) {
5046
logger.info("User not logged in; attempting auto-login..");
5147
autoLoginUser();
@@ -55,58 +51,68 @@ export default function Index() {
5551
try {
5652
const data = await fetchUserSettings();
5753
if (data) {
58-
console.log('Fetched user settings data successfully: ', data.findme)
5954
logger.info('Fetched user settings data successfully:', { data });
6055
setDbUserSettings(data);
61-
setSetSearchCenter(data.search_map_center.coordinates)
56+
if (data.search_map_center?.coordinates) {
57+
setSearchCenter({
58+
lat: data.search_map_center.coordinates[1],
59+
lng: data.search_map_center.coordinates[0],
60+
});
61+
}
6262
} else {
6363
logger.warn('User Settings not found.');
6464
setDbUserSettings(null);
65+
setSearchCenter(null)
6566
}
6667
} catch (error) {
6768
logger.error('Error fetching user settings data:', { error });
6869
}
6970
};
70-
getUserSettingsData();
71-
}, [currentUser]);
7271

73-
// useEffect(() => {
74-
// const fetchLocationOnLoad = async () => {
75-
// try {
76-
// const location = await fetchUserLocation();
77-
// setMapCenter(location.origin);
78-
// setZoomLevel(location.radius);
79-
// logger.info('User location obtained successfully on initial load:', {
80-
// location,
81-
// });
82-
// } catch (error) {
83-
// logger.error('Error getting location on initial load.', { error });
84-
// setMapCenter(defaultMapCenter);
85-
// setZoomLevel(2);
86-
// }
87-
// };
72+
getUserSettingsData();
73+
}, [currentUser, reload]);
8874

89-
// fetchLocationOnLoad();
90-
// }, [isSigningInUser]);
75+
useEffect(() => {
76+
const resolveLocation = async () => {
77+
if (dbUserSettings && dbUserSettings.findme !== DeviceLocationType.SearchCenter) {
78+
const loc = await userLocation(dbUserSettings);
79+
if (loc) {
80+
setSearchCenter({ lat: loc[0], lng: loc[1] });
81+
}
82+
else{
83+
setSearchCenter(null)
84+
}
85+
}
86+
};
87+
resolveLocation();
88+
}, [dbUserSettings]);
9189

9290
const handleLocationButtonClick = async () => {
93-
try {
94-
const location = await fetchUserLocation();
95-
setMapCenter(location.origin);
96-
setZoomLevel(location.radius);
97-
setLocationError(null);
98-
logger.info('User location obtained successfully on button click:', {
99-
location,
100-
});
101-
} catch (error) {
102-
logger.error('Error getting location on button click.', { error });
103-
setLocationError(
104-
t('HOME.LOCATION_SERVICES.ENABLE_LOCATION_SERVICES_MESSAGE'),
105-
);
91+
if (dbUserSettings) {
92+
const loc = await userLocation(dbUserSettings);
93+
if (loc) {
94+
setSearchCenter({ lat: loc[0], lng: loc[1] });
95+
logger.info('User location obtained successfully on button click:', { location });
96+
}
97+
else{
98+
setSearchCenter(null)
99+
}
106100
}
101+
// try {
102+
// setReload(true);
103+
// setLocationError(null);
104+
// logger.info('User location obtained successfully on button click:', { location });
105+
// } catch (error) {
106+
// setReload(false)
107+
// logger.error('Error getting location on button click.', { error });
108+
// setLocationError(t('HOME.LOCATION_SERVICES.ENABLE_LOCATION_SERVICES_MESSAGE'));
109+
// }
110+
// finally{
111+
// setReload(false);
112+
// }
107113
};
108114

109-
// handle search query update from SearchBar and associated results
115+
// Handle search query update from SearchBar and associated results
110116
const handleSearch = async (query: string) => {
111117
setSearchQuery(query);
112118
setSearchClicked(true);
@@ -135,7 +141,7 @@ export default function Index() {
135141
searchResults={searchResults || []}
136142
/>
137143
<SearchBar page={'default'} onSearch={handleSearch} />
138-
<div className="absolute bottom-8 z-10 right-0 left-0 m-auto pointer-events-none">
144+
<div className="absolute bottom-8 z-10 right-0 left-0 m-auto pointer-events-none">
139145
<div className="w-[90%] lg:w-full lg:px-6 mx-auto flex items-center justify-between">
140146
{/* Add Seller Button */}
141147
<div className="pointer-events-auto">

src/components/shared/map/Map.tsx

Lines changed: 23 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,10 @@ const Map = ({
5757
isSearchClicked,
5858
searchResults,
5959
}: {
60-
center: LatLngExpression;
60+
center: LatLngExpression | null;
6161
zoom: number;
62-
mapRef: React.MutableRefObject<L.Map | null>; searchQuery: string;
62+
mapRef: React.MutableRefObject<L.Map | null>;
63+
searchQuery: string;
6364
isSearchClicked: boolean;
6465
searchResults: ISeller[];
6566
}) => {
@@ -81,20 +82,12 @@ const Map = ({
8182

8283
const [position, setPosition] = useState<L.LatLng | null>(null);
8384
const [sellers, setSellers] = useState<ISellerWithSettings[]>([]);
84-
const [origin, setOrigin] = useState(center);
8585
const [loading, setLoading] = useState(false);
8686
const [error, setError] = useState<string | null>(null);
8787
const [locationError, setLocationError] = useState(false);
8888
const [isLocationAvailable, setIsLocationAvailable] = useState(false);
8989
const [initialLocationSet, setInitialLocationSet] = useState(false);
9090

91-
// Update origin when center prop changes
92-
useEffect(() => {
93-
if (center) {
94-
setOrigin(center);
95-
}
96-
}, [center]);
97-
9891
useEffect(() => {
9992
if (searchResults.length > 0) {
10093
const sellersWithCoordinates = searchResults.map((seller: any) => {
@@ -180,8 +173,17 @@ const Map = ({
180173
logger.warn('Map instance is not ready yet');
181174
return;
182175
}
183-
console.log("initial user center:", center.toString())
184-
mapInstance.setView(center, 8, { animate: true })
176+
// Set and zoom map center to search center if available
177+
if (center){
178+
console.log("initial map center is focus to user center:", center.toString())
179+
mapInstance.setView(center, 8, { animate: true })
180+
} else {
181+
const worldCenter = mapRef.current?.getCenter()
182+
console.log("initial map center focus to world:", worldCenter?.toString())
183+
worldCenter
184+
? mapInstance.setView(worldCenter, 2, { animate: false })
185+
: mapRef.current = mapInstance;
186+
}
185187

186188
const bounds = mapInstance.getBounds();
187189
if (bounds) {
@@ -241,10 +243,10 @@ const Map = ({
241243
logger.info(`Location found: ${e.latlng.toString()}`);
242244
setPosition(e.latlng);
243245
setLocationError(false);
244-
if (!initialLocationSet) {
245-
map.setView(e.latlng, zoom, { animate: false });
246-
setInitialLocationSet(true);
247-
setIsLocationAvailable(true);
246+
if (center) {
247+
map.setView(center, zoom, { animate: false });
248+
// setInitialLocationSet(true);
249+
// setIsLocationAvailable(true);
248250
}
249251
},
250252
locationerror() {
@@ -275,7 +277,7 @@ const Map = ({
275277
}
276278
}, [position, map, initialLocationSet]);
277279

278-
return position === null ? null : <Marker position={position} />;
280+
return center === null ? null : <Marker position={center} icon={crosshairIcon} />;
279281
}
280282

281283
// Define map boundaries
@@ -321,8 +323,8 @@ const Map = ({
321323
</div>
322324
) : (
323325
<MapContainer
324-
center={isLocationAvailable ? origin : [0, 0]}
325-
zoom={isLocationAvailable ? zoom : 2}
326+
center={center ? center : [0,0]}
327+
zoom={center ? zoom : 2}
326328
zoomControl={false}
327329
minZoom={2}
328330
maxZoom={18}
@@ -338,10 +340,10 @@ const Map = ({
338340
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
339341
noWrap={true}
340342
/>
341-
<Marker
343+
{/* <Marker
342344
position={center as LatLngExpression}
343345
icon={crosshairIcon}
344-
></Marker>
346+
></Marker> */}
345347
<LocationMarker />
346348
{sellers.map((seller) => (
347349
<Marker

src/components/shared/sidebar/sidebar.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import styles from './sidebar.module.css';
22

3-
import { useTranslations } from 'next-intl';
3+
import { useTranslations, useLocale } from 'next-intl';
44
import { useTheme } from 'next-themes';
55
import Image from 'next/image';
66
import Link from 'next/link';
@@ -53,9 +53,10 @@ function isLanguageMenuItem(item: MenuItem): item is LanguageMenuItem {
5353
function Sidebar(props: any) {
5454
const t = useTranslations();
5555
const pathname = usePathname();
56+
const local = useLocale();
5657
const router = useRouter();
5758

58-
const { currentUser, autoLoginUser } = useContext(AppContext);
59+
const { currentUser, autoLoginUser, setReload } = useContext(AppContext);
5960
const [dbUserSettings, setDbUserSettings] = useState<IUserSettings | null>(null);
6061
// Initialize state with appropriate types
6162
const [formData, setFormData] = useState<{
@@ -249,6 +250,9 @@ function Sidebar(props: any) {
249250
setIsSaveEnabled(false);
250251
logger.info('User Settings saved successfully:', { data });
251252
toast.success(t('SIDE_NAVIGATION.VALIDATION.SUCCESSFUL_PREFERENCES_SUBMISSION'));
253+
if (pathname === '/' || pathname === `/${local}`) {
254+
setReload(true)
255+
}
252256
}
253257
} catch (error) {
254258
logger.error('Error saving user settings:', { error });

src/utils/resolveUserLocation.ts

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
import { IUserSettings } from '@/constants/types';
2+
import logger from '../../logger.config.mjs';
3+
4+
export enum DeviceLocationType {
5+
Automatic = 'Auto',
6+
GPS = 'GPS',
7+
SearchCenter = 'searchCenter',
8+
}
9+
10+
// Get device location, first trying GPS, and then falling back to IP-based geolocation
11+
const getDeviceLocation = async (): Promise<[number, number] | null> => {
12+
if (navigator.geolocation) {
13+
try {
14+
const position = await new Promise<GeolocationPosition>((resolve, reject) =>
15+
navigator.geolocation.getCurrentPosition(resolve, reject, {
16+
enableHighAccuracy: true,
17+
timeout: 5000,
18+
maximumAge: 0,
19+
})
20+
);
21+
return [position.coords.latitude, position.coords.longitude];
22+
} catch (error) {
23+
logger.warn('GPS location error:', (error as GeolocationPositionError).message);
24+
return null
25+
}
26+
}
27+
logger.warn('Unable to get device location by GPS');
28+
return null;
29+
};
30+
31+
// Function to check user search center and return appropriate location
32+
export const userLocation = async (userSettings: IUserSettings): Promise<[number, number] | null> => {
33+
if (!userSettings) {
34+
logger.warn('User settings not found');
35+
return null;
36+
}
37+
38+
// Handle Automatic location finding preference
39+
if (userSettings.findme === DeviceLocationType.Automatic) {
40+
try {
41+
let location = await getDeviceLocation();
42+
if (location) {
43+
logger.info(`[Auto FindMe] GPS location: ${location[0]}, ${location[1]}`);
44+
return location;
45+
}
46+
47+
// Fallback to search center if GPS fails
48+
if (userSettings.search_map_center?.coordinates) {
49+
const searchCenter = userSettings.search_map_center.coordinates;
50+
location = [searchCenter[1], searchCenter[0]];
51+
logger.info(`[Auto FindMe] Using search center location: ${location[0]}, ${location[1]}`);
52+
return location;
53+
}
54+
55+
return null;
56+
} catch (error) {
57+
logger.error('Failed to retrieve automatic device location:', error);
58+
return null;
59+
}
60+
}
61+
62+
// Handle GPS-only preference
63+
if (userSettings.findme === DeviceLocationType.GPS) {
64+
try {
65+
const location = await getDeviceLocation();
66+
if (location) {
67+
logger.info(`[GPS] User location: ${location[0]}, ${location[1]}`);
68+
return location;
69+
}
70+
return null;
71+
} catch (error) {
72+
logger.error('Failed to retrieve GPS device location:', error);
73+
return null;
74+
}
75+
}
76+
77+
// Handle Search Center-only preference
78+
if (
79+
userSettings.findme === DeviceLocationType.SearchCenter &&
80+
Array.isArray(userSettings.search_map_center?.coordinates) &&
81+
userSettings.search_map_center.coordinates.length === 2
82+
) {
83+
const searchCenter = userSettings.search_map_center.coordinates;
84+
const location: [number, number] = [searchCenter[1], searchCenter[0]]; // Ensures it's a tuple of exactly two numbers
85+
logger.info(`[Search Center] User location: ${location[0]}, ${location[1]}`);
86+
return location;
87+
} else {
88+
logger.warn('Invalid search center coordinates.');
89+
return null;
90+
}
91+
92+
};

0 commit comments

Comments
 (0)