diff --git a/apps/site/assets/ts/stop/__tests__/DepartureListTest.tsx b/apps/site/assets/ts/stop/__tests__/DepartureListTest.tsx
index 4d4b091555..497aea537b 100644
--- a/apps/site/assets/ts/stop/__tests__/DepartureListTest.tsx
+++ b/apps/site/assets/ts/stop/__tests__/DepartureListTest.tsx
@@ -67,6 +67,7 @@ describe("DepartureList", () => {
directionId={0}
headsign={"Cucamonga"}
alerts={[]}
+ hasService={true}
/>
);
expect(screen.queryAllByRole("listitem")).toHaveLength(predictions.length);
@@ -83,6 +84,7 @@ describe("DepartureList", () => {
directionId={0}
headsign={"Atlantis"}
alerts={[]}
+ hasService={true}
/>
);
@@ -101,6 +103,7 @@ describe("DepartureList", () => {
directionId={0}
headsign={"Disney"}
alerts={[]}
+ hasService={true}
/>
);
@@ -119,6 +122,7 @@ describe("DepartureList", () => {
directionId={0}
headsign={"Bermuda"}
alerts={[]}
+ hasService={true}
/>
);
expect(
@@ -161,6 +165,7 @@ describe("DepartureList", () => {
directionId={0}
headsign={"San Fransokyo"}
alerts={alerts}
+ hasService={true}
/>
);
@@ -179,6 +184,7 @@ describe("DepartureList", () => {
directionId={0}
headsign={"Gotham"}
alerts={[]}
+ hasService={true}
/>
);
expect(
@@ -195,6 +201,7 @@ describe("DepartureList", () => {
departures={[]}
directionId={0}
headsign="Riverdale"
+ hasService={true}
/>
);
expect(screen.getByText("No upcoming trips today")).toBeDefined();
@@ -225,6 +232,7 @@ describe("DepartureList", () => {
departures={mergeIntoDepartureInfo(schedules, predictions)}
directionId={0}
headsign="Smallville"
+ hasService={true}
/>
);
expect(screen.getByText("Cancelled")).toBeInTheDocument();
@@ -265,6 +273,7 @@ describe("DepartureList", () => {
directionId={0}
headsign="Emerald City"
targetDate={new Date("2022-04-27T11:00:00-04:00")}
+ hasService={true}
/>
);
expect(screen.queryByText("Cancelled")).not.toBeInTheDocument();
@@ -292,8 +301,26 @@ describe("DepartureList", () => {
directionId={0}
headsign="Emerald City"
targetDate={new Date("2022-04-27T11:00:00-04:00")}
+ hasService={true}
/>
);
expect(screen.queryAllByRole("listitem")).toHaveLength(departures.length);
});
+
+ it("can show no service message", () => {
+ const expectedMessage = "No service today";
+ render(
+
+ );
+
+ expect(screen.findByText(expectedMessage)).toBeDefined();
+ });
});
diff --git a/apps/site/assets/ts/stop/__tests__/components/DepartureTimesTest.tsx b/apps/site/assets/ts/stop/__tests__/components/DepartureTimesTest.tsx
index 413bbe7e84..bfa658adcf 100644
--- a/apps/site/assets/ts/stop/__tests__/components/DepartureTimesTest.tsx
+++ b/apps/site/assets/ts/stop/__tests__/components/DepartureTimesTest.tsx
@@ -19,6 +19,7 @@ describe("DepartureTimes", () => {
alertsForDirection={[]}
isCR={false}
onClick={jest.fn()}
+ hasService={true}
/>
);
await waitFor(() => {
@@ -80,6 +81,7 @@ describe("DepartureTimes", () => {
alertsForDirection={[]}
isCR={false}
onClick={jest.fn()}
+ hasService={true}
/>
);
await waitFor(() => {
@@ -116,6 +118,7 @@ describe("DepartureTimes", () => {
alertsForDirection={alerts}
isCR={false}
onClick={jest.fn()}
+ hasService={true}
/>
);
await waitFor(() => {
@@ -154,6 +157,7 @@ describe("DepartureTimes", () => {
alertsForDirection={alerts}
isCR={false}
onClick={jest.fn()}
+ hasService={true}
/>
);
await waitFor(() => {
@@ -205,6 +209,7 @@ describe("DepartureTimes", () => {
overrideDate={dateToCompare}
isCR={false}
onClick={jest.fn()}
+ hasService={true}
/>
);
await waitFor(() => {
@@ -357,6 +362,7 @@ describe("DepartureTimes", () => {
overrideDate={compareTime}
isCR={false}
onClick={setRowSpy}
+ hasService={true}
/>
);
@@ -442,6 +448,7 @@ describe("DepartureTimes", () => {
alertsForDirection={[]}
isCR={true}
onClick={jest.fn()}
+ hasService={true}
/>
);
@@ -460,6 +467,7 @@ describe("DepartureTimes", () => {
alertsForDirection={[]}
isCR={false}
onClick={jest.fn()}
+ hasService={true}
/>
);
await waitFor(() => {
@@ -482,6 +490,7 @@ describe("DepartureTimes", () => {
alertsForDirection={[closureAlert]}
isCR={true}
onClick={jest.fn()}
+ hasService={true}
/>
);
await waitFor(() => {
@@ -504,6 +513,7 @@ describe("DepartureTimes", () => {
alertsForDirection={[closureAlert]}
isCR={false}
onClick={jest.fn()}
+ hasService={true}
/>
);
@@ -512,4 +522,21 @@ describe("DepartureTimes", () => {
expect(screen.getByText("See alternatives")).toBeInTheDocument();
});
});
+
+ it("can show no service message", async () => {
+ const expectedMessage = "No service today";
+ renderWithRouter(
+
+ );
+ await waitFor(() => {
+ expect(screen.findByText(expectedMessage)).toBeDefined();
+ });
+ });
});
diff --git a/apps/site/assets/ts/stop/components/DepartureCard.tsx b/apps/site/assets/ts/stop/components/DepartureCard.tsx
index f5d3441f62..666cd7ae66 100644
--- a/apps/site/assets/ts/stop/components/DepartureCard.tsx
+++ b/apps/site/assets/ts/stop/components/DepartureCard.tsx
@@ -73,6 +73,7 @@ const DepartureCard = ({
)}
onClick={onClick}
isCR={isACommuterRailRoute(route)}
+ hasService={routePatterns.length !== 0}
/>
);
}
diff --git a/apps/site/assets/ts/stop/components/DepartureList.tsx b/apps/site/assets/ts/stop/components/DepartureList.tsx
index 80458c3c71..4d87620296 100644
--- a/apps/site/assets/ts/stop/components/DepartureList.tsx
+++ b/apps/site/assets/ts/stop/components/DepartureList.tsx
@@ -9,6 +9,7 @@ import renderSvg from "../../helpers/render-svg";
import { isSuppressiveAlert } from "../../models/alert";
import Alerts from "../../components/Alerts";
import { isACommuterRailRoute } from "../../models/route";
+import { todayDateString } from "../../helpers/date";
interface DepartureListProps {
route: Route;
@@ -17,13 +18,16 @@ interface DepartureListProps {
directionId: DirectionId;
headsign: string;
alerts: Alert[];
+ hasService: boolean;
targetDate?: Date | undefined;
}
-const displayNoUpcomingTrips = (): JSX.Element => {
+const displayNoUpcomingTrips = (
+ message = "No upcoming trips today"
+): JSX.Element => {
return (
- No upcoming trips today
+ {message}
);
};
@@ -35,6 +39,7 @@ const DepartureList = ({
directionId,
headsign,
alerts,
+ hasService,
targetDate
}: DepartureListProps): ReactElement => {
const isCR = isACommuterRailRoute(route);
@@ -52,6 +57,13 @@ const DepartureList = ({
const tripForSelectedRoutePattern: Trip | undefined =
modeSpecificDepartures[0]?.trip;
+ const noTrips =
+ modeSpecificDepartures.length === 0 && displayNoUpcomingTrips();
+ const noService =
+ !hasService &&
+ displayNoUpcomingTrips(`No service today, ${todayDateString()}`);
+ const noServiceOrNoTrips = noService || noTrips;
+
return (
<>
@@ -74,17 +86,12 @@ const DepartureList = ({
{headsign}
{alerts.length ?
: null}
- {modeSpecificDepartures.length === 0
- ? displayNoUpcomingTrips()
- : !alertsShouldSuppressDepartures && (
-
- {departuresListFromInfos(
- modeSpecificDepartures,
- isCR,
- targetDate
- )}
-
- )}
+ {noServiceOrNoTrips ||
+ (!alertsShouldSuppressDepartures && (
+
+ {departuresListFromInfos(modeSpecificDepartures, isCR, targetDate)}
+
+ ))}
>
);
};
diff --git a/apps/site/assets/ts/stop/components/DepartureTimes.tsx b/apps/site/assets/ts/stop/components/DepartureTimes.tsx
index 64cc2e445c..b3f160bca9 100644
--- a/apps/site/assets/ts/stop/components/DepartureTimes.tsx
+++ b/apps/site/assets/ts/stop/components/DepartureTimes.tsx
@@ -13,6 +13,7 @@ interface DepartureTimesProps {
headsign: string;
onClick: () => void;
isCR: boolean;
+ hasService: boolean;
// override date primarily used for testing
overrideDate?: Date;
}
@@ -50,6 +51,7 @@ const DepartureTimes = ({
headsign,
onClick,
isCR,
+ hasService,
overrideDate
}: DepartureTimesProps): ReactElement
| null => {
const timeList = departuresListFromInfos(
@@ -66,18 +68,24 @@ const DepartureTimes = ({
return (
-
- {timeList.length > 0 ? (
- {timeList}
- ) : (
-
- No upcoming trips
-
- )}
-
+ {hasService ? (
+
+ {timeList.length > 0 ? (
+ {timeList}
+ ) : (
+
+ No upcoming trips
+
+ )}
+
+ ) : (
+
+ No service today
+
+ )}
);
diff --git a/apps/site/assets/ts/stop/components/DeparturesAndMap.tsx b/apps/site/assets/ts/stop/components/DeparturesAndMap.tsx
index 896e677ee7..c2b30bd0b5 100644
--- a/apps/site/assets/ts/stop/components/DeparturesAndMap.tsx
+++ b/apps/site/assets/ts/stop/components/DeparturesAndMap.tsx
@@ -240,6 +240,7 @@ const DeparturesAndMap = ({
directionId={activeRow.directionId}
headsign={activeRow.headsign}
alerts={realtimeAlerts}
+ hasService={routePatternsForSelection.length !== 0}
/>
) : (