From 23d83065ad05f5910d2cd32218d3385acfbbd65d Mon Sep 17 00:00:00 2001 From: pro028 Date: Sun, 4 May 2025 00:30:45 +0200 Subject: [PATCH 01/10] small change to the constant popup and zoom when searching and selecting waste --- .idea/misc.xml | 5 --- .../src/main/resources/dev-data/waste.json | 1 - frontend/sortify/components/map.jsx | 36 ++++++++++++++++--- 3 files changed, 31 insertions(+), 11 deletions(-) diff --git a/.idea/misc.xml b/.idea/misc.xml index cd5457df..e8311ab3 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -3,9 +3,4 @@ - - - \ No newline at end of file diff --git a/backend/src/main/resources/dev-data/waste.json b/backend/src/main/resources/dev-data/waste.json index 2f3f1164..eeee5255 100644 --- a/backend/src/main/resources/dev-data/waste.json +++ b/backend/src/main/resources/dev-data/waste.json @@ -134,7 +134,6 @@ {"name": "Skap", "type": "Brennbart avfall", "info": "???"}, {"name": "Seng", "type": "Brennbart avfall", "info": "???"}, {"name": "Madrass", "type": "Brennbart avfall", "info": "???"}, - {"name": "Teppe", "type": "Brennbart avfall", "info": "???"}, {"name": "Speil", "type": "Restavfall", "info": "???"}, {"name": "Sykkel", "type": "Brennbart avfall", "info": "???"}, {"name": "Barnevogn", "type": "Brennbart avfall", "info": "???"}, diff --git a/frontend/sortify/components/map.jsx b/frontend/sortify/components/map.jsx index f54041e6..2e2c0003 100644 --- a/frontend/sortify/components/map.jsx +++ b/frontend/sortify/components/map.jsx @@ -28,6 +28,7 @@ export default function Map({filter}) { const routeLayerRef = useRef(null); const [routeVisible, setRouteVisible] = useState(false); + // For testing purposes console.log("filter: " + filter) // Initialize map only once on component mount @@ -64,7 +65,16 @@ export default function Map({filter}) { ); }, []); - // When both map and location are available, update the map view + // When both map and location are available, mark and zoom onto the users geolocation + useEffect( () => { + if (!mapRef.current || !userLocation) { + console.log("Could not find map or userLocation") + return; + } + createUserMarker(mapRef.current, userLocation); + }, []); + + // Update the displayed users location and the displayed locations, if they have changed useEffect(() => { console.log("Trying to display locations") @@ -135,7 +145,7 @@ export default function Map({filter}) { /** * Places a marker at the user's location and centers the map */ -function updateUserMarker(map, location) { +function createUserMarker(map, location) { if (map._userMarker) { map.removeLayer(map._userMarker); } @@ -149,29 +159,45 @@ function updateUserMarker(map, location) { map.setView([location.lat, location.lon], 17); } +/** + * Updates the userMarkers location + */ +function updateUserMarker(map, location) { + if (map._userMarker) { + map.removeLayer(map._userMarker); + } + + const marker = L.marker([location.lat, location.lon]) + .addTo(map) + + map._userMarker = marker; +} + /** * Fetches nearby locations from the backend, * highlights the nearest, and displays all with markers. */ async function fetchAndDisplayLocations(map, userLocation, setLocations, setNearestLocation, filter) { - console.log("Fetching Locations") + console.log("Fetching Locations: ") try { const res = await fetch(`http://localhost:9876/api/locations/sorted?lat=${userLocation.lat}&lon=${userLocation.lon}`); if (!res.ok) throw new Error("Failed to fetch locations"); let allLocations = await res.json(); setLocations(allLocations); + console.log(allLocations) - // Set filter + // If filter, only keep relevant locations in list if(filter) { console.log("Before filter: " + filter, allLocations) allLocations = allLocations.filter(location => location.wasteTypes.includes(filter)) console.log("After filter: " + filter, allLocations) } - console.log(allLocations) + // If no locations, return if (!allLocations.length) return; + // makes the routing go to the nearest location const nearest = allLocations[0]; setNearestLocation(nearest); From 6c46df054fadafcd7e104a48bfa6c58b53228dcd Mon Sep 17 00:00:00 2001 From: pro028 Date: Sun, 4 May 2025 15:21:09 +0200 Subject: [PATCH 02/10] displaying distance and estimated time for route --- frontend/sortify/components/map.css | 36 ++++++++++++++++ frontend/sortify/components/map.jsx | 67 ++++++++++++++++++++++++----- 2 files changed, 93 insertions(+), 10 deletions(-) create mode 100644 frontend/sortify/components/map.css diff --git a/frontend/sortify/components/map.css b/frontend/sortify/components/map.css new file mode 100644 index 00000000..6cbdc506 --- /dev/null +++ b/frontend/sortify/components/map.css @@ -0,0 +1,36 @@ +/* map.css */ +.map-container { + height: 500px; + width: 800px; + display: flex; + flex-direction: row; + align-items: flex-start; + gap: 20px; +} + +.map { +} + +.route-button { + margin-top: 10px; + margin-right: 10px; +} + +.info-box { + border: 1px solid #ccc; + border-radius: 8px; + padding: 10px; + min-width: 150px; + background: #f9f9f9; + font-size: 14px; +} + +.info-box div { + margin-bottom: 8px; +} + +.info-box button { + margin-top: 10px; + padding: 6px 12px; + cursor: pointer; +} diff --git a/frontend/sortify/components/map.jsx b/frontend/sortify/components/map.jsx index 2e2c0003..045c975d 100644 --- a/frontend/sortify/components/map.jsx +++ b/frontend/sortify/components/map.jsx @@ -3,6 +3,7 @@ import { useEffect, useRef, useState } from "react"; import L from "leaflet"; import "leaflet/dist/leaflet.css"; +import './map.css'; import markerIcon2x from 'leaflet/dist/images/marker-icon-2x.png'; import markerIcon from 'leaflet/dist/images/marker-icon.png'; @@ -27,6 +28,7 @@ export default function Map({filter}) { const routeLayerRef = useRef(null); const [routeVisible, setRouteVisible] = useState(false); + const [routeInfo, setRouteInfo] = useState(null); // For testing purposes console.log("filter: " + filter) @@ -111,6 +113,18 @@ export default function Map({filter}) { const routeData = await routeRes.json(); if (routeData.routes?.length) { + + const distanceMeters = routeData.routes[0].distance; + const durationSeconds = routeData.routes[0].duration; + + setRouteInfo({ + distance: (distanceMeters / 1000).toFixed(2), + duration: (durationSeconds / 60).toFixed(2), + }); + + console.log(`Distance to nearest: ${(distanceMeters / 1000).toFixed(2)} km`); + console.log(`ETA: ${(durationSeconds / 60).toFixed(2)} minutes`); + const geoJSON = routeData.routes[0].geometry; const routeLine = L.geoJSON(geoJSON, { style: { color: 'blue', weight: 4 }, @@ -119,6 +133,24 @@ export default function Map({filter}) { routeLayerRef.current = routeLine; setRouteVisible(true); map.fitBounds(routeLine.getBounds()); + + // Retrieves distance and estimates time for a trip to the destination (driving). + const midpoint = routeLine.getBounds().getCenter(); + + L.popup({ + closeButton: false, + autoClose: false, + className: 'route-popup' + }) + .setLatLng(midpoint) + .setContent(` +
+ Distance: ${(distanceMeters / 1000).toFixed(2)} km
+ ETA: ${(durationSeconds / 60).toFixed(2)} min +
+ `) + .openOn(map); + } } catch (err) { console.error("Error drawing route:", err); @@ -129,16 +161,31 @@ export default function Map({filter}) { // Map component // Button for toggling the route on or off return ( - <> -
- - +
+
+
+ +
+ + + {/* ➕ Interactive Box */} + {routeInfo && ( +
+
Distance: {routeInfo.distance} km
+
ETA: {routeInfo.duration} min
+
+ +
+ )} +
+
+
); } From 2950bba9ca2b9e22c1ee35ffb597ed456c62e3dc Mon Sep 17 00:00:00 2001 From: pro028 Date: Sun, 4 May 2025 16:41:55 +0200 Subject: [PATCH 03/10] added proper styling to info and route finder --- frontend/sortify/components/map.css | 82 +++++++++++++++++++++++++---- frontend/sortify/components/map.jsx | 27 ++-------- 2 files changed, 77 insertions(+), 32 deletions(-) diff --git a/frontend/sortify/components/map.css b/frontend/sortify/components/map.css index 6cbdc506..913bbcaa 100644 --- a/frontend/sortify/components/map.css +++ b/frontend/sortify/components/map.css @@ -1,36 +1,98 @@ /* map.css */ -.map-container { - height: 500px; - width: 800px; + +.container { display: flex; - flex-direction: row; + flex-direction: column; align-items: flex-start; - gap: 20px; + width: 800px; + height: 600px; } .map { + height: 600px; + width: 800px; } +/* Route button with .signupButton styles */ .route-button { - margin-top: 10px; - margin-right: 10px; + display: inline-block; + background-color: #D9996B; + color: #3E4739; + padding: 12px 24px; + border-radius: 30px; + text-decoration: none; + font-weight: 600; + text-transform: uppercase; + font-size: 14px; + transition: all 0.3s ease; + cursor: pointer; + box-sizing: border-box; + border: 2px solid #3E4739; +} + +/* Hover effect for the route button */ +.route-button:hover { + background-color: #B6CBBC; +} + +/* Disabled route button style */ +.route-button:disabled { + background-color: #ddd; + cursor: not-allowed; + border: 2px solid #ccc; } +/* Container for the info box and button */ +.info-box-container { + background-color: #DBBC99; /* Warm beige color for the container */ + padding: 20px; + border-radius: 8px; + margin-top: 20px; + display: flex; + flex-direction: column; + gap: 10px; + max-width: 220px; /* Limit the width of the container */ + width: 100%; /* Makes sure it is responsive */ + margin: 0 auto; /* Centers the container horizontally */ +} + +/* Styling for the info box */ .info-box { - border: 1px solid #ccc; + border: 2px solid #3E4739; /* Dark green border for contrast */ border-radius: 8px; padding: 10px; min-width: 150px; - background: #f9f9f9; + background: #f9f9f9; /* Light background */ font-size: 14px; + color: #3E4739; /* Text color to match the border */ } +/* Info box text spacing */ .info-box div { margin-bottom: 8px; } +/* Button inside the info box */ .info-box button { - margin-top: 10px; + background-color: #D9996B; /* Same background color as route button */ + color: #3E4739; /* Text color */ padding: 6px 12px; cursor: pointer; + font-size: 14px; + border-radius: 30px; + border: 2px solid #3E4739; /* Matching border */ + font-weight: 600; + transition: all 0.3s ease; +} + +/* Hover effect for info box button */ +.info-box button:hover { + background-color: #B6CBBC; /* Lighter color on hover */ +} + +/* Disabled button in info box */ +.info-box button:disabled { + background-color: #ddd; + cursor: not-allowed; + border: 2px solid #ccc; } diff --git a/frontend/sortify/components/map.jsx b/frontend/sortify/components/map.jsx index 045c975d..efb30df9 100644 --- a/frontend/sortify/components/map.jsx +++ b/frontend/sortify/components/map.jsx @@ -134,23 +134,6 @@ export default function Map({filter}) { setRouteVisible(true); map.fitBounds(routeLine.getBounds()); - // Retrieves distance and estimates time for a trip to the destination (driving). - const midpoint = routeLine.getBounds().getCenter(); - - L.popup({ - closeButton: false, - autoClose: false, - className: 'route-popup' - }) - .setLatLng(midpoint) - .setContent(` -
- Distance: ${(distanceMeters / 1000).toFixed(2)} km
- ETA: ${(durationSeconds / 60).toFixed(2)} min -
- `) - .openOn(map); - } } catch (err) { console.error("Error drawing route:", err); @@ -162,24 +145,24 @@ export default function Map({filter}) { // Button for toggling the route on or off return (
-
+
-
+
- {/* ➕ Interactive Box */} + {/* Additional Info */} {routeInfo && (
Distance: {routeInfo.distance} km
ETA: {routeInfo.duration} min
-
+
)} From fcb45dc0bf11c2f48b116eefa5e25f6758238476 Mon Sep 17 00:00:00 2001 From: pro028 Date: Sun, 4 May 2025 16:46:52 +0200 Subject: [PATCH 04/10] put footer in the correct spot --- frontend/sortify/app/mainContent.module.css | 1 + frontend/sortify/components/map.css | 6 ++++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/frontend/sortify/app/mainContent.module.css b/frontend/sortify/app/mainContent.module.css index 6edf2f0a..87eceeb1 100644 --- a/frontend/sortify/app/mainContent.module.css +++ b/frontend/sortify/app/mainContent.module.css @@ -7,6 +7,7 @@ flex-direction: column; align-items: center; margin: 0 auto; + flex-grow: 1; } .title { diff --git a/frontend/sortify/components/map.css b/frontend/sortify/components/map.css index 913bbcaa..2c26382c 100644 --- a/frontend/sortify/components/map.css +++ b/frontend/sortify/components/map.css @@ -6,11 +6,13 @@ align-items: flex-start; width: 800px; height: 600px; + position: relative; } .map { - height: 600px; - width: 800px; + width: 800px; /* Full width of the container */ + height: 500px; /* Fixed height for the map */ + flex-shrink: 0; /* Prevent map from shrinking */ } /* Route button with .signupButton styles */ From 50733d0a6f01e76693701c59802c9bd832b515b9 Mon Sep 17 00:00:00 2001 From: pro028 Date: Sun, 4 May 2025 21:33:14 +0200 Subject: [PATCH 05/10] trying with filters --- frontend/sortify/components/map.css | 39 ++++- frontend/sortify/components/map.jsx | 151 ++++++++++++++++-- .../components/searchbar/searchbar.module.css | 18 ++- .../components/searchbar/searchbar.tsx | 8 +- 4 files changed, 194 insertions(+), 22 deletions(-) diff --git a/frontend/sortify/components/map.css b/frontend/sortify/components/map.css index 2c26382c..691a9c83 100644 --- a/frontend/sortify/components/map.css +++ b/frontend/sortify/components/map.css @@ -5,14 +5,45 @@ flex-direction: column; align-items: flex-start; width: 800px; - height: 600px; position: relative; } +/* Wrap map and filters horizontally */ +.map-and-filters { + display: flex; + flex-direction: row; + width: 100%; +} + +.filter-panel { + background-color: #DBBC99; + padding: 20px; + border-radius: 15px; + border: 2px solid #3E4739; /* Dark green border for consistency */ + max-width: 180px; + box-sizing: border-box; + display: flex; + flex-direction: column; + gap: 10px; + font-size: 14px; + color: #3E4739; + margin-left: 20px; /* Space between map and panel */ + height: 100%; + margin-top: 12px; +} + +/* Optional: Style for each filter checkbox line */ +.filter-panel label { + display: flex; + align-items: center; + gap: 0.5rem; + cursor: pointer; +} + +/* Adjust map width to allow space for filter panel */ .map { - width: 800px; /* Full width of the container */ - height: 500px; /* Fixed height for the map */ - flex-shrink: 0; /* Prevent map from shrinking */ + flex-grow: 1; + height: 500px; } /* Route button with .signupButton styles */ diff --git a/frontend/sortify/components/map.jsx b/frontend/sortify/components/map.jsx index efb30df9..2d36cb89 100644 --- a/frontend/sortify/components/map.jsx +++ b/frontend/sortify/components/map.jsx @@ -30,6 +30,34 @@ export default function Map({filter}) { const [routeVisible, setRouteVisible] = useState(false); const [routeInfo, setRouteInfo] = useState(null); + const [filters, setFilters] = useState({ + "Plast": true, + "Restavfall": false, + "Matavfall": true, + "Papp og papir": false, + "El-avfall": false, + "Klær": false, + "Farlig avfall": false, + "Glass og metall": false, + "Hageavfall": false, + "Brennbart avfall": false + }); + + const toggleFilter = (type) => { + setFilters(prev => ({ + ...prev, + [type]: !prev[type] + })); + }; + + const handleCheckboxChange = (key, isChecked) => { + // Reset local filters when interacting with checkboxes + setFilters(prevFilters => ({ + ...prevFilters, + [key]: isChecked + })); + }; + // For testing purposes console.log("filter: " + filter) @@ -91,9 +119,9 @@ export default function Map({filter}) { userLocation, setLocations, setNearestLocation, - filter + filter, filters, setFilters ); - }, [userLocation, filter]); + }, [userLocation, filter, filters]); // Functionality to toggle the route on or off const toggleRoute = async () => { @@ -146,7 +174,93 @@ export default function Map({filter}) { return (
-
+
+
+
+

Filters

+ + + + + + + + + + + +
+
)}
@@ -207,7 +319,7 @@ function updateUserMarker(map, location) { * Fetches nearby locations from the backend, * highlights the nearest, and displays all with markers. */ -async function fetchAndDisplayLocations(map, userLocation, setLocations, setNearestLocation, filter) { +async function fetchAndDisplayLocations(map, userLocation, setLocations, setNearestLocation, filter, filters, setFilters) { console.log("Fetching Locations: ") try { const res = await fetch(`http://localhost:9876/api/locations/sorted?lat=${userLocation.lat}&lon=${userLocation.lon}`); @@ -216,22 +328,31 @@ async function fetchAndDisplayLocations(map, userLocation, setLocations, setNear let allLocations = await res.json(); setLocations(allLocations); console.log(allLocations) - - // If filter, only keep relevant locations in list - if(filter) { - console.log("Before filter: " + filter, allLocations) - allLocations = allLocations.filter(location => location.wasteTypes.includes(filter)) - console.log("After filter: " + filter, allLocations) - } - // If no locations, return if (!allLocations.length) return; + if (filter) { + allLocations = allLocations.filter(location => + location.wasteTypes.includes(filter) + ); + console.log("After filter: ", allLocations); + } else { + // If no filter, apply the checkbox filters + const selectedFilters = Object.entries(filters) + .filter(([_, isChecked]) => isChecked) + .map(([type]) => type); + + if (selectedFilters.length > 0) { + allLocations = allLocations.filter(location => + location.wasteTypes.some(type => selectedFilters.includes(type)) + ); + } + } + // makes the routing go to the nearest location const nearest = allLocations[0]; setNearestLocation(nearest); - addLocationMarkers(map, allLocations); //showNearestMarker(map, nearest); } catch (err) { diff --git a/frontend/sortify/components/searchbar/searchbar.module.css b/frontend/sortify/components/searchbar/searchbar.module.css index 474ebe97..7d4ad863 100644 --- a/frontend/sortify/components/searchbar/searchbar.module.css +++ b/frontend/sortify/components/searchbar/searchbar.module.css @@ -27,4 +27,20 @@ width: 100%; padding: 0 1rem; box-sizing: border-box; -} \ No newline at end of file +} + +.listItem { + padding: 0.5rem 1rem; + cursor: pointer; + border-radius: 6px; + transition: background-color 0.2s ease, font-weight 0.2s ease; +} + +.listItem:hover { + background-color: #D7D1C8; + font-weight: bold; +} + +.listItem:active { + background-color: #BEB7AC; +} diff --git a/frontend/sortify/components/searchbar/searchbar.tsx b/frontend/sortify/components/searchbar/searchbar.tsx index 9895b6f3..f63109f3 100644 --- a/frontend/sortify/components/searchbar/searchbar.tsx +++ b/frontend/sortify/components/searchbar/searchbar.tsx @@ -105,8 +105,12 @@ export default function Searcbar(){ {queryResult.map((item) => ( - -

setSearch(item.type)}>{item.name}

