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