chore: lint

This commit is contained in:
dancingCycle 2024-02-15 22:12:28 +01:00
parent f3be1cd91d
commit 787f525e0f
105 changed files with 10445 additions and 4557 deletions

View File

@ -2,5 +2,13 @@
"presets": [
"@babel/preset-env",
"@babel/preset-react"
],
"plugins": [
[
"@babel/plugin-transform-runtime",
{
"regenerator": true
}
]
]
}

9
.eslintrc Normal file
View File

@ -0,0 +1,9 @@
{
"parser": "@babel/eslint-parser",
"extends": ["airbnb"],
"rules": {
"no-tabs": 0,
"no-mixed-spaces-and-tabs": 0
}
}

View File

@ -2,6 +2,7 @@
const HtmlWebpackPlugin = require('html-webpack-plugin');
// path is used to resolve properly across the OS
const path = require('path');
module.exports = {
// bundle *.js from this entry point
entry: path.resolve(__dirname, '../src/index.jsx'),
@ -19,35 +20,23 @@ module.exports = {
test: /\.(js|jsx)$/,
exclude: /node_modules/,
include: path.resolve(__dirname, '../src'),
use: ['babel-loader'],
use: {
loader: 'babel-loader',
options: {
presets: [
'@babel/preset-env',
'@babel/preset-react',
],
},
},
},
{
// test all *.css using style-loader and css-loader
test: /\.css$/i,
use: ["style-loader", "css-loader"],
},
{
//test all *.svg using svg-loader
test: /\.svg$/,
use: [
{
loader: 'svg-url-loader',
options: {
limit: 10000,
},
use: ['style-loader', 'css-loader'],
},
],
},
{
test: /\.(png|jpe?g|gif)$/i,
use: [
{
loader: 'file-loader',
},
],
},
]
},
resolve: {
extensions: ['*', '.js', '.jsx'],
},
@ -55,7 +44,7 @@ module.exports = {
// create a plugin instance so that you can use it several times anywhere
new HtmlWebpackPlugin({
title: 'Production',
template: path.resolve(__dirname, "../public/index.html")
template: path.resolve(__dirname, '../public/index.html'),
}),
],
};

View File

@ -1,7 +1,7 @@
// path is used to resolve properly across the OS
const path = require('path');
const { merge } = require('webpack-merge');
const common = require('./webpack.common.js');
const common = require('./webpack.common');
// merge() calls in the environment-specific configuration to include commons
module.exports = merge(common, {
// set development mode
@ -10,7 +10,11 @@ module.exports = merge(common, {
devtool: 'inline-source-map',
devServer: {
static: path.resolve(__dirname, '../dist'),
//When using the HTML5 History API, the index.html page will likely have to be served in place of any 404 responses. Enable devServer.historyApiFallback by setting it to true.
/*
When using the HTML5 History API,
the index.html page will likely have to be served in place of any 404 responses.
Enable devServer.historyApiFallback by setting it to true.
*/
historyApiFallback: true,
},
});

View File

@ -1,5 +1,6 @@
const { merge } = require('webpack-merge');
const common = require('./webpack.common.js');
const common = require('./webpack.common');
module.exports = merge(common, {
mode: 'production',
// source maps encouraged in production

8014
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -14,29 +14,35 @@
"author": "Software Ingenieur Begerad <dialog@SwIngBe.de>",
"license": "GPL-3.0-or-later",
"engines": {
"node": ">=18.19.0"
"node": ">=18.17.0"
},
"scripts": {
"start": "webpack serve --config config/webpack.dev.js",
"build": "webpack --config config/webpack.prod.js",
"test": "echo \"Error: no test specified\" && exit 1"
"test": "echo \"Error: no test specified\" && exit 1",
"lint": "eslint .",
"lint:fix": "eslint --fix ."
},
"devDependencies": {
"@babel/core": "7.22.10",
"@babel/preset-env": "7.22.10",
"@babel/preset-react": "7.22.5",
"@babel/core": "7.23.9",
"@babel/eslint-parser": "7.23.10",
"@babel/plugin-transform-runtime": "7.23.9",
"@babel/preset-env": "7.23.9",
"@babel/preset-react": "7.23.3",
"@babel/runtime": "7.23.9",
"babel-loader": "9.1.3",
"css-loader": "6.8.1",
"file-loader": "6.2.0",
"html-webpack-plugin": "5.5.3",
"style-loader": "3.3.2",
"svg-url-loader": "8.0.0",
"webpack": "5.88.2",
"css-loader": "6.10.0",
"eslint": "8.56.0",
"eslint-config-airbnb": "19.0.4",
"eslint-webpack-plugin": "4.0.1",
"style-loader": "3.3.4",
"webpack": "5.90.2",
"webpack-cli": "5.1.4",
"webpack-dev-server": "4.15.1",
"webpack-merge": "5.9.0"
"webpack-dev-server": "5.0.1"
},
"dependencies": {
"webpack-merge": "5.10.0",
"html-webpack-plugin": "5.6.0",
"axios": "1.3.6",
"prop-types": "15.8.1",
"react": "18.2.0",

View File

@ -1,25 +1,24 @@
import React from 'react';
import PropTypes from 'prop-types';
const AgencyTableEntry = ({
function AgencyTableEntry({
agencyId,
agencyName,
tripCalendar
}) => {
tripCalendar,
}) {
if (tripCalendar !== undefined && Object.keys(tripCalendar).length > 0) {
return (
<tr>
<td>{agencyId}</td>
<td>{agencyName}</td>
{
Object.values(tripCalendar).map((value,index)=>{
return (
Object.values(tripCalendar).map((value, index) => (
<th key={index}>{value}</th>
);
})
))
}
</tr>
);
}else{
}
// console.log('AgencyTableEntry waiting for prop');
return (
<tr>
@ -27,11 +26,10 @@ const AgencyTableEntry = ({
</tr>
);
}
};
AgencyTableEntry.propTypes = {
agencyId: PropTypes.string,
agencyName: PropTypes.string,
tripCalendar: PropTypes.object
tripCalendar: PropTypes.object,
};
export default AgencyTableEntry;

View File

@ -17,15 +17,13 @@ export default function AgencyTableHead({tripCalendar}) {
<th>agency_id</th>
<th>agency_name</th>
{
Object.keys(tripCalendar).map((key,index)=>{
return (
Object.keys(tripCalendar).map((key, index) => (
<th key={index}>{handleTs(key)}</th>
);
})
))
}
</tr>
);
}else{
}
// console.log('AgencyTableHead waiting for prop');
return (
<tr>
@ -33,8 +31,7 @@ export default function AgencyTableHead({tripCalendar}) {
</tr>
);
}
};
AgencyTableHead.propTypes = {
tripCalendar: PropTypes.object
tripCalendar: PropTypes.object,
};

View File

@ -5,28 +5,49 @@ export default function AgencyPerDayTableEntries ({array}) {
if (array !== undefined && array !== null && array.length > 0) {
// TODO Shall we switch from UTC to local time zone for item.timestamp_pgsql?
// iterate over array
return array.map((item, index) => {
return (
return array.map((item, index) => (
<tr
key={index}
>
<td>{item.agency_name}&nbsp;|</td>
<td>{item.agency_id}&nbsp;|</td>
<td>{item.route_id}&nbsp;|</td>
<td>{item.route_short_name}&nbsp;|</td>
<td>{item.trip_id}&nbsp;|</td>
<td>{item.rt_part}&nbsp;|</td>
<td>{item.trip_id === 0 ? 0 : ((item.rt_part / item.trip_id) * 100).toFixed(2)}&nbsp;|</td>
<td>{item.timestamp_pgsql}&nbsp;|</td>
<td>
{item.agency_name}
&nbsp;|
</td>
<td>
{item.agency_id}
&nbsp;|
</td>
<td>
{item.route_id}
&nbsp;|
</td>
<td>
{item.route_short_name}
&nbsp;|
</td>
<td>
{item.trip_id}
&nbsp;|
</td>
<td>
{item.rt_part}
&nbsp;|
</td>
<td>
{item.trip_id === 0 ? 0 : ((item.rt_part / item.trip_id) * 100).toFixed(2)}
&nbsp;|
</td>
<td>
{item.timestamp_pgsql}
&nbsp;|
</td>
</tr>
);
});
}else{
));
}
// data is empty
return null;
}
};
AgencyPerDayTableEntries.propTypes = {
array: PropTypes.array
array: PropTypes.array,
};

View File

@ -5,12 +5,19 @@ import AgencyPerDayTableEntries from './agency-per-day-table-entries';
/* destructure props object */
export default function AgencyPerDayTable({ array, title, date }) {
if (array !== undefined && array !== null) {
/* return a React element */
return (
<>
<p>Table of {array.length}&nbsp;{title} for {date}:</p>
<p>
Table of
{array.length}
{title}
{' '}
for
{date}
:
</p>
<table>
<thead>
<tr>
@ -30,16 +37,13 @@ export default function AgencyPerDayTable ({array, title, date}){
</table>
</>
);
}else{
}
return (
<>
<p>loading...</p>
</>
);
}
};
AgencyPerDayTable.propTypes = {
array: PropTypes.array,
title: PropTypes.string,
date: PropTypes.string
date: PropTypes.string,
};

View File

@ -2,33 +2,35 @@ import React from 'react';
import PropTypes from 'prop-types';
import Dropdown from 'react-bootstrap/Dropdown';
export default function AgencySelect({ name, onChange, placeholder, rry, title }) {
export default function AgencySelect({
name, onChange, placeholder, rry, title,
}) {
if (rry.length > 0) {
return (<>
return (
<Dropdown>
<Dropdown.Toggle id="dropdown-basic">{placeholder}
<Dropdown.Toggle id="dropdown-basic">
{placeholder}
</Dropdown.Toggle>
<Dropdown.Menu>
{rry.map((item) => (
<Dropdown.Item
eventKey={item.agency_id}
key={item.agency_id}>
key={item.agency_id}
>
{item.agency_name}
</Dropdown.Item>
))}
</Dropdown.Menu>
</Dropdown>
</>);
} else {
);
}
return <p>Loading...</p>;
}
};
AgencySelect.propTypes = {
name: PropTypes.string,
onChange: PropTypes.func,
title: PropTypes.string,
placeholder: PropTypes.string,
rry: PropTypes.array
rry: PropTypes.array,
};

View File

@ -2,10 +2,11 @@ import React from 'react';
import PropTypes from 'prop-types';
import Form from 'react-bootstrap/Form';
export default function AgencySelect({ name, onChange, placeholder, rry, title }) {
export default function AgencySelect({
name, onChange, placeholder, rry, title,
}) {
if (rry.length > 0) {
return (<>
return (
<Form.Select
aria-label="select table entries per page"
name={name}
@ -24,16 +25,15 @@ export default function AgencySelect({ name, onChange, placeholder, rry, title }
</option>
))}
</Form.Select>
</>);
} else {
);
}
return <p>Loading...</p>;
}
};
AgencySelect.propTypes = {
name: PropTypes.string,
onChange: PropTypes.func,
title: PropTypes.string,
placeholder: PropTypes.string,
rry: PropTypes.array
rry: PropTypes.array,
};

View File

@ -2,33 +2,35 @@ import React from 'react';
import PropTypes from 'prop-types';
import Dropdown from 'react-bootstrap/Dropdown';
export default function AgencySelect({ name, onChange, placeholder, rry, title }) {
export default function AgencySelect({
name, onChange, placeholder, rry, title,
}) {
if (rry.length > 0) {
return (<>
return (
<Dropdown>
<Dropdown.Toggle id="dropdown-basic">{placeholder}
<Dropdown.Toggle id="dropdown-basic">
{placeholder}
</Dropdown.Toggle>
<Dropdown.Menu>
{rry.map((item) => (
<Dropdown.Item
eventKey={item.agency_id}
key={item.agency_id}>
key={item.agency_id}
>
{item.agency_name}
</Dropdown.Item>
))}
</Dropdown.Menu>
</Dropdown>
</>);
} else {
);
}
return <p>Loading...</p>;
}
};
AgencySelect.propTypes = {
name: PropTypes.string,
onChange: PropTypes.func,
title: PropTypes.string,
placeholder: PropTypes.string,
rry: PropTypes.array
rry: PropTypes.array,
};

View File

@ -5,10 +5,14 @@ import PropTypes from 'prop-types';
* @param rry Array of agency objects containing id and name
*/
export default function AgencySelect({ name, onChange, rry }) {
if (rry !== undefined && rry !== null && rry.length > 0) {
return <form >
<label htmlFor="input-agency">{name}: </label>
return (
<form>
<label htmlFor="input-agency">
{name}
:
{' '}
</label>
<select
name={name}
id={name}
@ -26,14 +30,14 @@ export default function AgencySelect({ name, onChange, rry }) {
</option>
))}
</select>
</form>;
} else {
</form>
);
}
return <p>Loading...</p>;
}
};
AgencySelect.propTypes = {
name: PropTypes.string,
onChange: PropTypes.func,
rry: PropTypes.array
rry: PropTypes.array,
};

View File