+ setSearch(item.type)} + > +

{item.name}

))}
From dfe8a21a25020c1fe36b04f98bc827ba1339da8a Mon Sep 17 00:00:00 2001 From: pro028 Date: Mon, 5 May 2025 14:01:39 +0200 Subject: [PATCH 06/10] filters and search works pretty good now --- frontend/sortify/components/map.jsx | 34 ++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/frontend/sortify/components/map.jsx b/frontend/sortify/components/map.jsx index 2d36cb89..68f9caa1 100644 --- a/frontend/sortify/components/map.jsx +++ b/frontend/sortify/components/map.jsx @@ -8,6 +8,7 @@ import './map.css'; import markerIcon2x from 'leaflet/dist/images/marker-icon-2x.png'; import markerIcon from 'leaflet/dist/images/marker-icon.png'; import markerShadow from 'leaflet/dist/images/marker-shadow.png'; +import {useSearch} from "@/app/context/searchContext"; delete L.Icon.Default.prototype._getIconUrl; @@ -30,6 +31,9 @@ export default function Map({filter}) { const [routeVisible, setRouteVisible] = useState(false); const [routeInfo, setRouteInfo] = useState(null); + const { search, setSearch } = useSearch(); + const skipNextSearchEffect = useRef(false); + const [filters, setFilters] = useState({ "Plast": true, "Restavfall": false, @@ -58,9 +62,6 @@ export default function Map({filter}) { })); }; - // For testing purposes - console.log("filter: " + filter) - // Initialize map only once on component mount useEffect(() => { @@ -107,6 +108,12 @@ export default function Map({filter}) { // Update the displayed users location and the displayed locations, if they have changed useEffect(() => { + // Skip this render cycle, used for filtering + if (skipNextSearchEffect.current) { + skipNextSearchEffect.current = false; + return; + } + console.log("Trying to display locations") if (!mapRef.current || !userLocation) { @@ -119,9 +126,9 @@ export default function Map({filter}) { userLocation, setLocations, setNearestLocation, - filter, filters, setFilters + search, setSearch, filters, setFilters, skipNextSearchEffect ); - }, [userLocation, filter, filters]); + }, [userLocation, search, filters]); // Functionality to toggle the route on or off const toggleRoute = async () => { @@ -319,7 +326,7 @@ function updateUserMarker(map, location) { * Fetches nearby locations from the backend, * highlights the nearest, and displays all with markers. */ -async function fetchAndDisplayLocations(map, userLocation, setLocations, setNearestLocation, filter, filters, setFilters) { +async function fetchAndDisplayLocations(map, userLocation, setLocations, setNearestLocation, filter, setFilter, filters, setFilters, skipNextSearchEffect) { console.log("Fetching Locations: ") try { const res = await fetch(`http://localhost:9876/api/locations/sorted?lat=${userLocation.lat}&lon=${userLocation.lon}`); @@ -331,11 +338,18 @@ async function fetchAndDisplayLocations(map, userLocation, setLocations, setNear // If no locations, return if (!allLocations.length) return; - if (filter) { + // Check filter + console.log("Filter value before: " + filter) + + if (filter && filter !== "") { allLocations = allLocations.filter(location => location.wasteTypes.includes(filter) ); - console.log("After filter: ", allLocations); + console.log("Locations after searchbar filter: ", allLocations); + const updatedFilters = Object.fromEntries( + Object.keys(filters).map(type => [type, type === filter]) + ); + setFilters(updatedFilters); } else { // If no filter, apply the checkbox filters const selectedFilters = Object.entries(filters) @@ -348,6 +362,10 @@ async function fetchAndDisplayLocations(map, userLocation, setLocations, setNear ); } } + // Reset filter after use + skipNextSearchEffect.current = true; + setFilter(""); + console.log("Filter value after : " + filter) // makes the routing go to the nearest location const nearest = allLocations[0]; From d2e47eb412fbcaaad3ebad96dfdaa32e50aaa58c Mon Sep 17 00:00:00 2001 From: pro028 Date: Mon, 5 May 2025 14:03:38 +0200 Subject: [PATCH 07/10] removed filter variable from Map --- frontend/sortify/app/page.tsx | 3 +-- frontend/sortify/components/map.jsx | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/frontend/sortify/app/page.tsx b/frontend/sortify/app/page.tsx index 4bf0543e..a19b4488 100644 --- a/frontend/sortify/app/page.tsx +++ b/frontend/sortify/app/page.tsx @@ -6,11 +6,10 @@ const Map = dynamic(() => import('../components/map'), {ssr: false}); import { useSearch } from "@/app/context/searchContext"; export default function Page(){ - const { search } = useSearch(); return(

