Skip to content

Commit

Permalink
Merge pull request #425 from MobilityData/indraneel/feed-page
Browse files Browse the repository at this point in the history
feat: add single GTFS Feed and GTFS-RT Feed pages
  • Loading branch information
Indraneel Purohit authored Jun 5, 2024
2 parents 5adf620 + cd54b1f commit 70e7195
Show file tree
Hide file tree
Showing 26 changed files with 1,192 additions and 21 deletions.
4 changes: 4 additions & 0 deletions web-app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,19 @@
"@mui/material": "^5.14.9",
"@mui/x-tree-view": "^6.17.0",
"@reduxjs/toolkit": "^1.9.6",
"@turf/center": "^6.5.0",
"@types/leaflet": "^1.9.12",
"date-fns": "^2.30.0",
"date-fns-tz": "^2.0.0",
"firebase": "^10.4.0",
"formik": "^2.4.5",
"leaflet": "^1.9.4",
"openapi-fetch": "^0.9.3",
"react": "^17.0.0 || ^18.0.0",
"react-dom": "^17.0.0 || ^18.0.0",
"react-ga4": "^2.1.0",
"react-google-recaptcha": "^3.1.0",
"react-leaflet": "^4.2.1",
"react-loading-overlay-ts": "^2.0.2",
"react-redux": "^8.1.3",
"react-router-dom": "^6.16.0",
Expand Down
39 changes: 39 additions & 0 deletions web-app/src/app/components/ContentBox.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import * as React from 'react';
import { Box, Grid } from '@mui/material';

export interface ContentBoxProps {
title: string;
width: Record<string, string>;
outlineColor: string;
}

export const ContentBox = (
props: React.PropsWithChildren<ContentBoxProps>,
): JSX.Element => {
return (
<Box
width={props.width}
sx={{
background: '#FFFFFF',
borderRadius: '6px',
border: `2px solid ${props.outlineColor}`,
p: 5,
fontSize: '18px',
fontWeight: 700,
mr: 0,
}}
>
<Grid
container
sx={{
width: '100%',
}}
>
<Grid item xs={12} fontSize={24}>
{props.title}
</Grid>
{props.children}
</Grid>
</Box>
);
};
24 changes: 24 additions & 0 deletions web-app/src/app/components/Map.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import * as React from 'react';
import 'leaflet/dist/leaflet.css';
import { MapContainer, TileLayer, Polygon } from 'react-leaflet';
import { type LatLngBoundsExpression, type LatLngExpression } from 'leaflet';

export interface MapProps {
polygon: LatLngExpression[];
}

