diff --git a/lib/dotcom_web/components/preview_components.ex b/lib/dotcom_web/components/preview_components.ex new file mode 100644 index 0000000000..5858b4b817 --- /dev/null +++ b/lib/dotcom_web/components/preview_components.ex @@ -0,0 +1,165 @@ +defmodule DotcomWeb.PreviewComponents do + @moduledoc """ + Some silly components to be used in non-rider-facing preview explorations + """ + + use DotcomWeb, :component + + attr :clear_button_click, :string, required: true + attr :class, :string, default: "" + attr :style, :string, default: "" + slot :inner_block + + defp banner(assigns) do + ~H""" +
+
+
+ {render_slot(@inner_block)} +
+ <.icon class="size-5" name="circle-xmark" /> +
+
+
+
+ """ + end + + attr :route, Routes.Route, required: true + + def route_banner(assigns) do + ~H""" + <.banner + style={"background-color: ##{@route.color}; color: #{text_color(@route)}; fill: #{text_color(@route)};"} + clear_button_click="clear-route" + > + {@route.name} + + """ + end + + attr :direction_id, :string, required: true + attr :route, Routes.Route, required: true + + def direction_banner(assigns) do + ~H""" + <.banner clear_button_click="clear-direction" class="bg-gray-lightest"> + {direction_description(@route, @direction_id)} + + """ + end + + attr :stop, Stops.Stop, required: true + + def stop_banner(assigns) do + ~H""" + <.banner clear_button_click="clear-stop" class="bg-charcoal-10 text-white fill-white"> +
+ {@stop.name} + {@stop.id} +
+ + """ + end + + attr :route, Routes.Route, default: nil + attr :routes, :list, required: true + slot :inner_block + + def route_picker_or(%{route: nil} = assigns) do + ~H""" +
+
+ +
+
+ """ + end + + def route_picker_or(assigns) do + ~H""" + {render_slot(@inner_block)} + """ + end + + attr :route, Routes.Route, required: true + attr :direction_id, :string, required: true + slot :inner_block + + def direction_picker_or(%{direction_id: nil} = assigns) do + ~H""" +
+
+ +
+
+ """ + end + + def direction_picker_or(assigns) do + ~H""" + {render_slot(@inner_block)} + """ + end + + attr :stop, Stops.Stop, default: nil + attr :stops, :list, required: true + slot :inner_block + + def stop_picker_or(%{stop: nil} = assigns) do + ~H""" +
+
+ +
+
+ """ + end + + def stop_picker_or(assigns) do + ~H""" + {render_slot(@inner_block)} + """ + end + + defp direction_description(route, direction_id) do + "#{route.direction_names[direction_id]} towards #{route.direction_destinations[direction_id]}" + end + + defp text_color(route) do + if(route.type == 3 and not String.contains?(route.name, "SL"), do: "black", else: "white") + end +end diff --git a/lib/dotcom_web/live/preview_live.ex b/lib/dotcom_web/live/preview_live.ex index 0fc7a7b2a9..e24cb4bea6 100644 --- a/lib/dotcom_web/live/preview_live.ex +++ b/lib/dotcom_web/live/preview_live.ex @@ -7,15 +7,15 @@ defmodule DotcomWeb.PreviewLive do use DotcomWeb, :live_view alias DotcomWeb.Router.Helpers - alias DotcomWeb.ScheduleFinderLive + alias DotcomWeb.ScheduleFinderPickerLive alias DotcomWeb.StopMapLive alias Phoenix.LiveView @pages [ %{ - arguments: [[route_id: "Red", direction_id: "0"]], + arguments: [], icon_name: "icon-realtime-tracking", - module: ScheduleFinderLive, + module: ScheduleFinderPickerLive, title: "Schedule Finder 2.0" }, %{ diff --git a/lib/dotcom_web/live/schedule_finder_picker_live.ex b/lib/dotcom_web/live/schedule_finder_picker_live.ex new file mode 100644 index 0000000000..129e09f6df --- /dev/null +++ b/lib/dotcom_web/live/schedule_finder_picker_live.ex @@ -0,0 +1,163 @@ +defmodule DotcomWeb.ScheduleFinderPickerLive do + @moduledoc """ + A page that allows us to easily navigate to the new Schedule Finder page + """ + + use DotcomWeb, :live_view + + import DotcomWeb.PreviewComponents, + only: [ + direction_banner: 1, + direction_picker_or: 1, + route_banner: 1, + route_picker_or: 1, + stop_banner: 1, + stop_picker_or: 1 + ] + + alias Phoenix.LiveView + + @impl LiveView + def mount(_params, _session, socket) do + {:ok, + socket + |> assign(:routes, Routes.Repo.all())} + end + + @impl LiveView + def handle_params(params, _uri, socket) do + route_id = Map.get(params, "route_id") + + direction_id = + params + |> Map.get("direction_id") + |> case do + nil -> nil + str when is_binary(str) -> String.to_integer(str) + end + + stop_id = Map.get(params, "stop_id") + + {:noreply, + socket + |> assign_route(route_id) + |> assign_direction(direction_id) + |> assign_stop(stop_id)} + end + + defp assign_route(socket, nil) do + socket + |> assign(:route_id, nil) + |> assign(:route, nil) + end + + defp assign_route(socket, route_id) do + socket + |> assign(:route_id, route_id) + |> assign(:route, Routes.Repo.get(route_id)) + end + + defp assign_direction(socket, nil) do + socket + |> assign(:direction_id, nil) + |> assign(:stops, nil) + end + + defp assign_direction(socket, direction_id) do + stops = + Stops.Repo.by_route(socket.assigns.route_id, direction_id) + + socket + |> assign(:direction_id, direction_id) + |> assign(:stops, stops) + end + + defp assign_stop(socket, nil) do + socket + |> assign(:stop_id, nil) + |> assign(:stop, nil) + end + + defp assign_stop(socket, stop_id) do + socket + |> assign(:stop_id, stop_id) + |> assign(:stop, Stops.Repo.get(stop_id)) + end + + @impl LiveView + def render(assigns) do + ~H""" + <.route_picker_or route={@route} routes={@routes}> + <.route_banner route={@route} /> + + <.direction_picker_or route={@route} direction_id={@direction_id}> + <.direction_banner route={@route} direction_id={@direction_id} /> + + <.stop_picker_or + stop={@stop} + stops={@stops} + > + <.stop_banner stop={@stop} /> + +
+ <.link + navigate={ + ~p"/departures?route_id=#{@route_id}&direction_id=#{@direction_id}&stop_id=#{@stop_id}" + } + target="_blank" + class="bg-gray-lightest text-black font-bold p-2 rounded" + > + See Departures Page + +
+ + + + """ + end + + @impl LiveView + def handle_event("clear-route", _params, socket) do + {:noreply, socket |> push_patch(to: ~p"/preview/schedule-finder-picker")} + end + + def handle_event("clear-direction", _params, socket) do + route_id = socket.assigns.route_id + + params = %{route_id: route_id} + {:noreply, socket |> push_patch(to: ~p"/preview/schedule-finder-picker?#{params}")} + end + + def handle_event("clear-stop", _params, socket) do + route_id = socket.assigns.route_id + direction_id = socket.assigns.direction_id + + params = %{route_id: route_id, direction_id: direction_id} + {:noreply, socket |> push_patch(to: ~p"/preview/schedule-finder-picker?#{params}")} + end + + def handle_event("select-direction", %{"direction-id" => direction_id}, socket) do + route_id = socket.assigns.route_id + + params = %{route_id: route_id, direction_id: direction_id} + {:noreply, socket |> push_patch(to: ~p"/preview/schedule-finder-picker?#{params}")} + end + + def handle_event("select-route", %{"route-id" => route_id}, socket) do + params = %{route_id: route_id} + {:noreply, socket |> push_patch(to: ~p"/preview/schedule-finder-picker?#{params}")} + end + + def handle_event("select-stop", %{"stop-id" => stop_id}, socket) do + route_id = socket.assigns.route_id + direction_id = socket.assigns.direction_id + + params = %{route_id: route_id, direction_id: direction_id, stop_id: stop_id} + {:noreply, socket |> push_patch(to: ~p"/preview/schedule-finder-picker?#{params}")} + end + + @impl LiveView + def terminate(_reason, _socket) do + :ok + end +end diff --git a/lib/dotcom_web/router.ex b/lib/dotcom_web/router.ex index 84f1880174..de9feebb5a 100644 --- a/lib/dotcom_web/router.ex +++ b/lib/dotcom_web/router.ex @@ -334,6 +334,7 @@ defmodule DotcomWeb.Router do live_session :default, layout: {DotcomWeb.LayoutView, :preview} do live "/", PreviewLive + live "/schedule-finder-picker", ScheduleFinderPickerLive live "/schedules/bostonstadium", WorldCupTimetableLive live "/stop-map", StopMapLive end