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} =