diff --git a/lib/berrypod/products.ex b/lib/berrypod/products.ex index d6b5e54..b8fea26 100644 --- a/lib/berrypod/products.ex +++ b/lib/berrypod/products.ex @@ -64,6 +64,59 @@ defmodule Berrypod.Products do |> Repo.insert() end + @doc """ + Tests an API key, creates the connection with config (shop_id etc), + and enqueues a product sync. Used by both setup wizard and providers form. + + Returns `{:ok, connection}` or `{:error, reason}`. + """ + def connect_provider(api_key, provider_type) do + alias Berrypod.Providers + + encrypted = + case Berrypod.Vault.encrypt(api_key) do + {:ok, enc} -> enc + _ -> nil + end + + temp_conn = %ProviderConnection{ + provider_type: provider_type, + api_key_encrypted: encrypted + } + + with {:ok, test_result} <- Providers.test_connection(temp_conn) do + name = provider_display_name(provider_type, test_result) + config = provider_config(provider_type, test_result) + + params = + %{"api_key" => api_key, "provider_type" => provider_type, "name" => name} + |> then(fn p -> if config != %{}, do: Map.put(p, "config", config), else: p end) + + case create_provider_connection(params) do + {:ok, connection} -> + enqueue_sync(connection) + {:ok, connection} + + {:error, _} = error -> + error + end + end + end + + defp provider_display_name("printify", %{shop_name: name}) when is_binary(name), do: name + defp provider_display_name("printful", %{store_name: name}) when is_binary(name), do: name + + defp provider_display_name(type, _) do + case Berrypod.Providers.Provider.get(type) do + nil -> type + info -> info.name + end + end + + defp provider_config("printify", %{shop_id: id}), do: %{"shop_id" => to_string(id)} + defp provider_config("printful", %{store_id: id}), do: %{"store_id" => to_string(id)} + defp provider_config(_, _), do: %{} + @doc """ Updates a provider connection. """ diff --git a/lib/berrypod_web/live/admin/products.ex b/lib/berrypod_web/live/admin/products.ex index 53ab2bb..05e28a2 100644 --- a/lib/berrypod_web/live/admin/products.ex +++ b/lib/berrypod_web/live/admin/products.ex @@ -184,12 +184,19 @@ defmodule BerrypodWeb.Admin.Products do
<.icon name="hero-cube" class="admin-empty-state-icon" />

No products yet

-

+

<.link navigate={~p"/admin/providers"} class="admin-link"> Connect a provider to sync your products.

+

+ Head to the + <.link navigate={~p"/admin/providers"} class="admin-link"> + providers page + + to sync your products. +

