diff --git a/app/assets/Logo_SIB_electricindigo.svg b/app/assets/Logo_SIB_electricindigo.svg
new file mode 100644
index 0000000..458e73e
--- /dev/null
+++ b/app/assets/Logo_SIB_electricindigo.svg
@@ -0,0 +1,35 @@
+
+
+
diff --git a/app/components/map.jsx b/app/components/map.jsx
index fff0a12..52f991b 100644
--- a/app/components/map.jsx
+++ b/app/components/map.jsx
@@ -1,10 +1,18 @@
import React from 'react';
+import PropTypes from 'prop-types';
+
+import EntitiesMap from './map/entities-map';
//destructure props
-export default function Map(){
+export default function Map({entities}){
return (
<>
-
Map
+ Map
+ Entity Map
+
>
);
}
+Map.propTypes = {
+ entities: PropTypes.array,
+};
diff --git a/app/components/map/entities-map.css b/app/components/map/entities-map.css
new file mode 100644
index 0000000..747a5bb
--- /dev/null
+++ b/app/components/map/entities-map.css
@@ -0,0 +1,4 @@
+/*set up the height of*/
+.leaflet-container {
+ height: 85vh;
+}
diff --git a/app/components/map/entities-map.jsx b/app/components/map/entities-map.jsx
new file mode 100644
index 0000000..8a9ce5a
--- /dev/null
+++ b/app/components/map/entities-map.jsx
@@ -0,0 +1,46 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import {MapContainer,TileLayer} from 'react-leaflet';
+
+/*JS module import (vs cdn or style link)*/
+import 'leaflet/dist/leaflet.css'
+import './entities-map.css';
+
+import EntitiesMarker from './entities-marker';
+
+export default function EntitiesMap({entities}) {
+ /*lat and lon of Braunschweig,DE*/
+ const position = [52.26594, 10.52673]
+ //TODO make this switch available via configuration!
+ const hasGtfs = false;
+ return (
+ <>
+
+
+ {
+ entities.map(function(value,key) {
+ //console.log(`key: ${key}, tripId: ${value.tripId}`);
+ return ;
+ })
+ }
+
+ >
+ );
+}
+EntitiesMap.propTypes = {
+ entities: PropTypes.array
+};
diff --git a/app/components/map/entities-marker-plus.jsx b/app/components/map/entities-marker-plus.jsx
new file mode 100644
index 0000000..b8bc570
--- /dev/null
+++ b/app/components/map/entities-marker-plus.jsx
@@ -0,0 +1,48 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import {Marker} from 'react-leaflet';
+
+import PopupElem from './entities-popup';
+import getIcon from './icon';
+
+export default function EntitiesMarkerPlus({name,lat,lon}){
+ if(lat===undefined || lat===null || lon===undefined || lon===null){
+ console.error('lat or lon undefined or null');
+ return null;
+ }else{
+ const markerIcon=getIcon();
+ if(markerIcon===null){
+ //TODO Handle issue!
+ console.error('ERROR: icon null');
+ return null;
+ }else if(lat===undefined||lat===null){
+ //TODO Handle issue!
+ console.error('ERROR: lat undefined or null');
+ return null;
+ }else if(lon===undefined||lon===null){
+ //TODO Handle issue!
+ console.error('ERROR: lon undefined or null');
+ return null;
+ }else{
+ return(
+ <>
+
+
+
+ >
+ );
+ }
+ }
+};
+EntitiesMarkerPlus.propTypes = {
+ name: PropTypes.string,
+ lat: PropTypes.string,
+ lon: PropTypes.string
+};
diff --git a/app/components/map/entities-marker.jsx b/app/components/map/entities-marker.jsx
new file mode 100644
index 0000000..cf7a4a7
--- /dev/null
+++ b/app/components/map/entities-marker.jsx
@@ -0,0 +1,26 @@
+import React, {useEffect,useState} from 'react';
+import PropTypes from 'prop-types';
+
+import EntitiesMarkerPlus from './entities-marker-plus';
+
+export default function EntitiesMarker({name,lat,lon}){
+ if(lat===undefined || lat===null || lon===undefined || lon===null){
+ console.error('lat or lon undefined or null');
+ return null;
+ }else{
+ return(
+ <>
+
+ >
+ );
+ }
+};
+EntitiesMarker.propTypes = {
+ name: PropTypes.string,
+ lat: PropTypes.string,
+ lon: PropTypes.string
+};
diff --git a/app/components/map/entities-popup.jsx b/app/components/map/entities-popup.jsx
new file mode 100644
index 0000000..311e13e
--- /dev/null
+++ b/app/components/map/entities-popup.jsx
@@ -0,0 +1,20 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import {Popup} from 'react-leaflet';
+
+export default function EntitiesPopup({name,lat,lon}){
+ return (
+ <>
+
+ name: {name}
+ lat: {lat}
+ lon: {lon}
+
+ >
+ );
+};
+EntitiesPopup.propTypes = {
+ name: PropTypes.string,
+ lat: PropTypes.string,
+ lon: PropTypes.string
+};
diff --git a/app/components/map/icon.js b/app/components/map/icon.js
new file mode 100644
index 0000000..3b24a5e
--- /dev/null
+++ b/app/components/map/icon.js
@@ -0,0 +1,28 @@
+import bfly from '../../assets/Logo_SIB_electricindigo.svg';
+
+/*return icon object*/
+export default function getIcon(){
+ //console.log('getIcon(): ptByIfleet available')
+ const icon = new L.Icon({
+ /*path to icon graphic*/
+ iconUrl: bfly,
+ /*path to graphic used for high resolution monitors*/
+ iconRetinaUrl: bfly,
+ popupAnchor: [-0, -0],
+ /*size of the icon in width and hight*/
+ iconSize: [32,32],
+ /*determine how the popup is positions relative to the actual point on the map*/
+ popupAnchor:[0,-10],
+ /*determine how the image is positions relative to the actual point on the map*/
+ iconAnchor: null,
+ /*path to shadow graphic*/
+ shadowUrl: null,
+ /*size of the shadow in width and hight*/
+ shadowSize: null,
+ /*determine how the mage is positions relative to the actual point on the map*/
+ shadowAnchor: null,
+ className: 'marker-msg'
+ });
+ //console.log('getIcon(): icon available')
+ return icon;
+}
diff --git a/config/webpack.common.js b/config/webpack.common.js
index 5038060..0337ff7 100644
--- a/config/webpack.common.js
+++ b/config/webpack.common.js
@@ -26,6 +26,18 @@ module.exports = {
test: /\.css$/i,
use: ["style-loader", "css-loader"],
},
+ {
+ //test all *.svg using svg-loader
+ test: /\.svg$/,
+ use: [
+ {
+ loader: 'svg-url-loader',
+ options: {
+ limit: 10000,
+ },
+ },
+ ],
+ },
]
},
resolve: {
diff --git a/package-lock.json b/package-lock.json
index 6e7326c..eac5253 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -9,10 +9,12 @@
"version": "0.1.0",
"license": "GPL-3.0-or-later",
"dependencies": {
- "axios": "^1.3.6",
+ "axios": "1.3.6",
+ "leaflet": "^1.9.3",
"prop-types": "15.8.1",
"react": "18.2.0",
"react-dom": "18.2.0",
+ "react-leaflet": "^4.2.1",
"react-router-dom": "^6.10.0"
},
"devDependencies": {
@@ -20,9 +22,10 @@
"@babel/preset-env": "7.21.4",
"@babel/preset-react": "7.18.6",
"babel-loader": "9.1.2",
- "css-loader": "^6.7.3",
+ "css-loader": "6.7.3",
"html-webpack-plugin": "5.5.1",
- "style-loader": "^3.3.2",
+ "style-loader": "3.3.2",
+ "svg-url-loader": "^8.0.0",
"webpack": "5.80.0",
"webpack-cli": "5.0.1",
"webpack-dev-server": "4.13.3",
@@ -1840,6 +1843,16 @@
"integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==",
"dev": true
},
+ "node_modules/@react-leaflet/core": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/@react-leaflet/core/-/core-2.1.0.tgz",
+ "integrity": "sha512-Qk7Pfu8BSarKGqILj4x7bCSZ1pjuAPZ+qmRwH5S7mDS91VSbVVsJSrW4qA+GPrro8t69gFYVMWb1Zc4yFmPiVg==",
+ "peerDependencies": {
+ "leaflet": "^1.9.0",
+ "react": "^18.0.0",
+ "react-dom": "^18.0.0"
+ }
+ },
"node_modules/@remix-run/router": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.5.0.tgz",
@@ -2458,6 +2471,15 @@
"integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==",
"dev": true
},
+ "node_modules/big.js": {
+ "version": "5.2.2",
+ "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz",
+ "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==",
+ "dev": true,
+ "engines": {
+ "node": "*"
+ }
+ },
"node_modules/binary-extensions": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
@@ -3178,6 +3200,15 @@
"integrity": "sha512-e2aeCAixCj9M7nJxdB/wDjO6mbYX+lJJxSJCXDzlr5YPGYVofuJwGN9nKg2o6wWInjX6XmxRinn3AeJMK81ltw==",
"dev": true
},
+ "node_modules/emojis-list": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz",
+ "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==",
+ "dev": true,
+ "engines": {
+ "node": ">= 4"
+ }
+ },
"node_modules/encodeurl": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
@@ -3466,6 +3497,44 @@
"node": ">=0.8.0"
}
},
+ "node_modules/file-loader": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.2.0.tgz",
+ "integrity": "sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==",
+ "dev": true,
+ "dependencies": {
+ "loader-utils": "^2.0.0",
+ "schema-utils": "^3.0.0"
+ },
+ "engines": {
+ "node": ">= 10.13.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ },
+ "peerDependencies": {
+ "webpack": "^4.0.0 || ^5.0.0"
+ }
+ },
+ "node_modules/file-loader/node_modules/schema-utils": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.2.tgz",
+ "integrity": "sha512-pvjEHOgWc9OWA/f/DE3ohBWTD6EleVLf7iFUkoSwAxttdBhB9QUebQgxER2kWueOvRJXPHNnyrvvh9eZINB8Eg==",
+ "dev": true,
+ "dependencies": {
+ "@types/json-schema": "^7.0.8",
+ "ajv": "^6.12.5",
+ "ajv-keywords": "^3.5.2"
+ },
+ "engines": {
+ "node": ">= 10.13.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ }
+ },
"node_modules/fill-range": {
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
@@ -4252,6 +4321,11 @@
"shell-quote": "^1.7.3"
}
},
+ "node_modules/leaflet": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/leaflet/-/leaflet-1.9.3.tgz",
+ "integrity": "sha512-iB2cR9vAkDOu5l3HAay2obcUHZ7xwUBBjph8+PGtmW/2lYhbLizWtG7nTeYht36WfOslixQF9D/uSIzhZgGMfQ=="
+ },
"node_modules/loader-runner": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz",
@@ -4261,6 +4335,20 @@
"node": ">=6.11.5"
}
},
+ "node_modules/loader-utils": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz",
+ "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==",
+ "dev": true,
+ "dependencies": {
+ "big.js": "^5.2.2",
+ "emojis-list": "^3.0.0",
+ "json5": "^2.1.2"
+ },
+ "engines": {
+ "node": ">=8.9.0"
+ }
+ },
"node_modules/locate-path": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
@@ -5040,6 +5128,19 @@
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
},
+ "node_modules/react-leaflet": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/react-leaflet/-/react-leaflet-4.2.1.tgz",
+ "integrity": "sha512-p9chkvhcKrWn/H/1FFeVSqLdReGwn2qmiobOQGO3BifX+/vV/39qhY8dGqbdcPh1e6jxh/QHriLXr7a4eLFK4Q==",
+ "dependencies": {
+ "@react-leaflet/core": "^2.1.0"
+ },
+ "peerDependencies": {
+ "leaflet": "^1.9.0",
+ "react": "^18.0.0",
+ "react-dom": "^18.0.0"
+ }
+ },
"node_modules/react-router": {
"version": "6.10.0",
"resolved": "https://registry.npmjs.org/react-router/-/react-router-6.10.0.tgz",
@@ -5761,6 +5862,21 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/svg-url-loader": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/svg-url-loader/-/svg-url-loader-8.0.0.tgz",
+ "integrity": "sha512-5doSXvl18hY1fGsRLdhWAU5jgzgxJ06/gc/26cpuDnN0xOz1HmmfhkpL29SSrdIvhtxQ1UwGzmk7wTT/l48mKw==",
+ "dev": true,
+ "dependencies": {
+ "file-loader": "~6.2.0"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "peerDependencies": {
+ "webpack": "^5.0.0"
+ }
+ },
"node_modules/tapable": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz",
@@ -7625,6 +7741,12 @@
"integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==",
"dev": true
},
+ "@react-leaflet/core": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/@react-leaflet/core/-/core-2.1.0.tgz",
+ "integrity": "sha512-Qk7Pfu8BSarKGqILj4x7bCSZ1pjuAPZ+qmRwH5S7mDS91VSbVVsJSrW4qA+GPrro8t69gFYVMWb1Zc4yFmPiVg==",
+ "requires": {}
+ },
"@remix-run/router": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.5.0.tgz",
@@ -8159,6 +8281,12 @@
"integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==",
"dev": true
},
+ "big.js": {
+ "version": "5.2.2",
+ "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz",
+ "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==",
+ "dev": true
+ },
"binary-extensions": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
@@ -8694,6 +8822,12 @@
"integrity": "sha512-e2aeCAixCj9M7nJxdB/wDjO6mbYX+lJJxSJCXDzlr5YPGYVofuJwGN9nKg2o6wWInjX6XmxRinn3AeJMK81ltw==",
"dev": true
},
+ "emojis-list": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz",
+ "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==",
+ "dev": true
+ },
"encodeurl": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
@@ -8915,6 +9049,29 @@
"websocket-driver": ">=0.5.1"
}
},
+ "file-loader": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.2.0.tgz",
+ "integrity": "sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==",
+ "dev": true,
+ "requires": {
+ "loader-utils": "^2.0.0",
+ "schema-utils": "^3.0.0"
+ },
+ "dependencies": {
+ "schema-utils": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.2.tgz",
+ "integrity": "sha512-pvjEHOgWc9OWA/f/DE3ohBWTD6EleVLf7iFUkoSwAxttdBhB9QUebQgxER2kWueOvRJXPHNnyrvvh9eZINB8Eg==",
+ "dev": true,
+ "requires": {
+ "@types/json-schema": "^7.0.8",
+ "ajv": "^6.12.5",
+ "ajv-keywords": "^3.5.2"
+ }
+ }
+ }
+ },
"fill-range": {
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
@@ -9485,12 +9642,28 @@
"shell-quote": "^1.7.3"
}
},
+ "leaflet": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/leaflet/-/leaflet-1.9.3.tgz",
+ "integrity": "sha512-iB2cR9vAkDOu5l3HAay2obcUHZ7xwUBBjph8+PGtmW/2lYhbLizWtG7nTeYht36WfOslixQF9D/uSIzhZgGMfQ=="
+ },
"loader-runner": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz",
"integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==",
"dev": true
},
+ "loader-utils": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz",
+ "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==",
+ "dev": true,
+ "requires": {
+ "big.js": "^5.2.2",
+ "emojis-list": "^3.0.0",
+ "json5": "^2.1.2"
+ }
+ },
"locate-path": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
@@ -10066,6 +10239,14 @@
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
},
+ "react-leaflet": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/react-leaflet/-/react-leaflet-4.2.1.tgz",
+ "integrity": "sha512-p9chkvhcKrWn/H/1FFeVSqLdReGwn2qmiobOQGO3BifX+/vV/39qhY8dGqbdcPh1e6jxh/QHriLXr7a4eLFK4Q==",
+ "requires": {
+ "@react-leaflet/core": "^2.1.0"
+ }
+ },
"react-router": {
"version": "6.10.0",
"resolved": "https://registry.npmjs.org/react-router/-/react-router-6.10.0.tgz",
@@ -10635,6 +10816,15 @@
"integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
"dev": true
},
+ "svg-url-loader": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/svg-url-loader/-/svg-url-loader-8.0.0.tgz",
+ "integrity": "sha512-5doSXvl18hY1fGsRLdhWAU5jgzgxJ06/gc/26cpuDnN0xOz1HmmfhkpL29SSrdIvhtxQ1UwGzmk7wTT/l48mKw==",
+ "dev": true,
+ "requires": {
+ "file-loader": "~6.2.0"
+ }
+ },
"tapable": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz",
diff --git a/package.json b/package.json
index bf31430..0118e3d 100644
--- a/package.json
+++ b/package.json
@@ -25,6 +25,7 @@
"css-loader": "6.7.3",
"html-webpack-plugin": "5.5.1",
"style-loader": "3.3.2",
+ "svg-url-loader": "^8.0.0",
"webpack": "5.80.0",
"webpack-cli": "5.0.1",
"webpack-dev-server": "4.13.3",
@@ -32,9 +33,11 @@
},
"dependencies": {
"axios": "1.3.6",
+ "leaflet": "^1.9.3",
"prop-types": "15.8.1",
"react": "18.2.0",
"react-dom": "18.2.0",
+ "react-leaflet": "^4.2.1",
"react-router-dom": "^6.10.0"
}
}