add no-JS fallback for provider forms
Progressive enhancement: provider form now works without JavaScript. Forms POST to ProvidersController (create/update), which handles validation and redirects with flash messages. With JS: LiveView phx-submit handles save, navigates with flash. Without JS: Form POSTs to controller, redirects with flash. Completes Task 3 of notification overhaul (admin forms migration). Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
3e29a89fff
commit
0834437340
@ -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)
|
- Fully Tailwind-free CSS (12 KB gzipped shop+theme, 95 KB gzipped admin total)
|
||||||
- CI pipeline (compile warnings, format, credo, dialyzer, tests)
|
- CI pipeline (compile warnings, format, credo, dialyzer, tests)
|
||||||
- Deployed on Fly.io with observability (LiveDashboard, ErrorTracker, structured logging)
|
- 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
|
## 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 |
|
| 1 | Build inline feedback component | 1.5h | done |
|
||||||
| 2 | Build persistent top banner component (replaces flash) | 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 |
|
| 4 | Migrate remaining admin pages (media, products, activity, newsletter, redirects, nav) | 2h | planned |
|
||||||
| 5 | Migrate shop pages (cart, contact, checkout, auth) | 2h | planned |
|
| 5 | Migrate shop pages (cart, contact, checkout, auth) | 2h | planned |
|
||||||
| 6 | Migrate setup wizard notifications | 1h | planned |
|
| 6 | Migrate setup wizard notifications | 1h | planned |
|
||||||
|
|||||||
54
lib/berrypod_web/controllers/providers_controller.ex
Normal file
54
lib/berrypod_web/controllers/providers_controller.ex
Normal file
@ -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
|
||||||
@ -27,7 +27,18 @@
|
|||||||
</div>
|
</div>
|
||||||
<% end %>
|
<% 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 type="hidden" name="provider_connection[provider_type]" value={@provider_type} />
|
<input type="hidden" name="provider_connection[provider_type]" value={@provider_type} />
|
||||||
|
|
||||||
<.input
|
<.input
|
||||||
|
|||||||
@ -144,6 +144,8 @@ defmodule BerrypodWeb.Router do
|
|||||||
post "/settings/from-address", SettingsController, :update_from_address
|
post "/settings/from-address", SettingsController, :update_from_address
|
||||||
post "/settings/stripe/signing-secret", SettingsController, :update_signing_secret
|
post "/settings/stripe/signing-secret", SettingsController, :update_signing_secret
|
||||||
post "/navigation", NavigationController, :save
|
post "/navigation", NavigationController, :save
|
||||||
|
post "/providers", ProvidersController, :create
|
||||||
|
post "/providers/:id", ProvidersController, :update
|
||||||
|
|
||||||
live_session :admin,
|
live_session :admin,
|
||||||
layout: {BerrypodWeb.Layouts, :admin},
|
layout: {BerrypodWeb.Layouts, :admin},
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user