@ -1,13 +1,14 @@
import React from 'react';
import PropTypes from 'prop-types';
const AgencyTableEntry = ({
function AgencyTableEntry({
agencyId,
agencyName,
agencyUrl,
agencyTimezone,
agencyLang,
agencyPhone
}) => {
agencyPhone,
}) {
return (
<tr>
<td>{agencyId}</td>
@ -18,13 +19,13 @@ const AgencyTableEntry = ({
<td>{agencyPhone}</td>
</tr>
);
};
}
AgencyTableEntry.propTypes = {
agencyId: PropTypes.string,
agencyName: PropTypes.string,
agencyUrl: PropTypes.string,
agencyTimezone: PropTypes.string,
agencyLang: PropTypes.string,
agencyPhone: PropTypes.string
agencyPhone: PropTypes.string,
};
export default AgencyTableEntry;

View File

@ -1,5 +1,6 @@
import React from 'react';
const AgencyTableHead = () => {
function AgencyTableHead() {
return (
<tr>
<th>agency_id</th>
@ -10,5 +11,5 @@ const AgencyTableHead = () => {
<th>agency_phone</th>
</tr>
);
};
}
export default AgencyTableHead;

View File

@ -2,7 +2,7 @@ import React from 'react';
import PropTypes from 'prop-types';
/* destructure props object */
const CalendarDatesTableEntry = ({ serviceId, date, exceptionType }) => {
function CalendarDatesTableEntry({ serviceId, date, exceptionType }) {
return (
<tr>
<td>{serviceId}</td>
@ -10,12 +10,12 @@ const CalendarDatesTableEntry = ({ serviceId, date, exceptionType }) => {
<td>{exceptionType}</td>
</tr>
);
};
}
CalendarDatesTableEntry.propTypes = {
serviceId: PropTypes.string,
date: PropTypes.string,
exceptionType: PropTypes.number
exceptionType: PropTypes.number,
};
export default CalendarDatesTableEntry;

View File

@ -1,6 +1,6 @@
import React from 'react';
const CalendarDatesTableHead = () => {
function CalendarDatesTableHead() {
return (
<tr>
<th>service_id</th>
@ -8,6 +8,6 @@ const CalendarDatesTableHead = () => {
<th>exception_type</th>
</tr>
);
};
}
export default CalendarDatesTableHead;

View File

@ -2,7 +2,7 @@ import React from 'react';
import PropTypes from 'prop-types';
/* destructure props object */
const CalendarTableEntry = ({
function CalendarTableEntry({
serviceId,
monday,
tuesday,
@ -12,8 +12,8 @@ const CalendarTableEntry = ({
saturday,
sunday,
startDate,
endDate
}) => {
endDate,
}) {
return (
<tr>
<td>{serviceId}</td>
@ -28,7 +28,7 @@ const CalendarTableEntry = ({
<td>{endDate}</td>
</tr>
);
};
}
CalendarTableEntry.propTypes = {
serviceId: PropTypes.string,
@ -40,7 +40,7 @@ CalendarTableEntry.propTypes = {
saturday: PropTypes.number,
sunday: PropTypes.number,
startDate: PropTypes.string,
endDate: PropTypes.string
endDate: PropTypes.string,
};
export default CalendarTableEntry;

View File

@ -1,6 +1,6 @@
import React from 'react';
const CalendarTableHead = () => {
function CalendarTableHead() {
return (
<tr>
<th>service_id</th>
@ -15,6 +15,6 @@ const CalendarTableHead = () => {
<th>end_date</th>
</tr>
);
};
}
export default CalendarTableHead;

View File

@ -7,19 +7,20 @@ import {
BarElement,
Title,
Tooltip,
Legend
Legend,
} from 'chart.js';
import { Bar } from 'react-chartjs-2';
ChartJS.register(
CategoryScale,
LinearScale,
BarElement,
Title,
Tooltip,
Legend
Legend,
);
/* destructure props */
const ChartBarVertical = ({ route, time, trip }) => {
function ChartBarVertical({ route, time, trip }) {
const data = {
labels: time,
datasets: [
@ -27,53 +28,51 @@ const ChartBarVertical = ({ route, time, trip }) => {
label: `trip count of route ${route}`,
data: trip,
backgroundColor: 'rgba(255, 99, 132, 0.5)',
borderColor: 'rgba(255, 99, 132, 0.2)'
}
]
borderColor: 'rgba(255, 99, 132, 0.2)',
},
],
};
const options = {
responsive: true,
plugins: {
legend: {
display: true,
position: 'top'
position: 'top',
},
title: {
display: true,
text: `trip count of route ${route}`
}
text: `trip count of route ${route}`,
},
},
scales: {
y: {
ticks: {
max: 300,
min: 0,
stepSize: 10
stepSize: 10,
},
scaleLabel: {
display: false
}
}
}
display: false,
},
},
},
};
return (
<>
<div className="ChartBar">
<div
style={{
height: '300px',
width: '900px'
width: '900px',
}}
>
<Bar data={data} options={options} />
</div>
</div>
</>
);
};
}
ChartBarVertical.propTypes = {
time: PropTypes.array,
trip: PropTypes.array,
route: PropTypes.string
route: PropTypes.string,
};
export default ChartBarVertical;

View File

@ -8,9 +8,10 @@ import {
Title,
Tooltip,
Legend,
PointElement
PointElement,
} from 'chart.js';
import { Line } from 'react-chartjs-2';
ChartJS.register(
CategoryScale,
LinearScale,
@ -18,10 +19,10 @@ ChartJS.register(
Title,
Tooltip,
Legend,
PointElement
PointElement,
);
/* destructure props */
const ChartLine = ({ route, time, trip }) => {
function ChartLine({ route, time, trip }) {
const data = {
labels: time,
datasets: [
@ -30,53 +31,51 @@ const ChartLine = ({ route, time, trip }) => {
data: trip,
fill: false,
backgroundColor: 'rgb(255, 99, 132)',
borderColor: 'rgba(255, 99, 132, 0.2)'
}
]
borderColor: 'rgba(255, 99, 132, 0.2)',
},
],
};
const options = {
responsive: true,
plugins: {
legend: {
display: true,
position: 'top'
position: 'top',
},
title: {
display: true,
text: `trip count of route ${route}`
}
text: `trip count of route ${route}`,
},
},
scales: {
y: {
ticks: {
max: 300,
min: 0,
stepSize: 10
stepSize: 10,
},
scaleLabel: {
display: false
}
}
}
display: false,
},
},
},
};
return (
<>
<div className="ChartLine">
<div
style={{
height: '300px',
width: '900px'
width: '900px',
}}
>
<Line data={data} options={options} />
</div>
</div>
</>
);
};
}
ChartLine.propTypes = {
time: PropTypes.array,
trip: PropTypes.array,
route: PropTypes.string
route: PropTypes.string,
};
export default ChartLine;

View File

@ -1,10 +1,17 @@
import React from 'react';
import PropTypes from 'prop-types';
export default function FileSelect({ options, name, onChange, title }) {
export default function FileSelect({
options, name, onChange, title,
}) {
if (options.length > 0) {
return <form >
<label htmlFor="input-agency">{name}: </label>
return (
<form>
<label htmlFor="input-agency">
{name}
:
{' '}
</label>
<select
name={name}
id={name}
@ -22,15 +29,15 @@ export default function FileSelect({ options, name, onChange, title }) {
</option>
))}
</select>
</form>;
} else {
</form>
);
}
return <p>Loading...</p>;
}
};
FileSelect.propTypes = {
name: PropTypes.string,
onChange: PropTypes.func,
title: PropTypes.string,
options: PropTypes.array
options: PropTypes.array,
};

View File

@ -1,32 +1,32 @@
import React, { useState } from 'react';
import PropTypes from 'prop-types';
import FileSelect from '../components/file-select';
import TablePage from '../components/table-page';
import FileSelect from './file-select';
import TablePage from './table-page';
import gtfs from '../utils/gtfs';
export default function FileSelection({ options }) {
/* store and initialize data in function component state */
const [fileName, setFileName] = useState(gtfs.datasetFiles[0]);
const handleChangeFile = (event) => {
setFileName((fileName) => event.target.value);
};
if (options.length > 0) {
return <>
return (
<>
<FileSelect
name="file"
onChange={handleChangeFile}
options={options}
title='Select GTFS dataset file'
title="Select GTFS dataset file"
/>
<TablePage name={fileName} />
</>;
} else {
</>
);
}
return <p>Loading...</p>;
}
};
FileSelection.propTypes = {
options: PropTypes.array
options: PropTypes.array,
};

View File

@ -2,29 +2,33 @@ import React from 'react';
import PropTypes from 'prop-types';
/* controlled component: input form value controlled by React */
const FormValue = (props) => {
function FormValue(props) {
/* destructuring */
const { value, valueName, onChange, onSubmit } = props;
const {
value, valueName, onChange, onSubmit,
} = props;
return (
/* one onChange handler for each value */
/* input names should match state names */
<>
<form onSubmit={onSubmit}>
<label>
<p>Please enter {valueName}:</p>
<p>
Please enter
{valueName}
:
</p>
<input type="text" name="value" value={value} onChange={onChange} />
</label>
<input type="submit" value="Submit" />
</form>
</>
);
};
}
export default FormValue;
FormValue.propTypes = {
value: PropTypes.string,
valueName: PropTypes.string,
onChange: PropTypes.func,
onSubmit: PropTypes.func
onSubmit: PropTypes.func,
};

View File

@ -2,13 +2,13 @@ import React from 'react';
import PropTypes from 'prop-types';
/* destructure props object */
const FrequenciesTableEntry = ({
function FrequenciesTableEntry({
tripId,
startTime,
endTime,
headwaySecs,
exactTimes
}) => {
exactTimes,
}) {
return (
<tr>
<td>{tripId}</td>
@ -18,14 +18,14 @@ const FrequenciesTableEntry = ({
<td>{exactTimes}</td>
</tr>
);
};
}
FrequenciesTableEntry.propTypes = {
tripId: PropTypes.string,
startTime: PropTypes.string,
endTime: PropTypes.string,
headwaySecs: PropTypes.number,
exactTimes: PropTypes.number
exactTimes: PropTypes.number,
};
export default FrequenciesTableEntry;

View File

@ -1,6 +1,6 @@
import React from 'react';
const FrequenciesTableHead = () => {
function FrequenciesTableHead() {
return (
<tr>
<th>trip_id</th>
@ -10,6 +10,6 @@ const FrequenciesTableHead = () => {
<th>exact_times</th>
</tr>
);
};
}
export default FrequenciesTableHead;

View File

@ -5,25 +5,37 @@ export default function GroupAgencyPerDayTableEntries ({array}) {
if (array !== undefined && array !== null && array.length > 0) {
// TODO Shall we switch from UTC to local time zone for item.timestamp_pgsql?
// iterate over array
return array.map((item, index) => {
return (
return array.map((item, index) => (
<tr
key={index}
>
<td>{item.agency_name}&nbsp;|</td>
<td>{item.agency_id}&nbsp;|</td>
<td>{item.rt_part}&nbsp;|</td>
<td>{item.agency_id === 0 ? 0 : ((item.rt_part / item.agency_id) * 100).toFixed(2)}&nbsp;|</td>
<td>{item.timestamp_pgsql}&nbsp;|</td>
<td>
{item.agency_name}
&nbsp;|
</td>
<td>
{item.agency_id}
&nbsp;|
</td>
<td>
{item.rt_part}
&nbsp;|
</td>
<td>
{item.agency_id === 0 ? 0 : ((item.rt_part / item.agency_id) * 100).toFixed(2)}
&nbsp;|
</td>
<td>
{item.timestamp_pgsql}
&nbsp;|
</td>
</tr>
);
});
}else{
));
}
// data is empty
return null;
}
};
GroupAgencyPerDayTableEntries.propTypes = {
array: PropTypes.array
array: PropTypes.array,
};

View File

@ -7,12 +7,19 @@ import GroupAgencyPerDayTableEntries from './group-agency-per-day-table-entries'
/* destructure props object */
export default function GroupAgencyPerDayTable({ array, title, date }) {
if (array !== undefined && array !== null) {
/* return a React element */
return (
<>
<p>Table of {array.length}&nbsp;{title} for {date}:</p>
<p>
Table of
{array.length}
{title}
{' '}
for
{date}
:
</p>
<table>
<thead>
<tr>
@ -29,14 +36,11 @@ export default function GroupAgencyPerDayTable ({array, title, date}){
</table>
</>
);
}else{
}
return (
<>
<p>loading...</p>
</>
);
}
};
GroupAgencyPerDayTable.propTypes = {
array: PropTypes.array,
title: PropTypes.string,

View File

@ -18,9 +18,9 @@ export default function GtfsFile({ name }) {
const count = await axios.get(address);
/* set state */
setCount(count.data[0]['count']);
setCount(count.data[0].count);
} catch (err) {
console.error('err.message: ' + err.message);
console.error(`err.message: ${err.message}`);
}
};
@ -35,11 +35,15 @@ export default function GtfsFile({ name }) {
/* TODO study dependency array: https://reactjs.org/docs/hooks-effect.html */
}, []);
return <li key={name}>
{name}:&nbsp;{count ? count : 'loading...'}
</li>;
};
return (
<li key={name}>
{name}
:&nbsp;
{count || 'loading...'}
</li>
);
}
GtfsFile.propTypes = {
name: PropTypes.string
name: PropTypes.string,
};

