feat(ui): add current number of B+R, taxi, ticket machine and ticket office stations

This commit is contained in:
dancingCycle 2023-08-01 14:06:45 +02:00
parent cddb3de560
commit 8633192150
11 changed files with 207 additions and 87 deletions

View File

@ -1,9 +1,8 @@
import React from 'react'; import React from 'react';
import { BrowserRouter as Router, Link, Route, Routes } from 'react-router-dom'; import { BrowserRouter as Router, Link, Route, Routes } from 'react-router-dom';
import Entity from './pages/entity';
import Home from './pages/home'; import Home from './pages/home';
import TrainStation from './pages/train-station';
import ParkRide from './pages/park-ride';
export default function App(){ export default function App(){
return ( return (
@ -11,8 +10,12 @@ export default function App(){
<Router> <Router>
<Routes> <Routes>
<Route path='/' element={<Home/>}/> <Route path='/' element={<Home/>}/>
<Route path='/park-ride' element={<ParkRide/>}/> <Route path='/bike-ride' element={<Entity apiRoute='bike-ride/info' title='B+R Stations'/>}/>
<Route path='/train-station' element={<TrainStation/>}/> <Route path='/park-ride' element={<Entity apiRoute='park-ride/info' title='P+R Stations'/>}/>
<Route path='/taxi' element={<Entity apiRoute='taxi/info' title='Taxi Stations'/>}/>
<Route path='/ticket-machine' element={<Entity apiRoute='ticket-machine/info' title='Ticket Machines'/>}/>
<Route path='/ticket-office' element={<Entity apiRoute='ticket-office/info' title='Ticket Offices'/>}/>
<Route path='/train-station' element={<Entity apiRoute='train-station/info' title='Train Stations'/>}/>
</Routes> </Routes>
</Router> </Router>
</div> </div>

View File

@ -7,7 +7,7 @@ import Map from './map';
import Table from './table'; import Table from './table';
/*destructure props object*/ /*destructure props object*/
export default function Fetch ({route}) { export default function Fetch ({route, title}) {
const [array, setArray] = useState([]); const [array, setArray] = useState([]);
@ -16,17 +16,16 @@ export default function Fetch ({route}) {
if(config && route){ if(config && route){
try { try {
//console.log("Fetch:fetch(): route: " + route); //console.log("Fetch:fetch(): route: " + route);
/*TODO handle errors: https://www.valentinog.com/blog/await-react/*/ /*TODO handle errors: https://www.valentinog.com/blog/await-react/*/
//fetch data only if user selection is unequal default value const address = `${config.API}${route}`;
const address = `${config.API}${route}`; //console.log("Fetch:fetch(): address: "+address);
//console.log("Fetch:fetch(): address: "+address); const res = await axios.get(address);
const res = await axios.get(address); //console.log("Fetch:fetch(): res.length: "+res.data.length);
//console.log("Fetch:fetch(): res.length: "+res.data.length); setArray((array) => res.data);
setArray((array) => res.data); } catch (err) {
} catch (err) { console.error('err.message: ' + err.message);
console.error('err.message: ' + err.message); setArray((array) => []);
setArray((array) => []); }
}
}else{ }else{
console.error('config or route NOT available'); console.error('config or route NOT available');
} }
@ -46,9 +45,11 @@ export default function Fetch ({route}) {
<> <>
<Map <Map
array={array} array={array}
title={title}
/> />
<Table <Table
array={array} array={array}
title={title}
/> />
</> </>
); );
@ -61,5 +62,6 @@ export default function Fetch ({route}) {
} }
}; };
Fetch.propTypes = { Fetch.propTypes = {
route: PropTypes.string route: PropTypes.string,
title: PropTypes.string
}; };

View File

@ -4,12 +4,12 @@ import PropTypes from 'prop-types';
import EntitiesMap from './map/entities-map'; import EntitiesMap from './map/entities-map';
/*destructure props object*/ /*destructure props object*/
export default function Map ({array}){ export default function Map ({array, title}){
if (array !== undefined || array !== null || array.length > 0) { if (array !== undefined || array !== null || array.length > 0) {
/*return a React element*/ /*return a React element*/
return ( return (
<> <>
<h2>Map of Train Stations</h2> <h2>Map of {title}</h2>
<EntitiesMap entities={array} /> <EntitiesMap entities={array} />
</> </>
); );
@ -22,5 +22,6 @@ export default function Map ({array}){
} }
}; };
Map.propTypes = { Map.propTypes = {
array: PropTypes.array array: PropTypes.array,
title: PropTypes.string
}; };

View File

@ -1,4 +1,4 @@
/*set up the height of*/ /*set up the height of*/
.leaflet-container { .leaflet-container {
height: 45vh; height: 75vh;
} }

View File

@ -10,12 +10,14 @@ import EntitiesMarker from './entities-marker';
export default function EntitiesMap({entities}) { export default function EntitiesMap({entities}) {
/*lat and lon of Braunschweig,DE*/ /*lat and lon of Braunschweig,DE*/
const position = [52.26594, 10.52673] //const position = [52.26594, 10.52673];
/*center map in the middle of RVB*/
const position = [52.16594, 10.52673];
return ( return (
<> <>
<MapContainer <MapContainer
center={position} center={position}
zoom={8} zoom={9}
minZoom={4} minZoom={4}
maxZoom={18} maxZoom={18}
maxBounds={[[-60, -180], [85, 180]]} maxBounds={[[-60, -180], [85, 180]]}

View File

@ -4,13 +4,13 @@ import PropTypes from 'prop-types';
import TableEntries from './table-entries'; import TableEntries from './table-entries';
/*destructure props object*/ /*destructure props object*/
export default function Table ({array}){ export default function Table ({array, title}){
if (array !== undefined || array !== null || array.length > 0) { if (array !== undefined || array !== null || array.length > 0) {
/*return a React element*/ /*return a React element*/
return ( return (
<> <>
<h2>Table</h2> <h2>Table of {title}</h2>
<table> <table>
<thead> <thead>
<tr> <tr>
<th>id</th> <th>id</th>
@ -23,18 +23,19 @@ export default function Table ({array}){
<tbody> <tbody>
<TableEntries array={array} /> <TableEntries array={array} />
</tbody> </tbody>
</table> </table>
</> </>
); );
}else{ }else{
return ( return (
<> <>
<h2>Table</h2> <h2>Table of {title}</h2>
<p>Table loading...</p> <p>Table loading...</p>
</> </>
); );
} }
}; };
Table.propTypes = { Table.propTypes = {
array: PropTypes.array array: PropTypes.array,
title: PropTypes.string
}; };

View File

@ -1,9 +1,10 @@
import React from 'react' import React from 'react'
import PropTypes from 'prop-types';
import { Link} from 'react-router-dom'; import { Link} from 'react-router-dom';
import Fetch from '../components/fetch'; import Fetch from '../components/fetch';
export default function ParkRide() { export default function Entity({apiRoute, title}) {
return( return(
<> <>
<Link <Link
@ -13,10 +14,14 @@ export default function ParkRide() {
Home Home
</button> </button>
</Link> </Link>
<h1>RVB Display</h1>
<Fetch <Fetch
route='park-ride/info' route={apiRoute}
title={title}
/> />
</> </>
); );
}; };
Entity.propTypes = {
apiRoute: PropTypes.string,
title: PropTypes.string
};

View File

@ -2,12 +2,27 @@ import React, { useState, useEffect } from 'react'
import { Link} from 'react-router-dom'; import { Link} from 'react-router-dom';
import '../style.css'; import '../style.css';
import {getBusStopCount, getParkRideCount, getTrainStationCount} from '../utils/api'; import {getBusStopCount, getBikeRideCount, getParkRideCount, getTrainStationCount, getTaxiCount, getTicketMachineCount, getTicketOfficeCount} from '../utils/api';
export default function Home(){ export default function Home(){
const [bikeRideCount, setBikeRideCount] = useState('loading...');
const [busStopCount, setBusStopCount] = useState('loading...'); const [busStopCount, setBusStopCount] = useState('loading...');
const [parkRideCount, setParkRideCount] = useState('loading...'); const [parkRideCount, setParkRideCount] = useState('loading...');
const [taxiCount, setTaxiCount] = useState('loading...');
const [ticketMachineCount, setTicketMachineCount] = useState('loading...');
const [ticketOfficeCount, setTicketOfficeCount] = useState('loading...');
const [trainStationCount, setTrainStationCount] = useState('loading...'); const [trainStationCount, setTrainStationCount] = useState('loading...');
const fetchBikeRideCount = async () => {
try {
const rsp=await getBikeRideCount();
setBikeRideCount((bikeRideCount) => rsp);
} catch (err) {
console.error('err.message: ' + err.message);
setBikeRideCount((bikeRideCount) => 'loading...');
}
};
const fetchBusStopCount = async () => { const fetchBusStopCount = async () => {
try { try {
const rsp=await getBusStopCount(); const rsp=await getBusStopCount();
@ -28,6 +43,36 @@ export default function Home(){
} }
}; };
const fetchTaxiCount = async () => {
try {
const rsp=await getTaxiCount();
setTaxiCount((taxiCount) => rsp);
} catch (err) {
console.error('err.message: ' + err.message);
setTaxiCount((taxiCount) => 'loading...');
}
};
const fetchTicketMachineCount = async () => {
try {
const rsp=await getTicketMachineCount();
setTicketMachineCount((ticketMachineCount) => rsp);
} catch (err) {
console.error('err.message: ' + err.message);
setTicketMachineCount((ticketMachineCount) => 'loading...');
}
};
const fetchTicketOfficeCount = async () => {
try {
const rsp=await getTicketOfficeCount();
setTicketOfficeCount((ticketOfficeCount) => rsp);
} catch (err) {
console.error('err.message: ' + err.message);
setTicketOfficeCount((ticketOfficeCount) => 'loading...');
}
};
const fetchTrainStationCount = async () => { const fetchTrainStationCount = async () => {
try { try {
const rsp=await getTrainStationCount(); const rsp=await getTrainStationCount();
@ -41,8 +86,12 @@ export default function Home(){
useEffect(() => { useEffect(() => {
/*effect goes here*/ /*effect goes here*/
fetchBusStopCount(); fetchBusStopCount();
fetchBikeRideCount();
fetchParkRideCount(); fetchParkRideCount();
fetchTicketMachineCount();
fetchTicketOfficeCount();
fetchTrainStationCount(); fetchTrainStationCount();
fetchTaxiCount();
}, []); }, []);
return ( return (
@ -54,20 +103,58 @@ export default function Home(){
Home Home
</button> </button>
</Link> </Link>
<Link
to='https://www.swingbe.de/imprint/'
>
<button>
Imprint
</button>
</Link>
<Link
to='https://www.swingbe.de/privacy-policy/'
>
<button>
Privacy Policy
</button>
</Link>
<h1>RVB Display</h1> <h1>RVB Display</h1>
<h2>Wellcome to the RVB Display!</h2> <h2>Wellcome to the RVB Display!</h2>
<h3>Number of bus stops in the RVB area: {busStopCount}</h3> <h3>Number of bike and ride (B&R) stations in the RVB area: {bikeRideCount}</h3>
<h3>Number of train stations in the RVB area: {trainStationCount}</h3>
<Link <Link
to={'/train-station'} to={'/bike-ride'}
> >
<button>Map of Train Stations</button> <button>Details for B&R Stations</button>
</Link> </Link>
<h3>Number of bus stops in the RVB area: {busStopCount}</h3>
<h3>Number of park and ride (P&R) stations in the RVB area: {parkRideCount}</h3> <h3>Number of park and ride (P&R) stations in the RVB area: {parkRideCount}</h3>
<Link <Link
to={'/park-ride'} to={'/park-ride'}
> >
<button>Map of P&R Stations</button> <button>Details for P&R Stations</button>
</Link>
<h3>Number of taxi stations in the RVB area: {taxiCount}</h3>
<Link
to={'/taxi'}
>
<button>Details for Taxi Stations</button>
</Link>
<h3>Number of ticket machines in the RVB area: {ticketMachineCount}</h3>
<Link
to={'/ticket-machine'}
>
<button>Details for Ticket Machines</button>
</Link>
<h3>Number of ticket offices in the RVB area: {ticketOfficeCount}</h3>
<Link
to={'/ticket-office'}
>
<button>Details for Ticket Offices</button>
</Link>
<h3>Number of train stations in the RVB area: {trainStationCount}</h3>
<Link
to={'/train-station'}
>
<button>Details for Train Stations</button>
</Link> </Link>
</> </>
); );

View File

@ -1,19 +0,0 @@
import React from 'react'
import { Link} from 'react-router-dom';
export default function Map() {
return(
<>
<Link
to='/'
>
<button>
Home
</button>
</Link>
<h1>RVB Display</h1>
<h2>Wellcome to the RVB Display!</h2>
<h3>Map</h3>
</>
);
};

View File

@ -1,22 +0,0 @@
import React from 'react'
import { Link} from 'react-router-dom';
import Fetch from '../components/fetch';
export default function TrainStation() {
return(
<>
<Link
to='/'
>
<button>
Home
</button>
</Link>
<h1>RVB Display</h1>
<Fetch
route='train-station/info'
/>
</>
);
};

View File

@ -40,6 +40,25 @@ export async function getParkRideCount(){
return count; return count;
}; };
/*
*get count of bike and ride (B&R)
*/
export async function getBikeRideCount(){
//console.log('getBikeRideCount() Start...');
let count=null;
try {
//TODO handle errors: https://www.valentinog.com/blog/await-react/
const address = `${config.API}bike-ride/count`;
const rsp = await axios.get(address);
count = rsp.data[0][0];
} catch (err) {
console.error('err.message: ' + err.message);
}
//console.log('getBikeRideCount() Done.');
return count;
};
/* /*
*get count of train stations *get count of train stations
*/ */
@ -60,20 +79,61 @@ export async function getTrainStationCount(){
}; };
/* /*
*get all train stations *get count of taxi stations
*/ */
export async function getTrainStationInfo(){ export async function getTaxiCount(){
//console.log('getTrainStationInfo() Start...'); //console.log('getTaxiCount() Start...');
let count=null; let count=null;
try { try {
//TODO handle errors: https://www.valentinog.com/blog/await-react/ //TODO handle errors: https://www.valentinog.com/blog/await-react/
const address = `${config.API}train-station/count`; const address = `${config.API}taxi/count`;
//console.log('getTaxiCount() address: ' + address);
const rsp = await axios.get(address); const rsp = await axios.get(address);
console.log('getTrainStationInfo() rsp.length: ' +rsp.length); count = rsp.data[0][0];
} catch (err) { } catch (err) {
console.error('err.message: ' + err.message); console.error('err.message: ' + err.message);
} }
//console.log('getTrainStationInfo() Done.'); //console.log('getTaxiCount() Done.');
return null; return count;
};
/*
*get count of ticket machines
*/
export async function getTicketMachineCount(){
//console.log('getTicketMachineCount() Start...');
let count=null;
try {
//TODO handle errors: https://www.valentinog.com/blog/await-react/
const address = `${config.API}ticket-machine/count`;
//console.log('getTicketMachineCount() address: ' + address);
const rsp = await axios.get(address);
count = rsp.data[0][0];
} catch (err) {
console.error('err.message: ' + err.message);
}
//console.log('getTicketMachineCount() Done.');
return count;
};
/*
*get count of ticket offices
*/
export async function getTicketOfficeCount(){
//console.log('getTicketOfficeCount() Start...');
let count=null;
try {
//TODO handle errors: https://www.valentinog.com/blog/await-react/
const address = `${config.API}ticket-office/count`;
//console.log('getTicketOfficeCount() address: ' + address);
const rsp = await axios.get(address);
count = rsp.data[0][0];
} catch (err) {
console.error('err.message: ' + err.message);
}
//console.log('getTicketOfficeCount() Done.');
return count;
}; };