Recycling map

- +
); } \ No newline at end of file diff --git a/frontend/sortify/components/map.jsx b/frontend/sortify/components/map.jsx index 68f9caa1..7b705faf 100644 --- a/frontend/sortify/components/map.jsx +++ b/frontend/sortify/components/map.jsx @@ -18,7 +18,7 @@ L.Icon.Default.mergeOptions({ shadowUrl: markerShadow.src ?? markerShadow, }); -export default function Map({filter}) { +export default function Map() { // Store references to map and marker instances const mapRef = useRef(null); const markerRef = useRef(null); From 32e47616dd24738566b51e5069d8ca02921d29c2 Mon Sep 17 00:00:00 2001 From: pro028 Date: Mon, 5 May 2025 14:13:24 +0200 Subject: [PATCH 08/10] translated to norwegian --- frontend/sortify/app/page.tsx | 2 +- frontend/sortify/components/map.jsx | 8 ++++---- .../sortify/components/searchbar/searchbar.tsx | 2 +- frontend/sortify/components/signup/signup.tsx | 16 ++++++++-------- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/frontend/sortify/app/page.tsx b/frontend/sortify/app/page.tsx index a19b4488..a848de95 100644 --- a/frontend/sortify/app/page.tsx +++ b/frontend/sortify/app/page.tsx @@ -8,7 +8,7 @@ import { useSearch } from "@/app/context/searchContext"; export default function Page(){ return(
-

Recycling map

+

Gjenvinningskart

); diff --git a/frontend/sortify/components/map.jsx b/frontend/sortify/components/map.jsx index 7b705faf..f77c1714 100644 --- a/frontend/sortify/components/map.jsx +++ b/frontend/sortify/components/map.jsx @@ -184,7 +184,7 @@ export default function Map() {
-

Filters

+

Filter

diff --git a/frontend/sortify/components/map.jsx b/frontend/sortify/components/map.jsx index 0e970c03..e4d30b32 100644 --- a/frontend/sortify/components/map.jsx +++ b/frontend/sortify/components/map.jsx @@ -105,7 +105,11 @@ export default function Map() { let filtered = [...locations]; // Start with all locations + // Debug + console.log(locations) + // Apply search filter if there's a search term + console.log(search) if (search) { filtered = filtered.filter(loc => loc.wasteTypes.includes(search)); const updatedFilters = Object.fromEntries( @@ -305,12 +309,10 @@ function createUserMarker(map, location) { if (map._userMarker) { map.removeLayer(map._userMarker); } - const marker = L.marker([location.lat, location.lon]) .addTo(map) .bindPopup("You are here!") .openPopup(); - map._userMarker = marker; map.setView([location.lat, location.lon], 17); } @@ -322,10 +324,8 @@ function updateUserMarker(map, location) { if (map._userMarker) { map.removeLayer(map._userMarker); } - const marker = L.marker([location.lat, location.lon]) .addTo(map) - map._userMarker = marker; } @@ -335,23 +335,52 @@ function updateUserMarker(map, location) { let currentMarkerGroup = null; function addLocationMarkers(map, locations) { if (currentMarkerGroup) { - map.removeLayer(currentMarkerGroup) + map.removeLayer(currentMarkerGroup); + } + const markerGroup = L.layerGroup().addTo(map); + currentMarkerGroup = markerGroup; + + // Function to determine color based on waste types + function getMarkerColor(wasteTypes) { + // Remove duplicates by converting to a Set + const uniqueWasteTypes = [...new Set(wasteTypes)]; + + if (uniqueWasteTypes.length > 1) { + // If the location handles multiple waste types, set it to blue + return { color: 'blue', fillColor: 'lightgray' }; + } else if (uniqueWasteTypes.includes("Plast")) { + return { color: 'green', fillColor: 'lightgray' }; + } else if (uniqueWasteTypes.includes("Glass og metall")) { + return { color: 'blue', fillColor: 'lightgray' }; + } else if (uniqueWasteTypes.includes("El-avfall")) { + return { color: 'gray', fillColor: 'lightgray' }; + } else if (uniqueWasteTypes.includes("Papp og papir")) { + return { color: 'brown', fillColor: 'lightgray' }; + } else if (uniqueWasteTypes.includes("Restavfall")) { + return { color: 'red', fillColor: 'lightgray' }; + } else { + return { color: 'purple', fillColor: 'lightgray' }; // Default color + } } - const markerGroup = L.layerGroup().addTo(map) - currentMarkerGroup = markerGroup locations.forEach((loc) => { + // Clean up the wasteTypes by removing duplicates + const uniqueWasteTypes = [...new Set(loc.wasteTypes)]; + + // Determine marker color based on wasteTypes + const { color, fillColor } = getMarkerColor(uniqueWasteTypes); + L.circleMarker([loc.latitude, loc.longitude], { radius: 8, - color: 'blue', - fillColor: '#3f51b5', + color: color, // Border color + fillColor: fillColor, // Fill color fillOpacity: 0.8, }) .addTo(markerGroup) .bindPopup(` - ${loc.name}, ${loc.address}
- ${[...new Set(loc.wasteTypes)].join(", ")} -`); + ${loc.name}, ${loc.address}
+ ${uniqueWasteTypes.join(", ")} + `); }); }