defmodule VaccinsWeb.IndexLive do use VaccinsWeb, :live_view alias Vaccins.LocationStore @impl true def mount(_params, %{"is_local?" => is_local?}, socket) do locations = LocationStore.get_locations() Phoenix.PubSub.subscribe(Vaccins.PubSub, "locations") {:ok, socket |> assign( noob_mode: false, is_local?: is_local?, locations: locations, locations_with_early_slots: MapSet.new(), locations_with_slots: MapSet.new(), pending: %{}, location_cs: LocationStore.LocationRaw.changeset(%{}), display_cs: false ) |> set_title()} end defp set_title(socket = %{assigns: %{locations_with_early_slots: early}}) do if early |> Enum.empty?(), do: socket |> assign(page_title: "Disponibilités vaccins"), else: socket |> assign(page_title: "(!!) Disponibilités vaccins") end @impl true def handle_params(params, _url, socket) when params == %{}, do: {:noreply, socket} def handle_params(%{"noob" => _}, _url, socket), do: {:noreply, socket |> assign(noob_mode: true)} @impl true def handle_event("add_location", %{"location_raw" => params}, socket) do case params |> LocationStore.add_location() do :ok -> {:noreply, socket |> push_patch(to: Routes.index_path(socket, :index))} {:error, cs} -> {:noreply, socket |> assign(location_cs: cs)} end end def handle_event("reload_file", _, socket) do :ok = LocationStore.reload() {:noreply, socket |> assign(locations: LocationStore.get_locations())} end def handle_event("toggle_form", _, socket = %{assigns: %{display_cs: display}}), do: {:noreply, socket |> assign(display_cs: not display)} def handle_event("trigger_noob_mode", _, socket = %{assigns: %{noob_mode: true}}), do: {:noreply, socket |> assign(noob_mode: false) |> push_patch(to: Routes.index_path(socket, :index))} def handle_event("trigger_noob_mode", _, socket = %{assigns: %{noob_mode: false}}), do: {:noreply, socket |> push_patch(to: Routes.index_path(socket, :index, noob: true))} @impl true def handle_info({:location_has_slots, id, true}, socket) do {:noreply, socket |> update(:locations_with_early_slots, &(&1 |> MapSet.put(id))) |> set_title} end def handle_info({:location_has_slots, id, false}, socket) do {:noreply, socket |> update(:locations_with_slots, &(&1 |> MapSet.put(id))) |> set_title} end def handle_info({:location_no_more_slots, id}, socket) do {:noreply, socket |> update(:locations_with_slots, &(&1 |> MapSet.delete(id))) |> update(:locations_with_early_slots, &(&1 |> MapSet.delete(id))) |> set_title} end def handle_info({:location_deleted, _}, socket), do: socket |> push_patch(to: Routes.index_path(socket, :index)) @impl true def handle_info({:new_availabilities, id, res}, socket) do send_update(VaccinsWeb.LocationComponent, id: id, availabilities: res) {:noreply, socket} end defp locations_by_availability(%{ locations: locations, locations_with_slots: with_slots, locations_with_early_slots: with_early_slots }) do locations |> Enum.sort(fn e1, e2 -> e1_has_early_spot? = e1.id in with_early_slots e1_has_spot? = e1.id in with_slots e2_has_early_spot? = e2.id in with_early_slots e2_has_spot? = e2.id in with_slots cond do e2_has_early_spot? -> false e2_has_spot? and not e1_has_early_spot? -> false e2_has_spot? and e1_has_spot? -> false true -> true end end) end end