瀏覽代碼

Allow creation of new locations

theenglishway (time) 4 年之前
父節點
當前提交
27a8dd553e
共有 5 個文件被更改,包括 78 次插入2 次删除
  1. 43 0
      lib/vaccins/location_store.ex
  2. 10 1
      lib/vaccins_web/live/index.ex
  3. 16 0
      lib/vaccins_web/live/index_live.html.leex
  4. 3 1
      mix.exs
  5. 6 0
      mix.lock

+ 43 - 0
lib/vaccins/location_store.ex

@@ -30,7 +30,36 @@ defmodule Vaccins.LocationStore do
     end
   end
 
+  defmodule LocationRaw do
+    use Ecto.Schema
+    import Ecto.Changeset
+    @primary_key {:id, :id, autogenerate: false}
+
+    embedded_schema do
+      field(:name, :string)
+      field(:booking_page, :string)
+      field(:raw_query, :string)
+    end
+
+    @doc false
+    def changeset(location \\ %__MODULE__{}, attrs),
+      do:
+        location
+        |> cast(attrs, [:name, :booking_page, :raw_query])
+        |> validate_required([:name, :booking_page, :raw_query])
+
+    def to_query_params(%__MODULE__{raw_query: raw}) do
+      raw
+      |> URI.parse()
+      |> Map.get(:query)
+      |> URI.decode_query()
+      |> Map.new(fn {k, v} -> {k |> String.to_atom(), v} end)
+      |> Map.take([:agenda_ids, :limit, :practice_ids, :visit_motive_ids])
+    end
+  end
+
   require Ex2ms
+  import Ecto.Changeset
   alias Vaccins.Queries.Doctolib
   @name Vaccins.LocationStore
 
@@ -48,4 +77,18 @@ defmodule Vaccins.LocationStore do
   end
 
   def build_location(l = %Location{}), do: l |> Location.set_id() |> Location.build_query()
+
+  def add_location(params) do
+    with {:ok, raw_location} <- params |> LocationRaw.changeset() |> apply_action(:insert),
+         processed <-
+           %Location{
+             name: raw_location.name,
+             booking_page: raw_location.booking_page,
+             availability_query_params: raw_location |> LocationRaw.to_query_params(),
+             provider: Doctolib
+           }
+           |> build_location,
+         true <- :dets.insert_new(@name, {processed.id, processed}),
+         do: :ok
+  end
 end

+ 10 - 1
lib/vaccins_web/live/index.ex

@@ -11,10 +11,19 @@ defmodule VaccinsWeb.IndexLive do
      |> assign(
        locations: locations,
        pending: %{},
-       availabilities: locations |> Map.new(&{&1.id, []})
+       availabilities: locations |> Map.new(&{&1.id, []}),
+       location_cs: LocationStore.LocationRaw.changeset(%{})
      )}
   end
 
+  @impl true
+  def handle_event("add_location", %{"location_raw" => params}, socket) do
+    case params |> LocationStore.add_location() do
+      :ok -> {:noreply, socket}
+      {:error, cs} -> {:noreply, socket |> assign(location_cs: cs)}
+    end
+  end
+
   @impl true
   def handle_info({:query_sent, id, ref}, socket = %{assigns: %{pending: pending}}) do
     {:noreply, socket |> assign(pending: pending |> Map.put(ref, id))}

+ 16 - 0
lib/vaccins_web/live/index_live.html.leex

@@ -1,3 +1,19 @@
+<%= f = form_for @location_cs, "#", [phx_submit: :add_location] %>
+  <%= label f, :name %>
+  <%= text_input f, :name %>
+  <%= error_tag f, :name %>
+
+  <%= label f, :booking_page %>
+  <%= text_input f, :booking_page %>
+  <%= error_tag f, :booking_page %>
+
+  <%= label f, :raw_query %>
+  <%= text_input f, :raw_query %>
+  <%= error_tag f, :raw_query %>
+
+  <%= submit "send" %>
+</form>
+
 <ul>
   <%= for l <- @locations do %>
     <li><%= live_component @socket, VaccinsWeb.LocationComponent, id: l.id, location: l %></li>

+ 3 - 1
mix.exs

@@ -45,7 +45,9 @@ defmodule Vaccins.MixProject do
       {:plug_cowboy, "~> 2.0"},
       {:floki, "~> 0.30.0"},
       {:finch, "~> 0.6"},
-      {:ex2ms, "~> 1.0"}
+      {:ex2ms, "~> 1.0"},
+      {:ecto, "~> 3.6"},
+      {:phoenix_ecto, "~> 4.1"}
     ]
   end
 

File diff suppressed because it is too large
+ 6 - 0
mix.lock