export const Map = (props: React.PropsWithChildren<MapProps>): JSX.Element => {
return (
<MapContainer
bounds={props.polygon as LatLngBoundsExpression}
zoom={8}
style={{ minHeight: '400px', height: '100%' }}
>
<TileLayer
attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
url='https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png'
/>
<Polygon positions={props.polygon}></Polygon>
</MapContainer>
);
};
1 change: 1 addition & 0 deletions web-app/src/app/constants/Navigation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export const MOBILITY_DATA_LINKS = {

export const navigationItems: NavigationItem[] = [
{ title: 'About', target: 'about', color: 'inherit', variant: 'text' },
{ title: 'Feeds', target: 'feeds', color: 'inherit', variant: 'text' },
{ title: 'FAQ', target: 'faq', color: 'inherit', variant: 'text' },
{
title: 'Add a Feed',
Expand Down
2 changes: 2 additions & 0 deletions web-app/src/app/router/Router.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import Contribute from '../screens/Contribute';
import PostRegistration from '../screens/PostRegistration';
import TermsAndConditions from '../screens/TermsAndConditions';
import PrivacyPolicy from '../screens/PrivacyPolicy';
import Feeds from '../screens/Feed';

export const AppRouter: React.FC = () => {
return (
Expand All @@ -41,6 +42,7 @@ export const AppRouter: React.FC = () => {
<Route path='forgot-password' element={<ForgotPassword />} />
<Route path='faq' element={<FAQ />} />
<Route path='about' element={<About />} />
<Route path='feeds/:feedId' element={<Feeds />} />
<Route path='contribute' element={<Contribute />} />
<Route path='privacy-policy' element={<PrivacyPolicy />} />
<Route path='terms-and-conditions' element={<TermsAndConditions />} />
Expand Down
47 changes: 47 additions & 0 deletions web-app/src/app/screens/Feed/AssociatedGTFSFeeds.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import * as React from 'react';
import { ContentBox } from '../../components/ContentBox';
import {
TableBody,
TableCell,
TableContainer,
TableRow,
colors,
} from '@mui/material';
import { OpenInNewOutlined } from '@mui/icons-material';
import { type GTFSRTFeedType } from '../../services/feeds/utils';

export interface AssociatedGTFSFeedsProps {
feed: GTFSRTFeedType | undefined;
}

export default function AssociatedGTFSFeeds({
feed,
}: AssociatedGTFSFeedsProps): React.ReactElement {
return (
<ContentBox
width={{ xs: '100%', md: '50%' }}
title={'Associated GTFS Schedule Feed'}
outlineColor={colors.indigo[500]}
>
<TableContainer>
<TableBody>
{feed?.data_type === 'gtfs_rt' &&
feed?.feed_references?.map((feedRef) => {
return (
<TableRow key={feedRef}>
<TableCell>
<span style={{ display: 'flex' }}>
<a href={`/feeds/${feedRef}`} rel='noreferrer'>
{feedRef}
</a>
<OpenInNewOutlined />
</span>
</TableCell>
</TableRow>
);
})}
</TableBody>
</TableContainer>
</ContentBox>
);
}
94 changes: 94 additions & 0 deletions web-app/src/app/screens/Feed/DataQualitySummary.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import * as React from 'react';
import { ContentBox } from '../../components/ContentBox';
import {
Chip,
TableCell,
TableContainer,
TableRow,
colors,
} from '@mui/material';

import {
ErrorOutlineOutlined,
OpenInNewOutlined,
ReportOutlined,
ReportProblemOutlined,
} from '@mui/icons-material';
import { type components } from '../../services/feeds/types';

export interface DataQualitySummaryProps {
latestDataset: components['schemas']['GtfsDataset'] | undefined;
}

export default function DataQualitySummary({
latestDataset,
}: DataQualitySummaryProps): React.ReactElement {
return (
<ContentBox
width={{ xs: '100%', md: '50%' }}
title={'Data Quality Summary'}
outlineColor={colors.indigo[500]}
>
<TableContainer>
<TableRow>
<TableCell>
<Chip
icon={<ReportOutlined />}
label={`${
latestDataset?.validation_report?.total_error ?? '0'
} Error`}
color='error'
variant='outlined'
/>
<Chip
icon={<ReportProblemOutlined />}
label={`${
latestDataset?.validation_report?.total_warning ?? '0'
} Warning`}
color='warning'
variant='outlined'
/>
<Chip
icon={<ErrorOutlineOutlined />}
label={`${
latestDataset?.validation_report?.total_info ?? '0'
} Info Notices`}
color='primary'
variant='outlined'
/>
</TableCell>
</TableRow>
<TableRow>
{latestDataset?.validation_report?.url_html !== undefined && (
<TableCell>
<span style={{ display: 'flex' }}>
<a
href={`${latestDataset?.validation_report?.url_html}`}
target='_blank'
rel='noreferrer'
>
Open Full Report
</a>
<OpenInNewOutlined />
</span>
</TableCell>
)}
{latestDataset?.validation_report?.url_json !== undefined && (
<TableCell>
<span style={{ display: 'flex' }}>
<a
href={`${latestDataset?.validation_report?.url_json}`}
target='_blank'
rel='noreferrer'
>
Open JSON Report
</a>
<OpenInNewOutlined />
</span>
</TableCell>
)}
</TableRow>
</TableContainer>
</ContentBox>
);
}
44 changes: 44 additions & 0 deletions web-app/src/app/screens/Feed/FeaturesList.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import * as React from 'react';
import { ContentBox } from '../../components/ContentBox';
import {
TableBody,
TableCell,
TableContainer,
TableRow,
colors,
} from '@mui/material';
import { type components } from '../../services/feeds/types';

export interface FeaturesListProps {
latestDataset: components['schemas']['GtfsDataset'] | undefined;
}

export default function FeaturesList({
latestDataset,
}: FeaturesListProps): React.ReactElement {
return (
<ContentBox
width={{ xs: '100%', md: '50%' }}
title={'Features List'}
outlineColor={colors.indigo[500]}
>
<TableContainer>
<TableBody>
{latestDataset?.validation_report?.features !== undefined &&
latestDataset?.validation_report?.features?.length > 0 && (
<TableRow>
<TableCell>
<b>Feature</b>
</TableCell>
</TableRow>
)}
{latestDataset?.validation_report?.features?.map((v) => (
<TableRow key={v}>
<TableCell>{v}</TableCell>
</TableRow>
))}
</TableBody>
</TableContainer>
</ContentBox>
);
}
Loading

0 comments on commit 70e7195

Please sign in to comment.