Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
165 changes: 165 additions & 0 deletions lib/dotcom_web/components/preview_components.ex
Original file line number Diff line number Diff line change
@@ -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"""
<div
class={"w-full py-4 #{@class}"}
style={@style}
>
<div class="container">
<div class="flex items-center">
{render_slot(@inner_block)}
<div
phx-click={@clear_button_click}
class="ml-auto cursor-pointer opacity-75 hover:opacity-100"
>
<.icon class="size-5" name="circle-xmark" />
</div>
</div>
</div>
</div>
"""
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"
>
<span class="text-2xl font-bold">{@route.name}</span>
</.banner>
"""
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">
<span class="text-lg font-bold">{direction_description(@route, @direction_id)}</span>
</.banner>
"""
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">
<div class="flex flex-col">
<span class="text-lg font-bold">{@stop.name}</span>
<span class="text-md">{@stop.id}</span>
</div>
</.banner>
"""
end

attr :route, Routes.Route, default: nil
attr :routes, :list, required: true
slot :inner_block

def route_picker_or(%{route: nil} = assigns) do
~H"""
<div class="container">
<div class="flex gap-2 flex-wrap">
<button
:for={route <- @routes}
class="p-2 rounded opacity-75 hover:opacity-100"
style={"background-color: ##{route.color}; color: #{text_color(route)};"}
phx-click="select-route"
phx-value-route-id={route.id}
>
{route.name}
</button>
</div>
</div>
"""
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"""
<div class="mt-4 container">
<div class="w-full flex gap-2 justify-around">
<button
:for={
direction_id <-
@route.direction_names
|> Stream.reject(fn {_, name} -> is_nil(name) end)
|> Stream.map(fn {id, _} -> id end)
}
class="bg-gray-lightest opacity-75 hover:opacity-100 p-2 rounded"
phx-click="select-direction"
phx-value-direction-id={direction_id}
>
{direction_description(@route, direction_id)}
</button>
</div>
</div>
"""
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"""
<div class="container">
<div class="mt-4 flex flex-wrap gap-2">
<button
:for={stop <- @stops}
class="bg-charcoal-10 p-2 rounded text-white opacity-75 hover:opacity-100"
phx-click="select-stop"
phx-value-stop-id={stop.id}
>
{stop.name}
</button>
</div>
</div>
"""
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
6 changes: 3 additions & 3 deletions lib/dotcom_web/live/preview_live.ex
Original file line number Diff line number Diff line change
Expand Up @@ -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"
},
%{
Expand Down
163 changes: 163 additions & 0 deletions lib/dotcom_web/live/schedule_finder_picker_live.ex
Original file line number Diff line number Diff line change
@@ -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} />

<div class="container flex items-center justify-content-center py-8 px-2">
<.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
</.link>
</div>
</.stop_picker_or>
</.direction_picker_or>
</.route_picker_or>
"""
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
1 change: 1 addition & 0 deletions lib/dotcom_web/router.ex
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading