From 09b9310fd2968e635d08edeaa13a67c5f9351561 Mon Sep 17 00:00:00 2001 From: Josh Larson Date: Thu, 19 Dec 2024 11:00:57 -0500 Subject: [PATCH] ui(TripPlanner): Make <.itinerary_detail /> more closely match final designs (#2275) Co-authored-by: Cristen Jones --- .../components/trip_planner/alert_group.ex | 40 ----- .../trip_planner/itinerary_detail.ex | 4 +- .../components/trip_planner/place.ex | 69 ++++----- .../trip_planner/start_or_end_place.ex | 29 ++++ .../components/trip_planner/transit_leg.ex | 141 ++++++++++++++---- .../components/trip_planner/walking_leg.ex | 42 +++--- 6 files changed, 195 insertions(+), 130 deletions(-) delete mode 100644 lib/dotcom_web/components/trip_planner/alert_group.ex create mode 100644 lib/dotcom_web/components/trip_planner/start_or_end_place.ex diff --git a/lib/dotcom_web/components/trip_planner/alert_group.ex b/lib/dotcom_web/components/trip_planner/alert_group.ex deleted file mode 100644 index afecae4d88..0000000000 --- a/lib/dotcom_web/components/trip_planner/alert_group.ex +++ /dev/null @@ -1,40 +0,0 @@ -defmodule DotcomWeb.Components.TripPlanner.AlertGroup do - @moduledoc """ - A component to display an alert for a route or location - """ - - use DotcomWeb, :component - - attr :alerts, :list, required: true - attr :class, :string, default: "" - - def alert_group(assigns) do - ~H""" - <%= if @alerts do %> -
- <.alert alert={alert} /> -
- <% end %> - """ - end - - defp alert(assigns) do - ~H""" -
- - <.icon name="triangle-exclamation" class="w-3 h-3" /> - - {Phoenix.Naming.humanize(@alert.effect)} - Show Details - - - -
- {@alert.header} -
-
- """ - end -end diff --git a/lib/dotcom_web/components/trip_planner/itinerary_detail.ex b/lib/dotcom_web/components/trip_planner/itinerary_detail.ex index 1c58386d99..f27f1f9ec0 100644 --- a/lib/dotcom_web/components/trip_planner/itinerary_detail.ex +++ b/lib/dotcom_web/components/trip_planner/itinerary_detail.ex @@ -6,7 +6,7 @@ defmodule DotcomWeb.Components.TripPlanner.ItineraryDetail do use DotcomWeb, :component - import DotcomWeb.Components.TripPlanner.Place + import DotcomWeb.Components.TripPlanner.StartOrEndPlace import DotcomWeb.Components.TripPlanner.TransitLeg, only: [transit_leg: 1] import DotcomWeb.Components.TripPlanner.WalkingLeg, only: [walking_leg: 1] @@ -95,7 +95,7 @@ defmodule DotcomWeb.Components.TripPlanner.ItineraryDetail do |> assign(:place, place) ~H""" - <.place place={@place} time={@time} /> + <.start_or_end_place place={@place} time={@time} /> """ end diff --git a/lib/dotcom_web/components/trip_planner/place.ex b/lib/dotcom_web/components/trip_planner/place.ex index 81a5672357..34944880c6 100644 --- a/lib/dotcom_web/components/trip_planner/place.ex +++ b/lib/dotcom_web/components/trip_planner/place.ex @@ -5,69 +5,52 @@ defmodule DotcomWeb.Components.TripPlanner.Place do use DotcomWeb, :component - import DotcomWeb.Components.TripPlanner.AlertGroup, only: [alert_group: 1] - - alias Routes.Route - alias Stops.Stop - - attr :place, :map, required: true + attr :accessible, :boolean, default: false + attr :name, :string, required: true attr :time, :any, required: true - attr :route, :map, default: nil - attr :alerts, :list, default: [] + attr :url, :string, default: nil + slot :icon def place(assigns) do - stop_url = stop_url(assigns.route, assigns.place.stop) - - assigns = - assign(assigns, %{ - stop_url: stop_url, - tag_name: if(stop_url, do: "a", else: "div") - }) - ~H""" -
- <.location_icon route={@route} class="h-6 w-6" /> - <.dynamic_tag class="hover:no-underline text-black" tag_name={@tag_name} href={@stop_url}> - - {@place.name} +
+
+ {render_slot(@icon)} +
+ + <.wrap_with_url url={@url}> + + {@name} <.icon - :if={!is_nil(@place.stop) and Stop.accessible?(@place.stop)} + :if={@accessible} type="icon-svg" name="icon-accessible-default" - class="h-5 w-5 ml-0.5 shrink-0" + class="h-3 w-3 shrink-0 ml-1.5" aria-hidden="true" /> - - - <.alert_group class="col-start-2 col-end-4 mr-4" alerts={@alerts} /> + + +
""" end - defp stop_url(%Route{external_agency_name: nil}, %Stop{} = stop) do - ~p"/stops/#{stop}" - end - - defp stop_url(_, _), do: nil - - defp location_icon(%{route: %Route{}} = assigns) do - icon_name = - if(Routes.Route.type_atom(assigns.route) in [:bus, :logan_express, :massport_shuttle], - do: "icon-stop-default", - else: "icon-circle-t-default" - ) - - assigns = assign(assigns, :icon_name, icon_name) + attr :url, :string, required: true + slot :inner_block + defp wrap_with_url(assigns) + defp wrap_with_url(%{url: nil} = assigns) do ~H""" - <.icon type="icon-svg" class={@class} name={@icon_name} /> + {render_slot(@inner_block)} """ end - defp location_icon(assigns) do + defp wrap_with_url(assigns) do ~H""" - <.icon class={"#{@class} fill-brand-primary"} name="location-dot" /> + + {render_slot(@inner_block)} + """ end diff --git a/lib/dotcom_web/components/trip_planner/start_or_end_place.ex b/lib/dotcom_web/components/trip_planner/start_or_end_place.ex new file mode 100644 index 0000000000..e94babe80c --- /dev/null +++ b/lib/dotcom_web/components/trip_planner/start_or_end_place.ex @@ -0,0 +1,29 @@ +defmodule DotcomWeb.Components.TripPlanner.StartOrEndPlace do + @moduledoc """ + A component to display a specific location in the itinerary detail. + """ + + use DotcomWeb, :component + + import DotcomWeb.Components.TripPlanner.Place, only: [place: 1] + + alias Routes.Route + alias Stops.Stop + + attr :place, :map, required: true + attr :time, :any, required: true + attr :route, :map, default: nil + attr :alerts, :list, default: [] + + def start_or_end_place(assigns) do + ~H""" +
+ <.place name={@place.name} time={@time}> + <:icon> + <.icon name="location-dot" class="fill-brand-primary h-5 w-5" /> + + +
+ """ + end +end diff --git a/lib/dotcom_web/components/trip_planner/transit_leg.ex b/lib/dotcom_web/components/trip_planner/transit_leg.ex index fee31f8689..6d98eb251f 100644 --- a/lib/dotcom_web/components/trip_planner/transit_leg.ex +++ b/lib/dotcom_web/components/trip_planner/transit_leg.ex @@ -4,9 +4,8 @@ defmodule DotcomWeb.Components.TripPlanner.TransitLeg do Includes styling for the traversed route & a list of intermediate stops. """ - use Phoenix.Component + use DotcomWeb, :component - import DotcomWeb.Components.TripPlanner.AlertGroup, only: [alert_group: 1] import DotcomWeb.Components.RouteSymbols, only: [route_symbol: 1] import DotcomWeb.Components.TripPlanner.Place import MbtaMetro.Components.Icon, only: [icon: 1] @@ -14,6 +13,7 @@ defmodule DotcomWeb.Components.TripPlanner.TransitLeg do alias Dotcom.TripPlan.{Alerts, TransitDetail} alias Routes.Route + alias Stops.Stop @doc """ Renders a transit leg. @@ -25,35 +25,47 @@ defmodule DotcomWeb.Components.TripPlanner.TransitLeg do attr :leg, :any, required: true def transit_leg(assigns) do - assigns = assign(assigns, :alerts, Alerts.by_mode_and_stops(assigns.alerts, assigns.leg)) + assigns = + assigns + |> assign(:alerts, Alerts.by_mode_and_stops(assigns.alerts, assigns.leg)) ~H""" -
- <.place +
+ <.transit_place + show_leg_line place={@leg.from} time={@leg.start} route={if(match?(%TransitDetail{}, @leg.mode), do: @leg.mode.route)} alerts={@alerts.from} /> -
+
+
+
+
+
+ <%= if Enum.count(@leg.mode.intermediate_stops) < 2 do %> - <.leg_summary leg={@leg} alerts={@alerts.route} /> - <.leg_details leg={@leg} /> +
+ <.leg_summary leg={@leg} alerts={@alerts.route} /> + <.leg_details leg={@leg} /> +
<% else %> -
- +
+ <.leg_summary leg={@leg} alerts={@alerts.route} /> + <.icon - name="chevron-up" - class="group-open/stops:rotate-180 w-4 h-4 absolute top-3 right-3 fill-brand-primary" + name="chevron-down" + class="ml-auto shrink-0 w-4 h-4 fill-brand-primary group-open/stops:rotate-180" /> <.leg_details leg={@leg} />
<% end %>
- <.place + + <.transit_place place={@leg.to} time={@leg.stop} route={if(match?(%TransitDetail{}, @leg.mode), do: @leg.mode.route)} @@ -63,12 +75,52 @@ defmodule DotcomWeb.Components.TripPlanner.TransitLeg do """ end + attr :place, :any, required: true + attr :time, :any, required: true + attr :route, :any, required: true + attr :alerts, :list, required: true + attr :show_leg_line, :boolean, default: false + + defp transit_place(assigns) do + ~H""" +
+ <.place + time={@time} + name={@place.stop.name} + accessible={!is_nil(@place.stop) and Stop.accessible?(@place.stop)} + url={stop_url(@route, @place.stop)} + > + <:icon> + <.transit_leg_icon route={@route} /> + +
+ + +
+
+
+
+
+
+ <.alert :for={alert <- @alerts} alert={alert} /> +
+
+
+ """ + end + + defp stop_url(%Route{external_agency_name: nil}, %Stop{} = stop) do + ~p"/stops/#{stop}" + end + + defp stop_url(_, _), do: nil + defp leg_line_class(%Route{external_agency_name: "Massport"}) do - "border-massport" + "bg-massport" end defp leg_line_class(%Route{external_agency_name: "Logan Express", name: name}) do - "border-logan-express-#{name}" + "bg-logan-express-#{name}" end defp leg_line_class(%Route{} = route) do @@ -76,10 +128,42 @@ defmodule DotcomWeb.Components.TripPlanner.TransitLeg do |> Route.to_naive() |> Route.icon_atom() |> CSSHelpers.atom_to_class() - |> then(&"border-#{&1}") + |> then(&"bg-#{&1}") + end + + defp transit_leg_icon(assigns) do + name = + case Route.vehicle_name(assigns.route) do + "Bus" -> "icon-stop-default" + _ -> "icon-circle-t-default" + end + + assigns = assigns |> assign(:name, name) + + ~H""" + <.icon type="icon-svg" class="shrink-0 h-5 w-5" name={@name} /> + """ end - defp leg_line_class(_), do: "" + defp alert(assigns) do + ~H""" +
+ + <.icon name="triangle-exclamation" class="h-3 w-3" /> + + {Phoenix.Naming.humanize(@alert.effect)} + + Show Details + + +
+ {@alert.header} +
+
+ """ + end defp leg_summary(assigns) do assigns = @@ -88,14 +172,19 @@ defmodule DotcomWeb.Components.TripPlanner.TransitLeg do |> assign(:headsign, headsign(assigns.leg.mode)) ~H""" -
- <.route_symbol route={@leg.mode.route} /> - {@headsign} -
- <.ride_message mode={@leg.mode} /> - {@stops_count} {Inflex.inflect("stop", @stops_count)} +
+ <.route_symbol class="shrink-0" route={@leg.mode.route} /> + +
+ {@headsign} + + <.ride_message mode={@leg.mode} /> + + {@stops_count} {Inflex.inflect("stop", @stops_count)} + + + <.alert :for={alert <- @alerts} alert={alert} />
- <.alert_group class="col-start-2 mb-2 mr-4" alerts={@alerts} />
""" end @@ -169,12 +258,12 @@ defmodule DotcomWeb.Components.TripPlanner.TransitLeg do defp leg_details(assigns) do ~H""" -
    +
    • - <.icon name="circle" class="w-2 h-2 absolute -left-6 fill-white" /> + <.icon name="circle" class="h-1.5 w-1.5 absolute -left-7 fill-white" /> {stop.name}
    diff --git a/lib/dotcom_web/components/trip_planner/walking_leg.ex b/lib/dotcom_web/components/trip_planner/walking_leg.ex index 8f659e3022..f68b0b98a4 100644 --- a/lib/dotcom_web/components/trip_planner/walking_leg.ex +++ b/lib/dotcom_web/components/trip_planner/walking_leg.ex @@ -6,7 +6,6 @@ defmodule DotcomWeb.Components.TripPlanner.WalkingLeg do use Phoenix.Component - import MbtaMetro.Components.Accordion, only: [accordion: 1] import MbtaMetro.Components.Icon, only: [icon: 1] import MbtaMetro.Components.List, only: [list: 1] @@ -25,31 +24,36 @@ defmodule DotcomWeb.Components.TripPlanner.WalkingLeg do def walking_leg(assigns) do ~H""" -
    -
    - <.accordion> - <:heading> - <.icon name="person-walking" class="w-5 h-5 mr-1 fill-black" /> -
    -
    - Walk -
    -
    - {@leg.duration} min, {@leg.distance} mi +
    +
    +
    +
    +
    +
    + +
    + + <.icon name="person-walking" class="shrink-0 w-4 h-6 fill-black" /> +
    +
    Walk
    +
    + {@leg.duration} min, {@leg.distance} mi +
    -
    - - <:content> - <.list class="w-full m-0 ps-0"> + <.icon + name="chevron-down" + class="ml-auto shrink-0 w-4 h-4 fill-brand-primary group-open:rotate-180" + /> + + <.list class="m-0"> <:item :for={step <- @leg.mode.steps}> {Step.walk_summary(step)} - - -
    + +
    """ end