View File

@ -7,16 +7,20 @@ import gtfs from '../utils/gtfs';
export default function GtfsFiles() {
// TODO Do we have to call an API for each and every dataset file?
return <fieldset>
<legend><b>GTFS Schedule</b> feed overview (file: item count)</legend>
return (
<fieldset>
<legend>
<b>GTFS Schedule</b>
{' '}
feed overview (file: item count)
</legend>
<ul>
{gtfs.datasetFiles.map((item, index) => {
return <GtfsFile key={index} name={item} />;
})}
{gtfs.datasetFiles.map((item, index) => <GtfsFile key={index} name={item} />)}
</ul>
</fieldset>;
};
</fieldset>
);
}
GtfsFiles.propTypes = {
data: PropTypes.array
data: PropTypes.array,
};

View File

@ -1,31 +1,36 @@
import React, { useState } from 'react';
import Alert from 'react-bootstrap/Alert';
import config from '../config';
const GtfsValidatorReport = () => {
function GtfsValidatorReport() {
const [show, setShow] = useState(true);
if (show) {
return (
<>
<Alert variant={'secondary'} onClose={() => setShow(false)} dismissible>
A daily{' '}
<Alert variant="secondary" onClose={() => setShow(false)} dismissible>
A daily
{' '}
<Alert.Link href={config.GTFS_VALIDATOR_REPORT}>
report
</Alert.Link>{' '}
about compliance of this GTFS feed with these{' '}
</Alert.Link>
{' '}
about compliance of this GTFS feed with these
{' '}
<Alert.Link href="https://github.com/MobilityData/GTFS_Schedule_Best-Practices">
Best Practices{' '}
</Alert.Link>{' '}
is generated using the{' '}
Best Practices
{' '}
</Alert.Link>
{' '}
is generated using the
{' '}
<Alert.Link href="https://github.com/MobilityData/gtfs-validator">
gtfs-validator{' '}
gtfs-validator
{' '}
</Alert.Link>
.
</Alert>
</>
);
} else {
}
return null;
}
};
export default GtfsValidatorReport;

View File

@ -1,49 +1,60 @@
import React from 'react'
import React from 'react';
export default function Header() {
return <>
<a href='/' rel="noopener noreferrer">
return (
<>
<a href="/" rel="noopener noreferrer">
<button>
Home
</button>
</a>
<a href='/agency' rel="noopener noreferrer">
<a href="/agency" rel="noopener noreferrer">
<button>
Agency
</button>
</a>
<a href='/files' rel="noopener noreferrer">
<a href="/files" rel="noopener noreferrer">
<button>
Files
</button>
</a>
<a href='/realtime' rel="noopener noreferrer">
<a href="/realtime" rel="noopener noreferrer">
<button>
Realtime
</button>
</a>
<a href='/contact' rel="noopener noreferrer">
<a href="/contact" rel="noopener noreferrer">
<button>
Contact
</button>
</a>
<a href='https://www.swingbe.de/imprint/'
target="_blank" rel="noopener noreferrer">
<a
href="https://www.swingbe.de/imprint/"
target="_blank"
rel="noopener noreferrer"
>
<button>
Imprint
</button>
</a>
<a href='https://www.swingbe.de/privacy-policy/'
target="_blank" rel="noopener noreferrer">
<a
href="https://www.swingbe.de/privacy-policy/"
target="_blank"
rel="noopener noreferrer"
>
<button>
Privacy Policy
</button>
</a>
<a href='https://git.wtf-eg.de/dancingCycle/gtfs-display'
target="_blank" rel="noopener noreferrer">
<a
href="https://git.wtf-eg.de/dancingCycle/gtfs-display"
target="_blank"
rel="noopener noreferrer"
>
<button>
Source
</button>
</a>
</>;
};
</>
);
}

View File

