diff --git a/PROGRESS.md b/PROGRESS.md index 230e94a..9c457b3 100644 --- a/PROGRESS.md +++ b/PROGRESS.md @@ -29,7 +29,7 @@ Tier 1 MVP complete. Tier 2 production readiness complete (except Litestream and - Fully Tailwind-free CSS (12 KB gzipped shop+theme, 95 KB gzipped admin total) - CI pipeline (compile warnings, format, credo, dialyzer, tests) - Deployed on Fly.io with observability (LiveDashboard, ErrorTracker, structured logging) -- 1716+ tests passing, 99-100 PageSpeed mobile +- 1759+ tests passing, 99-100 PageSpeed mobile ## Next up @@ -75,7 +75,7 @@ Replace floating toast/flash messages with inline feedback and persistent top ba |---|------|-----|--------| | 1 | Build inline feedback component | 1.5h | done | | 2 | Build persistent top banner component (replaces flash) | 1.5h | done | -| 3 | Migrate admin forms to inline feedback (theme, pages, settings, email, providers) | 3h | in progress | +| 3 | Migrate admin forms to inline feedback (theme, pages, settings, email, providers) | 3h | done | | 4 | Migrate remaining admin pages (media, products, activity, newsletter, redirects, nav) | 2h | planned | | 5 | Migrate shop pages (cart, contact, checkout, auth) | 2h | planned | | 6 | Migrate setup wizard notifications | 1h | planned | diff --git a/lib/berrypod_web/controllers/providers_controller.ex b/lib/berrypod_web/controllers/providers_controller.ex new file mode 100644 index 0000000..75fd508 --- /dev/null +++ b/lib/berrypod_web/controllers/providers_controller.ex @@ -0,0 +1,54 @@ +defmodule BerrypodWeb.ProvidersController do + @moduledoc """ + No-JS fallback for provider connection forms. + + With JS enabled, the LiveView handles everything. Without JS, + the form POSTs here and we redirect back to the settings page. + """ + use BerrypodWeb, :controller + + alias Berrypod.{KeyValidation, Products} + alias Berrypod.Providers.Provider + + def create(conn, %{"provider_connection" => params}) do + api_key = params["api_key"] + provider_type = params["provider_type"] + provider = Provider.get(provider_type) + + case KeyValidation.validate_provider_key(api_key, provider_type) do + {:error, message} -> + conn + |> put_flash(:error, message) + |> redirect(to: ~p"/admin/providers/new?type=#{provider_type}") + + {:ok, api_key} -> + case Products.connect_provider(api_key, provider_type) do + {:ok, _connection} -> + conn + |> put_flash(:info, "Connected to #{provider.name}!") + |> redirect(to: ~p"/admin/settings") + + {:error, _reason} -> + conn + |> put_flash(:error, "Could not connect. Check your API key and try again") + |> redirect(to: ~p"/admin/providers/new?type=#{provider_type}") + end + end + end + + def update(conn, %{"id" => id, "provider_connection" => params}) do + connection = Products.get_provider_connection!(id) + + case Products.update_provider_connection(connection, params) do + {:ok, _connection} -> + conn + |> put_flash(:info, "Settings saved") + |> redirect(to: ~p"/admin/settings") + + {:error, _changeset} -> + conn + |> put_flash(:error, "Could not save settings") + |> redirect(to: ~p"/admin/providers/#{id}/edit") + end + end +end diff --git a/lib/berrypod_web/live/admin/providers/form.html.heex b/lib/berrypod_web/live/admin/providers/form.html.heex index fe7398c..d796664 100644 --- a/lib/berrypod_web/live/admin/providers/form.html.heex +++ b/lib/berrypod_web/live/admin/providers/form.html.heex @@ -27,7 +27,18 @@ <% end %> - <.form for={@form} id="provider-form" phx-change="validate" phx-submit="save"> + <.form + for={@form} + id="provider-form" + action={ + if @live_action == :new, + do: ~p"/admin/providers", + else: ~p"/admin/providers/#{@connection.id}" + } + method="post" + phx-change="validate" + phx-submit="save" + > <.input diff --git a/lib/berrypod_web/router.ex b/lib/berrypod_web/router.ex index 7347e6d..07fde17 100644 --- a/lib/berrypod_web/router.ex +++ b/lib/berrypod_web/router.ex @@ -144,6 +144,8 @@ defmodule BerrypodWeb.Router do post "/settings/from-address", SettingsController, :update_from_address post "/settings/stripe/signing-secret", SettingsController, :update_signing_secret post "/navigation", NavigationController, :save + post "/providers", ProvidersController, :create + post "/providers/:id", ProvidersController, :update live_session :admin, layout: {BerrypodWeb.Layouts, :admin},