@@ -722,23 +718,19 @@ defmodule BasketWeb.CoreComponents do
for {^field, {msg, opts}} <- errors, do: translate_error({msg, opts})
end
- defp diff_color(col, row) do
- key = Map.get(col, :key)
+ defp diff_cell_color(%{key: nil}, _row), do: ""
- if is_nil(key) do
- ""
- else
- field = row[key]
-
- if field != nil && is_number(field.value) && is_number(field.prev_value) do
- case field.value - field.prev_value do
- x when x > 0 -> "bg-emerald-300 text-emerald-900"
- x when x < 0 -> "bg-rose-300 text-rose-900"
- _ -> ""
- end
- else
- ""
+ defp diff_cell_color(%{key: key} = _col, row) do
+ field = row[key]
+
+ if field != nil && is_number(field.value) && is_number(field.prev_value) do
+ case field.value - field.prev_value do
+ x when x > 0 -> "bg-emerald-300 text-emerald-900"
+ x when x < 0 -> "bg-rose-300 text-rose-900"
+ _ -> ""
end
+ else
+ ""
end
end
end
diff --git a/lib/basket_web/components/dark_mode_toggle.ex b/lib/basket_web/components/dark_mode_toggle.ex
deleted file mode 100644
index c772b7c..0000000
--- a/lib/basket_web/components/dark_mode_toggle.ex
+++ /dev/null
@@ -1,26 +0,0 @@
-defmodule BasketWeb.Components.DarkModeToggle do
- @moduledoc """
- A sample component generated by `mix surface.init`.
- """
- use Surface.Component
-
- import BasketWeb.CoreComponents
-
- alias Phoenix.LiveView.JS
-
- def render(assigns) do
- ~F"""
- """
-
- # ~F"""
- #
- #
- #
- #
- # """
- end
-end
diff --git a/lib/basket_web/components/nav_row.ex b/lib/basket_web/components/nav_row.ex
index 6bdfbc0..9862a30 100644
--- a/lib/basket_web/components/nav_row.ex
+++ b/lib/basket_web/components/nav_row.ex
@@ -2,14 +2,12 @@ defmodule BasketWeb.Components.NavRow do
@moduledoc """
The header for the home page.
"""
- alias BasketWeb.Components.DarkModeToggle
use Surface.Component
def render(assigns) do
~F"""
-
<.link href="/session" method="delete">Sign out
"""
diff --git a/lib/basket_web/live/overview.ex b/lib/basket_web/live/overview.ex
index ba1832b..74b12e5 100644
--- a/lib/basket_web/live/overview.ex
+++ b/lib/basket_web/live/overview.ex
@@ -6,10 +6,9 @@ defmodule BasketWeb.OverviewLive do
require Logger
- alias Basket.{Http, Websocket}
+ alias Basket.Websocket
alias BasketWeb.Components.{NavRow, TickerBarTable}
- alias BasketWeb.Live.Overview.Search
- alias BasketWeb.Live.Overview.TickerBar
+ alias BasketWeb.Live.Overview.{Search, TickerAdd, TickerBar}
def mount(_, _, socket) do
BasketWeb.Endpoint.subscribe(Websocket.Alpaca.bars_topic())
@@ -24,25 +23,18 @@ defmodule BasketWeb.OverviewLive do
{:noreply, socket}
else
socket =
- case Http.Alpaca.latest_quote(ticker) do
- {:ok, response} ->
- %{"bars" => ticker_bars} = response
- new_ticker_bars = Map.to_list(ticker_bars) |> List.first()
- # TODO: nil not a tuple - AKUMQ
- initial_bars = build_ticker_bars(elem(new_ticker_bars, 1))
-
- assign(
- socket,
- :basket,
- socket.assigns.basket ++
- [Map.merge(initial_bars, %{"S" => %TickerBar{value: ticker}})]
- )
-
- {:error, error} ->
- Logger.error("Could not subscribe to ticker: #{error}")
- end
+ case TickerAdd.call(ticker) do
+ row when is_map(row) ->
+ :ok = Websocket.Alpaca.subscribe(%{bars: [ticker], quotes: [], trades: []})
+ assign(socket, :basket, (socket.assigns.basket ++ [row]) |> sort_by_ticker())
+
+ :market_closed ->
+ # TODO: add market closed row
+ socket
- :ok = Websocket.Alpaca.subscribe(%{bars: [ticker], quotes: [], trades: []})
+ _ ->
+ socket
+ end
{:noreply, socket}
end
@@ -98,16 +90,6 @@ defmodule BasketWeb.OverviewLive do
"""
end
- defp build_ticker_bars(ticker_bars) do
- if ticker_bars == %{} do
- %{"t" => "Market Closed"}
- else
- Enum.reduce(ticker_bars, %{}, fn {k, v}, acc ->
- Map.put(acc, k, %TickerBar{value: v})
- end)
- end
- end
-
defp new_ticker_row(row, bars) do
Enum.reduce(row, %{}, fn {k, v}, acc ->
new_value = Map.get(bars, k)
@@ -115,5 +97,11 @@ defmodule BasketWeb.OverviewLive do
end)
end
+ defp sort_by_ticker(bars),
+ do:
+ Enum.sort(bars, fn a, b ->
+ a["S"].value < b["S"].value
+ end)
+
defp tickers(socket), do: Enum.map(socket.assigns.basket, &Map.get(&1, "S").value)
end
diff --git a/lib/basket_web/live/overview/ticker_add.ex b/lib/basket_web/live/overview/ticker_add.ex
new file mode 100644
index 0000000..f3bce66
--- /dev/null
+++ b/lib/basket_web/live/overview/ticker_add.ex
@@ -0,0 +1,58 @@
+defmodule BasketWeb.Live.Overview.TickerAdd do
+ @moduledoc """
+ Creates a new ticker in the table.
+ """
+
+ alias Basket.Http
+ alias BasketWeb.Live.Overview.TickerBar
+
+ require Logger
+
+ @doc """
+ Creates a row to be added to the ticker bar table.
+ """
+ def call(ticker) do
+ case Http.Alpaca.latest_quote(ticker) do
+ {:ok, response} ->
+ case build_ticker_bars(response) do
+ :no_data ->
+ # TODO: info flash
+ :no_data
+
+ :market_closed ->
+ :market_closed
+
+ bars ->
+ bars
+ end
+
+ {:error, error} ->
+ # TODO: error flash
+ Logger.error("Could not subscribe to ticker: #{error}")
+ end
+ end
+
+ defp build_ticker_bars(%{"bars" => nil}) do
+ end
+
+ defp build_ticker_bars(%{"bars" => ticker_bars}) do
+ # TODO: check first
+ new_ticker_bars = Map.to_list(ticker_bars) |> List.first()
+
+ case new_ticker_bars do
+ nil ->
+ :no_data
+
+ %{} ->
+ :market_closed
+
+ bars ->
+ Enum.reduce(bars, %{}, fn {k, v}, acc ->
+ Map.put(acc, k, %TickerBar{value: v})
+ end)
+
+ # TODO: check
+ # Map.merge(new_bars, %{"S" => %TickerBar{value: ticker}})
+ end
+ end
+end