diff --git a/packages/web/src/components/Map/Map.jsx b/packages/web/src/components/Map/Map.jsx
index a75e8e3..840d84f 100644
--- a/packages/web/src/components/Map/Map.jsx
+++ b/packages/web/src/components/Map/Map.jsx
@@ -1,10 +1,10 @@
import {
- useState,
- useRef,
- useMemo,
+ useCallback,
useContext,
useEffect,
- useCallback,
+ useMemo,
+ useRef,
+ useState,
} from "react";
// import { useMapEvents } from "react-leaflet/hooks";
// import mapuser from "../../assets/logos/mapuser.svg";
@@ -14,36 +14,35 @@ import L from "leaflet";
import "leaflet/dist/leaflet.css";
import Fuse from "fuse.js";
-import { othersDrag, flyImg, iconsMap } from "./MapIcons";
+import { flyImg, iconsMap, othersDrag } from "./MapIcons";
import {
+ Circle,
MapContainer,
- TileLayer,
Marker,
Popup,
- useMap,
Rectangle,
- Circle,
+ TileLayer,
+ useMap,
useMapEvents,
} from "react-leaflet";
-import { useDisclosure, useColorMode } from "@chakra-ui/react";
+import { useColorMode, useDisclosure } from "@chakra-ui/react";
import InfoModal from "../InfoModal/InfoModal";
import DataContext from "../../context/DataContext";
import { UserAuth } from "../../context/AuthContext";
import axios from "axios";
-import imageCompression from 'browser-image-compression';
+import imageCompression from "browser-image-compression";
import { filterItem } from "../../utils/Utils.js";
-import MarkerClusterGroup from 'react-leaflet-cluster'
-import { createClusterCustomIcon } from './MapIcons';
+import MarkerClusterGroup from "react-leaflet-cluster";
+import { createClusterCustomIcon } from "./MapIcons";
/**
* Map is uses react-leaflet's API to communicate user actions to map entities and information
*
* @component
*
- *
* @prop {number[]} focusLocation - coordinates to move map view to and zoom in on
* @prop {string} search - search bar query
* @prop {boolean} isEdit - if in Edit mode (i.e. user is trying to create a marker)
@@ -53,8 +52,6 @@ import { createClusterCustomIcon } from './MapIcons';
* @prop {number} centerPosition - center of map coordinates
* @prop {object} findFilter - search filters
*
- *
- *
* @returns {JSX.Element} Leaflet Map component
*/
@@ -85,6 +82,7 @@ export default function Map({
// State: itemData - currently selected item
// ! (doesn't erase when clicked off of previously selected item)
const [itemData, setItemData] = useState({});
+
// State: showDonut - if red ring around selected marker shows
const [showDonut, setShowDonut] = useState(false);
@@ -132,7 +130,7 @@ export default function Map({
const filterItemCallback = useCallback(
(item) => filterItem(item, findFilter, user),
- [findFilter, user]
+ [findFilter, user],
);
const markersData = results.length > 0 ? results : data;
@@ -148,12 +146,11 @@ export default function Map({
setFocusLocation(item.location);
},
}}
- icon={
- item.isresolved
- ? iconsMap["resolved"][item.islost]
- : (iconsMap[item.type] || iconsMap["others"])[item.islost]
- }
- >
+ icon={item.isresolved
+ ? iconsMap["resolved"][item.islost]
+ : (iconsMap[item.type] || iconsMap["others"])[item.islost]}
+ >
+
));
}, [markersData, filterItemCallback, onOpen, setItemData, setFocusLocation]);
@@ -164,9 +161,11 @@ export default function Map({
map.flyTo(location, 18);
}
- return location ? (
- // ? there is no fly image??
- ) : null;
+ return location
+ ? (
+ // ? there is no fly image??
+ )
+ : null;
}
const markerRef = useRef(null);
@@ -180,7 +179,7 @@ export default function Map({
}
},
}),
- [setPosition]
+ [setPosition],
);
async function handleSubmit() {
const date = new Date();
@@ -191,8 +190,14 @@ export default function Map({
useWebWorker: true,
fileType: "image/jpeg",
};
+ if (!token) {
+ return;
+ }
try {
- const compressedFile = await imageCompression(newAddedItem.image, options);
+ const compressedFile = await imageCompression(
+ newAddedItem.image,
+ options,
+ );
const response = await fetch(
`${import.meta.env.VITE_REACT_APP_AWS_BACKEND_URL}/upload/image`,
{
@@ -201,20 +206,19 @@ export default function Map({
headers: {
"Content-Type": "image/jpeg",
},
- }
+ },
);
if (!response.ok) {
throw new Error("Failed to upload file");
}
const data = await response.json();
- newAddedItem.image = data.url;
+ console.log("Image uploaded:", data.url);
+ setNewAddedItem((prev) => ({ ...prev, image: data.url }));
+ setUploadImg(data.url);
} catch (err) {
console.error("Error uploading image:", err);
}
}
- if (!token) {
- return;
- }
axios
.post(
`${import.meta.env.VITE_REACT_APP_AWS_BACKEND_URL}/items`,
@@ -235,7 +239,7 @@ export default function Map({
headers: {
Authorization: `Bearer ${token}`, // verify auth
},
- }
+ },
)
.then((item) => {
const newItem = {
@@ -281,7 +285,7 @@ export default function Map({
headers: {
Authorization: `Bearer ${token}`, // verify auth
},
- }
+ },
);
setLeaderboard((prev) =>
@@ -298,6 +302,14 @@ export default function Map({
}
const toggleDraggable = () => {
+ if (position.lat == null || position.lng == null) {
+ alert(
+ "Latitude and longitude cannot be null. Please pick a valid location.",
+ );
+ setPosition({ lat: centerPosition[0], lng: centerPosition[1] }); // Reset position to center
+ return;
+ }
+
if (!bounds.contains(position)) {
alert("ITEM OUT OF BOUNDS (UCI ONLY)");
return;
@@ -318,7 +330,7 @@ export default function Map({
map.fitBounds(bounds);
},
}),
- [map]
+ [map],
);
return (
@@ -332,10 +344,9 @@ export default function Map({
);
}
- const mapUrl =
- colorMode === "dark"
- ? import.meta.env.VITE_REACT_APP_MAPBOX_DARK_URL
- : "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png";
+ const mapUrl = colorMode === "dark"
+ ? import.meta.env.VITE_REACT_APP_MAPBOX_DARK_URL
+ : "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png";
const NewItemMarker = () => {
useMapEvents({
@@ -345,22 +356,24 @@ export default function Map({
});
return position.lat !== centerPosition[0] &&
- position.lng !== centerPosition[1] ? (
-
-
- toggleDraggable()}>
- Click to Confirm Location 🤔
-
-
-
- ) : null;
+ position.lng !== centerPosition[1]
+ ? (
+
+
+ toggleDraggable()}>
+ Click to Confirm Location 🤔
+
+
+
+ )
+ : null;
};
const createCluster = useMemo(() => {
@@ -369,7 +382,7 @@ export default function Map({
chunkedLoading: true,
iconCreateFunction: (cluster) => {
return createClusterCustomIcon(cluster, colorMode);
- }
+ },
};
}, [colorMode]); // Make sure colorMode is in dependency array