""" end diff --git a/lib/berrypod_web/live/admin/providers/form.ex b/lib/berrypod_web/live/admin/providers/form.ex index 19f5535..8ba2ddd 100644 --- a/lib/berrypod_web/live/admin/providers/form.ex +++ b/lib/berrypod_web/live/admin/providers/form.ex @@ -82,23 +82,18 @@ defmodule BerrypodWeb.Admin.Providers.Form do end defp save_connection(socket, :new, params) do + api_key = params["api_key"] || socket.assigns[:pending_api_key] provider_type = socket.assigns.provider_type - params = - params - |> Map.put("provider_type", provider_type) - |> maybe_add_config(provider_type, socket.assigns.test_result) - |> maybe_add_name(provider_type, socket.assigns.test_result) - - case Products.create_provider_connection(params) do + case Products.connect_provider(api_key, provider_type) do {:ok, _connection} -> {:noreply, socket |> put_flash(:info, "Connected to #{socket.assigns.provider.name}!") |> push_navigate(to: ~p"/admin/settings")} - {:error, %Ecto.Changeset{} = changeset} -> - {:noreply, assign(socket, form: to_form(changeset))} + {:error, _reason} -> + {:noreply, put_flash(socket, :error, "Could not connect — check your API key")} end end @@ -115,32 +110,6 @@ defmodule BerrypodWeb.Admin.Providers.Form do end end - # Printify returns shop_id, Printful returns store_id - defp maybe_add_config(params, "printify", {:ok, %{shop_id: shop_id}}) do - config = Map.get(params, "config", %{}) |> Map.put("shop_id", to_string(shop_id)) - Map.put(params, "config", config) - end - - defp maybe_add_config(params, "printful", {:ok, %{store_id: store_id}}) do - config = Map.get(params, "config", %{}) |> Map.put("store_id", to_string(store_id)) - Map.put(params, "config", config) - end - - defp maybe_add_config(params, _type, _result), do: params - - defp maybe_add_name(params, "printify", {:ok, %{shop_name: name}}) when is_binary(name) do - Map.put_new(params, "name", name) - end - - defp maybe_add_name(params, "printful", {:ok, %{store_name: name}}) when is_binary(name) do - Map.put_new(params, "name", name) - end - - defp maybe_add_name(params, type, _result) do - provider = Provider.get(type) - Map.put_new(params, "name", (provider && provider.name) || type) - end - defp encrypt_api_key(api_key) do case Berrypod.Vault.encrypt(api_key) do {:ok, encrypted} -> encrypted diff --git a/lib/berrypod_web/live/setup/onboarding.ex b/lib/berrypod_web/live/setup/onboarding.ex index 08836c0..2309f87 100644 --- a/lib/berrypod_web/live/setup/onboarding.ex +++ b/lib/berrypod_web/live/setup/onboarding.ex @@ -127,17 +127,8 @@ defmodule BerrypodWeb.Setup.Onboarding do else socket = assign(socket, provider_connecting: true) - name = - case Provider.get(type) do - nil -> type - info -> info.name - end - - params = %{"api_key" => api_key, "provider_type" => type, "name" => name} - - case Products.create_provider_connection(params) do + case Products.connect_provider(api_key, type) do {:ok, connection} -> - Products.enqueue_sync(connection) setup = Setup.setup_status() if setup.setup_complete do @@ -154,11 +145,17 @@ defmodule BerrypodWeb.Setup.Onboarding do |> put_flash(:info, "Connected! Product sync started in the background.")} end - {:error, _changeset} -> + {:error, :no_api_key} -> {:noreply, socket |> assign(:provider_connecting, false) - |> put_flash(:error, "Failed to save connection")} + |> put_flash(:error, "Please enter your API token")} + + {:error, _reason} -> + {:noreply, + socket + |> assign(:provider_connecting, false) + |> put_flash(:error, "Could not connect — check your API key and try again")} end end end @@ -448,7 +445,13 @@ defmodule BerrypodWeb.Setup.Onboarding do # ── Helpers ── defp account_summary(%{current_scope: %{user: user}}) when not is_nil(user) do - user.email + site_name = Settings.site_name() + + if site_name != "Store Name" do + "#{site_name} · #{user.email}" + else + user.email + end end defp account_summary(_), do: "Account created" diff --git a/test/berrypod_web/live/admin/products_test.exs b/test/berrypod_web/live/admin/products_test.exs index 48c5554..997f5cc 100644 --- a/test/berrypod_web/live/admin/products_test.exs +++ b/test/berrypod_web/live/admin/products_test.exs @@ -125,7 +125,7 @@ defmodule BerrypodWeb.Admin.ProductsTest do {:ok, _view, html} = live(conn, ~p"/admin/products") assert html =~ "No products yet" - assert html =~ "Connect a provider" + assert html =~ "providers page" end end diff --git a/test/berrypod_web/live/admin/providers_test.exs b/test/berrypod_web/live/admin/providers_test.exs index b18631a..cd77d46 100644 --- a/test/berrypod_web/live/admin/providers_test.exs +++ b/test/berrypod_web/live/admin/providers_test.exs @@ -136,6 +136,12 @@ defmodule BerrypodWeb.Admin.ProvidersTest do describe "form - new" do setup %{conn: conn, user: user} do + Application.put_env(:berrypod, :provider_modules, %{ + "printify" => MockProvider + }) + + on_exit(fn -> Application.delete_env(:berrypod, :provider_modules) end) + %{conn: log_in_user(conn, user)} end @@ -170,6 +176,10 @@ defmodule BerrypodWeb.Admin.ProvidersTest do end test "saves new connection", %{conn: conn} do + expect(MockProvider, :test_connection, fn _conn -> + {:ok, %{shop_name: "My Printify Shop", shop_id: 12345}} + end) + {:ok, view, _html} = live(conn, ~p"/admin/providers/new") {:ok, _view, html} =