| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104 |
- defmodule VaccinsWeb.LocationComponent do
- use VaccinsWeb, :live_component
- alias Vaccins.{LocationStore, Search}
- @impl true
- def mount(socket),
- do:
- {:ok,
- socket
- |> assign(
- slots_after: [],
- slots_before: [],
- loading: false,
- last_refresh_date: nil
- )}
- @impl true
- def update(assigns, socket) do
- {force_refresh, assigns} = assigns |> Map.pop(:force_refresh)
- assigns = assigns |> integrate_availabilities
- if is_nil(force_refresh) do
- {:ok, socket |> assign(assigns) |> assign(loading: false)}
- else
- trigger_and_signal_query(
- assigns |> Map.get(:location, socket.assigns.location),
- assigns.id
- )
- {:ok,
- socket |> assign(assigns) |> assign(loading: true, last_refresh_date: get_refresh_time())}
- end
- end
- @impl true
- def handle_event("trigger_query", _, socket = %{assigns: %{id: id, location: location}}) do
- trigger_and_signal_query(location, id)
- {:noreply, socket |> assign(loading: true, last_refresh_date: get_refresh_time())}
- end
- @impl true
- def render(assigns) do
- ~L"""
- <dl class="location">
- <dt>id</dt>
- <dd><%= @location.id %></dd>
- <dt>Status (<%= if @last_refresh_date, do: @last_refresh_date |> Time.to_string() %>) </dt>
- <dd>
- <%= cond do %>
- <%= @loading -> %>...
- <%= not has_slots?(assigns) -> %>Pas de créneau
- <%= has_slots?(assigns) -> %>Des dispos !
- <% end %>
- </dd>
- <dt>booking page</dt>
- <dd><%= link @location.booking_page, to: @location.booking_page %></dd>
- <%= if has_slots?(assigns) do %>
- <dt>Avant 24h</dt>
- <dd>
- <ul><%= for d <- @slots_before do %><li><%= d |> DateTime.to_string %></li><% end %></ul>
- </dd>
- <dt>Après 24h</dt>
- <dd>
- <ul><%= for d <- @slots_after do %><li><%= d |> DateTime.to_string %></li><% end %></ul>
- </dd>
- <% end %>
- <dt>test availability</dt>
- <dd><button phx-click="trigger_query" phx-target="<%= @myself %>">Trigger</button></dd>
- </dl>
- """
- end
- defp integrate_availabilities(assigns = %{availabilities: {:error, reason}}),
- do: assigns
- defp integrate_availabilities(assigns = %{availabilities: {:ok, after_slots}})
- when is_list(after_slots),
- do:
- assigns
- |> Map.put(:slots_after, after_slots |> Enum.take(5))
- defp integrate_availabilities(assigns = %{availabilities: {:ok, before_slots, after_slots}})
- when is_list(before_slots),
- do:
- assigns
- |> Map.put(:slots_after, after_slots |> Enum.take(5))
- |> Map.put(:slots_before, before_slots)
- defp integrate_availabilities(assigns), do: assigns
- defp has_slots?(assigns = %{slots_before: before, slots_after: after_}),
- do: not (before |> Enum.empty?() and after_ |> Enum.empty?())
- defp trigger_and_signal_query(location, id) do
- ref = Search.async_trigger_query(location)
- send(self(), {:query_sent, id, ref})
- end
- defp get_refresh_time() do
- with {:ok, now} <-
- DateTime.utc_now() |> DateTime.shift_zone("Europe/Paris", Tzdata.TimeZoneDatabase),
- do: now |> DateTime.to_time() |> Time.truncate(:second)
- end
- end
|