From db28cb8d9f1b52b25dce0152992b1f6d7a52d3cc Mon Sep 17 00:00:00 2001 From: jamey Date: Sun, 8 Mar 2026 07:34:17 +0000 Subject: [PATCH] migrate remaining admin pages to inline feedback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace put_flash with inline feedback for form saves: - Media library: metadata save shows "Saved" checkmark - Product show: storefront controls save shows "Saved" checkmark - Newsletter campaign form: draft save shows "Saved" checkmark Page-level outcomes (uploads, deletes, async operations) remain as flash/banner messages — these are the correct pattern for non-form actions. Completes Task 4 of notification overhaul. Co-Authored-By: Claude Opus 4.5 --- PROGRESS.md | 2 +- lib/berrypod_web/live/admin/media.ex | 17 +++++++++++------ .../live/admin/newsletter/campaign_form.ex | 10 ++++++---- lib/berrypod_web/live/admin/product_show.ex | 8 +++++--- 4 files changed, 23 insertions(+), 14 deletions(-) diff --git a/PROGRESS.md b/PROGRESS.md index 9c457b3..7698945 100644 --- a/PROGRESS.md +++ b/PROGRESS.md @@ -76,7 +76,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 | 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 | done | | 5 | Migrate shop pages (cart, contact, checkout, auth) | 2h | planned | | 6 | Migrate setup wizard notifications | 1h | planned | | 7 | Remove old flash/toast CSS and JS | 30m | planned | diff --git a/lib/berrypod_web/live/admin/media.ex b/lib/berrypod_web/live/admin/media.ex index 230289d..170bb8c 100644 --- a/lib/berrypod_web/live/admin/media.ex +++ b/lib/berrypod_web/live/admin/media.ex @@ -17,6 +17,7 @@ defmodule BerrypodWeb.Admin.Media do |> assign(:edit_form, nil) |> assign(:upload_alt, "") |> assign(:confirm_delete, false) + |> assign(:metadata_status, :idle) |> allow_upload(:media_upload, accept: ~w(.png .jpg .jpeg .webp .svg .gif), max_entries: 1, @@ -114,7 +115,8 @@ defmodule BerrypodWeb.Admin.Media do |> assign(:selected_image, Map.put(image, :data, nil)) |> assign(:selected_usages, usages) |> assign(:edit_form, form) - |> assign(:confirm_delete, false)} + |> assign(:confirm_delete, false) + |> assign(:metadata_status, :idle)} else {:noreply, socket} end @@ -141,10 +143,10 @@ defmodule BerrypodWeb.Admin.Media do socket |> stream_insert(:images, updated_no_blob) |> assign(:selected_image, updated_no_blob) - |> put_flash(:info, "Metadata updated")} + |> assign(:metadata_status, :saved)} {:error, _changeset} -> - {:noreply, put_flash(socket, :error, "Failed to update metadata")} + {:noreply, assign(socket, :metadata_status, :error)} end end @@ -398,9 +400,12 @@ defmodule BerrypodWeb.Admin.Media do <.input field={@edit_form[:alt]} label="Alt text" placeholder="Describe this image..." /> <.input field={@edit_form[:caption]} label="Caption" placeholder="Optional caption..." /> <.input field={@edit_form[:tags]} label="Tags" placeholder="hero, homepage, banner..." /> - +
+ + <.inline_feedback status={@metadata_status} /> +
<%= if @selected_usages != [] do %> diff --git a/lib/berrypod_web/live/admin/newsletter/campaign_form.ex b/lib/berrypod_web/live/admin/newsletter/campaign_form.ex index 2af9018..96d5fe9 100644 --- a/lib/berrypod_web/live/admin/newsletter/campaign_form.ex +++ b/lib/berrypod_web/live/admin/newsletter/campaign_form.ex @@ -10,7 +10,8 @@ defmodule BerrypodWeb.Admin.Newsletter.CampaignForm do |> assign(:page_title, "New campaign") |> assign(:campaign, nil) |> assign(:subscriber_count, Newsletter.confirmed_subscriber_count()) - |> assign(:form, to_form(%{"subject" => "", "body" => ""}, as: :campaign))} + |> assign(:form, to_form(%{"subject" => "", "body" => ""}, as: :campaign)) + |> assign(:save_status, :idle)} end @impl true @@ -42,7 +43,7 @@ defmodule BerrypodWeb.Admin.Newsletter.CampaignForm do @impl true def handle_event("validate", %{"campaign" => params}, socket) do - {:noreply, assign(socket, :form, to_form(params, as: :campaign))} + {:noreply, assign(socket, form: to_form(params, as: :campaign), save_status: :idle)} end def handle_event("save_draft", %{"campaign" => params}, socket) do @@ -51,10 +52,10 @@ defmodule BerrypodWeb.Admin.Newsletter.CampaignForm do {:noreply, socket |> assign(:campaign, campaign) - |> put_flash(:info, "Campaign saved")} + |> assign(:save_status, :saved)} {:error, _changeset} -> - {:noreply, put_flash(socket, :error, "Please fill in subject and body")} + {:noreply, assign(socket, :save_status, :error)} end end @@ -211,6 +212,7 @@ defmodule BerrypodWeb.Admin.Newsletter.CampaignForm do <.button type="submit"> Save draft + <.inline_feedback status={@save_status} />