From e0fdc564618b170ce92dc864d7b52b180aff5d17 Mon Sep 17 00:00:00 2001 From: cmaddox5 Date: Tue, 19 Nov 2024 13:38:29 -0500 Subject: [PATCH 01/18] Adjust margins so row width is consistent. --- assets/css/v2/elevator/elevator_closures.scss | 5 +++-- assets/src/components/v2/elevator/elevator_closures.tsx | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/assets/css/v2/elevator/elevator_closures.scss b/assets/css/v2/elevator/elevator_closures.scss index 0ce4ea92a..b4944d980 100644 --- a/assets/css/v2/elevator/elevator_closures.scss +++ b/assets/css/v2/elevator/elevator_closures.scss @@ -81,7 +81,7 @@ &__name-and-pills { display: flex; align-items: center; - margin-bottom: 14px; + margin: 0 48px 14px; .route-pill { width: 132px; @@ -104,13 +104,14 @@ } &__elevator-name { + margin: 0 48px; line-height: 64px; } &__elevator-name.list-item { display: list-item; margin-bottom: 8px; - margin-left: 48px; + margin-left: 96px; } } } diff --git a/assets/src/components/v2/elevator/elevator_closures.tsx b/assets/src/components/v2/elevator/elevator_closures.tsx index 4da4503e1..b3b374df9 100644 --- a/assets/src/components/v2/elevator/elevator_closures.tsx +++ b/assets/src/components/v2/elevator/elevator_closures.tsx @@ -153,8 +153,8 @@ const OutsideClosureList = ({ -
+
{
Date: Wed, 20 Nov 2024 08:54:40 -0500 Subject: [PATCH 02/18] Refactored a bit to prepare for in station closures view. --- .../v2/elevator/elevator_closures.tsx | 49 ++++++++++++------- 1 file changed, 32 insertions(+), 17 deletions(-) diff --git a/assets/src/components/v2/elevator/elevator_closures.tsx b/assets/src/components/v2/elevator/elevator_closures.tsx index b3b374df9..5dca71ac6 100644 --- a/assets/src/components/v2/elevator/elevator_closures.tsx +++ b/assets/src/components/v2/elevator/elevator_closures.tsx @@ -54,19 +54,13 @@ const ClosureRow = ({ station }: ClosureRowProps) => { ); }; -interface InStationSummaryProps { - closures: ElevatorClosure[]; -} - -const InStationSummary = ({ closures }: InStationSummaryProps) => { - const summaryText = closures.length - ? "" - : "All elevators at this station are currently working"; - +const InStationSummary = () => { return ( <>
- {summaryText} + + All elevators at this station are currently working + @@ -78,7 +72,6 @@ const InStationSummary = ({ closures }: InStationSummaryProps) => { interface OutsideClosureListProps extends WrappedComponentProps { stations: StationWithClosures[]; - lastUpdate: number | null; } const OutsideClosureList = ({ @@ -186,6 +179,25 @@ const OutsideClosureList = ({ ); }; +interface NoInStationClosuresViewProps extends OutsideClosureListProps {} + +const NoInStationClosuresView = ({ + stations, + lastUpdate, + onFinish, +}: NoInStationClosuresViewProps) => { + return ( + <> + + + + ); +}; + interface Props extends WrappedComponentProps { id: string; in_station_closures: ElevatorClosure[]; @@ -200,12 +212,15 @@ const ElevatorClosures: React.ComponentType = ({ }: Props) => { return (
- - + {inStationClosures.length === 0 ? ( + + ) : ( + <> + )}
); }; From 4ddc1eb04705919fab772d1f75cb6b5788952328 Mon Sep 17 00:00:00 2001 From: cmaddox5 Date: Wed, 20 Nov 2024 14:25:42 -0500 Subject: [PATCH 03/18] Added first page of CurrentElevatorClosedView. --- assets/css/colors.scss | 2 + assets/css/v2/elevator/elevator_closures.scss | 285 ++++++++++++------ .../v2/elevator/elevator_closures.tsx | 151 +++++++--- .../svgr_bundled/elevator-wayfinding.svg | 41 +++ .../images/svgr_bundled/no-service-black.svg | 6 + .../candidate_generator/elevator/closures.ex | 15 +- .../v2/widget_instance/elevator_closures.ex | 25 +- mix.exs | 2 +- mix.lock | 2 +- 9 files changed, 389 insertions(+), 140 deletions(-) create mode 100644 assets/static/images/svgr_bundled/elevator-wayfinding.svg create mode 100644 assets/static/images/svgr_bundled/no-service-black.svg diff --git a/assets/css/colors.scss b/assets/css/colors.scss index b4b0fb251..36a4f2b44 100644 --- a/assets/css/colors.scss +++ b/assets/css/colors.scss @@ -19,3 +19,5 @@ $cool-black-15: #171f26; $cool-black-30: #2e3e4d; $normal-service-green: #145a06; + +$accessibility-blue: #165c96; diff --git a/assets/css/v2/elevator/elevator_closures.scss b/assets/css/v2/elevator/elevator_closures.scss index b4944d980..c486eb984 100644 --- a/assets/css/v2/elevator/elevator_closures.scss +++ b/assets/css/v2/elevator/elevator_closures.scss @@ -3,22 +3,9 @@ display: flex; flex-direction: column; height: 100%; + color: $cool-black-15; background-color: $warm-neutral-90; - .in-station-summary { - display: flex; - justify-content: space-between; - padding: 24px 48px; - font-size: 48px; - font-weight: 400; - line-height: 64px; - color: $cool-black-30; - - .text { - margin-right: 82px; - } - } - hr.thick { min-height: 24px; margin: 0; @@ -34,119 +21,231 @@ opacity: 0.5; } - .outside-closure-list { + .subheading { + font-size: 80px; + font-weight: 700; + line-height: 80px; + } + + .current-elevator-closed-view { position: relative; height: 100%; - background-color: $warm-neutral-90; - .header-container { + .shape { + position: absolute; + top: 0; + right: 0; + display: inline-block; + border-right: 345px solid $accessibility-blue; + border-bottom: 300px solid transparent; + } + + .header { + margin: 53px 68px 51px 48px; + font-weight: 700; + + .icons { + margin-bottom: 21px; + + .no-service-icon { + margin-right: 16px; + } + } + + .closed-text { + margin-bottom: 18px; + font-size: 150px; + line-height: 150px; + } + } + + .accessible-path-container { margin: 48px; - margin-bottom: 0; - .header { + .subheading-container { display: flex; + justify-content: space-between; max-height: 432px; - margin-bottom: 48px; + margin-bottom: 28px; font-size: 112px; font-weight: 700; line-height: 112px; - &__title { - word-spacing: 9999px; + .subheading { + align-self: center; } - } - } - - .closure-list-container { - overflow: hidden; - .closure-list { - display: flex; - flex-flow: column wrap; - height: 904px; - transform: translateX(calc(-100% * var(--closure-list-offset))); - - .closure-row { - box-sizing: border-box; - width: 1080px; - padding: 0 48px; - - &__station-name { - font-size: 62px; - font-weight: 600; - line-height: 80px; - color: $cool-black-15; - } - - &__name-and-pills { - display: flex; - align-items: center; - margin: 0 48px 14px; + .arrow.e { + rotate: 90deg; + } - .route-pill { - width: 132px; - height: 68.13px; - margin-right: 24px; + .arrow.s { + rotate: 180deg; + } - &__text { - line-height: 68.13px; - } + .arrow.w { + rotate: -90deg; + } + } - &__icon { - height: 100%; - } + .alternate-direction-text { + margin-bottom: 39px; + font-size: 80px; + line-height: 96px; + color: $cool-black-30; + } - &__icon-image { - height: 100%; - margin-top: 0; - } - } - } + .feedback-text { + font-size: 48px; + line-height: 64px; + color: $cool-black-30; - &__elevator-name { - margin: 0 48px; - line-height: 64px; - } + .italic { + font-style: italic; + } - &__elevator-name.list-item { - display: list-item; - margin-bottom: 8px; - margin-left: 96px; - } + .bold { + font-weight: 700; } } } - .paging-info-container { + .paging-indicators { position: absolute; + right: 0; bottom: 0; + margin-bottom: 46px; + } + } + + .outside-closures-view { + .in-station-summary { display: flex; justify-content: space-between; - width: 100%; - height: 72px; - margin-bottom: 20px; + padding: 24px 48px; + font-size: 48px; + font-weight: 400; + line-height: 64px; + color: $cool-black-30; - .more-elevators-text { - align-self: center; - padding: 0 48px 20px; + .text { + margin-right: 82px; } + } - .paging-indicators { - display: flex; - align-items: center; - margin-right: 66px; + .outside-closure-list { + position: relative; + height: 100%; + background-color: $warm-neutral-90; + + .header-container { + margin: 48px; + margin-bottom: 0; + + .header { + display: flex; + max-height: 432px; + margin-bottom: 48px; + font-size: 112px; + font-weight: 700; + line-height: 112px; + + &__title { + word-spacing: 9999px; + } + } + } + + .closure-list-container { + overflow: hidden; + + .closure-list { + display: flex; + flex-flow: column wrap; + height: 904px; + transform: translateX(calc(-100% * var(--closure-list-offset))); + + .closure-row { + box-sizing: border-box; + width: 1080px; + padding: 0 48px; + + &__station-name { + font-size: 62px; + font-weight: 600; + line-height: 80px; + color: $cool-black-15; + } + + &__name-and-pills { + display: flex; + align-items: center; + margin-bottom: 14px; + + .route-pill { + width: 132px; + height: 68.13px; + margin-right: 24px; + + &__text { + line-height: 68.13px; + } + + &__icon { + height: 100%; + } + + &__icon-image { + height: 100%; + margin-top: 0; + } + } + } - .paging-indicator:first-child:not(:only-child) { - margin-right: 27px; + &__elevator-name { + line-height: 64px; + } + + &__elevator-name.list-item { + display: list-item; + margin-bottom: 8px; + margin-left: 48px; + } + } } } - } - .paging-info-container, - .closure-row__elevator-name { - font-size: 48px; - font-weight: 400; - color: $cool-black-30; + .paging-info-container { + position: absolute; + bottom: 0; + display: flex; + justify-content: space-between; + width: 100%; + height: 72px; + margin-bottom: 20px; + + .more-elevators-text { + align-self: center; + padding: 0 48px 20px; + } + } + + .paging-info-container, + .closure-row__elevator-name { + font-size: 48px; + font-weight: 400; + color: $cool-black-30; + } } } } + +.paging-indicators { + display: flex; + align-items: center; + margin-right: 66px; + + .paging-indicator:first-child:not(:only-child) { + margin-right: 27px; + } +} diff --git a/assets/src/components/v2/elevator/elevator_closures.tsx b/assets/src/components/v2/elevator/elevator_closures.tsx index 5dca71ac6..a972a8185 100644 --- a/assets/src/components/v2/elevator/elevator_closures.tsx +++ b/assets/src/components/v2/elevator/elevator_closures.tsx @@ -1,12 +1,16 @@ import React, { ComponentType, useLayoutEffect, useRef, useState } from "react"; import cx from "classnames"; +import _ from "lodash"; import NormalService from "Images/svgr_bundled/normal-service.svg"; import AccessibilityAlert from "Images/svgr_bundled/accessibility-alert.svg"; import PagingDotUnselected from "Images/svgr_bundled/paging_dot_unselected.svg"; import PagingDotSelected from "Images/svgr_bundled/paging_dot_selected.svg"; +import NoService from "Images/svgr_bundled/no-service-black.svg"; +import ElevatorWayfinding from "Images/svgr_bundled/elevator-wayfinding.svg"; +import Arrow from "Images/svgr_bundled/arrow-90.svg"; +import IsaNegative from "Images/svgr_bundled/isa-negative.svg"; import makePersistent, { WrappedComponentProps } from "../persistent_wrapper"; import RoutePill, { routePillKey, type Pill } from "../departures/route_pill"; -import _ from "lodash"; import useClientPaging from "Hooks/v2/use_client_paging"; type StationWithClosures = { @@ -24,6 +28,38 @@ type ElevatorClosure = { header_text: string; }; +type ArrowDirection = "n" | "e" | "s" | "w"; + +interface PagingIndicatorsProps { + numPages: number; + pageIndex: number; +} + +const PagingIndicators = ({ numPages, pageIndex }: PagingIndicatorsProps) => { + const indicators: JSX.Element[] = []; + for (let i = 0; i < numPages; i++) { + const indicator = + pageIndex === i ? ( + + ) : ( + + ); + indicators.push(indicator); + } + + return
{indicators}
; +}; + interface ClosureRowProps { station: StationWithClosures; } @@ -112,31 +148,6 @@ const OutsideClosureList = ({ setRowCounts(rowCounts); }, [stations]); - const getPagingIndicators = (num: number) => { - const indicators: JSX.Element[] = []; - for (let i = 0; i < num; i++) { - const indicator = - pageIndex === i ? ( - - ) : ( - - ); - indicators.push(indicator); - } - - return indicators; - }; - return (
@@ -146,8 +157,8 @@ const OutsideClosureList = ({
+
-
{
+{numOffsetRows} more elevators
-
- {getPagingIndicators(numPages)} -
+
)}
); }; -interface NoInStationClosuresViewProps extends OutsideClosureListProps {} +interface OutsideClosuresViewProps extends OutsideClosureListProps {} -const NoInStationClosuresView = ({ +const OutsideClosuresView = ({ stations, lastUpdate, onFinish, -}: NoInStationClosuresViewProps) => { +}: OutsideClosuresViewProps) => { return ( - <> +
- +
+ ); +}; + +interface CurrentElevatorClosedViewProps { + closure: ElevatorClosure; + alternateDirectionText: string; + accessiblePathDirectionArrow: ArrowDirection; + accessiblePathImageUrl: string; +} + +const CurrentElevatorClosedView = ({ + alternateDirectionText, + accessiblePathDirectionArrow, +}: CurrentElevatorClosedViewProps) => { + return ( +
+
+
+
+ + +
+
Closed
+
Until further notice
+
+
+
+
+
Accessible Path
+
+ + +
+
+
{alternateDirectionText}
+
+ + Are these directions unclear? Leave feedback here: + {" "} + www.feedback.com +
+
+ +
); }; @@ -202,24 +259,40 @@ interface Props extends WrappedComponentProps { id: string; in_station_closures: ElevatorClosure[]; other_stations_with_closures: StationWithClosures[]; + alternate_direction_text: string; + accessible_path_direction_arrow: ArrowDirection; + accessible_path_image_url: string; } const ElevatorClosures: React.ComponentType = ({ + id, other_stations_with_closures: otherStationsWithClosures, in_station_closures: inStationClosures, + alternate_direction_text: alternateDirectionText, + accessible_path_direction_arrow: accessiblePathDirectionArrow, + accessible_path_image_url: accessiblePathImageUrl, lastUpdate, onFinish, }: Props) => { + const currentElevatorClosure = inStationClosures.find( + (c) => c.elevator_id === id, + ); + return (
- {inStationClosures.length === 0 ? ( - + ) : ( + - ) : ( - <> )}
); diff --git a/assets/static/images/svgr_bundled/elevator-wayfinding.svg b/assets/static/images/svgr_bundled/elevator-wayfinding.svg new file mode 100644 index 000000000..2ea9539fa --- /dev/null +++ b/assets/static/images/svgr_bundled/elevator-wayfinding.svg @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/assets/static/images/svgr_bundled/no-service-black.svg b/assets/static/images/svgr_bundled/no-service-black.svg new file mode 100644 index 000000000..969faac38 --- /dev/null +++ b/assets/static/images/svgr_bundled/no-service-black.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/lib/screens/v2/candidate_generator/elevator/closures.ex b/lib/screens/v2/candidate_generator/elevator/closures.ex index 127564cba..c4a8fd8b2 100644 --- a/lib/screens/v2/candidate_generator/elevator/closures.ex +++ b/lib/screens/v2/candidate_generator/elevator/closures.ex @@ -6,6 +6,7 @@ defmodule Screens.V2.CandidateGenerator.Elevator.Closures do alias Screens.Alerts.{Alert, InformedEntity} alias Screens.Routes.Route alias Screens.Stops.Stop + alias Screens.Util.Assets alias Screens.V2.WidgetInstance.ElevatorClosures alias Screens.V2.WidgetInstance.Serializer.RoutePill alias ScreensConfig.Screen @@ -19,7 +20,14 @@ defmodule Screens.V2.CandidateGenerator.Elevator.Closures do @stop injected(Stop) @spec elevator_status_instances(Screen.t()) :: list(ElevatorClosures.t()) - def elevator_status_instances(%Screen{app_params: %Elevator{elevator_id: elevator_id}}) do + def elevator_status_instances(%Screen{ + app_params: %Elevator{ + elevator_id: elevator_id, + alternate_direction_text: alternate_direction_text, + accessible_path_direction_arrow: accessible_path_direction_arrow, + accessible_path_image_url: accessible_path_image_url + } + }) do with {:ok, %Stop{id: stop_id}} <- @facility.fetch_stop_for_facility(elevator_id), {:ok, parent_station_map} <- @stop.fetch_parent_station_name_map(), {:ok, alerts} <- @alert.fetch_elevator_alerts_with_facilities() do @@ -34,7 +42,10 @@ defmodule Screens.V2.CandidateGenerator.Elevator.Closures do id: elevator_id, in_station_closures: Enum.map(in_station_alerts, &alert_to_elevator_closure/1), other_stations_with_closures: - format_outside_closures(outside_alerts, parent_station_map, routes_map) + format_outside_closures(outside_alerts, parent_station_map, routes_map), + alternate_direction_text: alternate_direction_text, + accessible_path_direction_arrow: accessible_path_direction_arrow, + accessible_path_image_url: Assets.s3_asset_url(accessible_path_image_url) } ] else diff --git a/lib/screens/v2/widget_instance/elevator_closures.ex b/lib/screens/v2/widget_instance/elevator_closures.ex index a819ca248..c0eead7ed 100644 --- a/lib/screens/v2/widget_instance/elevator_closures.ex +++ b/lib/screens/v2/widget_instance/elevator_closures.ex @@ -2,13 +2,24 @@ defmodule Screens.V2.WidgetInstance.ElevatorClosures do @moduledoc false alias Screens.Stops.Stop + alias ScreensConfig.V2.Elevator - defstruct ~w[id in_station_closures other_stations_with_closures]a + defstruct ~w[ + id + in_station_closures + other_stations_with_closures + alternate_direction_text + accessible_path_direction_arrow + accessible_path_image_url + ]a @type t :: %__MODULE__{ id: String.t(), in_station_closures: list(__MODULE__.Closure.t()), - other_stations_with_closures: list(__MODULE__.Station.t()) + other_stations_with_closures: list(__MODULE__.Station.t()), + alternate_direction_text: String.t(), + accessible_path_direction_arrow: Elevator.arrow_direction(), + accessible_path_image_url: String.t() } defmodule Station do @@ -48,12 +59,18 @@ defmodule Screens.V2.WidgetInstance.ElevatorClosures do def serialize(%__MODULE__{ id: id, in_station_closures: in_station_closures, - other_stations_with_closures: other_stations_with_closures + other_stations_with_closures: other_stations_with_closures, + alternate_direction_text: alternate_direction_text, + accessible_path_direction_arrow: accessible_path_direction_arrow, + accessible_path_image_url: accessible_path_image_url }), do: %{ id: id, in_station_closures: in_station_closures, - other_stations_with_closures: other_stations_with_closures + other_stations_with_closures: other_stations_with_closures, + alternate_direction_text: alternate_direction_text, + accessible_path_direction_arrow: accessible_path_direction_arrow, + accessible_path_image_url: accessible_path_image_url } defimpl Screens.V2.WidgetInstance do diff --git a/mix.exs b/mix.exs index 496808d1b..62638ee48 100644 --- a/mix.exs +++ b/mix.exs @@ -94,7 +94,7 @@ defmodule Screens.MixProject do {:telemetry_metrics, "~> 0.4"}, {:screens_config, git: "https://github.com/mbta/screens-config-lib.git", - ref: "c0db78ecd43c633a55a1f24b268ae7b8a5214748"}, + ref: "fff14c3e4b98a19b19ec276b69ceb10e07d94579"}, {:nebulex, "~> 2.6"}, {:remote_ip, "~> 1.2"}, {:hackney_telemetry, "~> 0.2.0"}, diff --git a/mix.lock b/mix.lock index e27785181..d5b6fcfb6 100644 --- a/mix.lock +++ b/mix.lock @@ -62,7 +62,7 @@ "recon": {:hex, :recon, "2.5.6", "9052588e83bfedfd9b72e1034532aee2a5369d9d9343b61aeb7fbce761010741", [:mix, :rebar3], [], "hexpm", "96c6799792d735cc0f0fd0f86267e9d351e63339cbe03df9d162010cefc26bb0"}, "remote_ip": {:hex, :remote_ip, "1.2.0", "fb078e12a44414f4cef5a75963c33008fe169b806572ccd17257c208a7bc760f", [:mix], [{:combine, "~> 0.10", [hex: :combine, repo: "hexpm", optional: false]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "2ff91de19c48149ce19ed230a81d377186e4412552a597d6a5137373e5877cb7"}, "retry": {:hex, :retry, "0.18.0", "dc58ebe22c95aa00bc2459f9e0c5400e6005541cf8539925af0aa027dc860543", [:mix], [], "hexpm", "9483959cc7bf69c9e576d9dfb2b678b71c045d3e6f39ab7c9aa1489df4492d73"}, - "screens_config": {:git, "https://github.com/mbta/screens-config-lib.git", "c0db78ecd43c633a55a1f24b268ae7b8a5214748", [ref: "c0db78ecd43c633a55a1f24b268ae7b8a5214748"]}, + "screens_config": {:git, "https://github.com/mbta/screens-config-lib.git", "fff14c3e4b98a19b19ec276b69ceb10e07d94579", [ref: "fff14c3e4b98a19b19ec276b69ceb10e07d94579"]}, "sentry": {:hex, :sentry, "10.7.1", "33392222d80ccff99c503f972998d2858b4c1e5aca2219a34269b68dacba8e7d", [:mix], [{:hackney, "~> 1.8", [hex: :hackney, repo: "hexpm", optional: true]}, {:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: true]}, {:nimble_options, "~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:nimble_ownership, "~> 0.3.0 or ~> 1.0", [hex: :nimble_ownership, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.6", [hex: :phoenix, repo: "hexpm", optional: true]}, {:phoenix_live_view, "~> 0.20", [hex: :phoenix_live_view, repo: "hexpm", optional: true]}, {:plug, "~> 1.6", [hex: :plug, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: true]}], "hexpm", "56291312397bf2b6afab6cf4f7aa1f27413b0eb2ceeb63b8aab2d7658aaea882"}, "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.7", "354c321cf377240c7b8716899e182ce4890c5938111a1296add3ec74cf1715df", [:make, :mix, :rebar3], [], "hexpm", "fe4c190e8f37401d30167c8c405eda19469f34577987c76dde613e838bbc67f8"}, "stream_data": {:hex, :stream_data, "1.1.2", "05499eaec0443349ff877aaabc6e194e82bda6799b9ce6aaa1aadac15a9fdb4d", [:mix], [], "hexpm", "129558d2c77cbc1eb2f4747acbbea79e181a5da51108457000020a906813a1a9"}, From edb7dd529fd3bc65b532ca5bc3540c532d392e82 Mon Sep 17 00:00:00 2001 From: cmaddox5 Date: Thu, 21 Nov 2024 08:52:58 -0500 Subject: [PATCH 04/18] Polished up first page of CurrentElevatorClosedView. --- assets/css/v2/elevator/elevator_closures.scss | 41 +++++++++++++------ .../v2/elevator/elevator_closures.tsx | 24 +++++++---- 2 files changed, 44 insertions(+), 21 deletions(-) diff --git a/assets/css/v2/elevator/elevator_closures.scss b/assets/css/v2/elevator/elevator_closures.scss index c486eb984..058bd1521 100644 --- a/assets/css/v2/elevator/elevator_closures.scss +++ b/assets/css/v2/elevator/elevator_closures.scss @@ -41,7 +41,9 @@ } .header { - margin: 53px 68px 51px 48px; + box-sizing: border-box; + height: 528px; + padding: 53px 68px 51px 48px; font-weight: 700; .icons { @@ -59,17 +61,20 @@ } } + hr.thin { + margin: 0 20px; + } + .accessible-path-container { - margin: 48px; + box-sizing: border-box; + height: 984px; + padding: 48px; .subheading-container { display: flex; + align-items: center; justify-content: space-between; - max-height: 432px; - margin-bottom: 28px; - font-size: 112px; - font-weight: 700; - line-height: 112px; + height: 142px; .subheading { align-self: center; @@ -89,10 +94,22 @@ } .alternate-direction-text { - margin-bottom: 39px; + color: $cool-black-30; + } + + .alternate-direction-text.small { + font-size: 48px; + line-height: 64px; + } + + .alternate-direction-text.medium { + font-size: 62px; + line-height: 80px; + } + + .alternate-direction-text.large { font-size: 80px; line-height: 96px; - color: $cool-black-30; } .feedback-text { @@ -111,10 +128,8 @@ } .paging-indicators { - position: absolute; - right: 0; - bottom: 0; - margin-bottom: 46px; + justify-content: end; + height: 120px; } } diff --git a/assets/src/components/v2/elevator/elevator_closures.tsx b/assets/src/components/v2/elevator/elevator_closures.tsx index a972a8185..207a0b71d 100644 --- a/assets/src/components/v2/elevator/elevator_closures.tsx +++ b/assets/src/components/v2/elevator/elevator_closures.tsx @@ -12,6 +12,7 @@ import IsaNegative from "Images/svgr_bundled/isa-negative.svg"; import makePersistent, { WrappedComponentProps } from "../persistent_wrapper"; import RoutePill, { routePillKey, type Pill } from "../departures/route_pill"; import useClientPaging from "Hooks/v2/use_client_paging"; +import useTextResizer from "Hooks/v2/use_text_resizer"; type StationWithClosures = { id: string; @@ -207,7 +208,7 @@ const OutsideClosuresView = ({ ); }; -interface CurrentElevatorClosedViewProps { +interface CurrentElevatorClosedViewProps extends WrappedComponentProps { closure: ElevatorClosure; alternateDirectionText: string; accessiblePathDirectionArrow: ArrowDirection; @@ -217,7 +218,16 @@ interface CurrentElevatorClosedViewProps { const CurrentElevatorClosedView = ({ alternateDirectionText, accessiblePathDirectionArrow, + onFinish, + lastUpdate, }: CurrentElevatorClosedViewProps) => { + const pageIndex = useClientPaging({ numPages: 2, onFinish, lastUpdate }); + const { ref, size } = useTextResizer({ + sizes: ["small", "medium", "large"], + maxHeight: 746, + resetDependencies: [alternateDirectionText], + }); + return (
@@ -242,15 +252,11 @@ const CurrentElevatorClosedView = ({ />
-
{alternateDirectionText}
-
- - Are these directions unclear? Leave feedback here: - {" "} - www.feedback.com +
+ {alternateDirectionText}
- + ); }; @@ -286,6 +292,8 @@ const ElevatorClosures: React.ComponentType = ({ alternateDirectionText={alternateDirectionText} accessiblePathDirectionArrow={accessiblePathDirectionArrow} accessiblePathImageUrl={accessiblePathImageUrl} + onFinish={onFinish} + lastUpdate={lastUpdate} /> ) : ( Date: Thu, 21 Nov 2024 09:06:03 -0500 Subject: [PATCH 05/18] Added second page to view. --- assets/css/v2/elevator/elevator_closures.scss | 16 ++++------------ .../components/v2/elevator/elevator_closures.tsx | 11 ++++++++--- 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/assets/css/v2/elevator/elevator_closures.scss b/assets/css/v2/elevator/elevator_closures.scss index 058bd1521..6490c5642 100644 --- a/assets/css/v2/elevator/elevator_closures.scss +++ b/assets/css/v2/elevator/elevator_closures.scss @@ -112,18 +112,10 @@ line-height: 96px; } - .feedback-text { - font-size: 48px; - line-height: 64px; - color: $cool-black-30; - - .italic { - font-style: italic; - } - - .bold { - font-weight: 700; - } + .map { + width: 1080px; + margin-top: 26px; + margin-left: -48px; } } diff --git a/assets/src/components/v2/elevator/elevator_closures.tsx b/assets/src/components/v2/elevator/elevator_closures.tsx index 207a0b71d..1959bae97 100644 --- a/assets/src/components/v2/elevator/elevator_closures.tsx +++ b/assets/src/components/v2/elevator/elevator_closures.tsx @@ -218,6 +218,7 @@ interface CurrentElevatorClosedViewProps extends WrappedComponentProps { const CurrentElevatorClosedView = ({ alternateDirectionText, accessiblePathDirectionArrow, + accessiblePathImageUrl, onFinish, lastUpdate, }: CurrentElevatorClosedViewProps) => { @@ -252,9 +253,13 @@ const CurrentElevatorClosedView = ({ /> -
- {alternateDirectionText} -
+ {pageIndex === 0 ? ( +
+ {alternateDirectionText} +
+ ) : ( + + )} From 0746818177993d4e49a21112161f03d017047d59 Mon Sep 17 00:00:00 2001 From: cmaddox5 Date: Thu, 21 Nov 2024 09:48:31 -0500 Subject: [PATCH 06/18] Fixed some styles. --- assets/css/v2/elevator/elevator_closures.scss | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/assets/css/v2/elevator/elevator_closures.scss b/assets/css/v2/elevator/elevator_closures.scss index 6490c5642..c662e26b8 100644 --- a/assets/css/v2/elevator/elevator_closures.scss +++ b/assets/css/v2/elevator/elevator_closures.scss @@ -126,6 +126,10 @@ } .outside-closures-view { + display: flex; + flex: 1; + flex-direction: column; + .in-station-summary { display: flex; justify-content: space-between; @@ -141,7 +145,6 @@ } .outside-closure-list { - position: relative; height: 100%; background-color: $warm-neutral-90; From be41ba43bc133db3a80637cc4fb1d7ea7750b004 Mon Sep 17 00:00:00 2001 From: cmaddox5 Date: Thu, 21 Nov 2024 14:09:02 -0500 Subject: [PATCH 07/18] Use existing Arrow component. --- assets/css/elevator_v2.scss | 1 + assets/css/v2/elevator/elevator_closures.scss | 13 +++---------- .../components/v2/elevator/elevator_closures.tsx | 14 ++++---------- 3 files changed, 8 insertions(+), 20 deletions(-) diff --git a/assets/css/elevator_v2.scss b/assets/css/elevator_v2.scss index 5a0ea16c4..4356f049e 100644 --- a/assets/css/elevator_v2.scss +++ b/assets/css/elevator_v2.scss @@ -8,6 +8,7 @@ @import "v2/elevator/header"; @import "v2/elevator/footer"; @import "v2/lcd_common/route_pill"; +@import "v2/arrow"; .evergreen-content-image__container, .evergreen-content-image__image { diff --git a/assets/css/v2/elevator/elevator_closures.scss b/assets/css/v2/elevator/elevator_closures.scss index c662e26b8..a7df6e3d9 100644 --- a/assets/css/v2/elevator/elevator_closures.scss +++ b/assets/css/v2/elevator/elevator_closures.scss @@ -80,16 +80,9 @@ align-self: center; } - .arrow.e { - rotate: 90deg; - } - - .arrow.s { - rotate: 180deg; - } - - .arrow.w { - rotate: -90deg; + .arrow { + width: 100px; + height: 100px; } } diff --git a/assets/src/components/v2/elevator/elevator_closures.tsx b/assets/src/components/v2/elevator/elevator_closures.tsx index 1959bae97..79b161142 100644 --- a/assets/src/components/v2/elevator/elevator_closures.tsx +++ b/assets/src/components/v2/elevator/elevator_closures.tsx @@ -7,12 +7,12 @@ import PagingDotUnselected from "Images/svgr_bundled/paging_dot_unselected.svg"; import PagingDotSelected from "Images/svgr_bundled/paging_dot_selected.svg"; import NoService from "Images/svgr_bundled/no-service-black.svg"; import ElevatorWayfinding from "Images/svgr_bundled/elevator-wayfinding.svg"; -import Arrow from "Images/svgr_bundled/arrow-90.svg"; import IsaNegative from "Images/svgr_bundled/isa-negative.svg"; import makePersistent, { WrappedComponentProps } from "../persistent_wrapper"; import RoutePill, { routePillKey, type Pill } from "../departures/route_pill"; import useClientPaging from "Hooks/v2/use_client_paging"; import useTextResizer from "Hooks/v2/use_text_resizer"; +import Arrow, { Direction } from "../arrow"; type StationWithClosures = { id: string; @@ -29,8 +29,6 @@ type ElevatorClosure = { header_text: string; }; -type ArrowDirection = "n" | "e" | "s" | "w"; - interface PagingIndicatorsProps { numPages: number; pageIndex: number; @@ -211,7 +209,7 @@ const OutsideClosuresView = ({ interface CurrentElevatorClosedViewProps extends WrappedComponentProps { closure: ElevatorClosure; alternateDirectionText: string; - accessiblePathDirectionArrow: ArrowDirection; + accessiblePathDirectionArrow: Direction; accessiblePathImageUrl: string; } @@ -246,11 +244,7 @@ const CurrentElevatorClosedView = ({
Accessible Path
- +
{pageIndex === 0 ? ( @@ -271,7 +265,7 @@ interface Props extends WrappedComponentProps { in_station_closures: ElevatorClosure[]; other_stations_with_closures: StationWithClosures[]; alternate_direction_text: string; - accessible_path_direction_arrow: ArrowDirection; + accessible_path_direction_arrow: Direction; accessible_path_image_url: string; } From d9f356227f6fd585da738733fbd217d4827e017c Mon Sep 17 00:00:00 2001 From: cmaddox5 Date: Mon, 25 Nov 2024 08:16:30 -0500 Subject: [PATCH 08/18] Added map marker. --- assets/css/v2/elevator/elevator_closures.scss | 48 ++++++++++++++++++- .../v2/elevator/elevator_closures.tsx | 33 ++++++++++++- .../current-location-background.svg | 3 ++ .../svgr_bundled/current-location-marker.svg | 19 ++++++++ .../candidate_generator/elevator/closures.ex | 15 +----- .../v2/widget_instance/elevator_closures.ex | 33 ++++++------- 6 files changed, 115 insertions(+), 36 deletions(-) create mode 100644 assets/static/images/svgr_bundled/current-location-background.svg create mode 100644 assets/static/images/svgr_bundled/current-location-marker.svg diff --git a/assets/css/v2/elevator/elevator_closures.scss b/assets/css/v2/elevator/elevator_closures.scss index a7df6e3d9..2ed343dec 100644 --- a/assets/css/v2/elevator/elevator_closures.scss +++ b/assets/css/v2/elevator/elevator_closures.scss @@ -1,3 +1,43 @@ +.screen-normal:has(.current-elevator-closed-view) { + .normal-header, + .footer { + color: white; + background-color: $accessibility-blue; + } +} + +.marker-container { + position: absolute; + display: flex; + align-items: center; + justify-content: center; + width: 116px; + height: 116px; + + .marker-background, + .marker { + position: absolute; + } + + .marker-background { + animation: pulse-ring 1.5s infinite; + } +} + +@keyframes pulse-ring { + 0% { + transform: scale(0.5); + } + + 60% { + opacity: 0.25; + } + + 100% { + opacity: 0; + } +} + .elevator-closures { position: relative; display: flex; @@ -105,10 +145,14 @@ line-height: 96px; } - .map { - width: 1080px; + .map-container { + position: relative; margin-top: 26px; margin-left: -48px; + + .map { + width: 1080px; + } } } diff --git a/assets/src/components/v2/elevator/elevator_closures.tsx b/assets/src/components/v2/elevator/elevator_closures.tsx index 79b161142..07dec2cc9 100644 --- a/assets/src/components/v2/elevator/elevator_closures.tsx +++ b/assets/src/components/v2/elevator/elevator_closures.tsx @@ -8,6 +8,8 @@ import PagingDotSelected from "Images/svgr_bundled/paging_dot_selected.svg"; import NoService from "Images/svgr_bundled/no-service-black.svg"; import ElevatorWayfinding from "Images/svgr_bundled/elevator-wayfinding.svg"; import IsaNegative from "Images/svgr_bundled/isa-negative.svg"; +import CurrentLocationMarker from "Images/svgr_bundled/current-location-marker.svg"; +import CurrentLocationBackground from "Images/svgr_bundled/current-location-background.svg"; import makePersistent, { WrappedComponentProps } from "../persistent_wrapper"; import RoutePill, { routePillKey, type Pill } from "../departures/route_pill"; import useClientPaging from "Hooks/v2/use_client_paging"; @@ -29,6 +31,20 @@ type ElevatorClosure = { header_text: string; }; +type Coordinates = { + x: number; + y: number; +}; + +const PulsatingDot = ({ x, y }: Coordinates) => { + return ( +
+ + +
+ ); +}; + interface PagingIndicatorsProps { numPages: number; pageIndex: number; @@ -211,12 +227,14 @@ interface CurrentElevatorClosedViewProps extends WrappedComponentProps { alternateDirectionText: string; accessiblePathDirectionArrow: Direction; accessiblePathImageUrl: string; + accessiblePathImageHereCoordinates: Coordinates; } const CurrentElevatorClosedView = ({ alternateDirectionText, accessiblePathDirectionArrow, accessiblePathImageUrl, + accessiblePathImageHereCoordinates, onFinish, lastUpdate, }: CurrentElevatorClosedViewProps) => { @@ -247,12 +265,18 @@ const CurrentElevatorClosedView = ({ - {pageIndex === 0 ? ( + {pageIndex === 123 ? (
{alternateDirectionText}
) : ( - +
+ + +
)} @@ -267,6 +291,7 @@ interface Props extends WrappedComponentProps { alternate_direction_text: string; accessible_path_direction_arrow: Direction; accessible_path_image_url: string; + accessible_path_image_here_coordinates: Coordinates; } const ElevatorClosures: React.ComponentType = ({ @@ -276,6 +301,7 @@ const ElevatorClosures: React.ComponentType = ({ alternate_direction_text: alternateDirectionText, accessible_path_direction_arrow: accessiblePathDirectionArrow, accessible_path_image_url: accessiblePathImageUrl, + accessible_path_image_here_coordinates: accessiblePathImageHereCoordinates, lastUpdate, onFinish, }: Props) => { @@ -291,6 +317,9 @@ const ElevatorClosures: React.ComponentType = ({ alternateDirectionText={alternateDirectionText} accessiblePathDirectionArrow={accessiblePathDirectionArrow} accessiblePathImageUrl={accessiblePathImageUrl} + accessiblePathImageHereCoordinates={ + accessiblePathImageHereCoordinates + } onFinish={onFinish} lastUpdate={lastUpdate} /> diff --git a/assets/static/images/svgr_bundled/current-location-background.svg b/assets/static/images/svgr_bundled/current-location-background.svg new file mode 100644 index 000000000..4c6354c40 --- /dev/null +++ b/assets/static/images/svgr_bundled/current-location-background.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/assets/static/images/svgr_bundled/current-location-marker.svg b/assets/static/images/svgr_bundled/current-location-marker.svg new file mode 100644 index 000000000..430431a4f --- /dev/null +++ b/assets/static/images/svgr_bundled/current-location-marker.svg @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/lib/screens/v2/candidate_generator/elevator/closures.ex b/lib/screens/v2/candidate_generator/elevator/closures.ex index c4a8fd8b2..8be8cbf88 100644 --- a/lib/screens/v2/candidate_generator/elevator/closures.ex +++ b/lib/screens/v2/candidate_generator/elevator/closures.ex @@ -6,7 +6,6 @@ defmodule Screens.V2.CandidateGenerator.Elevator.Closures do alias Screens.Alerts.{Alert, InformedEntity} alias Screens.Routes.Route alias Screens.Stops.Stop - alias Screens.Util.Assets alias Screens.V2.WidgetInstance.ElevatorClosures alias Screens.V2.WidgetInstance.Serializer.RoutePill alias ScreensConfig.Screen @@ -20,14 +19,7 @@ defmodule Screens.V2.CandidateGenerator.Elevator.Closures do @stop injected(Stop) @spec elevator_status_instances(Screen.t()) :: list(ElevatorClosures.t()) - def elevator_status_instances(%Screen{ - app_params: %Elevator{ - elevator_id: elevator_id, - alternate_direction_text: alternate_direction_text, - accessible_path_direction_arrow: accessible_path_direction_arrow, - accessible_path_image_url: accessible_path_image_url - } - }) do + def elevator_status_instances(%Screen{app_params: %Elevator{elevator_id: elevator_id} = config}) do with {:ok, %Stop{id: stop_id}} <- @facility.fetch_stop_for_facility(elevator_id), {:ok, parent_station_map} <- @stop.fetch_parent_station_name_map(), {:ok, alerts} <- @alert.fetch_elevator_alerts_with_facilities() do @@ -39,13 +31,10 @@ defmodule Screens.V2.CandidateGenerator.Elevator.Closures do [ %ElevatorClosures{ - id: elevator_id, in_station_closures: Enum.map(in_station_alerts, &alert_to_elevator_closure/1), other_stations_with_closures: format_outside_closures(outside_alerts, parent_station_map, routes_map), - alternate_direction_text: alternate_direction_text, - accessible_path_direction_arrow: accessible_path_direction_arrow, - accessible_path_image_url: Assets.s3_asset_url(accessible_path_image_url) + elevator_config: config } ] else diff --git a/lib/screens/v2/widget_instance/elevator_closures.ex b/lib/screens/v2/widget_instance/elevator_closures.ex index c0eead7ed..ec4a04ccb 100644 --- a/lib/screens/v2/widget_instance/elevator_closures.ex +++ b/lib/screens/v2/widget_instance/elevator_closures.ex @@ -2,24 +2,15 @@ defmodule Screens.V2.WidgetInstance.ElevatorClosures do @moduledoc false alias Screens.Stops.Stop + alias Screens.Util.Assets alias ScreensConfig.V2.Elevator - defstruct ~w[ - id - in_station_closures - other_stations_with_closures - alternate_direction_text - accessible_path_direction_arrow - accessible_path_image_url - ]a + defstruct ~w[elevator_config in_station_closures other_stations_with_closures]a @type t :: %__MODULE__{ - id: String.t(), + elevator_config: Elevator.t(), in_station_closures: list(__MODULE__.Closure.t()), - other_stations_with_closures: list(__MODULE__.Station.t()), - alternate_direction_text: String.t(), - accessible_path_direction_arrow: Elevator.arrow_direction(), - accessible_path_image_url: String.t() + other_stations_with_closures: list(__MODULE__.Station.t()) } defmodule Station do @@ -57,12 +48,15 @@ defmodule Screens.V2.WidgetInstance.ElevatorClosures do end def serialize(%__MODULE__{ - id: id, + elevator_config: %Elevator{ + elevator_id: id, + alternate_direction_text: alternate_direction_text, + accessible_path_direction_arrow: accessible_path_direction_arrow, + accessible_path_image_url: accessible_path_image_url, + accessible_path_image_here_coordinates: accessible_path_image_here_coordinates + }, in_station_closures: in_station_closures, - other_stations_with_closures: other_stations_with_closures, - alternate_direction_text: alternate_direction_text, - accessible_path_direction_arrow: accessible_path_direction_arrow, - accessible_path_image_url: accessible_path_image_url + other_stations_with_closures: other_stations_with_closures }), do: %{ id: id, @@ -70,7 +64,8 @@ defmodule Screens.V2.WidgetInstance.ElevatorClosures do other_stations_with_closures: other_stations_with_closures, alternate_direction_text: alternate_direction_text, accessible_path_direction_arrow: accessible_path_direction_arrow, - accessible_path_image_url: accessible_path_image_url + accessible_path_image_url: Assets.s3_asset_url(accessible_path_image_url), + accessible_path_image_here_coordinates: accessible_path_image_here_coordinates } defimpl Screens.V2.WidgetInstance do From d3ef429822c6536e579e166ab6a6ab73ad66a2ca Mon Sep 17 00:00:00 2001 From: cmaddox5 Date: Mon, 25 Nov 2024 09:22:55 -0500 Subject: [PATCH 09/18] Update screens-config-lib. --- lib/screens/v2/widget_instance/blue_bikes.ex | 7 +++---- mix.exs | 2 +- mix.lock | 2 +- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/lib/screens/v2/widget_instance/blue_bikes.ex b/lib/screens/v2/widget_instance/blue_bikes.ex index d46bb0cf3..017c514e0 100644 --- a/lib/screens/v2/widget_instance/blue_bikes.ex +++ b/lib/screens/v2/widget_instance/blue_bikes.ex @@ -4,8 +4,7 @@ defmodule Screens.V2.WidgetInstance.BlueBikes do """ alias Screens.BlueBikes alias Screens.BlueBikes.StationStatus - alias ScreensConfig.Screen - alias ScreensConfig.V2.BlueBikes.Station + alias ScreensConfig.{Arrow, Screen} alias ScreensConfig.V2.PreFare @type t :: %__MODULE__{ @@ -24,7 +23,7 @@ defmodule Screens.V2.WidgetInstance.BlueBikes do @type normal_station :: %{ status: :normal, id: String.t(), - arrow: Station.arrow(), + arrow: Arrow.t(), walk_distance_minutes: non_neg_integer(), walk_distance_feet: non_neg_integer(), name: String.t(), @@ -35,7 +34,7 @@ defmodule Screens.V2.WidgetInstance.BlueBikes do @type special_station :: %{ status: :valet | :out_of_service, id: String.t(), - arrow: Station.arrow(), + arrow: Arrow.t(), walk_distance_minutes: non_neg_integer(), walk_distance_feet: non_neg_integer(), name: String.t() diff --git a/mix.exs b/mix.exs index 62638ee48..c6818aba8 100644 --- a/mix.exs +++ b/mix.exs @@ -94,7 +94,7 @@ defmodule Screens.MixProject do {:telemetry_metrics, "~> 0.4"}, {:screens_config, git: "https://github.com/mbta/screens-config-lib.git", - ref: "fff14c3e4b98a19b19ec276b69ceb10e07d94579"}, + ref: "bbc9575e375b28b0489732eefa66c2ca3f100d0e"}, {:nebulex, "~> 2.6"}, {:remote_ip, "~> 1.2"}, {:hackney_telemetry, "~> 0.2.0"}, diff --git a/mix.lock b/mix.lock index d5b6fcfb6..68b6eb004 100644 --- a/mix.lock +++ b/mix.lock @@ -62,7 +62,7 @@ "recon": {:hex, :recon, "2.5.6", "9052588e83bfedfd9b72e1034532aee2a5369d9d9343b61aeb7fbce761010741", [:mix, :rebar3], [], "hexpm", "96c6799792d735cc0f0fd0f86267e9d351e63339cbe03df9d162010cefc26bb0"}, "remote_ip": {:hex, :remote_ip, "1.2.0", "fb078e12a44414f4cef5a75963c33008fe169b806572ccd17257c208a7bc760f", [:mix], [{:combine, "~> 0.10", [hex: :combine, repo: "hexpm", optional: false]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "2ff91de19c48149ce19ed230a81d377186e4412552a597d6a5137373e5877cb7"}, "retry": {:hex, :retry, "0.18.0", "dc58ebe22c95aa00bc2459f9e0c5400e6005541cf8539925af0aa027dc860543", [:mix], [], "hexpm", "9483959cc7bf69c9e576d9dfb2b678b71c045d3e6f39ab7c9aa1489df4492d73"}, - "screens_config": {:git, "https://github.com/mbta/screens-config-lib.git", "fff14c3e4b98a19b19ec276b69ceb10e07d94579", [ref: "fff14c3e4b98a19b19ec276b69ceb10e07d94579"]}, + "screens_config": {:git, "https://github.com/mbta/screens-config-lib.git", "bbc9575e375b28b0489732eefa66c2ca3f100d0e", [ref: "bbc9575e375b28b0489732eefa66c2ca3f100d0e"]}, "sentry": {:hex, :sentry, "10.7.1", "33392222d80ccff99c503f972998d2858b4c1e5aca2219a34269b68dacba8e7d", [:mix], [{:hackney, "~> 1.8", [hex: :hackney, repo: "hexpm", optional: true]}, {:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: true]}, {:nimble_options, "~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:nimble_ownership, "~> 0.3.0 or ~> 1.0", [hex: :nimble_ownership, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.6", [hex: :phoenix, repo: "hexpm", optional: true]}, {:phoenix_live_view, "~> 0.20", [hex: :phoenix_live_view, repo: "hexpm", optional: true]}, {:plug, "~> 1.6", [hex: :plug, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: true]}], "hexpm", "56291312397bf2b6afab6cf4f7aa1f27413b0eb2ceeb63b8aab2d7658aaea882"}, "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.7", "354c321cf377240c7b8716899e182ce4890c5938111a1296add3ec74cf1715df", [:make, :mix, :rebar3], [], "hexpm", "fe4c190e8f37401d30167c8c405eda19469f34577987c76dde613e838bbc67f8"}, "stream_data": {:hex, :stream_data, "1.1.2", "05499eaec0443349ff877aaabc6e194e82bda6799b9ce6aaa1aadac15a9fdb4d", [:mix], [], "hexpm", "129558d2c77cbc1eb2f4747acbbea79e181a5da51108457000020a906813a1a9"}, From 1d0be22912d39457aa72cc5ed34394e9c0e0e36d Mon Sep 17 00:00:00 2001 From: cmaddox5 Date: Mon, 25 Nov 2024 09:36:47 -0500 Subject: [PATCH 10/18] Only show two pages if there is a configured image. --- .../components/v2/elevator/elevator_closures.tsx | 15 +++++++++------ .../v2/widget_instance/elevator_closures.ex | 6 +++++- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/assets/src/components/v2/elevator/elevator_closures.tsx b/assets/src/components/v2/elevator/elevator_closures.tsx index 07dec2cc9..ea8df368d 100644 --- a/assets/src/components/v2/elevator/elevator_closures.tsx +++ b/assets/src/components/v2/elevator/elevator_closures.tsx @@ -226,7 +226,7 @@ interface CurrentElevatorClosedViewProps extends WrappedComponentProps { closure: ElevatorClosure; alternateDirectionText: string; accessiblePathDirectionArrow: Direction; - accessiblePathImageUrl: string; + accessiblePathImageUrl: string | null; accessiblePathImageHereCoordinates: Coordinates; } @@ -238,7 +238,8 @@ const CurrentElevatorClosedView = ({ onFinish, lastUpdate, }: CurrentElevatorClosedViewProps) => { - const pageIndex = useClientPaging({ numPages: 2, onFinish, lastUpdate }); + const numPages = accessiblePathImageUrl ? 2 : 1; + const pageIndex = useClientPaging({ numPages, onFinish, lastUpdate }); const { ref, size } = useTextResizer({ sizes: ["small", "medium", "large"], maxHeight: 746, @@ -265,7 +266,7 @@ const CurrentElevatorClosedView = ({ - {pageIndex === 123 ? ( + {pageIndex === 0 ? (
{alternateDirectionText}
@@ -275,11 +276,13 @@ const CurrentElevatorClosedView = ({ x={accessiblePathImageHereCoordinates.x} y={accessiblePathImageHereCoordinates.y} /> - + )} - + {numPages === 2 && ( + + )} ); }; @@ -290,7 +293,7 @@ interface Props extends WrappedComponentProps { other_stations_with_closures: StationWithClosures[]; alternate_direction_text: string; accessible_path_direction_arrow: Direction; - accessible_path_image_url: string; + accessible_path_image_url: string | null; accessible_path_image_here_coordinates: Coordinates; } diff --git a/lib/screens/v2/widget_instance/elevator_closures.ex b/lib/screens/v2/widget_instance/elevator_closures.ex index ec4a04ccb..7efe1bd2f 100644 --- a/lib/screens/v2/widget_instance/elevator_closures.ex +++ b/lib/screens/v2/widget_instance/elevator_closures.ex @@ -64,7 +64,11 @@ defmodule Screens.V2.WidgetInstance.ElevatorClosures do other_stations_with_closures: other_stations_with_closures, alternate_direction_text: alternate_direction_text, accessible_path_direction_arrow: accessible_path_direction_arrow, - accessible_path_image_url: Assets.s3_asset_url(accessible_path_image_url), + accessible_path_image_url: + if(is_nil(accessible_path_image_url), + do: nil, + else: Assets.s3_asset_url(accessible_path_image_url) + ), accessible_path_image_here_coordinates: accessible_path_image_here_coordinates } From a2a70bce74cc7b8e7b727a5a66164269824946fa Mon Sep 17 00:00:00 2001 From: cmaddox5 Date: Mon, 25 Nov 2024 09:53:35 -0500 Subject: [PATCH 11/18] Test improvements. --- .../elevator/closures_test.exs | 34 ++++++++++++------- .../v2/candidate_generator/elevator_test.exs | 4 ++- .../elevator_closures_test.exs | 20 +++++++++-- 3 files changed, 43 insertions(+), 15 deletions(-) diff --git a/test/screens/v2/candidate_generator/elevator/closures_test.exs b/test/screens/v2/candidate_generator/elevator/closures_test.exs index 9dd6582ed..962da0be7 100644 --- a/test/screens/v2/candidate_generator/elevator/closures_test.exs +++ b/test/screens/v2/candidate_generator/elevator/closures_test.exs @@ -18,7 +18,17 @@ defmodule Screens.V2.CandidateGenerator.Elevator.ClosuresTest do @stop injected(Stop) describe "elevator_status_instances/1" do - test "Only returns alerts with effect of :elevator_closure" do + setup do + %{ + config: %Elevator{ + elevator_id: "111", + accessible_path_direction_arrow: :n, + alternate_direction_text: "Test" + } + } + end + + test "Only returns alerts with effect of :elevator_closure", %{config: config} do expect(@facility, :fetch_stop_for_facility, fn "111" -> {:ok, %Stop{id: "place-test"}} end) expect(@stop, :fetch_parent_station_name_map, fn -> @@ -51,7 +61,7 @@ defmodule Screens.V2.CandidateGenerator.Elevator.ClosuresTest do [ %Screens.V2.WidgetInstance.ElevatorClosures{ - id: "111", + elevator_config: ^config, in_station_closures: [ %{ id: "1", @@ -65,11 +75,11 @@ defmodule Screens.V2.CandidateGenerator.Elevator.ClosuresTest do } ] = ElevatorClosures.elevator_status_instances( - struct(Screen, app_id: :elevator_v2, app_params: %Elevator{elevator_id: "111"}) + struct(Screen, app_id: :elevator_v2, app_params: config) ) end - test "Groups outside closures by station" do + test "Groups outside closures by station", %{config: config} do expect(@facility, :fetch_stop_for_facility, fn "111" -> {:ok, %Stop{id: "place-test"}} end) expect(@stop, :fetch_parent_station_name_map, fn -> @@ -107,7 +117,7 @@ defmodule Screens.V2.CandidateGenerator.Elevator.ClosuresTest do [ %Screens.V2.WidgetInstance.ElevatorClosures{ - id: "111", + elevator_config: ^config, in_station_closures: [], other_stations_with_closures: [ %{ @@ -135,11 +145,11 @@ defmodule Screens.V2.CandidateGenerator.Elevator.ClosuresTest do } ] = ElevatorClosures.elevator_status_instances( - struct(Screen, app_id: :elevator_v2, app_params: %Elevator{elevator_id: "111"}) + struct(Screen, app_id: :elevator_v2, app_params: config) ) end - test "Filters alerts with no facilities or more than one facility" do + test "Filters alerts with no facilities or more than one facility", %{config: config} do expect(@facility, :fetch_stop_for_facility, fn "111" -> {:ok, %Stop{id: "place-test"}} end) expect(@stop, :fetch_parent_station_name_map, fn -> @@ -172,17 +182,17 @@ defmodule Screens.V2.CandidateGenerator.Elevator.ClosuresTest do [ %Screens.V2.WidgetInstance.ElevatorClosures{ - id: "111", + elevator_config: ^config, in_station_closures: [], other_stations_with_closures: [] } ] = ElevatorClosures.elevator_status_instances( - struct(Screen, app_id: :elevator_v2, app_params: %Elevator{elevator_id: "111"}) + struct(Screen, app_id: :elevator_v2, app_params: config) ) end - test "Return empty routes on API error" do + test "Return empty routes on API error", %{config: config} do expect(@facility, :fetch_stop_for_facility, fn "111" -> {:ok, %Stop{id: "place-test"}} end) expect(@stop, :fetch_parent_station_name_map, fn -> @@ -209,7 +219,7 @@ defmodule Screens.V2.CandidateGenerator.Elevator.ClosuresTest do [ %Screens.V2.WidgetInstance.ElevatorClosures{ - id: "111", + elevator_config: ^config, in_station_closures: [ %{ id: "1", @@ -223,7 +233,7 @@ defmodule Screens.V2.CandidateGenerator.Elevator.ClosuresTest do } ] = ElevatorClosures.elevator_status_instances( - struct(Screen, app_id: :elevator_v2, app_params: %Elevator{elevator_id: "111"}) + struct(Screen, app_id: :elevator_v2, app_params: config) ) end end diff --git a/test/screens/v2/candidate_generator/elevator_test.exs b/test/screens/v2/candidate_generator/elevator_test.exs index 979843fcf..84b6e57b1 100644 --- a/test/screens/v2/candidate_generator/elevator_test.exs +++ b/test/screens/v2/candidate_generator/elevator_test.exs @@ -9,7 +9,9 @@ defmodule Screens.V2.CandidateGenerator.ElevatorTest do config = %Screen{ app_id: :elevator_v2, app_params: %V2.Elevator{ - elevator_id: "1" + elevator_id: "1", + alternate_direction_text: "Test", + accessible_path_direction_arrow: :n }, device_id: "TEST", name: "TEST", diff --git a/test/screens/v2/widget_instance/elevator_closures_test.exs b/test/screens/v2/widget_instance/elevator_closures_test.exs index 553ea625a..73ccea921 100644 --- a/test/screens/v2/widget_instance/elevator_closures_test.exs +++ b/test/screens/v2/widget_instance/elevator_closures_test.exs @@ -3,11 +3,17 @@ defmodule Screens.V2.WidgetInstance.ElevatorClosuresTest do alias Screens.V2.WidgetInstance alias Screens.V2.WidgetInstance.ElevatorClosures + alias ScreensConfig.V2.Elevator setup do %{ instance: %ElevatorClosures{ - id: "111", + elevator_config: + struct(Elevator, + elevator_id: "1", + alternate_direction_text: "Test", + accessible_path_direction_arrow: :n + ), in_station_closures: [ %ElevatorClosures.Closure{ description: "Test Alert Description", @@ -44,7 +50,17 @@ defmodule Screens.V2.WidgetInstance.ElevatorClosuresTest do describe "serialize/1" do test "returns map with id and closures", %{instance: instance} do - assert Map.from_struct(instance) == WidgetInstance.serialize(instance) + assert %{ + in_station_closures: instance.in_station_closures, + other_stations_with_closures: instance.other_stations_with_closures, + accessible_path_direction_arrow: + instance.elevator_config.accessible_path_direction_arrow, + accessible_path_image_here_coordinates: + instance.elevator_config.accessible_path_image_here_coordinates, + accessible_path_image_url: instance.elevator_config.accessible_path_image_url, + alternate_direction_text: instance.elevator_config.alternate_direction_text, + id: instance.elevator_config.elevator_id + } == WidgetInstance.serialize(instance) end end From f72c50475ad55580f5d1239f1bab41230d744693 Mon Sep 17 00:00:00 2001 From: cmaddox5 Date: Tue, 26 Nov 2024 15:57:48 -0500 Subject: [PATCH 12/18] Refactored out some components and styles. --- assets/css/elevator_v2.scss | 4 + .../current_elevator_closed_view.scss | 126 ++++++++ .../closures/outside_closures_view.scss | 123 ++++++++ assets/css/v2/elevator/elevator_closures.scss | 254 +-------------- .../closures/current_elevator_closed_view.tsx | 94 ++++++ .../closures/outside_closures_view.tsx | 159 ++++++++++ .../elevator/closures/paging_indicators.tsx | 35 +++ .../v2/elevator/elevator_closures.tsx | 288 +----------------- 8 files changed, 557 insertions(+), 526 deletions(-) create mode 100644 assets/css/v2/elevator/closures/current_elevator_closed_view.scss create mode 100644 assets/css/v2/elevator/closures/outside_closures_view.scss create mode 100644 assets/src/components/v2/elevator/closures/current_elevator_closed_view.tsx create mode 100644 assets/src/components/v2/elevator/closures/outside_closures_view.tsx create mode 100644 assets/src/components/v2/elevator/closures/paging_indicators.tsx diff --git a/assets/css/elevator_v2.scss b/assets/css/elevator_v2.scss index 4356f049e..dd8f1d817 100644 --- a/assets/css/elevator_v2.scss +++ b/assets/css/elevator_v2.scss @@ -1,3 +1,7 @@ +// Our Mimo elevator screens run Webview 83. +// When writing styles for widgets on these screens, +// verify browser compatibility in the MDN web docs. + @import "https://rsms.me/inter/inter.css"; @import "colors"; @import "v2/lcd_common/screen_container"; diff --git a/assets/css/v2/elevator/closures/current_elevator_closed_view.scss b/assets/css/v2/elevator/closures/current_elevator_closed_view.scss new file mode 100644 index 000000000..14b695bbc --- /dev/null +++ b/assets/css/v2/elevator/closures/current_elevator_closed_view.scss @@ -0,0 +1,126 @@ +.current-elevator-closed-view { + position: relative; + height: 100%; + + .shape { + position: absolute; + top: 0; + right: 0; + display: inline-block; + border-right: 345px solid $accessibility-blue; + border-bottom: 300px solid transparent; + } + + .header { + box-sizing: border-box; + height: 528px; + padding: 53px 68px 51px 48px; + font-weight: 700; + + .icons { + margin-bottom: 21px; + + .no-service-icon { + margin-right: 16px; + } + } + + .closed-text { + margin-bottom: 18px; + font-size: 150px; + line-height: 150px; + } + } + + hr.thin { + margin: 0 20px; + } + + .accessible-path-container { + box-sizing: border-box; + height: 984px; + padding: 48px; + + .subheading-container { + display: flex; + align-items: center; + justify-content: space-between; + height: 142px; + + .subheading { + align-self: center; + } + + .arrow { + width: 100px; + height: 100px; + } + } + + .alternate-direction-text { + color: $cool-black-30; + + &.small { + font-size: 48px; + line-height: 64px; + } + + &.medium { + font-size: 62px; + line-height: 80px; + } + + &.large { + font-size: 80px; + line-height: 96px; + } + } + + .map-container { + position: relative; + margin-top: 26px; + margin-left: -48px; + + .map { + width: 1080px; + } + } + } + + .paging-indicators { + justify-content: end; + height: 120px; + } +} + +.marker-container { + position: absolute; + display: flex; + align-items: center; + justify-content: center; + width: 116px; + height: 116px; + + .marker-background, + .marker { + position: absolute; + } + + .marker-background { + animation: pulse-ring 1.5s infinite; + } +} + +@keyframes pulse-ring { + 0% { + transform: scale(0.5); + } + + 60% { + opacity: 0.25; + } + + 100% { + opacity: 0; + } +} diff --git a/assets/css/v2/elevator/closures/outside_closures_view.scss b/assets/css/v2/elevator/closures/outside_closures_view.scss new file mode 100644 index 000000000..996b5ae20 --- /dev/null +++ b/assets/css/v2/elevator/closures/outside_closures_view.scss @@ -0,0 +1,123 @@ +.outside-closures-view { + display: flex; + flex: 1; + flex-direction: column; + + .in-station-summary { + display: flex; + justify-content: space-between; + padding: 24px 48px; + font-size: 48px; + font-weight: 400; + line-height: 64px; + color: $cool-black-30; + + .text { + margin-right: 82px; + } + } + + .outside-closure-list { + height: 100%; + background-color: $warm-neutral-90; + + .header-container { + margin: 48px; + margin-bottom: 0; + + .header { + display: flex; + max-height: 432px; + margin-bottom: 48px; + font-size: 112px; + font-weight: 700; + line-height: 112px; + + &__title { + word-spacing: 9999px; + } + } + } + + .closure-list-container { + overflow: hidden; + + .closure-list { + display: flex; + flex-flow: column wrap; + height: 904px; + transform: translateX(calc(-100% * var(--closure-list-offset))); + + .closure-row { + box-sizing: border-box; + width: 1080px; + padding: 0 48px; + + &__station-name { + font-size: 62px; + font-weight: 600; + line-height: 80px; + color: $cool-black-15; + } + + &__name-and-pills { + display: flex; + align-items: center; + margin-bottom: 14px; + + .route-pill { + width: 132px; + height: 68.13px; + margin-right: 24px; + + &__text { + line-height: 68.13px; + } + + &__icon { + height: 100%; + } + + &__icon-image { + height: 100%; + margin-top: 0; + } + } + } + + &__elevator-name { + line-height: 64px; + } + + &__elevator-name.list-item { + display: list-item; + margin-bottom: 8px; + margin-left: 48px; + } + } + } + } + + .paging-info-container { + position: absolute; + bottom: 0; + display: flex; + justify-content: space-between; + width: 100%; + height: 72px; + margin-bottom: 20px; + + .more-elevators-text { + align-self: center; + padding: 0 48px 20px; + } + } + + .paging-info-container, + .closure-row__elevator-name { + font-size: 48px; + font-weight: 400; + color: $cool-black-30; + } + } +} diff --git a/assets/css/v2/elevator/elevator_closures.scss b/assets/css/v2/elevator/elevator_closures.scss index 2ed343dec..1a809423d 100644 --- a/assets/css/v2/elevator/elevator_closures.scss +++ b/assets/css/v2/elevator/elevator_closures.scss @@ -6,38 +6,6 @@ } } -.marker-container { - position: absolute; - display: flex; - align-items: center; - justify-content: center; - width: 116px; - height: 116px; - - .marker-background, - .marker { - position: absolute; - } - - .marker-background { - animation: pulse-ring 1.5s infinite; - } -} - -@keyframes pulse-ring { - 0% { - transform: scale(0.5); - } - - 60% { - opacity: 0.25; - } - - 100% { - opacity: 0; - } -} - .elevator-closures { position: relative; display: flex; @@ -66,225 +34,6 @@ font-weight: 700; line-height: 80px; } - - .current-elevator-closed-view { - position: relative; - height: 100%; - - .shape { - position: absolute; - top: 0; - right: 0; - display: inline-block; - border-right: 345px solid $accessibility-blue; - border-bottom: 300px solid transparent; - } - - .header { - box-sizing: border-box; - height: 528px; - padding: 53px 68px 51px 48px; - font-weight: 700; - - .icons { - margin-bottom: 21px; - - .no-service-icon { - margin-right: 16px; - } - } - - .closed-text { - margin-bottom: 18px; - font-size: 150px; - line-height: 150px; - } - } - - hr.thin { - margin: 0 20px; - } - - .accessible-path-container { - box-sizing: border-box; - height: 984px; - padding: 48px; - - .subheading-container { - display: flex; - align-items: center; - justify-content: space-between; - height: 142px; - - .subheading { - align-self: center; - } - - .arrow { - width: 100px; - height: 100px; - } - } - - .alternate-direction-text { - color: $cool-black-30; - } - - .alternate-direction-text.small { - font-size: 48px; - line-height: 64px; - } - - .alternate-direction-text.medium { - font-size: 62px; - line-height: 80px; - } - - .alternate-direction-text.large { - font-size: 80px; - line-height: 96px; - } - - .map-container { - position: relative; - margin-top: 26px; - margin-left: -48px; - - .map { - width: 1080px; - } - } - } - - .paging-indicators { - justify-content: end; - height: 120px; - } - } - - .outside-closures-view { - display: flex; - flex: 1; - flex-direction: column; - - .in-station-summary { - display: flex; - justify-content: space-between; - padding: 24px 48px; - font-size: 48px; - font-weight: 400; - line-height: 64px; - color: $cool-black-30; - - .text { - margin-right: 82px; - } - } - - .outside-closure-list { - height: 100%; - background-color: $warm-neutral-90; - - .header-container { - margin: 48px; - margin-bottom: 0; - - .header { - display: flex; - max-height: 432px; - margin-bottom: 48px; - font-size: 112px; - font-weight: 700; - line-height: 112px; - - &__title { - word-spacing: 9999px; - } - } - } - - .closure-list-container { - overflow: hidden; - - .closure-list { - display: flex; - flex-flow: column wrap; - height: 904px; - transform: translateX(calc(-100% * var(--closure-list-offset))); - - .closure-row { - box-sizing: border-box; - width: 1080px; - padding: 0 48px; - - &__station-name { - font-size: 62px; - font-weight: 600; - line-height: 80px; - color: $cool-black-15; - } - - &__name-and-pills { - display: flex; - align-items: center; - margin-bottom: 14px; - - .route-pill { - width: 132px; - height: 68.13px; - margin-right: 24px; - - &__text { - line-height: 68.13px; - } - - &__icon { - height: 100%; - } - - &__icon-image { - height: 100%; - margin-top: 0; - } - } - } - - &__elevator-name { - line-height: 64px; - } - - &__elevator-name.list-item { - display: list-item; - margin-bottom: 8px; - margin-left: 48px; - } - } - } - } - - .paging-info-container { - position: absolute; - bottom: 0; - display: flex; - justify-content: space-between; - width: 100%; - height: 72px; - margin-bottom: 20px; - - .more-elevators-text { - align-self: center; - padding: 0 48px 20px; - } - } - - .paging-info-container, - .closure-row__elevator-name { - font-size: 48px; - font-weight: 400; - color: $cool-black-30; - } - } - } } .paging-indicators { @@ -296,3 +45,6 @@ margin-right: 27px; } } + +@import "closures/current_elevator_closed_view"; +@import "closures/outside_closures_view"; diff --git a/assets/src/components/v2/elevator/closures/current_elevator_closed_view.tsx b/assets/src/components/v2/elevator/closures/current_elevator_closed_view.tsx new file mode 100644 index 000000000..f1826138b --- /dev/null +++ b/assets/src/components/v2/elevator/closures/current_elevator_closed_view.tsx @@ -0,0 +1,94 @@ +import React from "react"; +import cx from "classnames"; +import Arrow, { Direction } from "Components/v2/arrow"; +import { WrappedComponentProps } from "Components/v2/persistent_wrapper"; +import PagingIndicators from "Components/v2/elevator/closures/paging_indicators"; +import { type ElevatorClosure } from "Components/v2/elevator/elevator_closures"; +import useClientPaging from "Hooks/v2/use_client_paging"; +import useTextResizer from "Hooks/v2/use_text_resizer"; +import CurrentLocationMarker from "Images/svgr_bundled/current-location-marker.svg"; +import CurrentLocationBackground from "Images/svgr_bundled/current-location-background.svg"; +import NoService from "Images/svgr_bundled/no-service-black.svg"; +import ElevatorWayfinding from "Images/svgr_bundled/elevator-wayfinding.svg"; +import IsaNegative from "Images/svgr_bundled/isa-negative.svg"; + +export type Coordinates = { + x: number; + y: number; +}; + +const PulsatingDot = ({ x, y }: Coordinates) => { + return ( +
+ + +
+ ); +}; + +interface CurrentElevatorClosedViewProps extends WrappedComponentProps { + closure: ElevatorClosure; + alternateDirectionText: string; + accessiblePathDirectionArrow: Direction; + accessiblePathImageUrl: string | null; + accessiblePathImageHereCoordinates: Coordinates; +} + +const CurrentElevatorClosedView = ({ + alternateDirectionText, + accessiblePathDirectionArrow, + accessiblePathImageUrl, + accessiblePathImageHereCoordinates, + onFinish, + lastUpdate, +}: CurrentElevatorClosedViewProps) => { + const numPages = accessiblePathImageUrl ? 2 : 1; + const pageIndex = useClientPaging({ numPages, onFinish, lastUpdate }); + const { ref, size } = useTextResizer({ + sizes: ["small", "medium", "large"], + maxHeight: 746, + resetDependencies: [alternateDirectionText], + }); + + return ( +
+
+
+
+ + +
+
Closed
+
Until further notice
+
+
+
+
+
Accessible Path
+
+ + +
+
+ {pageIndex === 0 ? ( +
+ {alternateDirectionText} +
+ ) : ( +
+ + +
+ )} +
+ {numPages === 2 && ( + + )} +
+ ); +}; + +export default CurrentElevatorClosedView; diff --git a/assets/src/components/v2/elevator/closures/outside_closures_view.tsx b/assets/src/components/v2/elevator/closures/outside_closures_view.tsx new file mode 100644 index 000000000..e5ab35210 --- /dev/null +++ b/assets/src/components/v2/elevator/closures/outside_closures_view.tsx @@ -0,0 +1,159 @@ +import React, { useLayoutEffect, useRef, useState } from "react"; +import cx from "classnames"; +import _ from "lodash"; +import { type StationWithClosures } from "Components/v2/elevator/elevator_closures"; +import RoutePill, { routePillKey } from "Components/v2/departures/route_pill"; +import { WrappedComponentProps } from "Components/v2/persistent_wrapper"; +import PagingIndicators from "Components/v2/elevator/closures/paging_indicators"; +import useClientPaging from "Hooks/v2/use_client_paging"; +import NormalService from "Images/svgr_bundled/normal-service.svg"; +import AccessibilityAlert from "Images/svgr_bundled/accessibility-alert.svg"; + +interface ClosureRowProps { + station: StationWithClosures; +} + +const ClosureRow = ({ station }: ClosureRowProps) => { + const { name, closures, route_icons, id } = station; + + return ( +
+
+ {route_icons.map((route) => ( + + ))} +
{name}
+
+ {closures.map((closure) => ( +
1, + })} + > + {closure.elevator_name} ({closure.elevator_id}) +
+ ))} +
+
+ ); +}; + +const InStationSummary = () => { + return ( + <> +
+ + All elevators at this station are currently working + + + + +
+
+ + ); +}; + +interface OutsideClosureListProps extends WrappedComponentProps { + stations: StationWithClosures[]; +} + +const OutsideClosureList = ({ + stations, + lastUpdate, + onFinish, +}: OutsideClosureListProps) => { + const ref = useRef(null); + + // Each index represents a page number and each value represents the number of rows + // on the corresponding page index. + const [rowCounts, setRowCounts] = useState([]); + + const numPages = Object.keys(rowCounts).length; + const pageIndex = useClientPaging({ numPages, onFinish, lastUpdate }); + + const numOffsetRows = Object.keys(rowCounts).reduce((acc, key) => { + if (parseInt(key) === pageIndex) { + return acc; + } else { + return acc + rowCounts[key]; + } + }, 0); + + useLayoutEffect(() => { + if (!ref.current) return; + + const offsets = Array.from(ref.current.children).map((closure) => { + return (closure as HTMLDivElement).offsetLeft; + }); + + const rowCounts: number[] = []; + + _.uniq(offsets).forEach((uo) => { + rowCounts.push(offsets.filter((o) => o === uo).length); + }); + + setRowCounts(rowCounts); + }, [stations]); + + return ( +
+
+
+
MBTA Elevator Closures
+
+ +
+
+
+
+
+ { +
+ {stations.map((station) => ( + + ))} +
+ } +
+ {numPages > 1 && ( +
+
+ +{numOffsetRows} more elevators +
+ +
+ )} +
+ ); +}; + +interface OutsideClosuresViewProps extends OutsideClosureListProps {} + +const OutsideClosuresView = ({ + stations, + lastUpdate, + onFinish, +}: OutsideClosuresViewProps) => { + return ( +
+ + +
+ ); +}; + +export default OutsideClosuresView; diff --git a/assets/src/components/v2/elevator/closures/paging_indicators.tsx b/assets/src/components/v2/elevator/closures/paging_indicators.tsx new file mode 100644 index 000000000..406e68602 --- /dev/null +++ b/assets/src/components/v2/elevator/closures/paging_indicators.tsx @@ -0,0 +1,35 @@ +import React from "react"; +import PagingDotUnselected from "Images/svgr_bundled/paging_dot_unselected.svg"; +import PagingDotSelected from "Images/svgr_bundled/paging_dot_selected.svg"; + +interface PagingIndicatorsProps { + numPages: number; + pageIndex: number; +} + +const PagingIndicators = ({ numPages, pageIndex }: PagingIndicatorsProps) => { + const indicators: JSX.Element[] = []; + for (let i = 0; i < numPages; i++) { + const indicator = + pageIndex === i ? ( + + ) : ( + + ); + indicators.push(indicator); + } + + return
{indicators}
; +}; + +export default PagingIndicators; diff --git a/assets/src/components/v2/elevator/elevator_closures.tsx b/assets/src/components/v2/elevator/elevator_closures.tsx index ea8df368d..3f414a7fa 100644 --- a/assets/src/components/v2/elevator/elevator_closures.tsx +++ b/assets/src/components/v2/elevator/elevator_closures.tsx @@ -1,29 +1,23 @@ -import React, { ComponentType, useLayoutEffect, useRef, useState } from "react"; -import cx from "classnames"; +import React, { ComponentType } from "react"; import _ from "lodash"; -import NormalService from "Images/svgr_bundled/normal-service.svg"; -import AccessibilityAlert from "Images/svgr_bundled/accessibility-alert.svg"; -import PagingDotUnselected from "Images/svgr_bundled/paging_dot_unselected.svg"; -import PagingDotSelected from "Images/svgr_bundled/paging_dot_selected.svg"; -import NoService from "Images/svgr_bundled/no-service-black.svg"; -import ElevatorWayfinding from "Images/svgr_bundled/elevator-wayfinding.svg"; -import IsaNegative from "Images/svgr_bundled/isa-negative.svg"; -import CurrentLocationMarker from "Images/svgr_bundled/current-location-marker.svg"; -import CurrentLocationBackground from "Images/svgr_bundled/current-location-background.svg"; -import makePersistent, { WrappedComponentProps } from "../persistent_wrapper"; -import RoutePill, { routePillKey, type Pill } from "../departures/route_pill"; -import useClientPaging from "Hooks/v2/use_client_paging"; -import useTextResizer from "Hooks/v2/use_text_resizer"; -import Arrow, { Direction } from "../arrow"; - -type StationWithClosures = { +import makePersistent, { + WrappedComponentProps, +} from "Components/v2/persistent_wrapper"; +import { type Pill } from "Components/v2/departures/route_pill"; +import { Direction } from "Components/v2/arrow"; +import OutsideClosuresView from "Components/v2/elevator/closures/outside_closures_view"; +import CurrentElevatorClosedView, { + type Coordinates, +} from "Components/v2/elevator/closures/current_elevator_closed_view"; + +export type StationWithClosures = { id: string; name: string; route_icons: Pill[]; closures: ElevatorClosure[]; }; -type ElevatorClosure = { +export type ElevatorClosure = { id: string; elevator_name: string; elevator_id: string; @@ -31,262 +25,6 @@ type ElevatorClosure = { header_text: string; }; -type Coordinates = { - x: number; - y: number; -}; - -const PulsatingDot = ({ x, y }: Coordinates) => { - return ( -
- - -
- ); -}; - -interface PagingIndicatorsProps { - numPages: number; - pageIndex: number; -} - -const PagingIndicators = ({ numPages, pageIndex }: PagingIndicatorsProps) => { - const indicators: JSX.Element[] = []; - for (let i = 0; i < numPages; i++) { - const indicator = - pageIndex === i ? ( - - ) : ( - - ); - indicators.push(indicator); - } - - return
{indicators}
; -}; - -interface ClosureRowProps { - station: StationWithClosures; -} - -const ClosureRow = ({ station }: ClosureRowProps) => { - const { name, closures, route_icons, id } = station; - - return ( -
-
- {route_icons.map((route) => ( - - ))} -
{name}
-
- {closures.map((closure) => ( -
1, - })} - > - {closure.elevator_name} ({closure.elevator_id}) -
- ))} -
-
- ); -}; - -const InStationSummary = () => { - return ( - <> -
- - All elevators at this station are currently working - - - - -
-
- - ); -}; - -interface OutsideClosureListProps extends WrappedComponentProps { - stations: StationWithClosures[]; -} - -const OutsideClosureList = ({ - stations, - lastUpdate, - onFinish, -}: OutsideClosureListProps) => { - const ref = useRef(null); - - // Each index represents a page number and each value represents the number of rows - // on the corresponding page index. - const [rowCounts, setRowCounts] = useState([]); - - const numPages = Object.keys(rowCounts).length; - const pageIndex = useClientPaging({ numPages, onFinish, lastUpdate }); - - const numOffsetRows = Object.keys(rowCounts).reduce((acc, key) => { - if (parseInt(key) === pageIndex) { - return acc; - } else { - return acc + rowCounts[key]; - } - }, 0); - - useLayoutEffect(() => { - if (!ref.current) return; - - const offsets = Array.from(ref.current.children).map((closure) => { - return (closure as HTMLDivElement).offsetLeft; - }); - - const rowCounts: number[] = []; - - _.uniq(offsets).forEach((uo) => { - rowCounts.push(offsets.filter((o) => o === uo).length); - }); - - setRowCounts(rowCounts); - }, [stations]); - - return ( -
-
-
-
MBTA Elevator Closures
-
- -
-
-
-
-
- { -
- {stations.map((station) => ( - - ))} -
- } -
- {numPages > 1 && ( -
-
- +{numOffsetRows} more elevators -
- -
- )} -
- ); -}; - -interface OutsideClosuresViewProps extends OutsideClosureListProps {} - -const OutsideClosuresView = ({ - stations, - lastUpdate, - onFinish, -}: OutsideClosuresViewProps) => { - return ( -
- - -
- ); -}; - -interface CurrentElevatorClosedViewProps extends WrappedComponentProps { - closure: ElevatorClosure; - alternateDirectionText: string; - accessiblePathDirectionArrow: Direction; - accessiblePathImageUrl: string | null; - accessiblePathImageHereCoordinates: Coordinates; -} - -const CurrentElevatorClosedView = ({ - alternateDirectionText, - accessiblePathDirectionArrow, - accessiblePathImageUrl, - accessiblePathImageHereCoordinates, - onFinish, - lastUpdate, -}: CurrentElevatorClosedViewProps) => { - const numPages = accessiblePathImageUrl ? 2 : 1; - const pageIndex = useClientPaging({ numPages, onFinish, lastUpdate }); - const { ref, size } = useTextResizer({ - sizes: ["small", "medium", "large"], - maxHeight: 746, - resetDependencies: [alternateDirectionText], - }); - - return ( -
-
-
-
- - -
-
Closed
-
Until further notice
-
-
-
-
-
Accessible Path
-
- - -
-
- {pageIndex === 0 ? ( -
- {alternateDirectionText} -
- ) : ( -
- - -
- )} -
- {numPages === 2 && ( - - )} -
- ); -}; - interface Props extends WrappedComponentProps { id: string; in_station_closures: ElevatorClosure[]; From e867ab6b13c601cfd8eda98a4e4011d5dea32be0 Mon Sep 17 00:00:00 2001 From: cmaddox5 Date: Wed, 27 Nov 2024 09:36:29 -0500 Subject: [PATCH 13/18] Address PR feedback. --- assets/css/elevator_v2.scss | 6 ++ .../current_elevator_closed_view.scss | 9 +-- .../closures/outside_closures_view.scss | 1 - assets/css/v2/elevator/footer.scss | 1 - .../closures/current_elevator_closed_view.tsx | 2 +- .../svgr_bundled/elevator-wayfinding.svg | 63 +++++++++++-------- .../candidate_generator/elevator/closures.ex | 2 +- .../v2/widget_instance/elevator_closures.ex | 6 +- .../elevator/closures_test.exs | 8 +-- .../elevator_closures_test.exs | 12 ++-- 10 files changed, 63 insertions(+), 47 deletions(-) diff --git a/assets/css/elevator_v2.scss b/assets/css/elevator_v2.scss index dd8f1d817..fe322c454 100644 --- a/assets/css/elevator_v2.scss +++ b/assets/css/elevator_v2.scss @@ -28,3 +28,9 @@ body { .multi-screen-page { grid-auto-rows: 1920px; } + +*, +*::before, +*::after { + box-sizing: border-box; +} diff --git a/assets/css/v2/elevator/closures/current_elevator_closed_view.scss b/assets/css/v2/elevator/closures/current_elevator_closed_view.scss index 14b695bbc..821ec7280 100644 --- a/assets/css/v2/elevator/closures/current_elevator_closed_view.scss +++ b/assets/css/v2/elevator/closures/current_elevator_closed_view.scss @@ -2,7 +2,7 @@ position: relative; height: 100%; - .shape { + .notch { position: absolute; top: 0; right: 0; @@ -12,9 +12,11 @@ } .header { - box-sizing: border-box; + display: flex; + flex-direction: column; + justify-content: center; height: 528px; - padding: 53px 68px 51px 48px; + padding-left: 48px; font-weight: 700; .icons { @@ -37,7 +39,6 @@ } .accessible-path-container { - box-sizing: border-box; height: 984px; padding: 48px; diff --git a/assets/css/v2/elevator/closures/outside_closures_view.scss b/assets/css/v2/elevator/closures/outside_closures_view.scss index 996b5ae20..16de69558 100644 --- a/assets/css/v2/elevator/closures/outside_closures_view.scss +++ b/assets/css/v2/elevator/closures/outside_closures_view.scss @@ -49,7 +49,6 @@ transform: translateX(calc(-100% * var(--closure-list-offset))); .closure-row { - box-sizing: border-box; width: 1080px; padding: 0 48px; diff --git a/assets/css/v2/elevator/footer.scss b/assets/css/v2/elevator/footer.scss index 77d4264eb..86a964854 100644 --- a/assets/css/v2/elevator/footer.scss +++ b/assets/css/v2/elevator/footer.scss @@ -1,5 +1,4 @@ .footer { - box-sizing: border-box; height: 100%; padding: 26px 48px; font-size: 48px; diff --git a/assets/src/components/v2/elevator/closures/current_elevator_closed_view.tsx b/assets/src/components/v2/elevator/closures/current_elevator_closed_view.tsx index f1826138b..2adf6c9d4 100644 --- a/assets/src/components/v2/elevator/closures/current_elevator_closed_view.tsx +++ b/assets/src/components/v2/elevator/closures/current_elevator_closed_view.tsx @@ -52,7 +52,7 @@ const CurrentElevatorClosedView = ({ return (
-
+
diff --git a/assets/static/images/svgr_bundled/elevator-wayfinding.svg b/assets/static/images/svgr_bundled/elevator-wayfinding.svg index 2ea9539fa..3f3c5d4e7 100644 --- a/assets/static/images/svgr_bundled/elevator-wayfinding.svg +++ b/assets/static/images/svgr_bundled/elevator-wayfinding.svg @@ -1,41 +1,52 @@ - + - + - - + + + - - + + - - - - + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/lib/screens/v2/candidate_generator/elevator/closures.ex b/lib/screens/v2/candidate_generator/elevator/closures.ex index 8be8cbf88..c087d380f 100644 --- a/lib/screens/v2/candidate_generator/elevator/closures.ex +++ b/lib/screens/v2/candidate_generator/elevator/closures.ex @@ -34,7 +34,7 @@ defmodule Screens.V2.CandidateGenerator.Elevator.Closures do in_station_closures: Enum.map(in_station_alerts, &alert_to_elevator_closure/1), other_stations_with_closures: format_outside_closures(outside_alerts, parent_station_map, routes_map), - elevator_config: config + app_params: config } ] else diff --git a/lib/screens/v2/widget_instance/elevator_closures.ex b/lib/screens/v2/widget_instance/elevator_closures.ex index 7efe1bd2f..9f81a0262 100644 --- a/lib/screens/v2/widget_instance/elevator_closures.ex +++ b/lib/screens/v2/widget_instance/elevator_closures.ex @@ -5,10 +5,10 @@ defmodule Screens.V2.WidgetInstance.ElevatorClosures do alias Screens.Util.Assets alias ScreensConfig.V2.Elevator - defstruct ~w[elevator_config in_station_closures other_stations_with_closures]a + defstruct ~w[app_params in_station_closures other_stations_with_closures]a @type t :: %__MODULE__{ - elevator_config: Elevator.t(), + app_params: Elevator.t(), in_station_closures: list(__MODULE__.Closure.t()), other_stations_with_closures: list(__MODULE__.Station.t()) } @@ -48,7 +48,7 @@ defmodule Screens.V2.WidgetInstance.ElevatorClosures do end def serialize(%__MODULE__{ - elevator_config: %Elevator{ + app_params: %Elevator{ elevator_id: id, alternate_direction_text: alternate_direction_text, accessible_path_direction_arrow: accessible_path_direction_arrow, diff --git a/test/screens/v2/candidate_generator/elevator/closures_test.exs b/test/screens/v2/candidate_generator/elevator/closures_test.exs index 962da0be7..5cd56f596 100644 --- a/test/screens/v2/candidate_generator/elevator/closures_test.exs +++ b/test/screens/v2/candidate_generator/elevator/closures_test.exs @@ -61,7 +61,7 @@ defmodule Screens.V2.CandidateGenerator.Elevator.ClosuresTest do [ %Screens.V2.WidgetInstance.ElevatorClosures{ - elevator_config: ^config, + app_params: ^config, in_station_closures: [ %{ id: "1", @@ -117,7 +117,7 @@ defmodule Screens.V2.CandidateGenerator.Elevator.ClosuresTest do [ %Screens.V2.WidgetInstance.ElevatorClosures{ - elevator_config: ^config, + app_params: ^config, in_station_closures: [], other_stations_with_closures: [ %{ @@ -182,7 +182,7 @@ defmodule Screens.V2.CandidateGenerator.Elevator.ClosuresTest do [ %Screens.V2.WidgetInstance.ElevatorClosures{ - elevator_config: ^config, + app_params: ^config, in_station_closures: [], other_stations_with_closures: [] } @@ -219,7 +219,7 @@ defmodule Screens.V2.CandidateGenerator.Elevator.ClosuresTest do [ %Screens.V2.WidgetInstance.ElevatorClosures{ - elevator_config: ^config, + app_params: ^config, in_station_closures: [ %{ id: "1", diff --git a/test/screens/v2/widget_instance/elevator_closures_test.exs b/test/screens/v2/widget_instance/elevator_closures_test.exs index 73ccea921..3564088e3 100644 --- a/test/screens/v2/widget_instance/elevator_closures_test.exs +++ b/test/screens/v2/widget_instance/elevator_closures_test.exs @@ -8,7 +8,7 @@ defmodule Screens.V2.WidgetInstance.ElevatorClosuresTest do setup do %{ instance: %ElevatorClosures{ - elevator_config: + app_params: struct(Elevator, elevator_id: "1", alternate_direction_text: "Test", @@ -54,12 +54,12 @@ defmodule Screens.V2.WidgetInstance.ElevatorClosuresTest do in_station_closures: instance.in_station_closures, other_stations_with_closures: instance.other_stations_with_closures, accessible_path_direction_arrow: - instance.elevator_config.accessible_path_direction_arrow, + instance.app_params.accessible_path_direction_arrow, accessible_path_image_here_coordinates: - instance.elevator_config.accessible_path_image_here_coordinates, - accessible_path_image_url: instance.elevator_config.accessible_path_image_url, - alternate_direction_text: instance.elevator_config.alternate_direction_text, - id: instance.elevator_config.elevator_id + instance.app_params.accessible_path_image_here_coordinates, + accessible_path_image_url: instance.app_params.accessible_path_image_url, + alternate_direction_text: instance.app_params.alternate_direction_text, + id: instance.app_params.elevator_id } == WidgetInstance.serialize(instance) end end From fdfeffc69a738f50581d99e81298f6f64e3a9c27 Mon Sep 17 00:00:00 2001 From: cmaddox5 Date: Wed, 27 Nov 2024 09:53:39 -0500 Subject: [PATCH 14/18] Use absolute positioning instead of flex. --- .../css/v2/elevator/closures/current_elevator_closed_view.scss | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/assets/css/v2/elevator/closures/current_elevator_closed_view.scss b/assets/css/v2/elevator/closures/current_elevator_closed_view.scss index 821ec7280..f3c3f0f78 100644 --- a/assets/css/v2/elevator/closures/current_elevator_closed_view.scss +++ b/assets/css/v2/elevator/closures/current_elevator_closed_view.scss @@ -89,7 +89,8 @@ } .paging-indicators { - justify-content: end; + position: absolute; + right: 0; height: 120px; } } From 399804a369ef80a3f12d956553f3672f3d490607 Mon Sep 17 00:00:00 2001 From: cmaddox5 Date: Wed, 27 Nov 2024 13:38:50 -0500 Subject: [PATCH 15/18] Try using one widget to help with styling. --- assets/css/v2/elevator/elevator_closures.scss | 10 +--- assets/css/v2/elevator/footer.scss | 7 ++- assets/css/v2/elevator/header.scss | 7 ++- assets/css/v2/elevator/normal.scss | 17 +----- .../v2/elevator/elevator_closures.tsx | 55 ++++++++++++------- assets/src/components/v2/elevator/footer.tsx | 5 +- .../components/v2/elevator/normal_screen.tsx | 10 +--- .../v2/candidate_generator/elevator.ex | 23 +------- .../candidate_generator/elevator/closures.ex | 8 ++- .../v2/widget_instance/elevator_closures.ex | 13 +++-- .../v2/candidate_generator/elevator_test.exs | 35 ++++-------- .../elevator_closures_test.exs | 10 ++-- 12 files changed, 89 insertions(+), 111 deletions(-) diff --git a/assets/css/v2/elevator/elevator_closures.scss b/assets/css/v2/elevator/elevator_closures.scss index 1a809423d..4e76c5224 100644 --- a/assets/css/v2/elevator/elevator_closures.scss +++ b/assets/css/v2/elevator/elevator_closures.scss @@ -1,16 +1,8 @@ -.screen-normal:has(.current-elevator-closed-view) { - .normal-header, - .footer { - color: white; - background-color: $accessibility-blue; - } -} - .elevator-closures { position: relative; display: flex; flex-direction: column; - height: 100%; + height: 1632px; color: $cool-black-15; background-color: $warm-neutral-90; diff --git a/assets/css/v2/elevator/footer.scss b/assets/css/v2/elevator/footer.scss index 86a964854..696176347 100644 --- a/assets/css/v2/elevator/footer.scss +++ b/assets/css/v2/elevator/footer.scss @@ -1,5 +1,5 @@ .footer { - height: 100%; + height: 184px; padding: 26px 48px; font-size: 48px; font-weight: 500; @@ -7,6 +7,11 @@ color: white; background-color: $cool-black-30; + &--blue { + color: white; + background-color: $accessibility-blue; + } + b { letter-spacing: -0.2px; } diff --git a/assets/css/v2/elevator/header.scss b/assets/css/v2/elevator/header.scss index c3102b3cd..0b1e17726 100644 --- a/assets/css/v2/elevator/header.scss +++ b/assets/css/v2/elevator/header.scss @@ -2,11 +2,16 @@ display: flex; align-items: center; justify-content: space-between; - height: 100%; + height: 104px; padding: 0 48px; font-family: Inter, sans-serif; font-size: 48px; line-height: 62px; color: $warm-neutral-90; background-color: $cool-black-15; + + &--blue { + color: white; + background-color: $accessibility-blue; + } } diff --git a/assets/css/v2/elevator/normal.scss b/assets/css/v2/elevator/normal.scss index cdf209a7c..ceff2d56e 100644 --- a/assets/css/v2/elevator/normal.scss +++ b/assets/css/v2/elevator/normal.scss @@ -5,18 +5,7 @@ margin-left: auto; } -.screen-normal__header { - width: 1080px; - height: 104px; -} - -.screen-normal__body { - width: 1080px; - height: 1632px; -} - -.screen-normal__footer { - position: relative; - width: 1080px; - height: 184px; +.screen-normal__main-content { + width: 100%; + height: 1920px; } diff --git a/assets/src/components/v2/elevator/elevator_closures.tsx b/assets/src/components/v2/elevator/elevator_closures.tsx index 3f414a7fa..766fb4d40 100644 --- a/assets/src/components/v2/elevator/elevator_closures.tsx +++ b/assets/src/components/v2/elevator/elevator_closures.tsx @@ -9,6 +9,8 @@ import OutsideClosuresView from "Components/v2/elevator/closures/outside_closure import CurrentElevatorClosedView, { type Coordinates, } from "Components/v2/elevator/closures/current_elevator_closed_view"; +import Footer from "Components/v2/elevator/footer"; +import NormalHeader from "Components/v2/normal_header"; export type StationWithClosures = { id: string; @@ -33,6 +35,7 @@ interface Props extends WrappedComponentProps { accessible_path_direction_arrow: Direction; accessible_path_image_url: string | null; accessible_path_image_here_coordinates: Coordinates; + time: string; } const ElevatorClosures: React.ComponentType = ({ @@ -43,6 +46,7 @@ const ElevatorClosures: React.ComponentType = ({ accessible_path_direction_arrow: accessiblePathDirectionArrow, accessible_path_image_url: accessiblePathImageUrl, accessible_path_image_here_coordinates: accessiblePathImageHereCoordinates, + time, lastUpdate, onFinish, }: Props) => { @@ -51,27 +55,36 @@ const ElevatorClosures: React.ComponentType = ({ ); return ( -
- {currentElevatorClosure ? ( - - ) : ( - - )} -
+ <> + +
+ {currentElevatorClosure ? ( + + ) : ( + + )} +
+