feat: adjust Trips page
This commit is contained in:
parent
a34a7d241f
commit
e33b5e203c
|
@ -0,0 +1,34 @@
|
|||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import Dropdown from 'react-bootstrap/Dropdown';
|
||||
|
||||
export default function AgencySelect({ name, onChange, placeholder, rry, title }) {
|
||||
|
||||
if (rry.length > 0) {
|
||||
return (<>
|
||||
<Dropdown>
|
||||
<Dropdown.Toggle id="dropdown-basic">{placeholder}
|
||||
</Dropdown.Toggle>
|
||||
<Dropdown.Menu>
|
||||
{rry.map((item) => (
|
||||
<Dropdown.Item
|
||||
eventKey={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
|
||||
};
|
|
@ -0,0 +1,39 @@
|
|||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import Form from 'react-bootstrap/Form';
|
||||
|
||||
export default function AgencySelect({ name, onChange, placeholder, rry, title }) {
|
||||
|
||||
if (rry.length > 0) {
|
||||
return (<>
|
||||
<Form.Select
|
||||
aria-label="select table entries per page"
|
||||
name={name}
|
||||
id={name}
|
||||
className={name}
|
||||
onChange={onChange}
|
||||
placeholder={placeholder}
|
||||
defaultValue={placeholder}
|
||||
title={title}
|
||||
type="text"
|
||||
required
|
||||
>
|
||||
{rry.map((item) => (
|
||||
<option key={item.agency_id} value={item.agency_id}>
|
||||
{item.agency_name}
|
||||
</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
|
||||
};
|
|
@ -0,0 +1,34 @@
|
|||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import Dropdown from 'react-bootstrap/Dropdown';
|
||||
|
||||
export default function AgencySelect({ name, onChange, placeholder, rry, title }) {
|
||||
|
||||
if (rry.length > 0) {
|
||||
return (<>
|
||||
<Dropdown>
|
||||
<Dropdown.Toggle id="dropdown-basic">{placeholder}
|
||||
</Dropdown.Toggle>
|
||||
<Dropdown.Menu>
|
||||
{rry.map((item) => (
|
||||
<Dropdown.Item
|
||||
eventKey={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
|
||||
};
|
|
@ -0,0 +1,41 @@
|
|||
import React from 'react';
|
||||
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>
|
||||
<select
|
||||
name={name}
|
||||
id={name}
|
||||
className={name}
|
||||
onChange={onChange}
|
||||
placeholder={name}
|
||||
defaultValue={name}
|
||||
title={name}
|
||||
type="text"
|
||||
required
|
||||
>
|
||||
{rry.map((item) => (
|
||||
<option key={item.agency_id} value={item.agency_id}>
|
||||
{item.agency_name}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</form>
|
||||
</>);
|
||||
} else {
|
||||
return <p>Loading...</p>;
|
||||
}
|
||||
};
|
||||
|
||||
AgencySelect.propTypes = {
|
||||
name: PropTypes.string,
|
||||
onChange: PropTypes.func,
|
||||
rry: PropTypes.array
|
||||
};
|
|
@ -1,37 +1,28 @@
|
|||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import Form from 'react-bootstrap/Form';
|
||||
const FileSelect = ({ options, name, onChange, title }) => {
|
||||
|
||||
export default function FileSelect({ options, name, onChange, title }) {
|
||||
if (options.length > 0) {
|
||||
return (
|
||||
<div>
|
||||
<Form.Select
|
||||
aria-label="select table entries per page"
|
||||
name={name}
|
||||
id={name}
|
||||
className={name}
|
||||
onChange={onChange}
|
||||
title={title}
|
||||
>
|
||||
{options.map((item, index) => (
|
||||
<option key={index} value={item}>
|
||||
{item}
|
||||
</option>
|
||||
))}
|
||||
</Form.Select>
|
||||
</div>
|
||||
);
|
||||
return <Form.Select
|
||||
aria-label="select table entries per page"
|
||||
name={name}
|
||||
id={name}
|
||||
className={name}
|
||||
onChange={onChange}
|
||||
title={title}
|
||||
>
|
||||
{options.map((item, index) => (
|
||||
<option key={index} value={item}>
|
||||
{item}
|
||||
</option>
|
||||
))}
|
||||
</Form.Select>;
|
||||
} else {
|
||||
return (
|
||||
<div>
|
||||
<p>Loading...</p>
|
||||
</div>
|
||||
);
|
||||
return <p>Loading...</p>;
|
||||
}
|
||||
};
|
||||
|
||||
export default FileSelect;
|
||||
|
||||
FileSelect.propTypes = {
|
||||
name: PropTypes.string,
|
||||
onChange: PropTypes.func,
|
||||
|
|
|
@ -5,7 +5,9 @@ import FileSelect from '../components/file-select';
|
|||
import TablePage from '../components/table-page.js';
|
||||
import gtfs from '../utils/gtfs';
|
||||
|
||||
const FileSelection = ({ options }) => {
|
||||
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);
|
||||
|
@ -26,7 +28,7 @@ const FileSelection = ({ options }) => {
|
|||
return <p>Loading...</p>;
|
||||
}
|
||||
};
|
||||
export default FileSelection;
|
||||
|
||||
FileSelection.propTypes = {
|
||||
options: PropTypes.array
|
||||
};
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
import React from 'react';
|
||||
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 && rry.length > 0) {
|
||||
return (<>
|
||||
<form >
|
||||
<label htmlFor="input-route">{name}: </label>
|
||||
<select
|
||||
name={name}
|
||||
id={name}
|
||||
className={name}
|
||||
onChange={onChange}
|
||||
placeholder={name}
|
||||
defaultValue={name}
|
||||
title={name}
|
||||
type="text"
|
||||
required
|
||||
>
|
||||
{rry.map((item) => (
|
||||
<option key={item.route_id} value={item.route_id}>
|
||||
{item.route_short_name}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</form>
|
||||
</>);
|
||||
} else {
|
||||
return <p>Loading...</p>;
|
||||
}
|
||||
};
|
||||
|
||||
RouteSelect.propTypes = {
|
||||
name: PropTypes.string,
|
||||
onChange: PropTypes.func,
|
||||
rry: PropTypes.array
|
||||
};
|
|
@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
|
|||
|
||||
import FileSelection from './file-selection';
|
||||
|
||||
const Tables = ({ data }) => {
|
||||
export default function Tables({ data }) {
|
||||
if (data.length > 0) {
|
||||
return (
|
||||
<>
|
||||
|
@ -14,7 +14,7 @@ const Tables = ({ data }) => {
|
|||
return <p>Selection loading...</p>;
|
||||
}
|
||||
};
|
||||
|
||||
Tables.propTypes = {
|
||||
data: PropTypes.array
|
||||
};
|
||||
export default Tables;
|
||||
|
|
|
@ -2,42 +2,102 @@ import React, { useEffect, useState } from 'react';
|
|||
import axios from 'axios';
|
||||
|
||||
import config from '../config';
|
||||
import Table from '../components/trips-route-day-table';
|
||||
import TripsRouteDayTable from '../components/trips-route-day-table';
|
||||
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';
|
||||
|
||||
/*store and initialize data in function component state*/
|
||||
const [strngAgencyId, setStrngAgencyId] = useState(agencyNameDefault);
|
||||
const [strngRouteId, setStrngRouteId] = useState(routeNameDefault);
|
||||
const [rryTrips, setRryTrips] = useState([]);
|
||||
const [rryAgencies, setRryAgencies] = useState([]);
|
||||
const [rryRoutes, setRryRoutes] = useState([]);
|
||||
|
||||
const getAgencyIds = async () => {
|
||||
const getRryAgencies = async () => {
|
||||
try {
|
||||
/*get rryTrips*/
|
||||
/*TODO handle errors: https://www.valentinog.com/blog/await-react/*/
|
||||
const res = await axios.get(`${config.API}trips-by-route-day?routeid=68442&day=2023-11-24`);
|
||||
const address = `${config.API}agencyids`;
|
||||
console.log('trips-route-day res.data.length: address: ' + address);
|
||||
const res = await axios.get(address);
|
||||
console.log('trips-route-day res.data.length: Agencies: ' + res.data.length);
|
||||
setRryAgencies(res.data);
|
||||
} catch (err) {
|
||||
console.error('err.message: ' + err.message);
|
||||
}
|
||||
};
|
||||
|
||||
console.log('Trips res.data.length:' + res.data.length);
|
||||
const getRryRoutes = async () => {
|
||||
if ( strngAgencyId !== agencyNameDefault ) {
|
||||
try {
|
||||
/*TODO handle errors: https://www.valentinog.com/blog/await-react/*/
|
||||
const address = `${config.API}routes?agencyid=${strngAgencyId}`;
|
||||
console.log('trips-route-day res.data.length: address: ' + address);
|
||||
const res = await axios.get(address);
|
||||
console.log('trips-route-day res.data.length: Routes: ' + res.data.length);
|
||||
setRryRoutes(res.data);
|
||||
} catch (err) {
|
||||
console.error('err.message: ' + err.message);
|
||||
}
|
||||
} else {
|
||||
//TODO clean up
|
||||
console.log('trips-route-day strngAgencyId NOT available');
|
||||
}
|
||||
};
|
||||
|
||||
const getRryTrips = async () => {
|
||||
try {
|
||||
/*TODO handle errors: https://www.valentinog.com/blog/await-react/*/
|
||||
//TODO Get trips based on route_id
|
||||
const res = await axios.get(`${config.API}trips-by-route-day?routeid=68442&day=2023-11-24`);
|
||||
console.log('trips-route-day res.data.length: Trips: ' + res.data.length);
|
||||
setRryTrips(res.data);
|
||||
} catch (err) {
|
||||
console.error('err.message: ' + err.message);
|
||||
}
|
||||
};
|
||||
|
||||
const handleChangeAgencyId = (event) => {
|
||||
console.log('trips-route-day: handleChangeAgencyId() value: ' + event.target.value);
|
||||
setStrngAgencyId((strngAgencyId) => event.target.value);
|
||||
};
|
||||
|
||||
const handleChangeRouteId = (event) => {
|
||||
console.log('trips-route-day: handleChangeRouteId() value: ' + event.target.value);
|
||||
setStrngRouteId((strngRouteId) => event.target.value);
|
||||
};
|
||||
|
||||
/*this hook is run after a DOM update. Changing state might result in an infinite loop*/
|
||||
/*hook need to be placed in body of the function component in which it is used*/
|
||||
useEffect(() => {
|
||||
getAgencyIds();
|
||||
getRryAgencies();
|
||||
getRryTrips();
|
||||
/*use an empty dependency array to ensure the hook is running only once*/
|
||||
/*TODO study dependency array: https://reactjs.org/docs/hooks-effect.html*/
|
||||
}, []);
|
||||
|
||||
if(rryTrips.length > 0){
|
||||
return <>
|
||||
<Table
|
||||
array={rryTrips}
|
||||
title={'Trips'}
|
||||
/>
|
||||
</>
|
||||
}else{
|
||||
return <p>loading...</p>
|
||||
}
|
||||
useEffect(() => {
|
||||
console.log('trips-route-day: useEffect() strngAgencyId: ' + strngAgencyId);
|
||||
getRryRoutes();
|
||||
/*use an empty dependency array to ensure the hook is running only once*/
|
||||
/*TODO study dependency array: https://reactjs.org/docs/hooks-effect.html*/
|
||||
}, [strngAgencyId]);
|
||||
|
||||
useEffect(() => {
|
||||
console.log('trips-route-day: useEffect() strngRouteId: ' + strngRouteId);
|
||||
/*use an empty dependency array to ensure the hook is running only once*/
|
||||
/*TODO study dependency array: https://reactjs.org/docs/hooks-effect.html*/
|
||||
}, [strngRouteId]);
|
||||
|
||||
|
||||
//TODO get rry based on route_id!
|
||||
return <>
|
||||
<AgencySelect rry={rryAgencies} name={agencyNameDefault} onChange={handleChangeAgencyId} />
|
||||
<RouteSelect rry={rryRoutes} name={routeNameDefault} onChange={handleChangeRouteId} />
|
||||
<TripsRouteDayTable array={rryTrips} title={'Trips'} />
|
||||
</>;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue