ask for location permission
This commit is contained in:
@@ -85,6 +85,57 @@ function MapComponent({
|
|||||||
});
|
});
|
||||||
markerRef.current = initialMarker;
|
markerRef.current = initialMarker;
|
||||||
|
|
||||||
|
// Geocode the initial location if address is not provided
|
||||||
|
if (!initialLocation.address && onLocationSelect) {
|
||||||
|
const geocoder = new google.maps.Geocoder();
|
||||||
|
geocoder.geocode(
|
||||||
|
{
|
||||||
|
location: {
|
||||||
|
lat: initialLocation.lat,
|
||||||
|
lng: initialLocation.lng,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
(results, status) => {
|
||||||
|
if (status === "OK" && results && results[0]) {
|
||||||
|
const address = results[0].formatted_address;
|
||||||
|
console.log(
|
||||||
|
"Initial location geocoded - calling onLocationSelect:",
|
||||||
|
{
|
||||||
|
lat: initialLocation.lat,
|
||||||
|
lng: initialLocation.lng,
|
||||||
|
address,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
onLocationSelect(
|
||||||
|
initialLocation.lat,
|
||||||
|
initialLocation.lng,
|
||||||
|
address,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
console.log("Geocoding failed on initial location:", status);
|
||||||
|
// Fallback: use coordinates as address if geocoding fails
|
||||||
|
const fallbackAddress = `Location: ${initialLocation.lat.toFixed(6)}, ${initialLocation.lng.toFixed(6)}`;
|
||||||
|
console.log(
|
||||||
|
"Using fallback address for initial location:",
|
||||||
|
fallbackAddress,
|
||||||
|
);
|
||||||
|
onLocationSelect(
|
||||||
|
initialLocation.lat,
|
||||||
|
initialLocation.lng,
|
||||||
|
fallbackAddress,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
} else if (initialLocation.address && onLocationSelect) {
|
||||||
|
// If address is already provided, just call onLocationSelect
|
||||||
|
onLocationSelect(
|
||||||
|
initialLocation.lat,
|
||||||
|
initialLocation.lng,
|
||||||
|
initialLocation.address,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// Add drag end listener to the initial marker
|
// Add drag end listener to the initial marker
|
||||||
initialMarker.addListener("dragend", () => {
|
initialMarker.addListener("dragend", () => {
|
||||||
const position = initialMarker.getPosition();
|
const position = initialMarker.getPosition();
|
||||||
@@ -97,13 +148,22 @@ function MapComponent({
|
|||||||
geocoder.geocode({ location: { lat, lng } }, (results, status) => {
|
geocoder.geocode({ location: { lat, lng } }, (results, status) => {
|
||||||
if (status === "OK" && results && results[0]) {
|
if (status === "OK" && results && results[0]) {
|
||||||
const address = results[0].formatted_address;
|
const address = results[0].formatted_address;
|
||||||
console.log('Initial marker drag - calling onLocationSelect:', { lat, lng, address });
|
console.log(
|
||||||
|
"Initial marker drag - calling onLocationSelect:",
|
||||||
|
{ lat, lng, address },
|
||||||
|
);
|
||||||
onLocationSelect?.(lat, lng, address);
|
onLocationSelect?.(lat, lng, address);
|
||||||
} else {
|
} else {
|
||||||
console.log('Geocoding failed on initial marker drag:', status);
|
console.log(
|
||||||
|
"Geocoding failed on initial marker drag:",
|
||||||
|
status,
|
||||||
|
);
|
||||||
// Fallback: use coordinates as address if geocoding fails
|
// Fallback: use coordinates as address if geocoding fails
|
||||||
const fallbackAddress = `Location: ${lat.toFixed(6)}, ${lng.toFixed(6)}`;
|
const fallbackAddress = `Location: ${lat.toFixed(6)}, ${lng.toFixed(6)}`;
|
||||||
console.log('Using fallback address for initial marker drag:', fallbackAddress);
|
console.log(
|
||||||
|
"Using fallback address for initial marker drag:",
|
||||||
|
fallbackAddress,
|
||||||
|
);
|
||||||
onLocationSelect?.(lat, lng, fallbackAddress);
|
onLocationSelect?.(lat, lng, fallbackAddress);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ interface MapBottomSheetProps {
|
|||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
initialValue: string;
|
initialValue: string;
|
||||||
onSave: (value: string) => void;
|
onSave: (value: string) => void;
|
||||||
|
initialLocation?: { lat: number; lng: number; address?: string };
|
||||||
}
|
}
|
||||||
|
|
||||||
interface LocationData {
|
interface LocationData {
|
||||||
@@ -24,6 +25,7 @@ export function MapBottomSheet({
|
|||||||
onClose,
|
onClose,
|
||||||
initialValue,
|
initialValue,
|
||||||
onSave,
|
onSave,
|
||||||
|
initialLocation,
|
||||||
}: MapBottomSheetProps) {
|
}: MapBottomSheetProps) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const [value, setValue] = useState(initialValue);
|
const [value, setValue] = useState(initialValue);
|
||||||
@@ -35,8 +37,15 @@ export function MapBottomSheet({
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setValue(initialValue);
|
setValue(initialValue);
|
||||||
|
|
||||||
|
// Priority: initialLocation > parsed initialValue
|
||||||
|
if (initialLocation) {
|
||||||
|
setSelectedLocation({
|
||||||
|
lat: initialLocation.lat,
|
||||||
|
lng: initialLocation.lng,
|
||||||
|
address: initialLocation.address || "",
|
||||||
|
});
|
||||||
|
} else if (initialValue) {
|
||||||
// Try to parse initialValue as JSON to set selectedLocation
|
// Try to parse initialValue as JSON to set selectedLocation
|
||||||
if (initialValue) {
|
|
||||||
try {
|
try {
|
||||||
const parsed = JSON.parse(initialValue);
|
const parsed = JSON.parse(initialValue);
|
||||||
if (parsed.lat && parsed.lng && parsed.address) {
|
if (parsed.lat && parsed.lng && parsed.address) {
|
||||||
@@ -47,7 +56,7 @@ export function MapBottomSheet({
|
|||||||
setSelectedLocation(null);
|
setSelectedLocation(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, [initialValue]);
|
}, [initialValue, initialLocation]);
|
||||||
|
|
||||||
const handleLocationSelect = (lat: number, lng: number, address: string) => {
|
const handleLocationSelect = (lat: number, lng: number, address: string) => {
|
||||||
console.log('Location selected:', { lat, lng, address });
|
console.log('Location selected:', { lat, lng, address });
|
||||||
@@ -99,7 +108,11 @@ export function MapBottomSheet({
|
|||||||
initialAddress={selectedLocation?.address || ""}
|
initialAddress={selectedLocation?.address || ""}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<GoogleMap onLocationSelect={handleLocationSelect} height="100%" />
|
<GoogleMap
|
||||||
|
onLocationSelect={handleLocationSelect}
|
||||||
|
height="100%"
|
||||||
|
initialLocation={selectedLocation || initialLocation}
|
||||||
|
/>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import { Button, Card } from "antd";
|
import { Button, Card, message } from "antd";
|
||||||
import { GoogleMap } from "components/CustomBottomSheet/GoogleMap";
|
import { GoogleMap } from "components/CustomBottomSheet/GoogleMap";
|
||||||
import { MapBottomSheet } from "components/CustomBottomSheet/MapBottomSheet";
|
import { MapBottomSheet } from "components/CustomBottomSheet/MapBottomSheet";
|
||||||
import ProText from "components/ProText";
|
import ProText from "components/ProText";
|
||||||
import { selectCart, updateLocation } from "features/order/orderSlice";
|
import { selectCart, updateLocation } from "features/order/orderSlice";
|
||||||
import { useCallback, useMemo, useState } from "react";
|
import { useCallback, useEffect, useMemo, useState } from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { useAppDispatch, useAppSelector } from "redux/hooks";
|
import { useAppDispatch, useAppSelector } from "redux/hooks";
|
||||||
import styles from "../../address/address.module.css";
|
import styles from "../../address/address.module.css";
|
||||||
@@ -20,7 +20,8 @@ export const AddressSummary = () => {
|
|||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const { location } = useAppSelector(selectCart);
|
const { location } = useAppSelector(selectCart);
|
||||||
const [isMapBottomSheetOpen, setIsMapBottomSheetOpen] = useState(false);
|
const [isMapBottomSheetOpen, setIsMapBottomSheetOpen] = useState(false);
|
||||||
const { orderType } = useAppSelector(selectCart); // Default to delivery for now
|
const { orderType } = useAppSelector(selectCart);
|
||||||
|
const [userLocation, setUserLocation] = useState<LocationData | null>(null);
|
||||||
|
|
||||||
const handleLocationSave = useCallback(
|
const handleLocationSave = useCallback(
|
||||||
(locationString: string) => {
|
(locationString: string) => {
|
||||||
@@ -42,9 +43,58 @@ export const AddressSummary = () => {
|
|||||||
setIsMapBottomSheetOpen(false);
|
setIsMapBottomSheetOpen(false);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
// Request user location when delivery order type is selected and no location exists
|
||||||
|
useEffect(() => {
|
||||||
|
if (orderType === OrderType.Delivery && !location && !userLocation) {
|
||||||
|
if ("geolocation" in navigator) {
|
||||||
|
navigator.geolocation.getCurrentPosition(
|
||||||
|
(position) => {
|
||||||
|
const lat = position.coords.latitude;
|
||||||
|
const lng = position.coords.longitude;
|
||||||
|
|
||||||
|
// Set location with coordinates first, address will be geocoded by the map
|
||||||
|
const locationData: LocationData = {
|
||||||
|
lat,
|
||||||
|
lng,
|
||||||
|
address: "", // Will be filled by GoogleMap when it geocodes
|
||||||
|
};
|
||||||
|
setUserLocation(locationData);
|
||||||
|
// Automatically set as default location
|
||||||
|
dispatch(updateLocation(locationData));
|
||||||
|
},
|
||||||
|
(error) => {
|
||||||
|
console.error("Error getting user location:", error);
|
||||||
|
message.warning(
|
||||||
|
t("address.locationPermissionDenied") ||
|
||||||
|
"Location access denied. Please select location manually.",
|
||||||
|
);
|
||||||
|
},
|
||||||
|
{
|
||||||
|
enableHighAccuracy: true,
|
||||||
|
timeout: 10000,
|
||||||
|
maximumAge: 0,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
message.warning(
|
||||||
|
t("address.geolocationNotSupported") ||
|
||||||
|
"Geolocation is not supported by your browser",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [orderType, location, userLocation, dispatch, t]);
|
||||||
|
|
||||||
const initialValue = useMemo(
|
const initialValue = useMemo(
|
||||||
() => (location ? JSON.stringify(location) : ""),
|
() => {
|
||||||
[location],
|
if (location) {
|
||||||
|
return JSON.stringify(location);
|
||||||
|
}
|
||||||
|
if (userLocation) {
|
||||||
|
return JSON.stringify(userLocation);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
},
|
||||||
|
[location, userLocation],
|
||||||
);
|
);
|
||||||
|
|
||||||
const shouldRender = useMemo(
|
const shouldRender = useMemo(
|
||||||
@@ -102,6 +152,7 @@ export const AddressSummary = () => {
|
|||||||
onClose={handleMapBottomSheetClose}
|
onClose={handleMapBottomSheetClose}
|
||||||
initialValue={initialValue}
|
initialValue={initialValue}
|
||||||
onSave={handleLocationSave}
|
onSave={handleLocationSave}
|
||||||
|
initialLocation={location || userLocation || undefined}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user