location_component.ex 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. defmodule VaccinsWeb.LocationComponent do
  2. use VaccinsWeb, :live_component
  3. alias Vaccins.{LocationStore, Search}
  4. @impl true
  5. def mount(socket),
  6. do:
  7. {:ok,
  8. socket
  9. |> assign(
  10. has_availabilities: false,
  11. slots_after: [],
  12. slots_before: [],
  13. loading: false
  14. )}
  15. @impl true
  16. def update(assigns, socket) do
  17. {force_refresh, assigns} = assigns |> Map.pop(:force_refresh)
  18. assigns = assigns |> integrate_availabilities
  19. if is_nil(force_refresh) do
  20. {:ok, socket |> assign(assigns) |> assign(loading: false)}
  21. else
  22. trigger_and_signal_query(
  23. assigns |> Map.get(:location, socket.assigns.location),
  24. assigns.id
  25. )
  26. {:ok, socket |> assign(assigns) |> assign(loading: true)}
  27. end
  28. end
  29. @impl true
  30. def handle_event("trigger_query", _, socket = %{assigns: %{id: id, location: location}}) do
  31. trigger_and_signal_query(location, id)
  32. {:noreply, socket |> assign(loading: true)}
  33. end
  34. @impl true
  35. def render(assigns) do
  36. ~L"""
  37. <dl class="location">
  38. <dt>id</dt>
  39. <dd><%= @location.id %></dd>
  40. <dt>Status</dt>
  41. <dd>
  42. <%= cond do %>
  43. <%= @loading -> %>...
  44. <%= not has_slots?(assigns) -> %>Pas de créneau
  45. <%= has_slots?(assigns) -> %>Des dispos !
  46. <% end %>
  47. </dd>
  48. <dt>booking page</dt>
  49. <dd><%= link @location.booking_page, to: @location.booking_page %></dd>
  50. <%= if has_slots?(assigns) do %>
  51. <dt>Avant 24h</dt>
  52. <dd>
  53. <ul><%= for d <- @slots_before do %><li><%= d |> DateTime.to_string %></li><% end %></ul>
  54. </dd>
  55. <dt>Après 24h</dt>
  56. <dd>
  57. <ul><%= for d <- @slots_after do %><li><%= d |> DateTime.to_string %></li><% end %></ul>
  58. </dd>
  59. <% end %>
  60. <dt>test availability</dt>
  61. <dd><button phx-click="trigger_query" phx-target="<%= @myself %>">Trigger</button></dd>
  62. </dl>
  63. """
  64. end
  65. defp integrate_availabilities(assigns = %{availabilities: {:error, reason}}),
  66. do: assigns |> Map.put(:has_availabilities, false)
  67. defp integrate_availabilities(assigns = %{availabilities: {:ok, after_slots}})
  68. when is_list(after_slots),
  69. do:
  70. assigns
  71. |> Map.put(:has_availabilities, true)
  72. |> Map.put(:slots_after, after_slots |> Enum.take(5))
  73. defp integrate_availabilities(assigns = %{availabilities: {:ok, before_slots, after_slots}})
  74. when is_list(before_slots),
  75. do:
  76. assigns
  77. |> Map.put(:has_availabilities, true)
  78. |> Map.put(:slots_after, after_slots |> Enum.take(5))
  79. |> Map.put(:slots_before, before_slots)
  80. defp integrate_availabilities(assigns), do: assigns
  81. defp has_slots?(assigns = %{slots_before: before, slots_after: after_}),
  82. do: not (before |> Enum.empty?() and after_ |> Enum.empty?())
  83. defp trigger_and_signal_query(location, id) do
  84. ref = Search.async_trigger_query(location)
  85. send(self(), {:query_sent, id, ref})
  86. end
  87. end