From f21277cf4faf5647893b8c56485e3373ba487cdb Mon Sep 17 00:00:00 2001 From: Graham McIntire Date: Thu, 9 Apr 2026 13:46:27 -0500 Subject: [PATCH] Show upload progress and submission confirmation on /submit Add a per-entry progress bar (with cancel) while a CSV streams in, and replace the small post-commit alert with a prominent "X contacts submitted" confirmation card. --- lib/microwaveprop_web/live/submit_live.ex | 96 ++++++++++++++----- .../live/submit_live_test.exs | 2 +- 2 files changed, 71 insertions(+), 27 deletions(-) diff --git a/lib/microwaveprop_web/live/submit_live.ex b/lib/microwaveprop_web/live/submit_live.ex index 6d566046..3ae3c778 100644 --- a/lib/microwaveprop_web/live/submit_live.ex +++ b/lib/microwaveprop_web/live/submit_live.ex @@ -109,6 +109,10 @@ defmodule MicrowavepropWeb.SubmitLive do end end + def handle_event("cancel_csv_upload", %{"ref" => ref}, socket) do + {:noreply, cancel_upload(socket, :csv, ref)} + end + def handle_event("confirm_csv", _params, socket) do case socket.assigns.csv_preview do %{valid: valid_rows} when valid_rows != [] -> @@ -117,7 +121,7 @@ defmodule MicrowavepropWeb.SubmitLive do {:noreply, socket |> assign(csv_preview: nil, csv_result: commit_result) - |> put_flash(:info, "Imported #{length(commit_result.imported)} contacts.")} + |> put_flash(:info, "#{length(commit_result.imported)} contacts submitted.")} _ -> {:noreply, put_flash(socket, :error, "Nothing to import.")} @@ -164,6 +168,11 @@ defmodule MicrowavepropWeb.SubmitLive do end end + defp error_to_string(:too_large), do: "File is too large" + defp error_to_string(:too_many_files), do: "Only one file allowed" + defp error_to_string(:not_accepted), do: "Only .csv files are accepted" + defp error_to_string(other), do: to_string(other) + @impl true def render(assigns) do ~H""" @@ -348,6 +357,37 @@ defmodule MicrowavepropWeb.SubmitLive do +
+
+ {entry.client_name} + + {entry.progress}% + + +
+ + +
+ {error_to_string(err)} +
+
+ +
+ {error_to_string(err)} +
+ <%= if @current_user do %> <% else %> @@ -559,24 +599,32 @@ defmodule MicrowavepropWeb.SubmitLive do defp duplicate_source(_), do: "Duplicate" defp csv_results(assigns) do - ~H""" -
- <%= if length(@result.imported) > 0 do %> -
- <.icon name="hero-check-circle" class="w-5 h-5" /> - - {length(@result.imported)} {if length(@result.imported) == 1, - do: "contact", - else: "contacts"} imported successfully - -
- <% end %> + assigns = + assign(assigns, + imported_count: length(assigns.result.imported), + error_count: length(assigns.result.errors) + ) - <%= if length(@result.errors) > 0 do %> + ~H""" +
+
0} + class="rounded-box border border-success/40 bg-success/10 p-8 text-center" + > + <.icon name="hero-check-circle" class="w-16 h-16 text-success mx-auto mb-3" /> +
+ {@imported_count} {if @imported_count == 1, do: "contact", else: "contacts"} submitted +
+

+ Weather, terrain, and propagation data will be attached shortly. +

+
+ +
0} class="space-y-2">
<.icon name="hero-exclamation-triangle" class="w-5 h-5" /> - {length(@result.errors)} {if length(@result.errors) == 1, do: "row", else: "rows"} had errors at insert time + {@error_count} {if @error_count == 1, do: "row", else: "rows"} had errors at insert time
@@ -589,20 +637,16 @@ defmodule MicrowavepropWeb.SubmitLive do - <%= for {row_num, messages} <- @result.errors do %> - - Row {row_num} - - <%= for msg <- messages do %> -
{msg}
- <% end %> - - - <% end %> + + Row {row_num} + +
{msg}
+ +
- <% end %> +