160 lines
4.7 KiB
TypeScript
160 lines
4.7 KiB
TypeScript
import { Button, Card, message } from "antd";
|
|
import { GoogleMap } from "components/CustomBottomSheet/GoogleMap";
|
|
import { MapBottomSheet } from "components/CustomBottomSheet/MapBottomSheet";
|
|
import ProText from "components/ProText";
|
|
import { selectCart, updateLocation } from "features/order/orderSlice";
|
|
import { useCallback, useEffect, useMemo, useState } from "react";
|
|
import { useTranslation } from "react-i18next";
|
|
import { useAppDispatch, useAppSelector } from "redux/hooks";
|
|
import styles from "../../address/address.module.css";
|
|
import { OrderType } from "pages/checkout/hooks/types.ts";
|
|
|
|
interface LocationData {
|
|
lat: number;
|
|
lng: number;
|
|
address: string;
|
|
}
|
|
|
|
export const AddressSummary = () => {
|
|
const { t } = useTranslation();
|
|
const dispatch = useAppDispatch();
|
|
const { location } = useAppSelector(selectCart);
|
|
const [isMapBottomSheetOpen, setIsMapBottomSheetOpen] = useState(false);
|
|
const { orderType } = useAppSelector(selectCart);
|
|
const [userLocation, setUserLocation] = useState<LocationData | null>(null);
|
|
|
|
const handleLocationSave = useCallback(
|
|
(locationString: string) => {
|
|
try {
|
|
const locationData = JSON.parse(locationString) as LocationData;
|
|
dispatch(updateLocation(locationData));
|
|
} catch (error) {
|
|
console.error("Failed to parse location data:", error);
|
|
}
|
|
},
|
|
[dispatch],
|
|
);
|
|
|
|
const handleMapBottomSheetOpen = useCallback(() => {
|
|
setIsMapBottomSheetOpen(true);
|
|
}, []);
|
|
|
|
const handleMapBottomSheetClose = useCallback(() => {
|
|
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(
|
|
() => {
|
|
if (location) {
|
|
return JSON.stringify(location);
|
|
}
|
|
if (userLocation) {
|
|
return JSON.stringify(userLocation);
|
|
}
|
|
return "";
|
|
},
|
|
[location, userLocation],
|
|
);
|
|
|
|
const shouldRender = useMemo(
|
|
() => orderType === OrderType.Delivery,
|
|
[orderType],
|
|
);
|
|
|
|
if (!shouldRender) {
|
|
return null;
|
|
}
|
|
|
|
return (
|
|
<>
|
|
<Card
|
|
title={t("address.locationDetails")}
|
|
extra={
|
|
<Button
|
|
type="primary"
|
|
size="small"
|
|
onClick={handleMapBottomSheetOpen}
|
|
style={{
|
|
boxShadow: "none",
|
|
}}
|
|
>
|
|
{location
|
|
? t("address.changeLocation")
|
|
: t("address.selectLocation")}
|
|
</Button>
|
|
}
|
|
className={styles.addressCard}
|
|
>
|
|
{!location ? (
|
|
<div className={styles.noLocationContainer}>
|
|
<ProText type="secondary">
|
|
{t("address.noLocationSelected")}
|
|
</ProText>
|
|
<br />
|
|
<ProText type="secondary" className={styles.smallTextStyle}>
|
|
{t("address.clickEditToSelect")}
|
|
</ProText>
|
|
</div>
|
|
) : (
|
|
<div className={styles.mapContainer}>
|
|
<GoogleMap
|
|
readOnly={true}
|
|
initialLocation={location}
|
|
height="160px"
|
|
/>
|
|
</div>
|
|
)}
|
|
</Card>
|
|
|
|
<MapBottomSheet
|
|
isOpen={isMapBottomSheetOpen}
|
|
onClose={handleMapBottomSheetClose}
|
|
initialValue={initialValue}
|
|
onSave={handleLocationSave}
|
|
initialLocation={location || userLocation || undefined}
|
|
/>
|
|
</>
|
|
);
|
|
};
|