diff --git a/package-lock.json b/package-lock.json index 1c11e3d..6a10470 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,6 +10,7 @@ "dependencies": { "bootstrap": "^5.3.2", "bootstrap-icons": "^1.11.1", + "geolib": "^3.3.4", "i18next": "^23.7.6", "i18next-browser-languagedetector": "^7.2.0", "i18next-http-backend": "^2.4.2", @@ -1932,6 +1933,11 @@ "node": ">=6.9.0" } }, + "node_modules/geolib": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/geolib/-/geolib-3.3.4.tgz", + "integrity": "sha512-EicrlLLL3S42gE9/wde+11uiaYAaeSVDwCUIv2uMIoRBfNJCn8EsSI+6nS3r4TCKDO6+RQNM9ayLq2at+oZQWQ==" + }, "node_modules/get-intrinsic": { "version": "1.2.2", "dev": true, diff --git a/package.json b/package.json index 102f5fc..4849c65 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ "dependencies": { "bootstrap": "^5.3.2", "bootstrap-icons": "^1.11.1", + "geolib": "^3.3.4", "i18next": "^23.7.6", "i18next-browser-languagedetector": "^7.2.0", "i18next-http-backend": "^2.4.2", @@ -48,4 +49,4 @@ "prettier": "3.0.3", "vite": "^4.4.5" } -} \ No newline at end of file +} diff --git a/public/locales/en/translation.json b/public/locales/en/translation.json index ce1afb5..f35955c 100644 --- a/public/locales/en/translation.json +++ b/public/locales/en/translation.json @@ -44,7 +44,9 @@ "Varauksen tiedot": "Rent details", "Palaute": "Feedback", + "Jos haluat nähdä, kuinka kaukana asemat ovat sijainnistasi, ota sijaintilupa käyttöön selaimessasi.": "To view how far the stations are from your location, please enable location permission in your browser.", "Valitse asemat": "Select stations", + "Valitse kaikki asemat": "Select all stations", "Tuotevalinta & Päivämäärä": "Product & Date Selection", "Käyttäjän tiedot": "User information", "Maksaminen": "Payment", diff --git a/public/locales/fi/translation.json b/public/locales/fi/translation.json index 06a353c..3f8c80f 100644 --- a/public/locales/fi/translation.json +++ b/public/locales/fi/translation.json @@ -44,7 +44,9 @@ "Varauksen tiedot": "Varauksen tiedot", "Palaute": "Palaute", + "Jos haluat nähdä, kuinka kaukana asemat ovat sijainnistasi, ota sijaintilupa käyttöön selaimessasi.": "Jos haluat nähdä, kuinka kaukana asemat ovat sijainnistasi, ota sijaintilupa käyttöön selaimessasi.", "Valitse asemat": "Valitse asemat", + "Valitse kaikki asemat": "Valitse kaikki asemat", "Tuotevalinta & Päivämäärä": "Tuotevalinta & Päivämäärä", "Käyttäjän tiedot": "Käyttäjän tiedot", "Maksaminen": "Maksaminen", diff --git a/public/locales/sv/translation.json b/public/locales/sv/translation.json index 4e3967a..a788f9c 100644 --- a/public/locales/sv/translation.json +++ b/public/locales/sv/translation.json @@ -44,7 +44,9 @@ "Varauksen tiedot": "Hyresuppgifter", "Palaute": "Återkoppling", + "Jos haluat nähdä, kuinka kaukana asemat ovat sijainnistasi, ota sijaintilupa käyttöön selaimessasi.": "För att se hur långt stationerna är från din plats, vänligen aktivera platsbehörighet i din webbläsare.", "Valitse asemat": "Välj stationer", + "Valitse kaikki asemat": "Välj alla stationer", "Tuotevalinta & Päivämäärä": "Val av produkt och datum", "Käyttäjän tiedot": "Användarinformation", "Maksaminen": "Betalning", diff --git a/src/components/StationList.jsx b/src/components/StationList.jsx index 54842a3..65d4b71 100644 --- a/src/components/StationList.jsx +++ b/src/components/StationList.jsx @@ -9,18 +9,54 @@ import { useNavigate } from 'react-router'; import { ChevronCompactRight } from 'react-bootstrap-icons'; import { useStepper } from '../hooks/useStepper'; import PopUpWarningModal from './PopUpWarningModal'; -import { useState } from 'react'; +import { useEffect, useState } from 'react'; import { useTranslation } from 'react-i18next'; +import { getDistance } from 'geolib'; const StationList = ({ onStationSelected, handleWarningModal }) => { const [showWarningModal, setShowWarningModal] = useState(false); const [allSelected, setAllSelected] = useState(false); + const [userLocation, setUserLocation] = useState({}); + const [distance, setDistance] = useState([]); const { stationsData, setStationsData } = useStepper(); const { t } = useTranslation(); const navigate = useNavigate(); + // getting the user location and updating it every 5 seconds + useEffect(() => { + navigator.geolocation.getCurrentPosition(function (position) { + setUserLocation({ + latitude: position.coords.latitude, + longitude: position.coords.longitude, + }); + }); + + const intervalId = setInterval(() => { + navigator.geolocation.getCurrentPosition(function (position) { + setUserLocation({ + latitude: position.coords.latitude, + longitude: position.coords.longitude, + }); + }); + }, 5000); + + return () => clearInterval(intervalId); + }, []); + + // calculating the distance between user and stations and converting it to km + useEffect(() => { + if (userLocation.latitude && userLocation.longitude) { + stationsData.forEach((location) => { + const distance = (getDistance(userLocation, location) / 1000).toFixed( + 2, + ); + setDistance((prev) => [...prev, distance]); + }); + } + }, [userLocation]); + // handle the button click for selecting a station const handleSubmit = () => { if ( @@ -51,9 +87,7 @@ const StationList = ({ onStationSelected, handleWarningModal }) => { // handling the checkbox changes for a specific station const handleCheckbox = (index) => { - if (allSelected) { - return; - } + if (allSelected) return; const updatedStations = [...stationsData]; updatedStations[index].selected = !updatedStations[index].selected; @@ -74,6 +108,13 @@ const StationList = ({ onStationSelected, handleWarningModal }) => { />
+ {!distance.length && ( + + {t( + 'Jos haluat nähdä, kuinka kaukana asemat ovat sijainnistasi, ota sijaintilupa käyttöön selaimessasi.', + )} + + )} {stationsData.map((station, index) => ( {

{station.stationName}

- - - -

10 km

- {station.trailer && ( - trailer icon - )} - {station.cargoBike && ( - cargo bike icon + {distance[index] && ( + <> + + + + +

{distance[index]} km

+ )} +
+ {station.trailer && ( + trailer icon + )} + {station.cargoBike && ( + cargo bike icon + )} +
handleCheckbox(index)} value="station" @@ -127,7 +175,7 @@ const StationList = ({ onStationSelected, handleWarningModal }) => { ))} -

Valitse kaikki asemat

+

{t('Valitse kaikki asemat')}

{ cargoBike: true, trailer: true, selected: false, + latitude: 60.32061898389687, + longitude: 24.993732557209405, }, { stationName: 'Konala', @@ -19,6 +21,8 @@ export const StepperProvider = ({ children }) => { cargoBike: false, trailer: true, selected: false, + latitude: 60.25360884865695, + longitude: 24.836624427068696, }, { stationName: 'Kivikko', @@ -26,6 +30,8 @@ export const StepperProvider = ({ children }) => { cargoBike: true, trailer: false, selected: false, + latitude: 60.23686341263375, + longitude: 25.05107185536083, }, { stationName: 'Jorvas', @@ -33,6 +39,8 @@ export const StepperProvider = ({ children }) => { cargoBike: false, trailer: true, selected: false, + latitude: 60.13714913277058, + longitude: 24.523249868537707, }, { stationName: 'Ämmässuo', @@ -40,13 +48,17 @@ export const StepperProvider = ({ children }) => { cargoBike: true, trailer: true, selected: false, + latitude: 60.24107750488621, + longitude: 24.540993611186675, }, { - stationName: 'Koivusuo', + stationName: 'Koivukylä', timeSlots: ['15-16', '11-14', '12-15', '13-16', '14-17', '15-18'], cargoBike: true, trailer: false, selected: false, + latitude: 60.31712294344029, + longitude: 25.061342971463368, }, ]); const [selectedProduct, setSelectedProduct] = useState(''); diff --git a/src/css/StationList.module.css b/src/css/StationList.module.css index 31314a3..3cd3307 100644 --- a/src/css/StationList.module.css +++ b/src/css/StationList.module.css @@ -23,7 +23,6 @@ #trailer { margin: 0 4px 0 4px; height: 24px; - margin: 0 4px 0 4px; width: 33px; filter: drop-shadow(3px 2px 3px rgb(0 0 0 / 0.2)); } @@ -31,6 +30,13 @@ margin-left: auto; } +.stationListNote { + width: 50%; + color: gray; + font-size: 0.8rem; + font-family: sans-serif; + font-style: italic; +} .allCheckboxContainer { display: flex; justify-content: flex-end;