@ -2,9 +2,16 @@ import React from 'react';
import PropTypes from 'prop-types';
/* controlled component: input form value controlled by React */
export default function Input({id, name, onChange, placeholder, title, type, value}) {
return <form >
<label htmlFor="input-agency">{name}: </label>
export default function Input({
id, name, onChange, placeholder, title, type, value,
}) {
return (
<form>
<label htmlFor="input-agency">
{name}
:
{' '}
</label>
<input
name={name}
id={id}
@ -16,8 +23,9 @@ export default function Input({id, name, onChange, placeholder, title, type, val
value={value}
required
/>
</form>;
};
</form>
);
}
Input.propTypes = {
id: PropTypes.string,
@ -26,5 +34,5 @@ Input.propTypes = {
placeholder: PropTypes.string,
title: PropTypes.string,
type: PropTypes.string,
onChange: PropTypes.func
onChange: PropTypes.func,
};

View File

@ -1,15 +1,16 @@
import React from 'react';
import PropTypes from 'prop-types';
const LevelsTableEntry = ({ levelId, levelIndex }) => {
function LevelsTableEntry({ levelId, levelIndex }) {
return (
<tr>
<td>{levelId}</td>
<td>{levelIndex}</td>
</tr>
);
};
}
LevelsTableEntry.propTypes = {
levelId: PropTypes.string,
levelIndex: PropTypes.number
levelIndex: PropTypes.number,
};
export default LevelsTableEntry;

View File

@ -1,12 +1,12 @@
import React from 'react';
const LevelsTableHead = () => {
function LevelsTableHead() {
return (
<tr>
<th>level_id</th>
<th>level_index</th>
</tr>
);
};
}
export default LevelsTableHead;

View File

@ -7,13 +7,12 @@ function Loading (props) {
if (props.loading) {
/* return a React element */
return <p>Loading...</p>;
} else {
return null;
}
return null;
}
Loading.propTypes = {
loading: PropTypes.bool
loading: PropTypes.bool,
};
export default Loading;

View File

@ -2,10 +2,9 @@ import React, { useState, useEffect } from 'react';
import axios from 'axios';
import config from '../config';
import Input from '../components/input';
import Input from './input';
export default function OddTrips() {
const dateDefault = 'Select date';
const [date, setDate] = useState(dateDefault);
const [data, setData] = useState([]);
@ -14,8 +13,8 @@ export default function OddTrips() {
// TODO How do we handle invalid date input?
const handleDate = (e) => {
if (e.target.value.indexOf('2023') !== -1 ||
e.target.value.indexOf('2024') !== -1) {
if (e.target.value.indexOf('2023') !== -1
|| e.target.value.indexOf('2024') !== -1) {
setDate((date) => e.target.value);
}
};
@ -77,7 +76,13 @@ export default function OddTrips() {
/>
</label>
<p>
abs odd route count: {data.length}, total pages: {Math.ceil(data.length / itemsPerPage)}, current page: {currentPage}
abs odd route count:
{' '}
{data.length}
, total pages:
{Math.ceil(data.length / itemsPerPage)}
, current page:
{currentPage}
</p>
<dl>
{currentItems.map((item, index) => (
@ -88,4 +93,4 @@ export default function OddTrips() {
<button onClick={handleNextPage}>Next</button>
</>
);
};
}

View File

@ -2,10 +2,9 @@ import React, { useState, useEffect } from 'react';
import axios from 'axios';
import config from '../config';
import Input from '../components/input';
import Input from './input';
export default function OddTrips() {
const dateDefault = 'Select date';
const [date, setDate] = useState(dateDefault);
const [data, setData] = useState([]);
@ -14,8 +13,8 @@ export default function OddTrips() {
// TODO How do we handle invalid date input?
const handleDate = (e) => {
if (e.target.value.indexOf('2023') !== -1 ||
e.target.value.indexOf('2024') !== -1) {
if (e.target.value.indexOf('2023') !== -1
|| e.target.value.indexOf('2024') !== -1) {
setDate((date) => e.target.value);
}
};
@ -77,7 +76,13 @@ export default function OddTrips() {
/>
</label>
<p>
abs odd trip count: {data.length}, total pages: {Math.ceil(data.length / itemsPerPage)}, current page: {currentPage}
abs odd trip count:
{' '}
{data.length}
, total pages:
{Math.ceil(data.length / itemsPerPage)}
, current page:
{currentPage}
</p>
<dl>
{currentItems.map((item, index) => (
@ -88,4 +93,4 @@ export default function OddTrips() {
<button onClick={handleNextPage}>Next</button>
</>
);
};
}

View File

@ -6,11 +6,10 @@ export default function CountNext({ count }) {
|| count === null
|| count === undefined) {
return '0';
} else {
}
return count;
}
};
CountNext.propTypes = {
count: PropTypes.string
count: PropTypes.string,
};

View File

@ -4,7 +4,9 @@ import PropTypes from 'prop-types';
import Count from './overview-next-table-count';
/* destructure props object */
export default function OverviewNextTableEntry ({ agencyName, routeCount, stopCount, tripCount }) {
export default function OverviewNextTableEntry({
agencyName, routeCount, stopCount, tripCount,
}) {
const routeCountBadge = <Count count={routeCount} />;
const stopCountBadge = <Count count={stopCount} />;
const tripCountBadge = <Count count={tripCount} />;
@ -16,11 +18,11 @@ export default function OverviewNextTableEntry ({ agencyName, routeCount, stopCo
<td>{tripCountBadge}</td>
</tr>
);
};
}
OverviewNextTableEntry.propTypes = {
agencyName: PropTypes.string,
routeCount: PropTypes.string,
stopCount: PropTypes.string,
tripCount: PropTypes.string
tripCount: PropTypes.string,
};

View File

@ -9,4 +9,4 @@ export default function OverviewNextTableHead () {
<th>Trip Count&nbsp;|</th>
</tr>
);
};
}

View File

@ -8,11 +8,9 @@ import Head from './overview-next-table-head';
/* destructure props object */
export default function OverviewNextTable({ overview }) {
const handleOverview = () => {
if (overview !== null && overview !== undefined && overview.length !== 0) {
// iterate over array
return overview.map((item, index) => {
return (
return overview.map((item, index) => (
<Entry
agencyName={item.agency_name}
routeCount={item.rts_cnt}
@ -20,17 +18,20 @@ export default function OverviewNextTable ({ overview }) {
tripCount={item.trps_cnt}
key={item.agency_id}
/>
);
});
} else {
));
}
console.error('overview NOT available');
return null;
}
};
/* return a React element */
return <fieldset>
<legend><b>GTFS Schedule</b> agency overview</legend>
return (
<fieldset>
<legend>
<b>GTFS Schedule</b>
{' '}
agency overview
</legend>
{/* size="sm" cuts cell padding in half */}
{/* variant="dark" inverts colors */}
<table>
@ -39,9 +40,10 @@ export default function OverviewNextTable ({ overview }) {
</thead>
<tbody>{handleOverview()}</tbody>
</table>
</fieldset>;
};
</fieldset>
);
}
OverviewNextTable.propTypes = {
overview: PropTypes.array
overview: PropTypes.array,
};

View File

@ -2,16 +2,15 @@ import React from 'react';
import PropTypes from 'prop-types';
import Badge from '../utils/badge';
const count = ({ count }) => {
function count({ count }) {
if (count === 0) {
return <Badge msg={count} modifier={'danger'} />;
} else {
return <Badge msg={count} modifier="danger" />;
}
return count;
}
};
count.propTypes = {
count: PropTypes.number
count: PropTypes.number,
};
export default count;

View File

@ -3,7 +3,9 @@ import PropTypes from 'prop-types';
import Count from './overview-table-count.js';
/* destructure props object */
const OverviewTableEntry = ({ agencyName, routeCount, tripCount, day }) => {
function OverviewTableEntry({
agencyName, routeCount, tripCount, day,
}) {
const routeCountBadge = <Count count={routeCount} />;
const tripCountBadge = <Count count={tripCount} />;
return (
@ -14,13 +16,13 @@ const OverviewTableEntry = ({ agencyName, routeCount, tripCount, day }) => {
<td>{day === null ? 'loading...' : day}</td>
</tr>
);
};
}
OverviewTableEntry.propTypes = {
agencyName: PropTypes.string,
routeCount: PropTypes.number,
tripCount: PropTypes.number,
day: PropTypes.object
day: PropTypes.object,
};
export default OverviewTableEntry;

View File

@ -1,6 +1,6 @@
import React from 'react';
const OverviewTableHead = () => {
function OverviewTableHead() {
return (
<tr>
<th>Agency</th>
@ -9,6 +9,6 @@ const OverviewTableHead = () => {
<th>{new Date().toDateString()}</th>
</tr>
);
};
}
export default OverviewTableHead;

View File

@ -10,8 +10,7 @@ function OverviewTable ({ overview }) {
const handleOverview = () => {
if (overview) {
// iterate over array
return overview.map((item, index) => {
return (
return overview.map((item, index) => (
<Entry
agencyName={item.agency_name}
routeCount={item.route_count}
@ -19,12 +18,10 @@ function OverviewTable ({ overview }) {
day={item.day}
key={index}
/>
);
});
} else {
));
}
console.error('overview NOT available');
return null;
}
};
/* return a React element */
@ -43,7 +40,7 @@ function OverviewTable ({ overview }) {
}
OverviewTable.propTypes = {
overview: PropTypes.array
overview: PropTypes.array,
};
export default OverviewTable;

View File

@ -2,7 +2,7 @@ import React from 'react';
import PropTypes from 'prop-types';
/* destructure props object */
const PathwaysTableEntry = ({
function PathwaysTableEntry({
pathwayId,
fromStopId,
toStopId,
@ -14,8 +14,8 @@ const PathwaysTableEntry = ({
maxSlope,
minWidth,
signpostedAs,
reversedSignpostedAs
}) => {
reversedSignpostedAs,
}) {
return (
<tr>
<td>{pathwayId}</td>
@ -32,7 +32,7 @@ const PathwaysTableEntry = ({
<td>{reversedSignpostedAs}</td>
</tr>
);
};
}
PathwaysTableEntry.propTypes = {
pathwayId: PropTypes.string,
@ -46,7 +46,7 @@ PathwaysTableEntry.propTypes = {
maxSlope: PropTypes.number,
minWidth: PropTypes.number,
signpostedAs: PropTypes.string,
reversedSignpostedAs: PropTypes.string
reversedSignpostedAs: PropTypes.string,
};
export default PathwaysTableEntry;

View File

@ -1,6 +1,6 @@
import React from 'react';
const PathwaysTableHead = () => {
function PathwaysTableHead() {
return (
<tr>
<th>pathway_id</th>
@ -17,6 +17,6 @@ const PathwaysTableHead = () => {
<th>reversed_signposted_as</th>
</tr>
);
};
}
export default PathwaysTableHead;

View File

@ -5,24 +5,33 @@ export default function PerDayTableEntries ({array}) {
if (array !== undefined && array !== null && array.length > 0) {
// TODO Shall we switch from UTC to local time zone for item.timestamp_pgsql?
// iterate over array
return array.map((item, index) => {
return (
return array.map((item, index) => (
<tr
key={index}
>
<td>{item.count}&nbsp;|</td>
<td>{item.rt_part}&nbsp;|</td>
<td>{item.count === 0 ? 0 : ((item.rt_part / item.count) * 100).toFixed(2)}&nbsp;|</td>
<td>{item.timestamp_pgsql}&nbsp;|</td>
<td>
{item.count}
&nbsp;|
</td>
<td>
{item.rt_part}
&nbsp;|
</td>
<td>
{item.count === 0 ? 0 : ((item.rt_part / item.count) * 100).toFixed(2)}
&nbsp;|
</td>
<td>
{item.timestamp_pgsql}
&nbsp;|
</td>
</tr>
);
});
}else{
));
}
// data is empty
return null;
}
};
PerDayTableEntries.propTypes = {
array: PropTypes.array
array: PropTypes.array,
};

View File

@ -5,12 +5,19 @@ import PerDayTableEntries from './per-day-table-entries';
/* destructure props object */
export default function PerDayTable({ array, title, date }) {
if (array !== undefined && array !== null) {
/* return a React element */
return (
<>
<p>Table of {array.length}&nbsp;{title} for {date}:</p>
<p>
Table of
{array.length}
{title}
{' '}
for
{date}
:
</p>
<table>
<thead>
<tr>
@ -26,16 +33,13 @@ export default function PerDayTable ({array, title, date}){
</table>
</>
);
}else{
}
return (
<>
<p>loading...</p>
</>
);
}
};
PerDayTable.propTypes = {
array: PropTypes.array,
title: PropTypes.string,
date: PropTypes.string
date: PropTypes.string,
};

View File

@ -6,79 +6,164 @@ export default function RadioButton({ state, onChange }) {
<div>
<form>
<fieldset>
<legend>Select <b>GTFS Realtime</b> analysis rule</legend>
<legend>
Select
<b>GTFS Realtime</b>
{' '}
analysis rule
</legend>
<input
type="radio"
name="state"
id='state-odd-routes'
id="state-odd-routes"
value="odd-routes"
onChange={onChange}
checked={state === 'odd-routes'} />
checked={state === 'odd-routes'}
/>
<label htmlFor="state-odd-routes">
&nbsp;Show <b>GTFS Realtime</b> entities <b>TripUpdate</b> with <b>odd routes</b>
</label><br />
&nbsp;Show
{' '}
<b>GTFS Realtime</b>
{' '}
entities
{' '}
<b>TripUpdate</b>
{' '}
with
{' '}
<b>odd routes</b>
</label>
<br />
<input
type="radio"
name="state"
id='state-odd-trips'
id="state-odd-trips"
value="odd-trips"
onChange={onChange}
checked={state === 'odd-trips'} />
checked={state === 'odd-trips'}
/>
<label htmlFor="state-odd-trips">
&nbsp;Show <b>GTFS Realtime</b> entities <b>TripUpdate</b> with <b>odd trips</b>
</label><br />
&nbsp;Show
{' '}
<b>GTFS Realtime</b>
{' '}
entities
{' '}
<b>TripUpdate</b>
{' '}
with
{' '}
<b>odd trips</b>
</label>
<br />
<input
type="radio"
name="state"
id='state-feed'
id="state-feed"
value="feed"
onChange={onChange}
checked={state === 'feed'} />
checked={state === 'feed'}
/>
<label htmlFor="state-feed">
&nbsp;Analyse <b>GTFS Realtime</b> entities <b>TripUpdate</b> on <b>feed</b> level
</label><br />
&nbsp;Analyse
{' '}
<b>GTFS Realtime</b>
{' '}
entities
{' '}
<b>TripUpdate</b>
{' '}
on
{' '}
<b>feed</b>
{' '}
level
</label>
<br />
<input
type="radio"
name="state"
id='state-agencies'
id="state-agencies"
value="agencies"
onChange={onChange}
checked={state === 'agencies'} />
checked={state === 'agencies'}
/>
<label htmlFor="state-agencies">
&nbsp;Analyse <b>GTFS Realtime</b> entities <b>TripUpdate</b> on <b>agencies</b> level
</label><br />
&nbsp;Analyse
{' '}
<b>GTFS Realtime</b>
{' '}
entities
{' '}
<b>TripUpdate</b>
{' '}
on
{' '}
<b>agencies</b>
{' '}
level
</label>
<br />
<input
type="radio"
name="state"
id='state-routes'
id="state-routes"
value="routes"
onChange={onChange}
checked={state === 'routes'} />
checked={state === 'routes'}
/>
<label htmlFor="state-routes">
&nbsp;Analyse <b>GTFS Realtime</b> entities <b>TripUpdate</b> on <b>routes</b> level
</label><br />
&nbsp;Analyse
{' '}
<b>GTFS Realtime</b>
{' '}
entities
{' '}
<b>TripUpdate</b>
{' '}
on
{' '}
<b>routes</b>
{' '}
level
</label>
<br />
<input
type="radio"
name="state"
id='state-trips'
id="state-trips"
value="trips"
onChange={onChange}
checked={state === 'trips'} />
checked={state === 'trips'}
/>
<label htmlFor="state-trips">
&nbsp;Analyse <b>GTFS Realtime</b> entities <b>TripUpdate</b> on <b>trips</b> level
</label><br />
&nbsp;Analyse
{' '}
<b>GTFS Realtime</b>
{' '}
entities
{' '}
<b>TripUpdate</b>
{' '}
on
{' '}
<b>trips</b>
{' '}
level
</label>
<br />
</fieldset>
</form>
</div>
);
};
}
RadioButton.propTypes = {
state: PropTypes.string,
onChange: PropTypes.func
onChange: PropTypes.func,
};

View File

@ -13,63 +13,113 @@ export default function Realtime({ state }) {
return (
<>
<p>
Show <b>GTFS Realtime TripUpdate</b> entities that do <b>not</b> match any <b>GTFS Schedule routes</b>:
Show <b>GTFS Realtime TripUpdate</b>
{' '}
entities that do<b>not</b>
{' '}
match any<b>GTFS Schedule routes</b>
:
</p>
<OddRoutes />
</>
);
} else if ( state === 'odd-trips' ) {
} if (state === 'odd-trips') {
return (
<>
<p>
Show <b>GTFS Realtime TripUpdate</b> entities that do <b>not</b> match any <b>GTFS Schedule trips</b>:
Show <b>GTFS Realtime TripUpdate</b>
{' '}
entities that do<b>not</b>
{' '}
match any<b>GTFS Schedule trips</b>
:
</p>
<OddTrips />
</>
);
} else if ( state === 'feed' ) {
} if (state === 'feed') {
return (
<>
<p>
Analyse <b>GTFS Realtime</b> entities <b>TripUpdate</b> on <b>feed</b> level:
Analyse <b>GTFS Realtime</b>
{' '}
entities<b>TripUpdate</b>
{' '}
on<b>feed</b>
{' '}
level:
</p>
<PerDay />
</>
);
}
else if ( state === 'agencies' ) {
if (state === 'agencies') {
return (
<>
<p>
Analyse <b>GTFS Realtime</b> entities <b>TripUpdate</b> on <b>agencies</b> level:
Analyse
{' '}
<b>GTFS Realtime</b>
{' '}
entities
<b>TripUpdate</b>
{' '}
on
<b>agencies</b>
{' '}
level:
</p>
<GroupAgencyPerDay />
</>
);
} else if ( state === 'routes' ) {
} if (state === 'routes') {
return (
<>
<p>
Analyse <b>GTFS Realtime</b> entities <b>TripUpdate</b> on <b>routes</b> level:
Analyse
{' '}
<b>GTFS Realtime</b>
{' '}
entities
<b>TripUpdate</b>
{' '}
on
<b>routes</b>
{' '}
level:
</p>
<AgencyPerDay />
</>
);
} else if ( state === 'trips' ) {
} if (state === 'trips') {
return (
<>
<p>
Analyse <b>GTFS Realtime</b> entities <b>TripUpdate</b> on <b>trips</b> level:
Analyse
{' '}
<b>GTFS Realtime</b>
{' '}
entities
<b>TripUpdate</b>
{' '}
on
<b>trips</b>
{' '}
level:
</p>
<TripUpdates />
</>
);
} else {
return <p>Select a <b>GTFS Realtime</b> analysis rule to contine!</p>;
}
};
return (
<p>
Select a<b>GTFS Realtime</b>
{' '}
analysis rule to contine!
</p>
);
}
Realtime.propTypes = {
state: PropTypes.string
state: PropTypes.string,
};

View File

@ -5,11 +5,14 @@ import PropTypes from 'prop-types';
* @param rry Array of route objects containing id and name
*/
export default function RouteSelect({ name, onChange, rry }) {
if (rry !== undefined && rry !== null) {
return (<>
return (
<form>
<label htmlFor="input-route">{name}: </label>
<label htmlFor="input-route">
{name}
:
{' '}
</label>
<select
name={name}
id={name}
@ -28,14 +31,13 @@ export default function RouteSelect({ name, onChange, rry }) {
))}
</select>
</form>
</>);
} else {
);
}
return <p>Loading...</p>;
}
};
RouteSelect.propTypes = {
name: PropTypes.string,
onChange: PropTypes.func,
rry: PropTypes.array
rry: PropTypes.array,
};

View File

@ -2,7 +2,7 @@ import React from 'react';
import PropTypes from 'prop-types';
/* destructure props object */
const RoutesTableEntry = ({
function RoutesTableEntry({
routeId,
agencyId,
routeShortName,
@ -10,8 +10,8 @@ const RoutesTableEntry = ({
routeType,
routeColor,
routeTextColor,
routeDesc
}) => {
routeDesc,
}) {
return (
<tr>
<td>{routeId}</td>
@ -24,7 +24,7 @@ const RoutesTableEntry = ({
<td>{routeDesc}</td>
</tr>
);
};
}
RoutesTableEntry.propTypes = {
routeId: PropTypes.string,
@ -34,7 +34,7 @@ RoutesTableEntry.propTypes = {
routeType: PropTypes.number,
routeColor: PropTypes.string,
routeTextColor: PropTypes.string,
routeDesc: PropTypes.string
routeDesc: PropTypes.string,
};
export default RoutesTableEntry;

View File

@ -1,6 +1,6 @@
import React from 'react';
const RoutesTableHead = () => {
function RoutesTableHead() {
return (
<tr>
<th>route_id</th>
@ -13,6 +13,6 @@ const RoutesTableHead = () => {
<th>route_desc</th>
</tr>
);
};
}
export default RoutesTableHead;

View File

@ -2,10 +2,17 @@ import React from 'react';
import PropTypes from 'prop-types';
/* controlled component: select controlled by React */
export default function Select({defaultValue, id, name, onChange, options, title}) {
export default function Select({
defaultValue, id, name, onChange, options, title,
}) {
if (options) {
return <form >
<label htmlFor="input-agency">{name}: </label>
return (
<form>
<label htmlFor="input-agency">
{name}
:
{' '}
</label>
<select
name={name}
id={id}
@ -23,11 +30,11 @@ export default function Select({defaultValue, id, name, onChange, options, title
</option>
))}
</select>
</form>;
} else {
</form>
);
}
return <p>Select options unavailable.</p>;
}
};
Select.propTypes = {
id: PropTypes.string,
@ -35,5 +42,5 @@ Select.propTypes = {
defaultValue: PropTypes.number,
onChange: PropTypes.func,
options: PropTypes.array,
title: PropTypes.string
title: PropTypes.string,
};

View File

@ -14,7 +14,7 @@ class ServiceTableEntry extends Component {
ServiceTableEntry.propTypes = {
date: PropTypes.string,
count: PropTypes.number
count: PropTypes.number,
};
export default ServiceTableEntry;

View File

@ -13,19 +13,18 @@ function ServiceTable ({service,render}) {
return Object.entries(service).map((trips, key) => {
/* the strict equals operator does not converts operants of differnet type */
// console.log('key: ' + key);
let objTrips = trips[1];
let count = Object.keys(objTrips).length;
const objTrips = trips[1];
const count = Object.keys(objTrips).length;
// console.log('count: ' + count);
let time = parseInt(trips[0], 10);
const time = parseInt(trips[0], 10);
// console.log('time: ' + parseInt(time, 10));
let date = new Date(time);
const date = new Date(time);
// console.log('date: ' + date);
return <Entry date={date.toDateString()} count={count} key={key} />;
});
} else {
}
console.error('service NOT available');
return null;
}
};
if (render) {
@ -42,14 +41,13 @@ function ServiceTable ({service,render}) {
</Table>
</>
);
} else {
return null;
}
return null;
}
ServiceTable.propTypes = {
service: PropTypes.object,
render: PropTypes.bool
render: PropTypes.bool,
};
export default ServiceTable;

View File

@ -2,12 +2,12 @@ import React from 'react';
import PropTypes from 'prop-types';
/* destructure props object */
const ShapesTableEntry = ({
function ShapesTableEntry({
shapeId,
shapePtLat,
shapePtLon,
shapePtSequence
}) => {
shapePtSequence,
}) {
return (
<tr>
<td>{shapeId}</td>
@ -16,13 +16,13 @@ const ShapesTableEntry = ({
<td>{shapePtSequence}</td>
</tr>
);
};
}
ShapesTableEntry.propTypes = {
shapeId: PropTypes.string,
shapePtLat: PropTypes.number,
shapePtLon: PropTypes.number,
shapePtSequence: PropTypes.number
shapePtSequence: PropTypes.number,
};
export default ShapesTableEntry;

View File

@ -1,6 +1,6 @@
import React from 'react';
const ShapesTableHead = () => {
function ShapesTableHead() {
return (
<tr>
<th>shape_id</th>
@ -9,6 +9,6 @@ const ShapesTableHead = () => {
<th>shape_pt_sequence</th>
</tr>
);
};
}
export default ShapesTableHead;

View File

@ -2,7 +2,7 @@ import React from 'react';
import PropTypes from 'prop-types';
/* destructure props object */
const StopTimesTableEntry = ({
function StopTimesTableEntry({
tripId,
arrivalTimeHours,
arrivalTimeMinutes,
@ -12,8 +12,8 @@ const StopTimesTableEntry = ({
stopSequence,
pickupType,
dropOffType,
stopHeadsign
}) => {
stopHeadsign,
}) {
return (
<tr>
<td>{tripId}</td>
@ -28,7 +28,7 @@ const StopTimesTableEntry = ({
<td>{stopHeadsign}</td>
</tr>
);
};
}
StopTimesTableEntry.propTypes = {
tripId: PropTypes.string,
@ -40,7 +40,7 @@ StopTimesTableEntry.propTypes = {
stopSequence: PropTypes.number,
pickupType: PropTypes.number,
dropOffType: PropTypes.number,
stopHeadsign: PropTypes.string
stopHeadsign: PropTypes.string,
};
export default StopTimesTableEntry;

View File

@ -1,6 +1,6 @@
import React from 'react';
const StopTimesTableHead = () => {
function StopTimesTableHead() {
return (
<tr>
<th>trip_id</th>
@ -15,6 +15,6 @@ const StopTimesTableHead = () => {
<th>stop_headsign</th>
</tr>
);
};
}
export default StopTimesTableHead;

View File

@ -2,7 +2,7 @@ import React from 'react';
import PropTypes from 'prop-types';
/* destructure props object */
const StopsTableEntry = ({
function StopsTableEntry({
stopId,
stopCode,
stopName,
@ -13,8 +13,8 @@ const StopsTableEntry = ({
parentStation,
wheelchairBoarding,
platformCode,
zoneId
}) => {
zoneId,
}) {
return (
<tr>
<td>{stopId}</td>
@ -30,7 +30,7 @@ const StopsTableEntry = ({
<td>{zoneId}</td>
</tr>
);
};
}
StopsTableEntry.propTypes = {
stopId: PropTypes.string,
@ -43,7 +43,7 @@ StopsTableEntry.propTypes = {
parentStation: PropTypes.string,
wheelchairBoarding: PropTypes.number,
platformCode: PropTypes.string,
zoneId: PropTypes.string
zoneId: PropTypes.string,
};
export default StopsTableEntry;

View File

@ -1,6 +1,6 @@
import React from 'react';
const StopsTableHead = () => {
function StopsTableHead() {
return (
<tr>
<th>stop_id</th>
@ -16,6 +16,6 @@ const StopsTableHead = () => {
<th>zone_id</th>
</tr>
);
};
}
export default StopsTableHead;

View File

@ -155,28 +155,16 @@ function TableEntrySwitch ({ aryData, name }) {
);
break;
case 'stop_times':
let arrivalTime = item.arrival_time;
const arrivalTime = item.arrival_time;
/* TODO Why is this condition neccessary? */
if (arrivalTime) {
return (
<StopTimesEntry
tripId={item.trip_id}
arrivalTimeHours={item.arrival_time['hours']}
arrivalTimeMinutes={item.arrival_time['minutes']}
departureTimeHours={item.departure_time['hours']}
departureTimeMinutes={item.departure_time['minutes']}
stopId={item.stop_id}
stopSequence={item.stop_sequence}
pickupType={item.pickup_type}
dropOffType={item.drop_off_type}
stopHeadsign={item.stop_headsign}
key={index}
/>
);
} else {
return (
<StopTimesEntry
tripId={item.trip_id}
arrivalTimeHours={item.arrival_time.hours}
arrivalTimeMinutes={item.arrival_time.minutes}
departureTimeHours={item.departure_time.hours}
departureTimeMinutes={item.departure_time.minutes}
stopId={item.stop_id}
stopSequence={item.stop_sequence}
pickupType={item.pickup_type}
@ -186,6 +174,18 @@ function TableEntrySwitch ({ aryData, name }) {
/>
);
}
return (
<StopTimesEntry
tripId={item.trip_id}
stopId={item.stop_id}
stopSequence={item.stop_sequence}
pickupType={item.pickup_type}
dropOffType={item.drop_off_type}
stopHeadsign={item.stop_headsign}
key={index}
/>
);
break;
case 'transfers':
return (
@ -224,12 +224,11 @@ function TableEntrySwitch ({ aryData, name }) {
return null;
}
});
}else{
return null;
}
return null;
}
TableEntrySwitch.propTypes = {
aryData: PropTypes.array,
name: PropTypes.string
name: PropTypes.string,
};
export default TableEntrySwitch;

View File

@ -62,6 +62,6 @@ function TableHeadSwitch ({ name }) {
}
}
TableHeadSwitch.propTypes = {
name: PropTypes.string
name: PropTypes.string,
};
export default TableHeadSwitch;

View File

@ -6,7 +6,6 @@ import TableSwitchBody from './table-switch-trip-calendar-body';
import config from '../config';
export default function TablePageBody({ agencyIdName }) {
if (agencyIdName !== undefined) {
// console.log('TablePageBody agencyIdName:'+JSON.stringify(agencyIdName));
// console.log('TablePageBody agencyIdName.length:'+agencyIdName.length);
@ -26,11 +25,11 @@ export default function TablePageBody({ agencyIdName }) {
/* TODO handle errors: https://www.valentinog.com/blog/await-react/ */
const res = await axios.get(address);
let aryTripCalendar = res.data;
const aryTripCalendar = res.data;
// console.log('aryTripCalendar.length:'+aryTripCalendar.length);
setTripCalendar(aryTripCalendar);
} catch (err) {
console.error('err.message: ' + err.message);
console.error(`err.message: ${err.message}`);
}
};
/* this hook is run after a DOM update. Changing state might result in an infinite loop */
@ -41,19 +40,16 @@ export default function TablePageBody({ agencyIdName }) {
/* TODO study dependency array: https://reactjs.org/docs/hooks-effect.html */
}, []);
return (
<>
<TableSwitchBody
tripCalendar={tripCalendar}
agencyId={agencyId}
agencyName={agencyName}
/>
</>
);
}else{
return <p>Table Page Body loading...</p>
}
};
return <p>Table Page Body loading...</p>;
}
TablePageBody.propTypes = {
agencyIdName: PropTypes.object
agencyIdName: PropTypes.object,
};

View File

@ -6,7 +6,6 @@ import TableSwitchHead from './table-switch-trip-calendar-head';
import config from '../config';
export default function TablePageHead({ agencyIdName }) {
if (agencyIdName !== undefined) {
// console.log('TablePageHead agencyIdName:'+JSON.stringify(agencyIdName));
// console.log('TablePageHead agencyIdName.length:'+agencyIdName.length);
@ -19,7 +18,6 @@ export default function TablePageHead({ agencyIdName }) {
const [tripCalendar, setTripCalendar] = useState({});
const getTripCalendar = async () => {
try {
/* get trip calendar */
const address = `${config.API}trip-calendar-by-agency-id?agencyid=${agencyId}`;
@ -28,12 +26,11 @@ export default function TablePageHead({ agencyIdName }) {
/* TODO handle errors: https://www.valentinog.com/blog/await-react/ */
const res = await axios.get(address);
let aryTripCalendar = res.data;
const aryTripCalendar = res.data;
// console.log('TablePageHead aryTripCalendar.length:'+aryTripCalendar.length);
setTripCalendar(aryTripCalendar);
} catch (err) {
console.error('err.message: ' + err.message);
console.error(`err.message: ${err.message}`);
}
};
@ -42,30 +39,24 @@ export default function TablePageHead({ agencyIdName }) {
/* hook need to be placed in body of the function component in which it is used */
useEffect(() => {
getTripCalendar();
/* use an empty dependency array to ensure the hook is running only once */
/* TODO study dependency array: https://reactjs.org/docs/hooks-effect.html */
}, []);
return (
<>
<TableSwitchHead
tripCalendar={tripCalendar}
agencyId={agencyId}
agencyName={agencyName}
/>
</>
);
}else{
return <p>loading...</p>
}
};
return <p>loading...</p>;
}
TablePageHead.propTypes = {
agencyIdName: PropTypes.object
agencyIdName: PropTypes.object,
};

View File

@ -7,7 +7,7 @@ import TableSwitch from './table-switch';
import Select from './select';
import { selectOptions } from '../utils/select-options';
const TablePage = ({ name }) => {
function TablePage({ name }) {
/* store and initialise data in function component state */
const [oset, setOset] = useState(1);
const [limit, setLimit] = useState(parseInt(selectOptions[0], 10));
@ -25,8 +25,10 @@ const TablePage = ({ name }) => {
setSearchField((searchField) => e.target.value);
};
if (name && name.indexOf(' ') === -1) {
return <>
<button onClick={handleClickPrev}>prev</button>&nbsp;
return (
<>
<button onClick={handleClickPrev}>prev</button>
&nbsp;
<button onClick={handleClickNext}>next</button>
<Select
defaultValue={selectOptions[0]}
@ -51,12 +53,12 @@ const TablePage = ({ name }) => {
limit={limit}
filter={searchField}
/>
</>;
} else {
</>
);
}
return <p>Loading...</p>;
}
};
TablePage.propTypes = {
name: PropTypes.string
name: PropTypes.string,
};
export default TablePage;

View File

@ -7,17 +7,16 @@ import TableEntry from './agency-id-name-table-entry';
function TableSwitchBody({
tripCalendar,
agencyId,
agencyName
agencyName,
}) {
if(tripCalendar!==undefined &&
agencyId!==undefined &&
agencyName!==undefined){
if (tripCalendar !== undefined
&& agencyId !== undefined
&& agencyName !== undefined) {
// console.log('TableSwitchBody agencyId: '+agencyId);
// console.log('TableSwitchBody agencyName: '+agencyName);
// console.log('TableSwitchBody tripCalendar.length: '+Object.keys(tripCalendar).length);
/* return a React element */
return (
<>
<tbody>
<TableEntry
agencyId={agencyId}
@ -25,16 +24,14 @@ function TableSwitchBody ({
tripCalendar={tripCalendar}
/>
</tbody>
</>
);
}else{
//console.log('TableSwitchBody waiting for prop');
return <p>Table Switch Body loading...</p>
}
// console.log('TableSwitchBody waiting for prop');
return <p>Table Switch Body loading...</p>;
}
TableSwitchBody.propTypes = {
tripCalendar: PropTypes.object,
agencyId: PropTypes.string,
agencyName: PropTypes.string
agencyName: PropTypes.string,
};
export default TableSwitchBody;

View File

@ -9,19 +9,16 @@ export default function TableSwitchHead({tripCalendar}) {
if (tripCalendar !== undefined) {
/* return a React element */
return (
<>
<thead>
<TableHead
tripCalendar={tripCalendar}
/>
</thead>
</>
);
}else{
return <p>loading...</p>
}
return <p>loading...</p>;
}
TableSwitchHead.propTypes = {
tripCalendar: PropTypes.object
tripCalendar: PropTypes.object,
};

View File

@ -7,13 +7,11 @@ import TableEntrySwitch from './table-entry-switch';
import config from '../config';
import { filterData } from '../utils/filter-data';
/* the simplest way to define a component is to write a JavaScript function */
/* destructure props object */
function TableSwitch ({name, isFetched, oset, limit, filter}) {
function TableSwitch({
name, isFetched, oset, limit, filter,
}) {
// console.log('TableSwitch name: '+name);
// console.log('TableSwitch isFetched: '+isFetched);
// console.log('TableSwitch filter: '+filter);
@ -30,9 +28,8 @@ function TableSwitch ({name, isFetched, oset, limit, filter}) {
const res = await axios.get(address);
if (res.data) {
setAry((ary) => res.data);
let data=filterData(res.data,name,filter);
const data = filterData(res.data, name, filter);
setAryFiltered((aryFiltered) => data);
} else {
console.error('fetch() res NOT available');
@ -42,33 +39,15 @@ function TableSwitch ({name, isFetched, oset, limit, filter}) {
setAry((ary) => []);
}
} catch (err) {
console.error('err.message: ' + err.message);
console.error(`err.message: ${err.message}`);
setAry((ary) => []);
setAryFiltered((aryFiltered) => []);
}
};
useEffect(() => {
setAryFiltered((aryFiltered) => {
let filtered=filterData(ary,name,filter);
const filtered = filterData(ary, name, filter);
return filtered;
});
}, [filter]);
@ -82,7 +61,6 @@ function TableSwitch ({name, isFetched, oset, limit, filter}) {
if (fetchCompleted && aryFiltered.length > -1) {
/* return a React element */
return (
<>
<table>
<thead>
<TableHeadSwitch name={name} />
@ -91,17 +69,15 @@ function TableSwitch ({name, isFetched, oset, limit, filter}) {
<TableEntrySwitch aryData={aryFiltered} name={name} />
</tbody>
</table>
</>
);
}else{
return null;
}
return null;
}
TableSwitch.propTypes = {
name: PropTypes.string,
isFetched: PropTypes.bool,
offset: PropTypes.number,
limit: PropTypes.number,
filter: PropTypes.string
filter: PropTypes.string,
};
export default TableSwitch;

View File

@ -6,11 +6,10 @@ import FileSelection from './file-selection';
export default function Tables({ data }) {
if (data.length > 0) {
return <FileSelection options={data} />;
} else {
}
return <p>Selection loading...</p>;
}
};
Tables.propTypes = {
data: PropTypes.array
data: PropTypes.array,
};

View File

@ -2,7 +2,7 @@ import React from 'react';
import PropTypes from 'prop-types';
/* destructure props object */
const TransfersTableEntry = ({
function TransfersTableEntry({
fromStopId,
toStopId,
fromRouteId,
@ -10,8 +10,8 @@ const TransfersTableEntry = ({
fromTripId,
toTripId,
transferType,
minTransferTime
}) => {
minTransferTime,
}) {
return (
<tr>
<td>{fromStopId}</td>
@ -24,7 +24,7 @@ const TransfersTableEntry = ({
<td>{minTransferTime}</td>
</tr>
);
};
}
TransfersTableEntry.propTypes = {
fromStopId: PropTypes.string,
@ -34,7 +34,7 @@ TransfersTableEntry.propTypes = {
fromTripId: PropTypes.string,
toTripId: PropTypes.string,
transferType: PropTypes.number,
minTransferTime: PropTypes.number
minTransferTime: PropTypes.number,
};
export default TransfersTableEntry;

View File

@ -1,6 +1,6 @@
import React from 'react';
const TransfersTableHead = () => {
function TransfersTableHead() {
return (
<tr>
<th>from_stop_id</th>
@ -13,6 +13,6 @@ const TransfersTableHead = () => {
<th>min_transfer_time</th>
</tr>
);
};
}
export default TransfersTableHead;

View File

@ -3,31 +3,51 @@ import PropTypes from 'prop-types';
export default function TripUpdatesRouteDayTableEntries({ array }) {
if (array !== undefined && array !== null && array.length > 0) {
// TODO Shall we switch from UTC to local time zone for item.timestamp_pgsql?
// iterate over array
return array.map((item, index) => {
return (
return array.map((item, index) => (
<tr
key={index}
>
<td>{item.agency_name}&nbsp;|</td>
<td>{item.agency_id}&nbsp;|</td>
<td>{item.route_id}&nbsp;|</td>
<td>{item.route_short_name}&nbsp;|</td>
<td>{item.trip_id}&nbsp;|</td>
<td>{item.trip_short_name}&nbsp;|</td>
<td>{item.trip_headsign}&nbsp;|</td>
<td>{item.timestamp_pgsql}&nbsp;|</td>
<td>
{item.agency_name}
&nbsp;|
</td>
<td>
{item.agency_id}
&nbsp;|
</td>
<td>
{item.route_id}
&nbsp;|
</td>
<td>
{item.route_short_name}
&nbsp;|
</td>
<td>
{item.trip_id}
&nbsp;|
</td>
<td>
{item.trip_short_name}
&nbsp;|
</td>
<td>
{item.trip_headsign}
&nbsp;|
</td>
<td>
{item.timestamp_pgsql}
&nbsp;|
</td>
</tr>
);
});
}else{
));
}
// data is empty
return null;
}
};
TripUpdatesRouteDayTableEntries.propTypes = {
array: PropTypes.array
array: PropTypes.array,
};

View File

@ -5,12 +5,19 @@ import TripUpdatesRouteDayTableEntries from './trip-updates-route-day-table-entr
/* destructure props object */
export default function TripUpdatesRouteDayTable({ array, title, date }) {
if (array !== undefined && array !== null) {
/* return a React element */
return (
<>
<p>Table of {array.length}&nbsp;{title} for {date}:</p>
<p>
Table of
{array.length}
{title}
{' '}
for
{date}
:
</p>
<table>
<thead>
<tr>
@ -30,16 +37,13 @@ export default function TripUpdatesRouteDayTable ({array, title, date}){
</table>
</>
);
}else{
}
return (
<>
<p>loading...</p>
</>
);
}
};
TripUpdatesRouteDayTable.propTypes = {
array: PropTypes.array,
title: PropTypes.string,
date: PropTypes.string
date: PropTypes.string,
};

View File

@ -4,8 +4,7 @@ import PropTypes from 'prop-types';
export default function TableEntries({ array }) {
if (array !== undefined && array !== null && array.length > 0) {
// iterate over array
return array.map((item, index) => {
return (
return array.map((item, index) => (
<tr
key={item.trip_id}
>
@ -18,14 +17,12 @@ export default function TableEntries ({array}) {
<td>{item.trip_short_name}</td>
<td>{item.trip_headsign}</td>
</tr>
);
});
}else{
));
}
// data is empty
return null;
}
};
TableEntries.propTypes = {
array: PropTypes.array
array: PropTypes.array,
};

View File

@ -5,12 +5,17 @@ import TableEntries from './trips-route-day-table-entries';
/* destructure props object */
export default function TripsRouteDayTable({ array, title }) {
if (array !== undefined && array !== null) {
/* return a React element */
return (
<>
<p>Table of {array.length}&nbsp;{title} for today:</p>
<p>
Table of
{array.length}
{title}
{' '}
for today:
</p>
<table>
<thead>
<tr>
@ -30,15 +35,12 @@ export default function TripsRouteDayTable ({array, title}){
</table>
</>
);
}else{
}
return (
<>
<p>loading...</p>
</>
);
}
};
TripsRouteDayTable.propTypes = {
array: PropTypes.array,
title: PropTypes.string
title: PropTypes.string,
};

View File

@ -2,7 +2,7 @@ import React from 'react';
import PropTypes from 'prop-types';
/* destructure props object */
const TripsTableEntry = ({
function TripsTableEntry({
routeId,
serviceId,
tripId,
@ -12,8 +12,8 @@ const TripsTableEntry = ({
blockId,
shapeId,
wheelchairAccessible,
bikesAllowed
}) => {
bikesAllowed,
}) {
return (
<tr>
<td>{routeId}</td>
@ -28,7 +28,7 @@ const TripsTableEntry = ({
<td>{bikesAllowed}</td>
</tr>
);
};
}
TripsTableEntry.propTypes = {
routeId: PropTypes.string,
@ -40,7 +40,7 @@ TripsTableEntry.propTypes = {
blockId: PropTypes.string,
shapeId: PropTypes.string,
wheelchairAccessible: PropTypes.number,
bikesAllowed: PropTypes.number
bikesAllowed: PropTypes.number,
};
export default TripsTableEntry;

View File

@ -1,6 +1,6 @@
import React from 'react';
const TripsTableHead = () => {
function TripsTableHead() {
return (
<tr>
<th>route_id</th>
@ -15,6 +15,6 @@ const TripsTableHead = () => {
<th>bikes_allowed</th>
</tr>
);
};
}
export default TripsTableHead;

View File

@ -1,5 +1,7 @@
import React from 'react';
import { BrowserRouter as Router, Route, Routes, Navigate } from 'react-router-dom';
import {
BrowserRouter as Router, Route, Routes, Navigate,
} from 'react-router-dom';
import Header from './components/header';
import Home from './pages/homepage';
@ -12,7 +14,8 @@ import Realtime from './pages/realtime';
// TODO import Trips from './pages/trips-route-day';
import Contact from './pages/contact';
import packageInfo from '../package.json'
import packageInfo from '../package.json';
const VERSION = packageInfo.version;
export default function Main() {
@ -51,4 +54,4 @@ export default function Main() {
/** TODO Disable this route as it is way too much overhead for API and database!
<Route exact path="/trip-calendar" element={<TripCalendar />} />
*/
};
}

View File

@ -7,7 +7,6 @@ import AgencySelect from '../components/agency-select';
import Input from '../components/input';
export default function AgencyPerDay() {
const dateDefault = 'Select date';
const [date, setDate] = useState(dateDefault);
@ -21,8 +20,8 @@ export default function AgencyPerDay() {
// TODO How do we handle invalid date input?
const handleDate = (e) => {
if (e.target.value.indexOf('2023') !== -1 ||
e.target.value.indexOf('2024') !== -1) {
if (e.target.value.indexOf('2023') !== -1
|| e.target.value.indexOf('2024') !== -1) {
setDate((date) => e.target.value);
}
};
@ -36,13 +35,13 @@ export default function AgencyPerDay() {
// console.log('trip-updates-route-day res.data.length: Agencies: ' + res.data.length);
setRryAgencies((rryAgencies) => res.data);
} catch (err) {
console.error('err.message: ' + err.message);
console.error(`err.message: ${err.message}`);
}
};
const getRryAgencyPerDay = async () => {
if ( strngAgencyId !== agencyNameDefault &&
date !== dateDefault) {
if (strngAgencyId !== agencyNameDefault
&& date !== dateDefault) {
try {
/* TODO handle errors: https://www.valentinog.com/blog/await-react/ */
const address = `${config.API}trip-updates-by-agency-day?agencyid=${strngAgencyId}&day=${date}`;
@ -55,7 +54,7 @@ export default function AgencyPerDay() {
console.error('ERROR: trip-updates by routes and day request FAILED');
}
} catch (err) {
console.error('err.message: ' + err.message);
console.error(`err.message: ${err.message}`);
}
}
};
@ -79,8 +78,8 @@ export default function AgencyPerDay() {
/* TODO study dependency array: https://reactjs.org/docs/hooks-effect.html */
}, [strngAgencyId, date]);
return <>
return (
<>
<label>
<Input
id="inputDate"
@ -93,6 +92,7 @@ export default function AgencyPerDay() {
/>
</label>
<AgencySelect rry={rryAgencies} name={agencyNameDefault} onChange={handleChangeAgencyId} />
<AgencyPerDayTable array={rryAgencyPerDay} title={'routes'} date={date}/>
</>;
};
<AgencyPerDayTable array={rryAgencyPerDay} title="routes" date={date} />
</>
);
}

View File

@ -1,6 +1,7 @@
import React from 'react';
import packageInfo from '../../package.json'
import packageInfo from '../../package.json';
const VERSION = packageInfo.version;
export default function Contact() {
@ -10,18 +11,36 @@ export default function Contact() {
For questions about this website please do not hesitate to reach out to dialog (at) swingbe (dot) de.
</p>
<p>
Please feel <b>free</b> to <b>use</b>, <b>study</b>, <b>share</b> or <b>improve</b> the{' '}
Please feel
{' '}
<b>free</b>
{' '}
to
<b>use</b>
,
<b>study</b>
,
<b>share</b>
{' '}
or
<b>improve</b>
{' '}
the
{' '}
<a
href="https://git.wtf-eg.de/dancingCycle/gtfs-display"
target="_blank"
rel="noreferrer"
>
source
</a>
.
</p>
<p>
Version: {VERSION}
Version:
{' '}
{VERSION}
</p>
</>
);
};
}

View File

@ -4,10 +4,16 @@ import axios from 'axios';
import Tables from '../components/tables';
import gtfs from '../utils/gtfs';
const Files = () => {
return <fieldset>
<legend><b>GTFS Schedule</b> file overview</legend>
function Files() {
return (
<fieldset>
<legend>
<b>GTFS Schedule</b>
{' '}
file overview
</legend>
<Tables data={gtfs.datasetFiles} />
</fieldset>;
};
</fieldset>
);
}
export default Files;

View File

@ -6,7 +6,6 @@ import GroupAgencyPerDayTable from '../components/group-agency-per-day-table';
import Input from '../components/input';
export default function GroupAgencyPerDay() {
const dateDefault = 'Select date';
const [date, setDate] = useState(dateDefault);
@ -15,8 +14,8 @@ export default function GroupAgencyPerDay() {
// TODO How do we handle invalid date input?
const handleDate = (e) => {
if (e.target.value.indexOf('2023') !== -1 ||
e.target.value.indexOf('2024') !== -1) {
if (e.target.value.indexOf('2023') !== -1
|| e.target.value.indexOf('2024') !== -1) {
setDate((date) => e.target.value);
}
};
@ -35,7 +34,7 @@ export default function GroupAgencyPerDay() {
console.error('ERROR: trip-updates by routes and day request FAILED');
}
} catch (err) {
console.error('err.message: ' + err.message);
console.error(`err.message: ${err.message}`);
}
}
};
@ -48,7 +47,8 @@ export default function GroupAgencyPerDay() {
/* TODO study dependency array: https://reactjs.org/docs/hooks-effect.html */
}, [date]);
return <>
return (
<>
<label>
<Input
id="inputDate"
@ -60,6 +60,7 @@ export default function GroupAgencyPerDay() {
value={date}
/>
</label>
<GroupAgencyPerDayTable array={rryGroupAgencyPerDay} title={'agencies'} date={date}/>
</>;
};
<GroupAgencyPerDayTable array={rryGroupAgencyPerDay} title="agencies" date={date} />
</>
);
}

View File

@ -5,4 +5,4 @@ import GtfsFiles from '../components/gtfs-files';
export default function Homepage() {
return <GtfsFiles />;
};
}

View File

@ -5,7 +5,6 @@ import OverviewTable from '../components/overview-next-table';
import config from '../config';
export default function OverviewNext() {
const [cnts, setCnts] = useState([]);
const getCnts = async () => {
@ -17,9 +16,8 @@ export default function OverviewNext() {
if (res !== null && res !== undefined) {
setCnts(res.data);
}
} catch (err) {
console.error('err.message: ' + err.message);
console.error(`err.message: ${err.message}`);
}
};
@ -27,10 +25,8 @@ export default function OverviewNext() {
getCnts();
}, []);
if (cnts === null || cnts === undefined || cnts.length === 0) {
return <p>loading...</p>;
} else {
}
return <OverviewTable overview={cnts} />;
}
};

View File

@ -5,7 +5,6 @@ import OverviewTable from '../components/overview-table';
import config from '../config';
export default function Overview() {
/* store data in function component state */
/* initialise as empty array */
const [overview, setOverview] = useState([]);
@ -14,7 +13,7 @@ export default function Overview() {
const handleAsyncOps = async (isMounted) => {
/* get data for each agency */
for (var j = 0; j < overview.length; j++) {
for (let j = 0; j < overview.length; j++) {
// console.log('j: ' + j);
let isBreaking = false;
// 1. Make a shallow copy of the objects
@ -29,7 +28,7 @@ export default function Overview() {
// console.log('routeCount: ' + routeCount);
if (routeCount === null) {
const resRouteCount = await axios.get(
`${config.API}route-count?agencyid=${agencyId}`
`${config.API}route-count?agencyid=${agencyId}`,
);
obj.route_count = resRouteCount.data;
routeCount = obj.route_count;
@ -40,7 +39,7 @@ export default function Overview() {
// console.log('tripCount: ' + tripCount);
if (tripCount === null) {
const resTripCount = await axios.get(
`${config.API}trip-count?agencyid=${agencyId}`
`${config.API}trip-count?agencyid=${agencyId}`,
);
obj.trip_count = resTripCount.data;
tripCount = obj.trip_count;
@ -64,16 +63,16 @@ export default function Overview() {
/* TODO handle errors: https://www.valentinog.com/blog/await-react/ */
const res = await axios.get(`${config.API}agency-all`);
let aryOv = res.data;
for (var i = 0; i < aryOv.length; i++) {
let agencyId = aryOv[i].agency_id;
let agencyName = aryOv[i].agency_name;
let objOvItem = {};
objOvItem['agency_id'] = agencyId;
objOvItem['agency_name'] = agencyName;
objOvItem['route_count'] = null;
objOvItem['trip_count'] = null;
objOvItem['day'] = null;
const aryOv = res.data;
for (let i = 0; i < aryOv.length; i++) {
const agencyId = aryOv[i].agency_id;
const agencyName = aryOv[i].agency_name;
const objOvItem = {};
objOvItem.agency_id = agencyId;
objOvItem.agency_name = agencyName;
objOvItem.route_count = null;
objOvItem.trip_count = null;
objOvItem.day = null;
/* set state */
if (isMounted) {
@ -85,7 +84,7 @@ export default function Overview() {
/* set... is an async function and you cannot get the state value immediately after update. Use useEffect hook instead */
setAgencies((agencies) => !agencies);
} catch (err) {
console.error('err.message: ' + err.message);
console.error(`err.message: ${err.message}`);
}
};
@ -133,4 +132,4 @@ export default function Overview() {
}, []);
return <OverviewTable overview={overview} />;
};
}

View File

@ -6,7 +6,6 @@ import PerDayTable from '../components/per-day-table';
import Input from '../components/input';
export default function PerDay() {
const dateDefault = 'Select date';
const [date, setDate] = useState(dateDefault);
@ -15,8 +14,8 @@ export default function PerDay() {
// TODO How do we handle invalid date input?
const handleDate = (e) => {
if (e.target.value.indexOf('2023') !== -1 ||
e.target.value.indexOf('2024') !== -1) {
if (e.target.value.indexOf('2023') !== -1
|| e.target.value.indexOf('2024') !== -1) {
setDate((date) => e.target.value);
}
};
@ -35,7 +34,7 @@ export default function PerDay() {
console.error('ERROR: trip-updates by routes and day request FAILED');
}
} catch (err) {
console.error('err.message: ' + err.message);
console.error(`err.message: ${err.message}`);
}
}
};
@ -48,7 +47,8 @@ export default function PerDay() {
/* TODO study dependency array: https://reactjs.org/docs/hooks-effect.html */
}, [date]);
return <>
return (
<>
<label>
<Input
id="inputDate"
@ -60,6 +60,7 @@ export default function PerDay() {
value={date}
/>
</label>
<PerDayTable array={rryPerDay} title={'feeds'} date={date}/>
</>;
};
<PerDayTable array={rryPerDay} title="feeds" date={date} />
</>
);
}

View File

@ -8,7 +8,7 @@ export default function Realtime() {
const handleChange = (e) => {
setState(e.target.value);
}
};
return (
<>
<RadioButton state={state} onChange={handleChange} />
@ -16,5 +16,4 @@ export default function Realtime() {
<Rltm state={state} />
</>
);
};
}

View File

@ -7,7 +7,8 @@ import ChartBar from '../components/chart-bar';
import ChartLine from '../components/chart-line';
import GtfsService from '../utils/gtfs-service';
import config from '../config';
const Service = () => {
function Service() {
/* store route as string */
const [route, setRoute] = useState('');
const [render, setRender] = useState(false);
@ -20,7 +21,7 @@ const Service = () => {
const getObjService = async () => {
try {
/* TODO handle errors: https://www.valentinog.com/blog/await-react/ */
let url = `${config.API}servicedays?routeshortname=${route}`;
const url = `${config.API}servicedays?routeshortname=${route}`;
setLoading(true);
const objService = await axios.get(url);
setLoading(false);
@ -34,7 +35,7 @@ const Service = () => {
const aryDate = aryTime.map((time) => new Date(time).toDateString());
setTime(aryDate);
} catch (err) {
console.error('err.message: ' + err.message);
console.error(`err.message: ${err.message}`);
}
};
@ -56,7 +57,7 @@ const Service = () => {
<>
<FormValue
value={route}
valueName={'route'}
valueName="route"
onSubmit={handleSubmit}
onChange={handleChange}
/>
@ -64,7 +65,7 @@ const Service = () => {
<div
style={{
height: '500px',
width: '900px'
width: '900px',
}}
>
{bar}
@ -72,7 +73,7 @@ const Service = () => {
<div
style={{
height: '500px',
width: '900px'
width: '900px',
}}
>
{line}
@ -80,5 +81,5 @@ const Service = () => {
{msgTable}
</>
);
};
}
export default Service;

View File

@ -7,7 +7,6 @@ import TablePageHead from '../components/table-page-trip-calendar-head';
import TablePageBody from '../components/table-page-trip-calendar-body';
export default function TripCalendar() {
/* store and initialize data in function component state */
const [agencyIds, setAgencyIds] = useState([]);
@ -17,11 +16,11 @@ export default function TripCalendar() {
/* TODO handle errors: https://www.valentinog.com/blog/await-react/ */
const res = await axios.get(`${config.API}agencyids`);
let aryAgencyIds = res.data;
const aryAgencyIds = res.data;
// console.log('TripCalendar aryAgencyIds.length:'+aryAgencyIds.length);
setAgencyIds(aryAgencyIds);
} catch (err) {
console.error('err.message: ' + err.message);
console.error(`err.message: ${err.message}`);
}
};
@ -33,20 +32,22 @@ export default function TripCalendar() {
/* TODO study dependency array: https://reactjs.org/docs/hooks-effect.html */
}, []);
const agencysTableBody = agencyIds.map(value =>
const agencysTableBody = agencyIds.map((value) => (
<TablePageBody
className={value.agency_name}
agencyIdName={value}
key={value.agency_id}
/>
);
const agencysTableHead = <TablePageHead
className='tablePageHead'
));
const agencysTableHead = (
<TablePageHead
className="tablePageHead"
agencyIdName={agencyIds[0]}
/>
);
if (agencyIds.length > 0) {
/* TODO Introduce thead and tbody in Table? */
return <>
return (
<Table
striped
bordered
@ -58,8 +59,7 @@ export default function TripCalendar() {
{agencysTableHead}
{agencysTableBody}
</Table>
</>
}else{
return <p>loading...</p>
);
}
return <p>loading...</p>;
}
};

View File

@ -8,7 +8,6 @@ import RouteSelect from '../components/route-select';
import Input from '../components/input';
export default function TripUpdates() {
const dateDefault = 'Select date';
const [date, setDate] = useState(dateDefault);
@ -25,8 +24,8 @@ export default function TripUpdates() {
// TODO How do we handle invalid date input?
const handleDate = (e) => {
if (e.target.value.indexOf('2023') !== -1 ||
e.target.value.indexOf('2024') !== -1) {
if (e.target.value.indexOf('2023') !== -1
|| e.target.value.indexOf('2024') !== -1) {
setDate((date) => e.target.value);
}
};
@ -40,7 +39,7 @@ export default function TripUpdates() {
// console.log('trip-updates-route-day res.data.length: Agencies: ' + res.data.length);
setRryAgencies((rryAgency) => res.data);
} catch (err) {
console.error('err.message: ' + err.message);
console.error(`err.message: ${err.message}`);
}
};
@ -62,16 +61,15 @@ export default function TripUpdates() {
} else {
console.error('ERROR: routes by agency request FAILED');
}
} catch (err) {
console.error('err.message: ' + err.message);
console.error(`err.message: ${err.message}`);
}
}
};
const getRryTripUpdates = async () => {
if ( strngRouteId !== routeNameDefault &&
date !== dateDefault) {
if (strngRouteId !== routeNameDefault
&& date !== dateDefault) {
try {
/* TODO handle errors: https://www.valentinog.com/blog/await-react/ */
// console.log('route: ' + strngRouteId);
@ -85,7 +83,7 @@ export default function TripUpdates() {
console.error('ERROR: trip-updates by routes and day request FAILED');
}
} catch (err) {
console.error('err.message: ' + err.message);
console.error(`err.message: ${err.message}`);
}
}
};
@ -120,9 +118,9 @@ export default function TripUpdates() {
/* TODO study dependency array: https://reactjs.org/docs/hooks-effect.html */
}, [strngRouteId, date]);
// TODO get rry based on route_id!
return <>
return (
<>
<label>
<Input
id="inputDate"
@ -136,6 +134,7 @@ export default function TripUpdates() {
</label>
<AgencySelect rry={rryAgencies} name={agencyNameDefault} onChange={handleChangeAgencyId} />
<RouteSelect rry={rryRoutes} name={routeNameDefault} onChange={handleChangeRouteId} />
<TripUpdatesRouteDayTable array={rryTripUpdates} title={'trips'} date={date}/>
</>;
};
<TripUpdatesRouteDayTable array={rryTripUpdates} title="trips" date={date} />
</>
);
}

View File

@ -7,7 +7,6 @@ import AgencySelect from '../components/agency-select';
import RouteSelect from '../components/route-select';
export default function Trips() {
const agencyNameDefault = 'Select GTFS agency_name';
const routeNameDefault = 'Select GTFS route_short_name';
@ -27,7 +26,7 @@ export default function Trips() {
// console.log('trips-route-day res.data.length: Agencies: ' + res.data.length);
setRryAgencies((rryAgency) => res.data);
} catch (err) {
console.error('err.message: ' + err.message);
console.error(`err.message: ${err.message}`);
}
};
@ -49,9 +48,8 @@ export default function Trips() {
} else {
console.error('ERROR: routes by agency request FAILED');
}
} catch (err) {
console.error('err.message: ' + err.message);
console.error(`err.message: ${err.message}`);
}
}
};
@ -61,7 +59,7 @@ export default function Trips() {
try {
/* TODO handle errors: https://www.valentinog.com/blog/await-react/ */
const date = new Date();
const dateShort = date.getFullYear() + '-' + (date.getMonth()+1) + '-' + date.getDate();
const dateShort = `${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()}`;
// console.log('trips-route-day dateShort: ' + dateShort);
const address = `${config.API}trips-by-route-day?routeid=${strngRouteId}&day=${dateShort}`;
// console.log('trips-route-day res.data.length: address: ' + address);
@ -73,7 +71,7 @@ export default function Trips() {
console.error('ERROR: trips by routes and day request FAILED');
}
} catch (err) {
console.error('err.message: ' + err.message);
console.error(`err.message: ${err.message}`);
}
}
};
@ -108,11 +106,12 @@ export default function Trips() {
/* TODO study dependency array: https://reactjs.org/docs/hooks-effect.html */
}, [strngRouteId]);
// TODO get rry based on route_id!
return <>
return (
<>
<AgencySelect rry={rryAgencies} name={agencyNameDefault} onChange={handleChangeAgencyId} />
<RouteSelect rry={rryRoutes} name={routeNameDefault} onChange={handleChangeRouteId} />
<TripsRouteDayTable array={rryTrips} title={'Trips'} />
</>;
};
<TripsRouteDayTable array={rryTrips} title="Trips" />
</>
);
}

View File

@ -2,14 +2,14 @@ function getAryThisWeek (date) {
const dateToday = new Date();
let dateIncrement = new Date(dateToday);
const aryThisWeek = [];
for (var i = 0; i < 7; i++) {
for (let i = 0; i < 7; i++) {
aryThisWeek[i] = new Date(dateIncrement);
dateIncrement = new Date(
dateIncrement.setDate(dateIncrement.getDate() + 1)
dateIncrement.setDate(dateIncrement.getDate() + 1),
);
}
return aryThisWeek;
}
module.exports = {
getAryThisWeek
getAryThisWeek,
};

View File

@ -5,91 +5,77 @@ function filterData(data, name,filter){
// console.log('filterData() filter:'+filter);
switch (name) {
case 'agency':
return data.filter((item, index) => {
return (
(item.agency_id!==null && item.agency_id.toLowerCase().includes(filter.toLowerCase())) ||
item.agency_name.toLowerCase().includes(filter.toLowerCase()) ||
item.agency_url.toLowerCase().includes(filter.toLowerCase()) ||
item.agency_timezone.toLowerCase().includes(filter.toLowerCase()) ||
(item.agency_lang!==null && item.agency_lang.toLowerCase().includes(filter.toLowerCase())) ||
(item.agency_phone!==null && item.agency_phone.toLowerCase().includes(filter.toLowerCase()))
);
});
return data.filter((item, index) => (
(item.agency_id !== null && item.agency_id.toLowerCase().includes(filter.toLowerCase()))
|| item.agency_name.toLowerCase().includes(filter.toLowerCase())
|| item.agency_url.toLowerCase().includes(filter.toLowerCase())
|| item.agency_timezone.toLowerCase().includes(filter.toLowerCase())
|| (item.agency_lang !== null && item.agency_lang.toLowerCase().includes(filter.toLowerCase()))
|| (item.agency_phone !== null && item.agency_phone.toLowerCase().includes(filter.toLowerCase()))
));
break;
case 'agency-id-name':
return data.filter((item, index) => {
return (
(item.agency_id!==null && item.agency_id.toLowerCase().includes(filter.toLowerCase())) ||
item.agency_name.toLowerCase().includes(filter.toLowerCase())
);
});
return data.filter((item, index) => (
(item.agency_id !== null && item.agency_id.toLowerCase().includes(filter.toLowerCase()))
|| item.agency_name.toLowerCase().includes(filter.toLowerCase())
));
break;
case 'frequencies':
return data.filter((item, index) => {
return (
item.trip_id.toLowerCase().includes(filter.toLowerCase()) ||
item.start_time.toLowerCase().includes(filter.toLowerCase()) ||
item.end_time.toLowerCase().includes(filter.toLowerCase()) ||
item.headway_secs.toString().includes(filter) ||
(item.exact_times!==null && item.exact_times.toString().includes(filter))
);
});
return data.filter((item, index) => (
item.trip_id.toLowerCase().includes(filter.toLowerCase())
|| item.start_time.toLowerCase().includes(filter.toLowerCase())
|| item.end_time.toLowerCase().includes(filter.toLowerCase())
|| item.headway_secs.toString().includes(filter)
|| (item.exact_times !== null && item.exact_times.toString().includes(filter))
));
break;
case 'routes':
return data.filter((item, index) => {
return (
item.route_id.toLowerCase().includes(filter.toLowerCase()) ||
(item.agency_id!==null && item.agency_id.toLowerCase().includes(filter.toLowerCase())) ||
(item.route_short_name!==null && item.route_short_name.toLowerCase().includes(filter.toLowerCase())) ||
(item.route_long_name!==null && item.route_long_name.toLowerCase().includes(filter.toLowerCase())) ||
item.route_type.toString().includes(filter.toLowerCase()) ||
(item.route_color!==null && item.route_color.toLowerCase().includes(filter.toLowerCase())) ||
(item.route_text_color!==null && item.route_text_color.toLowerCase().includes(filter.toLowerCase())) ||
(item.route_desc!==null &&item.route_desc.toLowerCase().includes(filter.toLowerCase()))
);
});
return data.filter((item, index) => (
item.route_id.toLowerCase().includes(filter.toLowerCase())
|| (item.agency_id !== null && item.agency_id.toLowerCase().includes(filter.toLowerCase()))
|| (item.route_short_name !== null && item.route_short_name.toLowerCase().includes(filter.toLowerCase()))
|| (item.route_long_name !== null && item.route_long_name.toLowerCase().includes(filter.toLowerCase()))
|| item.route_type.toString().includes(filter.toLowerCase())
|| (item.route_color !== null && item.route_color.toLowerCase().includes(filter.toLowerCase()))
|| (item.route_text_color !== null && item.route_text_color.toLowerCase().includes(filter.toLowerCase()))
|| (item.route_desc !== null && item.route_desc.toLowerCase().includes(filter.toLowerCase()))
));
break;
case 'shapes':
return data.filter((item, index) => {
return (
item.shape_id.toLowerCase().includes(filter.toLowerCase()) ||
item.shape_pt_lat.toString().includes(filter) ||
item.shape_pt_lon.toString().includes(filter) ||
item.shape_pt_sequence.toString().includes(filter)
);
});
return data.filter((item, index) => (
item.shape_id.toLowerCase().includes(filter.toLowerCase())
|| item.shape_pt_lat.toString().includes(filter)
|| item.shape_pt_lon.toString().includes(filter)
|| item.shape_pt_sequence.toString().includes(filter)
));
break;
case 'stops':
return data.filter((item, index) => {
return (item.stop_id.toString().includes(filter) ||
(item.stop_code!==null && item.stop_code.toLowerCase().includes(filter.toLowerCase())) ||
(item.stop_name!==null && item.stop_name.toLowerCase().includes(filter.toLowerCase())) ||
(item.stop_desc!==null && item.stop_desc.toLowerCase().includes(filter.toLowerCase())) ||
(item.stop_lat!==null && item.stop_lat.toString().includes(filter)) ||
(item.stop_lon!==null && item.stop_lon.toString().includes(filter)) ||
(item.location_type!==null && item.location_type.toString().includes(filter)) ||
(item.parent_station!==null && item.parent_station.toLowerCase().includes(filter)) ||
(item.wheelchair_boarding!==null && item.wheelchair_boarding.toString().includes(filter)) ||
(item.platform_code!==null && item.platform_code.toLowerCase().includes(filter.toLowerCase())) ||
(item.zone_id!==null && item.zone_id.toLowerCase().includes(filter.toLowerCase()))
);
});
return data.filter((item, index) => (item.stop_id.toString().includes(filter)
|| (item.stop_code !== null && item.stop_code.toLowerCase().includes(filter.toLowerCase()))
|| (item.stop_name !== null && item.stop_name.toLowerCase().includes(filter.toLowerCase()))
|| (item.stop_desc !== null && item.stop_desc.toLowerCase().includes(filter.toLowerCase()))
|| (item.stop_lat !== null && item.stop_lat.toString().includes(filter))
|| (item.stop_lon !== null && item.stop_lon.toString().includes(filter))
|| (item.location_type !== null && item.location_type.toString().includes(filter))
|| (item.parent_station !== null && item.parent_station.toLowerCase().includes(filter))
|| (item.wheelchair_boarding !== null && item.wheelchair_boarding.toString().includes(filter))
|| (item.platform_code !== null && item.platform_code.toLowerCase().includes(filter.toLowerCase()))
|| (item.zone_id !== null && item.zone_id.toLowerCase().includes(filter.toLowerCase()))
));
break;
case 'trips':
return data.filter((item, index) => {
return (
item.route_id.toLowerCase().includes(filter.toLowerCase()) ||
item.service_id.toLowerCase().includes(filter.toLowerCase()) ||
item.trip_id.toLowerCase().includes(filter.toLowerCase()) ||
(item.trip_headsign!==null && item.trip_headsign.toLowerCase().includes(filter.toLowerCase())) ||
(item.trip_short_name!==null && item.trip_short_name.toLowerCase().includes(filter.toLowerCase())) ||
(item.direction_id!==null && item.direction_id.toString().includes(filter)) ||
(item.block_id!==null && item.block_id.toLowerCase().includes(filter.toLowerCase())) ||
(item.shape_id!==null && item.shape_id.toLowerCase().includes(filter.toLowerCase())) ||
(item.wheelchair_accessible!==null && item.wheelchair_accessible.toString().includes(filter)) ||
(item.bikes_allowed!==null && item.bikes_allowed.toString().includes(filter))
);
});
return data.filter((item, index) => (
item.route_id.toLowerCase().includes(filter.toLowerCase())
|| item.service_id.toLowerCase().includes(filter.toLowerCase())
|| item.trip_id.toLowerCase().includes(filter.toLowerCase())
|| (item.trip_headsign !== null && item.trip_headsign.toLowerCase().includes(filter.toLowerCase()))
|| (item.trip_short_name !== null && item.trip_short_name.toLowerCase().includes(filter.toLowerCase()))
|| (item.direction_id !== null && item.direction_id.toString().includes(filter))
|| (item.block_id !== null && item.block_id.toLowerCase().includes(filter.toLowerCase()))
|| (item.shape_id !== null && item.shape_id.toLowerCase().includes(filter.toLowerCase()))
|| (item.wheelchair_accessible !== null && item.wheelchair_accessible.toString().includes(filter))
|| (item.bikes_allowed !== null && item.bikes_allowed.toString().includes(filter))
));
break;
default:
return data;
@ -97,7 +83,7 @@ function filterData(data, name,filter){
} else {
return data;
}
};
}
module.exports = {
filterData
filterData,
};

View File

@ -2,9 +2,8 @@
function hasData(res) {
if ('data' in res) {
return true;
} else {
return false;
}
return false;
}
/* provide http get service day response and get trip array */
@ -28,7 +27,7 @@ function getAryTime (res) {
const objService = res.data;
const aryService = Object.entries(objService);
const arrTime = aryService.map((trips, key) => {
let time = parseInt(trips[0], 10);
const time = parseInt(trips[0], 10);
return time;
});
return arrTime;
@ -37,5 +36,5 @@ function getAryTime (res) {
module.exports = {
getAryTime,
getAryTripCount
getAryTripCount,
};

Some files were not shown because too many files have changed in this diff Show More