From 30736be332cbc2b583f1ca2de62c18df2b2b4830 Mon Sep 17 00:00:00 2001
From: juhomakkonen <69158965+juhomakkonen@users.noreply.github.com>
Date: Thu, 11 Apr 2024 14:08:33 +0300
Subject: [PATCH] Feature/barbecue places (#234)
* Show barbecue places on the map
* Use correct icons
* Render info about barbecue places
* Use new hook to fetch data of barbecue places
* Add info text & update translations
---
.../BarbecuePlaces/BarbecuePlaces.js | 46 ++++++++++++++++
.../BarbecuePlacesContent.js | 52 +++++++++++++++++++
.../components/BarbecuePlacesContent/index.js | 3 ++
.../MobilityPlatform/BarbecuePlaces/index.js | 3 ++
src/context/MobilityPlatformContext.js | 3 ++
src/i18n/en.js | 3 ++
src/i18n/fi.js | 3 ++
src/i18n/sv.js | 5 +-
.../MobilityPlatformMapView.js | 2 +
.../MobilitySettingsView.js | 28 +++++++++-
10 files changed, 146 insertions(+), 2 deletions(-)
create mode 100644 src/components/MobilityPlatform/BarbecuePlaces/BarbecuePlaces.js
create mode 100644 src/components/MobilityPlatform/BarbecuePlaces/components/BarbecuePlacesContent/BarbecuePlacesContent.js
create mode 100644 src/components/MobilityPlatform/BarbecuePlaces/components/BarbecuePlacesContent/index.js
create mode 100644 src/components/MobilityPlatform/BarbecuePlaces/index.js
diff --git a/src/components/MobilityPlatform/BarbecuePlaces/BarbecuePlaces.js b/src/components/MobilityPlatform/BarbecuePlaces/BarbecuePlaces.js
new file mode 100644
index 000000000..5ee035823
--- /dev/null
+++ b/src/components/MobilityPlatform/BarbecuePlaces/BarbecuePlaces.js
@@ -0,0 +1,46 @@
+/* eslint-disable react-hooks/exhaustive-deps */
+import React, { useEffect } from 'react';
+import { useMap } from 'react-leaflet';
+import { useSelector } from 'react-redux';
+import barbecuePlaceIconBw from 'servicemap-ui-turku/assets/icons/contrast/icons-icon_barbecue_place-bw.svg';
+import barbecuePlaceIcon from 'servicemap-ui-turku/assets/icons/icons-icon_barbecue_place.svg';
+import { useMobilityPlatformContext } from '../../../context/MobilityPlatformContext';
+import { useAccessibleMap } from '../../../redux/selectors/settings';
+import useMobilityDataFetch from '../utils/useMobilityDataFetch';
+import { createIcon, isDataValid, fitToMapBounds } from '../utils/utils';
+import MarkerComponent from '../MarkerComponent';
+import BarbecuePlacesContent from './components/BarbecuePlacesContent';
+
+const BarbecuePlaces = () => {
+ const options = {
+ type_name: 'BarbecuePlace',
+ };
+
+ const { showBarbecuePlaces } = useMobilityPlatformContext();
+
+ const map = useMap();
+
+ const useContrast = useSelector(useAccessibleMap);
+
+ const { icon } = global.L;
+
+ const customIcon = icon(createIcon(useContrast ? barbecuePlaceIconBw : barbecuePlaceIcon));
+
+ const { data } = useMobilityDataFetch(options, showBarbecuePlaces);
+ const renderData = isDataValid(showBarbecuePlaces, data);
+
+ useEffect(() => {
+ fitToMapBounds(renderData, data, map);
+ }, [showBarbecuePlaces, data]);
+
+ return (renderData
+ ? data.map(item => (
+
+
+
+ ))
+ : null
+ );
+};
+
+export default BarbecuePlaces;
diff --git a/src/components/MobilityPlatform/BarbecuePlaces/components/BarbecuePlacesContent/BarbecuePlacesContent.js b/src/components/MobilityPlatform/BarbecuePlaces/components/BarbecuePlacesContent/BarbecuePlacesContent.js
new file mode 100644
index 000000000..e71f1d8d6
--- /dev/null
+++ b/src/components/MobilityPlatform/BarbecuePlaces/components/BarbecuePlacesContent/BarbecuePlacesContent.js
@@ -0,0 +1,52 @@
+import PropTypes from 'prop-types';
+import React from 'react';
+import { Typography } from '@mui/material';
+import { useIntl } from 'react-intl';
+import styled from '@emotion/styled';
+
+const BarbecuePlacesContent = ({ item }) => {
+ const intl = useIntl();
+ return (
+
+
+
+ {intl.formatMessage({ id: 'mobilityPlatform.content.barbecuePlace.title' })}
+
+
+
+
+ {`${item.extra.malli.trim()} (${item.extra.valmistaja})`}
+
+
+
+ );
+};
+
+const StyledContainer = styled.div(({ theme }) => ({
+ margin: theme.spacing(1),
+}));
+
+const StyledHeader = styled.div(({ theme }) => ({
+ width: '85%',
+ borderBottom: '1px solid #000',
+ paddingBottom: theme.spacing(0.5),
+}));
+
+const StyledText = styled.div(({ theme }) => ({
+ marginTop: theme.spacing(0.5),
+}));
+
+BarbecuePlacesContent.propTypes = {
+ item: PropTypes.shape({
+ extra: PropTypes.shape({
+ malli: PropTypes.string,
+ valmistaja: PropTypes.string,
+ }),
+ }),
+};
+
+BarbecuePlacesContent.defaultProps = {
+ item: {},
+};
+
+export default BarbecuePlacesContent;
diff --git a/src/components/MobilityPlatform/BarbecuePlaces/components/BarbecuePlacesContent/index.js b/src/components/MobilityPlatform/BarbecuePlaces/components/BarbecuePlacesContent/index.js
new file mode 100644
index 000000000..93d6a21f8
--- /dev/null
+++ b/src/components/MobilityPlatform/BarbecuePlaces/components/BarbecuePlacesContent/index.js
@@ -0,0 +1,3 @@
+import BarbecuePlacesContent from './BarbecuePlacesContent';
+
+export default BarbecuePlacesContent;
diff --git a/src/components/MobilityPlatform/BarbecuePlaces/index.js b/src/components/MobilityPlatform/BarbecuePlaces/index.js
new file mode 100644
index 000000000..ac19a0091
--- /dev/null
+++ b/src/components/MobilityPlatform/BarbecuePlaces/index.js
@@ -0,0 +1,3 @@
+import BarbecuePlaces from './BarbecuePlaces';
+
+export default BarbecuePlaces;
diff --git a/src/context/MobilityPlatformContext.js b/src/context/MobilityPlatformContext.js
index aa9de8073..2c1713146 100644
--- a/src/context/MobilityPlatformContext.js
+++ b/src/context/MobilityPlatformContext.js
@@ -103,6 +103,7 @@ const MobilityPlatformContextProvider = ({ children }) => {
const [showUnderpasses, setShowUnderpasses] = useState(false);
const [showPublicBenches, setShowPublicBenches] = useState(false);
const [showRoadworks, setShowRoadworks] = useState(false);
+ const [showBarbecuePlaces, setShowBarbecuePlaces] = useState(false);
const getters = {
openMobilityPlatform,
@@ -172,6 +173,7 @@ const MobilityPlatformContextProvider = ({ children }) => {
showUnderpasses,
showPublicBenches,
showRoadworks,
+ showBarbecuePlaces,
};
const setters = {
@@ -242,6 +244,7 @@ const MobilityPlatformContextProvider = ({ children }) => {
setShowOverpasses,
setShowPublicBenches,
setShowRoadworks,
+ setShowBarbecuePlaces,
};
const contextValues = { ...getters, ...setters };
diff --git a/src/i18n/en.js b/src/i18n/en.js
index 4717311c5..3efcd5543 100644
--- a/src/i18n/en.js
+++ b/src/i18n/en.js
@@ -802,6 +802,7 @@ const translations = {
'mobilityPlatform.menu.show.railwayStations': 'Railway stations',
'mobilityPlatform.menu.show.airMonitoring': 'Air quality stations',
'mobilityPlatform.menu.show.parkAndRideBikes': 'Park and ride stops for bicycles',
+ 'mobilityPlatform.menu.show.barbecuePlaces': 'Sites for barbequing & making fire',
// Content
'mobilityPlatform.content.general.provider': 'Service provider: {value}',
@@ -908,6 +909,7 @@ const translations = {
'mobilityPlatform.content.departingTrains.empty': 'No departing trains',
'mobilityPlatform.content.arrivingTrains.empty': 'No incoming trains',
'mobilityPlatform.parkAndRide.content.subtitle': 'Park and ride stop for bicycles',
+ 'mobilityPlatform.content.barbecuePlace.title': 'Site for barbequing or making fire',
// Info text
'mobilityPlatform.info.description.title': 'Route description',
@@ -968,6 +970,7 @@ const translations = {
'mobilityPlatform.info.airMonitoring.paragraph.3': 'Air quality data for the service map is obtained from the Turku region air protection co-operative group.',
'mobilityPlatform.info.airMonitoring.link': 'For more information visit https://en.ilmatieteenlaitos.fi/air-quality',
'mobilityPlatform.info.parkAndRideBicycles': 'Park-and-ride arrangements provide the opportunity to leave your bicycle parked safely and hop on a bus to continue your journey. The Föli area boasts many park-and-ride sites for bicycles. Park-and-ride parking is free and intended for those using public transport for connections.',
+ 'mobilityPlatform.info.barbecuePlaces': 'The map shows official sites for barbequing or making fire. Making a fire on the land administered by Turku City is allowed only on places designated for making an open flame. Making a fire on any other place than the official campfire and barbeque sites is always forbidden.',
// Bicycle routes
'mobilityPlatform.menu.bicycleRoutes.euroVelo': 'The EuroVelo 10, is the European cycle route that stretches along the Finnish costal line. The distance between Helsinki and Turku has roadside directions for the route.',
diff --git a/src/i18n/fi.js b/src/i18n/fi.js
index 83a5c7a15..c80337b96 100644
--- a/src/i18n/fi.js
+++ b/src/i18n/fi.js
@@ -807,6 +807,7 @@ const translations = {
'mobilityPlatform.menu.show.railwayStations': 'Rautatieasemat',
'mobilityPlatform.menu.show.airMonitoring': 'Ilmanlaadun mittauspisteet',
'mobilityPlatform.menu.show.parkAndRideBikes': 'Liityntäpysäkit pyörille',
+ 'mobilityPlatform.menu.show.barbecuePlaces': 'Grillaus- ja tulentekopaikat',
// Content
'mobilityPlatform.content.general.provider': 'Palveluntarjoaja: {value}',
@@ -903,6 +904,7 @@ const translations = {
'mobilityPlatform.content.departingTrains.empty': 'Ei lähteviä junia',
'mobilityPlatform.content.arrivingTrains.empty': 'Ei saapuvia junia',
'mobilityPlatform.parkAndRide.content.subtitle': 'Liityntäpysäkki pyörille',
+ 'mobilityPlatform.content.barbecuePlace.title': 'Grillaus- ja tulentekopaikka',
// Info text
'mobilityPlatform.info.description.title': 'Tietoja reitistä',
@@ -963,6 +965,7 @@ const translations = {
'mobilityPlatform.info.airMonitoring.paragraph.3': 'Palvelukartan ilmanlaatutiedot saadaan Turun seudun ilmansuojelun yhteistyöryhmältä.',
'mobilityPlatform.info.airMonitoring.link': 'Lisätietoja saa osoitteesta https://www.ilmatieteenlaitos.fi/ilmanlaatu',
'mobilityPlatform.info.parkAndRideBicycles': 'Liityntäpysäköinti tarjoaa mahdollisuuden jättää oma pyörä parkkiin ja jatkaa matkaa bussilla. Föli-alueella on useita liityntäpysäköintipaikkoja pyörille. Liityntäpysäköinti on maksutonta ja tarkoitettu vain joukkoliikennettä vaihtoyhteytenä käyttäville.',
+ 'mobilityPlatform.info.barbecuePlaces': 'Kartalla näkyvät Turun viralliset tulenteko- ja grillauspaikat. Turun kaupungin hallinnoimilla mailla tulenteko on sallittu ainoastaan avotulen tekoon tarkoitetuilla paikoilla. Muilla kuin virallisilla nuotio- ja grillauspaikoilla avotulen teko on aina kielletty.',
// Bicycle routes
'mobilityPlatform.menu.bicycleRoutes.euroVelo': 'EuroVelo 10 on eurooppalainen Suomen rannikkoa seuraava polkupyöräreitti. Helsingin ja Turun välisellä matkalla reitti on merkitty opastein.',
diff --git a/src/i18n/sv.js b/src/i18n/sv.js
index eb942f088..44f034757 100644
--- a/src/i18n/sv.js
+++ b/src/i18n/sv.js
@@ -806,6 +806,7 @@ const translations = {
'mobilityPlatform.menu.show.roadworks': 'Vägarbeten',
'mobilityPlatform.menu.show.railwayStations': 'Järnvägsstationer',
'mobilityPlatform.menu.show.parkAndRideBikes': 'Infartsparkering för cyklar',
+ 'mobilityPlatform.menu.show.barbecuePlaces': 'Grill- och eldningsplatser',
// Content
'mobilityPlatform.content.general.provider': 'Tjänsteleverantör: {value}',
@@ -912,6 +913,7 @@ const translations = {
'mobilityPlatform.content.departingTrains.empty': 'Inga avgående tåg',
'mobilityPlatform.content.arrivingTrains.empty': 'Inga inkommande tåg',
'mobilityPlatform.parkAndRide.content.subtitle': 'Infartspark for cyklarna',
+ 'mobilityPlatform.content.barbecuePlace.title': 'Grill- och eldningplats',
// Info text
'mobilityPlatform.info.description.title': 'Beskrivning av rutten',
@@ -959,7 +961,7 @@ const translations = {
'mobilityPlatform.info.parkingMachines': 'Kartan visar de parkeringsautomater som ägs av Åbo stad. Bankkort och kontaktlös betalning används som betalningsmetoder i alla automater. Du kan se mer information om maskinen genom att trycka på ikonen på kartan.',
'mobilityPlatform.info.publicParkingSpaces': 'Allmänna parkeringsplatser visas på kartan. Det finns dock ingen information om deras utnyttjandegrad. Mer detaljerad information om det valda parkeringsområdet kan läsas genom att trycka på området på kartan.',
'mobilityPlatform.info.outdoorGymDevices': 'Åbo stad upprätthåller utomhusgym. De erbjuder ett roligt sätt att träna medan du njuter av den friska luften. På de utomhusgym som finns runt om i staden kan du träna hela kroppen. Overhead-remskivor, benpressar, armhävningar, surf- och promenadutrustning passar alla. Fler utmaningar erbjuds av armhävningsräcket, dip, magplanka och ryggbänk.',
- 'mobilityPlatform.info.crosswalks': 'Kartan visar placeringen av övergångsställen inne i Åbo stad. Zooma in på kartan för att se övergångsställen.',
+ 'mobilityPlatform.info.crosswalks': 'Kartan visar placeringarna av övergångsställen inne i Åbo stad. Zooma in på kartan för att se övergångsställen.',
'mobilityPlatform.info.short.crosswalks': 'Kartan visar övergångsställen inne i Åbo.',
'mobilityPlatform.info.busStops': 'Kartan visar Åboregionens kollektivtrafiks, Fölis, busshållplatser. Om du kilckar på ikonen kan du se nästa buss som går från hållplatsen. Zooma in på kartan för att se hållplatserna. Datan kommer från gränssnittet som underhålls av Digitransit.',
'mobilityPlatform.info.underAndOverpasses': 'Kartan visar gångtunnlar och gångbroar som ligger i Åbo stadsområdet.',
@@ -972,6 +974,7 @@ const translations = {
'mobilityPlatform.info.airMonitoring.paragraph.3': 'Luftkvalitetsdata för Servicekartan erhålls från Åboregionens samarbetsgrupp för luftskydd.',
'mobilityPlatform.info.airMonitoring.link': 'För mer information besök: https://sv.ilmatieteenlaitos.fi/luftkvalitet',
'mobilityPlatform.info.parkAndRideBicycles': 'Infartsparkeringen erbjuder möjlighet att lämna din egen cykel på parkeringsplatsen och fortsätta resan med buss. Inom Föli-området finns flera infartsparkeringsplatser för cyklar. Infartsparkeringen är gratis och endast avsedd för dem som fortsätter sin resa med kollektivtrafik.',
+ 'mobilityPlatform.info.barbecuePlaces': 'Kartan visar eldnings- och grillplatser i Åbo. Det är tillåtet att göra upp öppen eld endast vid särskilt avsedda eldningsplatser. Att göra upp eld på andra platser är förbjudet.',
// Bicycle routes
'mobilityPlatform.menu.bicycleRoutes.euroVelo': 'EuroVelo 10 är en europeisk cykelrutt som följer den finländska kusten. Sträckan mellan Helsingfors och Åbo är skyltad.',
diff --git a/src/views/MobilityPlatformMapView/MobilityPlatformMapView.js b/src/views/MobilityPlatformMapView/MobilityPlatformMapView.js
index 918e8c499..d445d8948 100644
--- a/src/views/MobilityPlatformMapView/MobilityPlatformMapView.js
+++ b/src/views/MobilityPlatformMapView/MobilityPlatformMapView.js
@@ -38,6 +38,7 @@ import Roadworks from '../../components/MobilityPlatform/Roadworks';
import RailwayStations from '../../components/MobilityPlatform/RailwayStations';
import AirMonitoring from '../../components/MobilityPlatform/EnvironmentObservations/AirMonitoring';
import ParkAndRideBikes from '../../components/MobilityPlatform/ParkAndRideStops/ParkAndRideBikes';
+import BarbecuePlaces from '../../components/MobilityPlatform/BarbecuePlaces';
const MobilityPlatformMapView = ({ mapObject }) => (
<>
@@ -79,6 +80,7 @@ const MobilityPlatformMapView = ({ mapObject }) => (
+
>
);
diff --git a/src/views/MobilitySettingsView/MobilitySettingsView.js b/src/views/MobilitySettingsView/MobilitySettingsView.js
index 5046655d1..1965cc769 100644
--- a/src/views/MobilitySettingsView/MobilitySettingsView.js
+++ b/src/views/MobilitySettingsView/MobilitySettingsView.js
@@ -172,6 +172,8 @@ const MobilitySettingsView = ({ classes, intl, navigator }) => {
setShowAirMonitoringStations,
showParkAndRideBikes,
setShowParkAndRideBikes,
+ showBarbecuePlaces,
+ setShowBarbecuePlaces,
} = useMobilityPlatformContext();
const locale = useSelector(state => state.user.locale);
@@ -346,7 +348,16 @@ const MobilitySettingsView = ({ classes, intl, navigator }) => {
checkVisibilityValues(showUnderpasses, setOpenWalkSettings);
checkVisibilityValues(showOverpasses, setOpenWalkSettings);
checkVisibilityValues(showPublicBenches, setOpenWalkSettings);
- }, [showPublicToilets, showOutdoorGymDevices, showCrossWalks, showUnderpasses, showOverpasses, showPublicBenches]);
+ checkVisibilityValues(showBarbecuePlaces, setOpenWalkSettings);
+ }, [
+ showPublicToilets,
+ showOutdoorGymDevices,
+ showCrossWalks,
+ showUnderpasses,
+ showOverpasses,
+ showPublicBenches,
+ showBarbecuePlaces,
+ ]);
useEffect(() => {
checkVisibilityValues(showTrafficCounter.walking, setOpenWalkSettings);
@@ -842,6 +853,10 @@ const MobilitySettingsView = ({ classes, intl, navigator }) => {
setShowParkAndRideBikes(current => !current);
};
+ const barbecuePlacesToggle = () => {
+ setShowBarbecuePlaces(current => !current);
+ };
+
const cultureRouteListToggle = () => {
setOpenCultureRouteList(current => !current);
if (cultureRouteId) {
@@ -1175,6 +1190,12 @@ const MobilitySettingsView = ({ classes, intl, navigator }) => {
checkedValue: showPublicBenches,
onChangeValue: publicBenchesToggle,
},
+ {
+ type: 'barbecuePlaces',
+ msgId: 'mobilityPlatform.menu.show.barbecuePlaces',
+ checkedValue: showBarbecuePlaces,
+ onChangeValue: barbecuePlacesToggle,
+ },
{
type: 'cultureRoutes',
msgId: 'mobilityPlatform.menu.showCultureRoutes',
@@ -1594,6 +1615,11 @@ const MobilitySettingsView = ({ classes, intl, navigator }) => {
type: 'publicBenchesInfo',
component: ,
},
+ {
+ visible: showBarbecuePlaces,
+ type: 'barbecuePlacesInfo',
+ component: ,
+ },
{
visible: openMarkedTrailsList,
type: 'markedTrailsListInfo',