diff --git a/common/components/nav/CommuterRailDropdown.tsx b/common/components/nav/CommuterRailDropdown.tsx index 522d0c1bf..a1cdf9607 100644 --- a/common/components/nav/CommuterRailDropdown.tsx +++ b/common/components/nav/CommuterRailDropdown.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { SidebarTabs } from '../../../modules/navigation/SidebarTabs'; -import { TRIP_PAGES, COMMUTER_RAIL_OVERVIEW } from '../../constants/pages'; +import { COMMUTER_RAIL_OVERVIEW } from '../../constants/pages'; import { CommuterRailRouteSelection } from './CommuterRailRouteSelection'; interface CommuterRailDropdownProps { @@ -18,8 +18,10 @@ export const CommuterRailDropdown: React.FC = ({ clos role={'navigation'} > -
- + + {/* TODO: Once we have reliable travel data for CR */} + {/*
*/} + {/* */} ); diff --git a/common/components/nav/MenuDropdown.tsx b/common/components/nav/MenuDropdown.tsx index db3919182..412cafa67 100644 --- a/common/components/nav/MenuDropdown.tsx +++ b/common/components/nav/MenuDropdown.tsx @@ -4,7 +4,7 @@ import classNames from 'classnames'; import Link from 'next/link'; import React, { useEffect, useState } from 'react'; import { LINE_OBJECTS } from '../../constants/lines'; -import { BUS_DEFAULTS } from '../../state/defaults/dateDefaults'; +import { BUS_DEFAULTS, COMMUTER_RAIL_DEFAULTS } from '../../state/defaults/dateDefaults'; import { lineColorBackground } from '../../styles/general'; import type { Line } from '../../types/lines'; import type { Route } from '../../types/router'; @@ -38,15 +38,20 @@ export const MenuDropdown: React.FC = ({ line, route, childre } }, [line]); + const href = React.useMemo(() => { + switch (line) { + case 'line-bus': + return `/bus/trips/single?busRoute=1&date=${BUS_DEFAULTS.singleTripConfig.date}`; + case 'line-commuter-rail': + return `/commuter-rail/ridership?crRoute=CR-Lowell&startDate=${COMMUTER_RAIL_DEFAULTS.lineConfig.startDate}&endDate=${COMMUTER_RAIL_DEFAULTS.lineConfig.endDate}`; + default: + return getLineSelectionItemHref(line, route); + } + }, [line, route]); + return (
- +
{ const isEndDateAfterBusMaxDay = endDate !== undefined && dayjs(endDate).isAfter(BUS_MAX_DAY); if ( - (line === 'line-bus' || linePath === 'bus') && + (line === 'line-commuter-rail' || linePath === 'commuter-rail') && (isStartDateAfterBusMaxDay || isEndDateAfterBusMaxDay) ) { return ( @@ -30,7 +30,9 @@ export const BetaDataNotice: React.FC = () => {
-

Real-time bus data is in beta

+

+ Real-time Commuter Rail data is in beta +

TransitMatters collects this data using the{' '} @@ -46,8 +48,7 @@ export const BetaDataNotice: React.FC = () => { Please expect reduced accuracy.

- We favor official performance data from the MBTA when it's available. Technical - details of our data collection are available in our{' '} + Technical details of our data collection are available in our{' '} { const isEndDateAfterBusMaxDay = endDate !== undefined && dayjs(endDate).isAfter(BUS_MAX_DAY); if ( - (line === 'line-bus' || linePath === 'bus') && - (isStartDateAfterBusMaxDay || isEndDateAfterBusMaxDay) + ((line === 'line-bus' || linePath === 'bus') && + (isStartDateAfterBusMaxDay || isEndDateAfterBusMaxDay)) || + line === 'line-commuter-rail' || + linePath === 'commuter-rail' ) { return (

diff --git a/common/components/notices/SameDayNotice.tsx b/common/components/notices/SameDayNotice.tsx index 96959ba79..258fe8232 100644 --- a/common/components/notices/SameDayNotice.tsx +++ b/common/components/notices/SameDayNotice.tsx @@ -6,21 +6,16 @@ import { TODAY_STRING } from '../../constants/dates'; export const SameDayNotice: React.FC = () => { const { - line, query: { date, endDate }, } = useDelimitatedRoute(); const isToday = date === TODAY_STRING || endDate === TODAY_STRING; - if (isToday && line !== 'line-bus') { + if (isToday) { return (
-

- Due to data not being cleaned yet, today's data may not be fully accurate and may look - messy. -

-

Data is cleaned up overnight and should be more accurate tomorrow.

+

Data from today may not be complete. Data comes in with a delay of up to two hours

); diff --git a/common/constants/baselines.ts b/common/constants/baselines.ts index 1eed84ff2..36500ec34 100644 --- a/common/constants/baselines.ts +++ b/common/constants/baselines.ts @@ -1,4 +1,4 @@ -import type { BusRouteId, Line } from '../types/lines'; +import type { BusRouteId, CommuterRailRoute, Line } from '../types/lines'; // These are manually chosen based off the peak *monthly* scheduled service. Selecting highest value " export const PEAK_SCHEDULED_SERVICE = { @@ -20,7 +20,7 @@ export const PEAK_SPEED = { // These are manually chosen based off the peak value. Need to be updated when all data is generated. export const PEAK_RIDERSHIP: { - [key in Exclude | BusRouteId | 'DEFAULT']: number; + [key in Exclude | BusRouteId | CommuterRailRoute | 'DEFAULT']: number; } = { 'line-red': 213703, 'line-orange': 169578, @@ -58,6 +58,19 @@ export const PEAK_RIDERSHIP: { '111': 11258, '114116117': 12867, '220221222': 3370, + 'CR-Fitchburg': 9302, + 'CR-Franklin': 11671, + 'CR-Greenbush': 6114, + 'CR-Haverhill': 7112, + 'CR-Lowell': 10925, + 'CR-Worcester': 18637, + 'CR-Fairmount': 2652, + 'CR-Kingston': 6089, + 'CR-Middleborough': 6863, + 'CR-Needham': 6690, + 'CR-Newburyport': 14972, + 'CR-Providence': 25728, + 'line-commuter-rail': 126755, DEFAULT: 520580, }; diff --git a/common/constants/colors.ts b/common/constants/colors.ts index af92c7083..d6178a649 100644 --- a/common/constants/colors.ts +++ b/common/constants/colors.ts @@ -1,3 +1,4 @@ +import type { Line } from '../types/lines'; import { hexWithAlpha } from '../utils/general'; export const COLORS = { @@ -44,20 +45,24 @@ export const CHART_COLORS = { BLOCKS_SOLID: '#d2d2d2', }; -export const LINE_COLORS = { - 'line-red': '#D13434', - 'line-orange': '#ed8b00', - 'line-blue': '#003da5', - 'line-green': '#00834d', - 'line-bus': '#ffc72c', +export const LINE_COLORS: { [key in Line | 'default']: string } = { + 'line-red': COLORS.mbta.red, + 'line-orange': COLORS.mbta.orange, + 'line-blue': COLORS.mbta.blue, + 'line-green': COLORS.mbta.green, + 'line-bus': COLORS.mbta.bus, + 'line-commuter-rail': COLORS.mbta.commuterRail, default: '#303030', }; -export const LINE_COLORS_LEVELS = { +export const LINE_COLORS_LEVELS: { + [key in Line | 'default']: { [num in number]: string } | string; +} = { 'line-red': { 0: '#D13434', 1: '#d64949', 2: '#da5e5e', 3: '#df7272' }, 'line-orange': { 0: '#ed8b00', 1: '#ff9907', 2: '#ffa321', 3: '#ffae3b' }, 'line-blue': { 0: '#003da5', 1: '#0046bf', 2: '#0050d8', 3: '#0059f2' }, 'line-green': { 0: '#00834d', 1: '#009d5c', 2: '#00b66b', 3: '#00d07a' }, 'line-bus': { 0: '#ffc72c', 1: '#ffce46', 2: '#ffd55f', 3: '#ffdb79' }, + 'line-commuter-rail': { 0: '#80276c', 1: '#8f2f7e', 2: '#9e3790', 3: '#ad41a2' }, default: '#303030', }; diff --git a/common/constants/dashboardTabs.ts b/common/constants/dashboardTabs.ts index 8e4084340..bbfd46a21 100644 --- a/common/constants/dashboardTabs.ts +++ b/common/constants/dashboardTabs.ts @@ -1,7 +1,5 @@ -import { BUS_DEFAULTS } from '../state/defaults/dateDefaults'; -import type { QueryParams } from '../types/router'; - -export type Tab = 'Subway' | 'Bus' | 'System'; +import { BUS_DEFAULTS, COMMUTER_RAIL_DEFAULTS } from '../state/defaults/dateDefaults'; +import type { QueryParams, Tab } from '../types/router'; export const DASHBOARD_TABS: { [key in Tab]: { name: Tab; path: string; disabled?: boolean; query?: QueryParams }; @@ -13,4 +11,9 @@ export const DASHBOARD_TABS: { path: '/bus/trips/single', query: { busRoute: '1', date: BUS_DEFAULTS.singleTripConfig.date }, }, + 'Commuter Rail': { + name: 'Commuter Rail', + path: '/commuter-rail', + query: { crRoute: 'CR-Lowell', date: COMMUTER_RAIL_DEFAULTS.singleTripConfig.date }, + }, }; diff --git a/common/constants/dates.ts b/common/constants/dates.ts index eb9c5c07e..47e2d7719 100644 --- a/common/constants/dates.ts +++ b/common/constants/dates.ts @@ -8,7 +8,7 @@ import type { DateSelectionDefaultOptions, SingleDateParams, } from '../components/inputs/DateSelection/types/DateSelectionTypes'; -import type { Tab } from './dashboardTabs'; +import type { Tab } from '../types/router'; dayjs.extend(utc); dayjs.extend(timezone); @@ -40,6 +40,7 @@ export const BUS_MAX_DAY = dayjs(BUS_MAX_DATE); export const BUS_MAX_DATE_MINUS_ONE_WEEK = dayjs(BUS_MAX_DATE) .subtract(7, 'days') .format(DATE_FORMAT); +export const COMMUTER_RAIL_MIN_DATE = '2022-06-22'; export const getESTDayjs = (date: string) => { return dayjs(date).tz(est); @@ -72,6 +73,14 @@ export const FLAT_PICKER_OPTIONS: { altFormat: 'M j, Y', dateFormat: 'Y-m-d', }, + 'Commuter Rail': { + enableTime: false, + minDate: COMMUTER_RAIL_MIN_DATE, + maxDate: TODAY_STRING, + altInput: true, + altFormat: 'M j, Y', + dateFormat: 'Y-m-d', + }, }; const SINGLE_RAPID_PRESETS: { @@ -143,6 +152,7 @@ export const SINGLE_PRESETS: { Subway: SINGLE_RAPID_PRESETS, Bus: SINGLE_RAPID_PRESETS, System: SINGLE_RAPID_PRESETS, + 'Commuter Rail': SINGLE_RAPID_PRESETS, }; const RANGE_RAPID_PRESETS: { @@ -265,6 +275,7 @@ export const RANGE_PRESETS: { Subway: RANGE_RAPID_PRESETS, Bus: RANGE_RAPID_PRESETS, System: RANGE_RAPID_PRESETS, + 'Commuter Rail': RANGE_RAPID_PRESETS, }; export type DatePresetKey = diff --git a/common/constants/pages.ts b/common/constants/pages.ts index 69f7c7950..27e473ca3 100644 --- a/common/constants/pages.ts +++ b/common/constants/pages.ts @@ -141,7 +141,7 @@ export const ALL_PAGES: PageMap = { key: 'ridership', path: '/ridership', name: 'Ridership', - lines: ['line-red', 'line-blue', 'line-green', 'line-orange', 'line-bus'], + lines: ['line-red', 'line-blue', 'line-green', 'line-orange', 'line-bus', 'line-commuter-rail'], icon: faUsers, dateStoreSection: 'line', }, diff --git a/common/constants/stations.ts b/common/constants/stations.ts index 3593d4847..2e8ad80e8 100644 --- a/common/constants/stations.ts +++ b/common/constants/stations.ts @@ -1,5 +1,5 @@ /* eslint-disable import/max-dependencies */ -import type { LineShort } from '../types/lines'; +import { COMMUTER_RAIL_ROUTES, type LineShort } from '../types/lines'; import type { LineMap } from '../types/stations'; import stations_json from './stations.json'; import bus_1 from './bus_constants/1.json'; @@ -82,5 +82,7 @@ export const getBusRoutes = (): string[] => { }; export const getCommuterRailRoutes = (): string[] => { + return COMMUTER_RAIL_ROUTES; + // TODO: use this once we are on trips return Object.keys(commuterRailStations); }; diff --git a/common/layouts/DashboardLayout.tsx b/common/layouts/DashboardLayout.tsx index 1826f6508..c2fb30d5d 100644 --- a/common/layouts/DashboardLayout.tsx +++ b/common/layouts/DashboardLayout.tsx @@ -14,7 +14,7 @@ interface DashboardLayoutProps { export const DashboardLayout: React.FC = ({ children }) => { const isMobile = !useBreakpoint('md'); const { line, page, query, tab } = useDelimitatedRoute(); - const { busRoute } = query; + const { busRoute, crRoute } = query; const dateStoreSection = page ? ALL_PAGES[page]?.dateStoreSection : undefined; const showControlParams = dateStoreSection && (line || tab === 'System') && dateStoreSection !== 'today'; diff --git a/common/state/dateStore.ts b/common/state/dateStore.ts index 3ced87efe..5154dbf00 100644 --- a/common/state/dateStore.ts +++ b/common/state/dateStore.ts @@ -1,6 +1,6 @@ import { create } from 'zustand'; import { OVERVIEW_OPTIONS, TODAY_STRING } from '../constants/dates'; -import type { Tab } from '../constants/dashboardTabs'; +import type { Tab } from '../types/router'; import type { LineSectionParams, MultiTripsSectionParams, diff --git a/common/state/defaults/dateDefaults.ts b/common/state/defaults/dateDefaults.ts index d018a02e8..1551ae7a6 100644 --- a/common/state/defaults/dateDefaults.ts +++ b/common/state/defaults/dateDefaults.ts @@ -1,4 +1,4 @@ -import type { Tab } from '../../constants/dashboardTabs'; +import type { Tab } from '../../types/router'; import type { DateStoreSection } from '../../constants/pages'; import type { DateStoreConfiguration } from '../types/dateStoreTypes'; import { @@ -7,6 +7,7 @@ import { TODAY_STRING, YESTERDAY_STRING, TODAY_SERVICE_STARTED, + COMMUTER_RAIL_MIN_DATE, } from '../../constants/dates'; import type { WithOptional } from '../../types/general'; @@ -34,6 +35,20 @@ export const BUS_DEFAULTS: WithOptional = { + lineConfig: { startDate: OVERVIEW_OPTIONS.year.startDate, endDate: TODAY_STRING }, + multiTripConfig: { + startDate: COMMUTER_RAIL_MIN_DATE, + endDate: TODAY_STRING, + }, + singleTripConfig: { + date: TODAY_SERVICE_STARTED ? TODAY_STRING : YESTERDAY_STRING, + }, +}; + const SYSTEM_DEFAULTS: Partial = { systemConfig: { startDate: OVERVIEW_OPTIONS.year.startDate, endDate: TODAY_STRING }, }; @@ -42,6 +57,7 @@ const TAB_DATE_MAP: { [key in Tab]: Partial } = { Subway: SUBWAY_DEFAULTS, Bus: BUS_DEFAULTS, System: SYSTEM_DEFAULTS, + 'Commuter Rail': COMMUTER_RAIL_DEFAULTS, }; export const getDefaultDates = (dateStoreSection: DateStoreSection, tab: Tab) => { diff --git a/common/styles/general.ts b/common/styles/general.ts index 3543b78da..37b763b6f 100644 --- a/common/styles/general.ts +++ b/common/styles/general.ts @@ -10,7 +10,7 @@ export const lineColorBackground: DefaultStyleMap = { DEFAULT: `bg-stone-800`, }; -export const lineColorLightBorder = { +export const lineColorLightBorder: DefaultStyleMap = { 'line-red': `border-mbta-lightRed`, 'line-orange': `border-mbta-lightOrange`, 'line-green': `border-mbta-lightGreen`, diff --git a/common/types/lines.ts b/common/types/lines.ts index 2ac419093..bb1ed7a1d 100644 --- a/common/types/lines.ts +++ b/common/types/lines.ts @@ -93,7 +93,13 @@ export const GTFS_COLOR_LINE_IDS = ['line-Red', 'line-Orange', 'line-Blue', 'lin export type GtfsColorLineId = (typeof GTFS_COLOR_LINE_IDS)[number]; export const HEAVY_RAIL_LINES: Line[] = ['line-red', 'line-orange', 'line-blue']; -export const LANDING_RAIL_LINES: Line[] = ['line-red', 'line-orange', 'line-blue', 'line-green']; +export const LANDING_RAIL_LINES: Line[] = [ + 'line-red', + 'line-orange', + 'line-blue', + 'line-green', + 'line-commuter-rail', +]; export const RAIL_LINES = ['red', 'orange', 'green', 'blue']; export const BUS_ROUTES: BusRoute[] = [ @@ -174,3 +180,9 @@ export const BUS_PATH = { line: 'bus', }, }; + +export const COMMUTER_RAIL_PATH = { + params: { + line: 'commuter-rail', + }, +}; diff --git a/common/types/router.ts b/common/types/router.ts index d76fbe78e..c9c59b19b 100644 --- a/common/types/router.ts +++ b/common/types/router.ts @@ -28,4 +28,4 @@ export type QueryParams = { export type QueryTypeOptions = 'single' | 'range'; -export type Tab = 'Bus' | 'Subway' | 'System'; +export type Tab = 'Bus' | 'Subway' | 'Commuter Rail' | 'System'; diff --git a/common/utils/ridership.ts b/common/utils/ridership.ts index 29726be8a..881167e83 100644 --- a/common/utils/ridership.ts +++ b/common/utils/ridership.ts @@ -1,7 +1,11 @@ -import type { BusRoute, Line } from '../types/lines'; +import type { BusRoute, CommuterRailRoute, Line } from '../types/lines'; import { RIDERSHIP_KEYS } from '../types/lines'; -export const getRidershipLineId = (line: Line | undefined, busRoute: BusRoute | undefined) => { +export const getRidershipLineId = ( + line: Line | undefined, + busRoute: BusRoute | undefined, + crRoute: CommuterRailRoute | undefined +) => { if (line === 'line-bus' && busRoute) { switch (busRoute) { case '34': @@ -11,6 +15,8 @@ export const getRidershipLineId = (line: Line | undefined, busRoute: BusRoute | default: return `line-${busRoute.replaceAll('/', '')}`; } + } else if (line === 'line-commuter-rail' && crRoute) { + return `line-${crRoute.substring(3)}`; } else { return RIDERSHIP_KEYS[line ?? '']; } diff --git a/common/utils/router.tsx b/common/utils/router.tsx index 92c5286e8..42c1f2a0e 100644 --- a/common/utils/router.tsx +++ b/common/utils/router.tsx @@ -16,12 +16,13 @@ import { useDateStore } from '../state/dateStore'; import type { DateStore } from '../state/dateStore'; import { LINE_COLORS } from '../constants/colors'; -const linePathToKeyMap: Record = { +const linePathToKeyMap: Record = { red: 'line-red', orange: 'line-orange', green: 'line-green', blue: 'line-blue', bus: 'line-bus', + 'commuter-rail': 'line-commuter-rail', }; const getParams = (params: ParsedUrlQuery | QueryParams) => { @@ -60,6 +61,8 @@ const getTab = (path: LinePath) => { return 'Subway'; } else if (path === 'bus') { return 'Bus'; + } else if (path === 'commuter-rail') { + return 'Commuter Rail'; } else { return 'System'; } diff --git a/modules/dashboard/DesktopHeader.tsx b/modules/dashboard/DesktopHeader.tsx index 8bed60e2a..649a59af2 100644 --- a/modules/dashboard/DesktopHeader.tsx +++ b/modules/dashboard/DesktopHeader.tsx @@ -5,12 +5,13 @@ import { useDelimitatedRoute } from '../../common/utils/router'; import { ALL_PAGES } from '../../common/constants/pages'; import { ControlPanel } from '../../common/components/controls/ControlPanel'; import { lineColorBackground } from '../../common/styles/general'; +import { COMMUTER_RAIL_LINE_NAMES } from '../../common/types/lines'; export const DesktopHeader: React.FC = () => { const { line, page, - query: { busRoute }, + query: { busRoute, crRoute }, tab, } = useDelimitatedRoute(); const dateStoreSection = page ? ALL_PAGES[page]?.dateStoreSection : undefined; @@ -20,6 +21,7 @@ export const DesktopHeader: React.FC = () => { const getLineName = () => { if (busRoute) return `Route ${busRoute}`; + if (crRoute) return COMMUTER_RAIL_LINE_NAMES[crRoute]; if (line) return LINE_OBJECTS[line]?.name; if (tab === 'System') return 'System'; }; diff --git a/modules/landing/LineButton.tsx b/modules/landing/LineButton.tsx index c66f49b1e..8985a1449 100644 --- a/modules/landing/LineButton.tsx +++ b/modules/landing/LineButton.tsx @@ -4,7 +4,7 @@ import classNames from 'classnames'; import type { Line } from '../../common/types/lines'; import { lineColorBackground, lineColorBorder } from '../../common/styles/general'; import { LINE_OBJECTS } from '../../common/constants/lines'; -import { BUS_DEFAULTS } from '../../common/state/defaults/dateDefaults'; +import { BUS_DEFAULTS, COMMUTER_RAIL_DEFAULTS } from '../../common/state/defaults/dateDefaults'; interface LineButtonProps { children: React.ReactNode; @@ -17,9 +17,11 @@ export const LineButton: React.FC = ({ children, line }) => { return ( @@ -34,7 +36,7 @@ export const LineButton: React.FC = ({ children, line }) => {

{LINE_OBJECTS[line].name}

- {line === 'line-bus' &&

(Beta)

} + {line === 'line-commuter-rail' &&

(Beta)

}
); diff --git a/modules/landing/LineSelectionLanding.tsx b/modules/landing/LineSelectionLanding.tsx index 99929ac97..1f39ecb53 100644 --- a/modules/landing/LineSelectionLanding.tsx +++ b/modules/landing/LineSelectionLanding.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { faBus, faTrainSubway, faTrainTram } from '@fortawesome/free-solid-svg-icons'; +import { faBus, faTrain, faTrainSubway, faTrainTram } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import classNames from 'classnames'; import { LineButton } from './LineButton'; @@ -40,6 +40,12 @@ export const LineSelectionLanding: React.FC = () => { className={classNames('h-16 w-16 lg:h-20 lg:w-20', 'text-white')} /> + + +
); diff --git a/modules/landing/charts/OverallRidershipChart.tsx b/modules/landing/charts/OverallRidershipChart.tsx index 97ddcff20..609e4ed76 100644 --- a/modules/landing/charts/OverallRidershipChart.tsx +++ b/modules/landing/charts/OverallRidershipChart.tsx @@ -12,6 +12,7 @@ interface OverallRidershipChartProps { export const OverallRidershipChart: React.FC = ({ ridershipData }) => { const labels = Object.values(ridershipData)[0].map((point) => point.date); const datasets = convertToRidershipDataset(ridershipData); + return ( diff --git a/modules/navigation/SideNavigation.tsx b/modules/navigation/SideNavigation.tsx index 541bfe1a3..205b4dd39 100644 --- a/modules/navigation/SideNavigation.tsx +++ b/modules/navigation/SideNavigation.tsx @@ -6,6 +6,7 @@ import classNames from 'classnames'; import { SubwaySection } from '../../common/components/nav/SubwaySection'; import { BusSection } from '../../common/components/nav/BusSection'; import { useDelimitatedRoute } from '../../common/utils/router'; +import { CommuterRailSection } from '../../common/components/nav/CommuterRailSection'; interface SideNavigationProps { close?: () => void; @@ -58,6 +59,7 @@ export const SideNavigation: React.FC = ({ close }) => {
+ ); diff --git a/modules/ridership/RidershipDetails.tsx b/modules/ridership/RidershipDetails.tsx index 3fbe3bd2f..2e9b2468d 100644 --- a/modules/ridership/RidershipDetails.tsx +++ b/modules/ridership/RidershipDetails.tsx @@ -14,10 +14,10 @@ import { RidershipGraphWrapper } from './RidershipGraphWrapper'; export function RidershipDetails() { const { line, - query: { startDate, endDate, busRoute }, + query: { startDate, endDate, busRoute, crRoute }, } = useDelimitatedRoute(); const config = SPEED_RANGE_PARAM_MAP.week; - const lineId = getRidershipLineId(line, busRoute); + const lineId = getRidershipLineId(line, busRoute, crRoute); const enabled = Boolean(startDate && endDate && lineId); const ridership = useRidershipData( @@ -28,7 +28,7 @@ export function RidershipDetails() { }, enabled ); - const ridershipDataReady = !ridership.isError && startDate && endDate && line; + const ridershipDataReady = !ridership.isError && startDate && endDate && line && lineId; return ( @@ -44,6 +44,7 @@ export function RidershipDetails() { endDate={endDate} line={line} busRoute={busRoute} + crRoute={crRoute} /> ) : (
diff --git a/modules/ridership/RidershipGraph.tsx b/modules/ridership/RidershipGraph.tsx index 4e39c317a..129cf0415 100644 --- a/modules/ridership/RidershipGraph.tsx +++ b/modules/ridership/RidershipGraph.tsx @@ -37,16 +37,17 @@ export const RidershipGraph: React.FC = ({ const { line, linePath, - query: { busRoute }, + query: { busRoute, crRoute }, } = useDelimitatedRoute(); const { tooltipFormat, unit, callbacks } = config; const isMobile = !useBreakpoint('md'); const ref = useRef(); const chart = useMemo(() => { - const routeIndex = busRoute ? busRoute.replaceAll('/', '') : line; + const routeIndex = busRoute ? busRoute.replaceAll('/', '') : crRoute ?? line; const labels = data.map((point) => point.date); const lineColor = LINE_COLORS[line ?? 'default']; + return ( diff --git a/modules/ridership/RidershipGraphWrapper.tsx b/modules/ridership/RidershipGraphWrapper.tsx index 08c74b613..92ea4199d 100644 --- a/modules/ridership/RidershipGraphWrapper.tsx +++ b/modules/ridership/RidershipGraphWrapper.tsx @@ -5,7 +5,7 @@ import { WidgetCarousel } from '../../common/components/general/WidgetCarousel'; import { PercentageWidgetValue, RidersWidgetValue } from '../../common/types/basicWidgets'; import { WidgetForCarousel } from '../../common/components/widgets/internal/WidgetForCarousel'; import { CarouselGraphDiv } from '../../common/components/charts/CarouselGraphDiv'; -import type { BusRoute, Line } from '../../common/types/lines'; +import type { BusRoute, CommuterRailRoute, Line } from '../../common/types/lines'; import { NoDataNotice } from '../../common/components/notices/NoDataNotice'; import { getRidershipWidgetValues } from './utils/utils'; import { RidershipGraph } from './RidershipGraph'; @@ -14,6 +14,7 @@ interface RidershipGraphWrapperProps { data: RidershipCount[]; line?: Line; busRoute?: BusRoute | undefined; + crRoute?: CommuterRailRoute | undefined; config: ParamsType; startDate: string; endDate: string; @@ -23,12 +24,13 @@ export const RidershipGraphWrapper: React.FC = ({ data, line, busRoute, + crRoute, config, startDate, endDate, }) => { if (!data.some((datapoint) => datapoint.count !== null)) return ; - const { average, percentage, peak } = getRidershipWidgetValues(data, line, busRoute); + const { average, percentage, peak } = getRidershipWidgetValues(data, line, busRoute, crRoute); return ( diff --git a/modules/ridership/RidershipWidget.tsx b/modules/ridership/RidershipWidget.tsx index 1a5cce7ed..75f933712 100644 --- a/modules/ridership/RidershipWidget.tsx +++ b/modules/ridership/RidershipWidget.tsx @@ -15,7 +15,7 @@ export const RidershipWidget: React.FC = () => { const { startDate } = OVERVIEW_OPTIONS[query.view ?? 'year']; const endDate = TODAY_STRING; const config = getSpeedGraphConfig(dayjs(startDate), dayjs(endDate)); - const lineId = getRidershipLineId(line, query.busRoute); + const lineId = getRidershipLineId(line, query.busRoute, query.crRoute); const ridership = useRidershipData({ line_id: lineId, start_date: startDate, @@ -30,6 +30,7 @@ export const RidershipWidget: React.FC = () => { { - const routeIndex = busRoute ? busRoute.replaceAll('/', '') : line; + const routeIndex = crRoute ?? (busRoute ? busRoute.replaceAll('/', '') : line); const average = ridership.reduce((sum, current) => sum + current.count, 0) / ridership.length; const peak = ridership.reduce( (max, datapoint) => (datapoint.count > max.count ? datapoint : max), diff --git a/modules/slowzones/SlowZonesWidget.tsx b/modules/slowzones/SlowZonesWidget.tsx index 8fc2da855..4184aac77 100644 --- a/modules/slowzones/SlowZonesWidget.tsx +++ b/modules/slowzones/SlowZonesWidget.tsx @@ -23,9 +23,10 @@ export const SlowZonesWidget: React.FC = () => { const totalSlowTimeReady = !delayTotals.isError && delayTotals.data && startDateUTC && endDateUTC && lineShort && line; - if (line === 'line-bus' || line === 'line-green') { + if (line === 'line-bus' || line === 'line-green' || line === 'line-commuter-rail') { return null; } + return ( <> diff --git a/pages/[line]/index.tsx b/pages/[line]/index.tsx index 64662be5e..3d9fe451d 100644 --- a/pages/[line]/index.tsx +++ b/pages/[line]/index.tsx @@ -1,4 +1,4 @@ -import { ALL_LINE_PATHS, BUS_PATH } from '../../common/types/lines'; +import { ALL_LINE_PATHS, BUS_PATH, COMMUTER_RAIL_PATH } from '../../common/types/lines'; import { Overview } from '../../modules/dashboard/Overview'; export async function getStaticProps() { @@ -7,7 +7,7 @@ export async function getStaticProps() { export async function getStaticPaths() { return { - paths: [...ALL_LINE_PATHS, BUS_PATH], + paths: [...ALL_LINE_PATHS, BUS_PATH, COMMUTER_RAIL_PATH], fallback: false, }; } diff --git a/pages/[line]/ridership.tsx b/pages/[line]/ridership.tsx index 11009ff1f..ec86bb369 100644 --- a/pages/[line]/ridership.tsx +++ b/pages/[line]/ridership.tsx @@ -1,4 +1,4 @@ -import { ALL_LINE_PATHS, BUS_PATH } from '../../common/types/lines'; +import { ALL_LINE_PATHS, BUS_PATH, COMMUTER_RAIL_PATH } from '../../common/types/lines'; import { RidershipDetails } from '../../modules/ridership/RidershipDetails'; export async function getStaticProps() { @@ -7,7 +7,7 @@ export async function getStaticProps() { export async function getStaticPaths() { return { - paths: [...ALL_LINE_PATHS, BUS_PATH], + paths: [...ALL_LINE_PATHS, BUS_PATH, COMMUTER_RAIL_PATH], fallback: false, }; }