All files / src/features/MerchantPortal/Customer/Modals/components CustomerLocation.tsx

90.47% Statements 19/21
93.1% Branches 27/29
80% Functions 4/5
90% Lines 18/20

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112                                                  112x 112x 112x   112x     112x       112x     112x   112x                                                         53x 53x 112x 109x 706x 52x 109x 109x     53x                                                 53x            
import useLoadGoogleScript from "@hooks/google-api/useLoadGoogleScript";
import { Stack } from "@mui/material";
import { GoogleMaps } from "@services/google-api";
import GiveText from "@shared/Text/GiveText";
import { Address } from "types/customer.types";
import { styled, useAppTheme } from "@theme/v2/Provider";
import { MinusIcon, PlusIcon } from "@phosphor-icons/react";
import GiveIconButton from "@shared/IconButton/GiveIconButton";
import { useCustomThemeV2 } from "@theme/hooks/useCustomThemeV2";
import { useMarkerGoogleMapsProps } from "@hooks/useMarkerGoogleMapsProps";
 
interface Props extends Address {
  lastKnownLatitude?: number;
  lastKnownLongitude?: number;
  locationString?: string;
  hideTitle?: boolean;
}
 
export default function CustomerLocation({
  address,
  lastKnownLatitude,
  lastKnownLongitude,
  hideTitle = false,
  locationString,
}: Props) {
  const { isLoaded, loadError } = useLoadGoogleScript();
  const { isMobileView } = useCustomThemeV2();
  const markerGoogleMapsProps = useMarkerGoogleMapsProps();
 
  const stringAddress = getStringAddress({ address });
 
  const coordinatesProps =
    lastKnownLatitude && lastKnownLatitude && !stringAddress && !locationString
      ? { lat: lastKnownLatitude ?? 0, lng: lastKnownLongitude ?? 0 }
      : undefined;
 
  const isWorldMap = Boolean(
    !stringAddress && !coordinatesProps && !locationString,
  );
  const defaultAddress = isWorldMap ? "Gibraltar" : "";
 
  return (
    <Stack gap="16px">
      {!hideTitle && (
        <GiveText data-testid="customer-location" variant="bodyM">
          Location
        </GiveText>
      )}
 
      <GoogleMaps
        address={locationString || stringAddress || defaultAddress}
        coordinates={coordinatesProps}
        isLoaded={isLoaded}
        loadError={loadError}
        containerStyle={{
          height: "184px",
          borderRadius: "20px",
          minHeight: "184px",
          width: "100%",
          position: "relative",
        }}
        viewMarker={!isWorldMap}
        initialZoom={isWorldMap ? 1.3 : 16}
        {...markerGoogleMapsProps}
        {...(!isMobileView && { CustomZoomControl })}
      />
    </Stack>
  );
}
 
const excludedKeys = ["id", "name", "createdAt", "updatedAt"];
const getStringAddress = ({ address }: Address) => {
  if (!address) return "";
  const addressValues = Object.entries(address)
    .filter(([key, value]) => !excludedKeys.includes(key) && !!value)
    .map(([, value]) => value);
  const stringValue = addressValues.join(", ");
  return stringValue;
};
 
const CustomZoomControl = ({
  onZoomIn,
  onZoomOut,
}: {
  onZoomIn: () => void;
  onZoomOut: () => void;
}) => {
  const { palette } = useAppTheme();
 
  return (
    <Stack
      style={{
        position: "absolute",
        bottom: 10,
        right: 10,
        backgroundColor: palette.common.white,
        borderRadius: "8px",
      }}
    >
      <StyledZoomButton onClick={onZoomIn} Icon={PlusIcon} />
      <StyledZoomButton onClick={onZoomOut} Icon={MinusIcon} />
    </Stack>
  );
};
 
const StyledZoomButton = styled(GiveIconButton)({
  backgroundColor: "transparent",
  boxShadow: "none",
  "&:hover": {
    backgroundColor: "transparent",
  },
});