feat: consistent and accessible modal on delete
Some checks failed
continuous-integration/drone/push Build is failing

This commit is contained in:
carla 2026-02-26 11:17:21 +01:00
parent 2922a4d1ee
commit e422e5f4ef
10 changed files with 424 additions and 102 deletions

View file

@ -99,10 +99,18 @@ defmodule MvWeb.CustomFieldLive.IndexComponent do
</.table>
</div>
<%!-- Delete Confirmation Modal --%>
<dialog :if={@show_delete_modal} id="delete-custom-field-modal" class="modal modal-open">
<%!-- Delete Confirmation Modal (WCAG: focus in modal, aria-labelledby) --%>
<dialog
:if={@show_delete_modal}
id="delete-custom-field-modal"
class="modal modal-open"
role="dialog"
aria-labelledby="delete-custom-field-modal-title"
>
<div class="modal-box">
<h3 class="text-lg font-bold">{gettext("Delete Data Field")}</h3>
<h3 id="delete-custom-field-modal-title" class="text-lg font-bold">
{gettext("Delete Data Field")}
</h3>
<div class="py-4 space-y-4">
<div class="alert alert-warning">

View file

@ -368,11 +368,18 @@ defmodule MvWeb.GroupLive.Show do
</section>
<% end %>
<%!-- Delete Confirmation Modal --%>
<%!-- Delete Confirmation Modal (WCAG: focus in modal, aria-labelledby) --%>
<%= if assigns[:show_delete_modal] do %>
<dialog id="delete-group-modal" class="modal modal-open" role="dialog">
<dialog
id="delete-group-modal"
class="modal modal-open"
role="dialog"
aria-labelledby="delete-group-modal-title"
>
<div class="modal-box">
<h3 class="text-lg font-bold mb-4">{gettext("Delete Group")}</h3>
<h3 id="delete-group-modal-title" class="text-lg font-bold mb-4">
{gettext("Delete Group")}
</h3>
<p class="mb-4">
{gettext("Are you sure you want to delete this group? This action cannot be undone.")}
</p>
@ -407,6 +414,7 @@ defmodule MvWeb.GroupLive.Show do
placeholder={gettext("Enter the group name to confirm")}
autocomplete="off"
phx-debounce="200"
phx-mounted={JS.focus()}
class="w-full input input-bordered"
/>
</form>

View file

@ -277,14 +277,7 @@ defmodule MvWeb.MemberLive.Form do
<.button
variant="danger"
type="button"
phx-click="delete"
phx-value-id={@member.id}
data-confirm={
gettext(
"Are you sure you want to delete %{name}? This action cannot be undone.",
name: MvWeb.Helpers.MemberHelpers.display_name(@member)
)
}
phx-click="open_delete_modal"
data-testid="member-delete"
aria-label={
gettext("Delete member %{name}",
@ -298,6 +291,40 @@ defmodule MvWeb.MemberLive.Form do
</div>
</section>
<% end %>
<%!-- Delete Member Confirmation Modal (WCAG: focus in modal, keyboard confirm/cancel) --%>
<%= if @member && assigns[:show_delete_modal] do %>
<dialog id="delete-member-form-modal" class="modal modal-open" role="dialog" aria-labelledby="delete-member-form-modal-title">
<div class="modal-box">
<h3 id="delete-member-form-modal-title" class="text-lg font-bold">{gettext("Delete Member")}</h3>
<p class="py-4">
{gettext("Are you sure you want to delete %{name}? This action cannot be undone.",
name: MvWeb.Helpers.MemberHelpers.display_name(@member)
)}
</p>
<div class="modal-action">
<.button
type="button"
variant="neutral"
phx-click="cancel_delete_modal"
phx-mounted={JS.focus()}
id="delete-member-form-modal-cancel"
aria-label={gettext("Cancel")}
>
{gettext("Cancel")}
</.button>
<.button
type="button"
variant="danger"
phx-click={JS.push("delete", value: %{id: @member.id})}
aria-label={gettext("Delete member")}
>
{gettext("Delete")}
</.button>
</div>
</div>
</dialog>
<% end %>
</div>
</div>
</.form>
@ -348,6 +375,7 @@ defmodule MvWeb.MemberLive.Form do
|> assign(:available_fee_types, available_fee_types)
|> assign(:interval_warning, nil)
|> assign(:member_field_required_map, member_field_required_map)
|> assign_new(:show_delete_modal, fn -> false end)
|> assign_form()}
end
@ -419,6 +447,16 @@ defmodule MvWeb.MemberLive.Form do
end
end
@impl true
def handle_event("open_delete_modal", _params, socket) do
{:noreply, assign(socket, :show_delete_modal, true)}
end
@impl true
def handle_event("cancel_delete_modal", _params, socket) do
{:noreply, assign(socket, :show_delete_modal, false)}
end
@impl true
def handle_event("delete", %{"id" => id}, socket) do
member = socket.assigns.member
@ -426,10 +464,16 @@ defmodule MvWeb.MemberLive.Form do
cond do
is_nil(member) ->
{:noreply, put_flash(socket, :error, gettext("Member not found"))}
{:noreply,
socket
|> put_flash(:error, gettext("Member not found"))
|> assign(:show_delete_modal, false)}
to_string(id) != to_string(member.id) ->
{:noreply, put_flash(socket, :error, gettext("Member not found"))}
{:noreply,
socket
|> put_flash(:error, gettext("Member not found"))
|> assign(:show_delete_modal, false)}
true ->
handle_member_delete_destroy(socket, member, actor)
@ -446,11 +490,16 @@ defmodule MvWeb.MemberLive.Form do
{:error, %Ash.Error.Forbidden{}} ->
{:noreply,
put_flash(socket, :error, gettext("You do not have permission to delete this member"))}
socket
|> put_flash(:error, gettext("You do not have permission to delete this member"))
|> assign(:show_delete_modal, false)}
{:error, error} ->
Logger.warning("Member delete failed: member_id=#{member.id} error=#{inspect(error)}")
{:noreply, put_flash(socket, :error, format_destroy_error(error))}
{:noreply,
socket
|> put_flash(:error, format_destroy_error(error))
|> assign(:show_delete_modal, false)}
end
end

View file

@ -316,13 +316,7 @@ defmodule MvWeb.MemberLive.Show do
</p>
<.button
variant="danger"
phx-click="delete"
phx-value-id={@member.id}
data-confirm={
gettext("Are you sure you want to delete %{name}? This action cannot be undone.",
name: MvWeb.Helpers.MemberHelpers.display_name(@member)
)
}
phx-click="open_delete_modal"
data-testid="member-delete"
aria-label={
gettext("Delete member %{name}",
@ -336,6 +330,40 @@ defmodule MvWeb.MemberLive.Show do
</div>
</section>
<% end %>
<%!-- Delete Member Confirmation Modal (WCAG: focus in modal, keyboard confirm/cancel) --%>
<%= if assigns[:show_delete_modal] do %>
<dialog id="delete-member-modal" class="modal modal-open" role="dialog" aria-labelledby="delete-member-modal-title">
<div class="modal-box">
<h3 id="delete-member-modal-title" class="text-lg font-bold">{gettext("Delete Member")}</h3>
<p class="py-4">
{gettext("Are you sure you want to delete %{name}? This action cannot be undone.",
name: MvWeb.Helpers.MemberHelpers.display_name(@member)
)}
</p>
<div class="modal-action">
<.button
type="button"
variant="neutral"
phx-click="cancel_delete_modal"
phx-mounted={JS.focus()}
id="delete-member-modal-cancel"
aria-label={gettext("Cancel")}
>
{gettext("Cancel")}
</.button>
<.button
type="button"
variant="danger"
phx-click={JS.push("delete", value: %{id: @member.id})}
aria-label={gettext("Delete member")}
>
{gettext("Delete")}
</.button>
</div>
</div>
</dialog>
<% end %>
</div>
</Layouts.app>
"""
@ -346,7 +374,8 @@ defmodule MvWeb.MemberLive.Show do
{:ok,
socket
|> assign(:active_tab, :contact)
|> assign(:vereinfacht_receipts, nil)}
|> assign(:vereinfacht_receipts, nil)
|> assign_new(:show_delete_modal, fn -> false end)}
end
@impl true
@ -398,13 +427,26 @@ defmodule MvWeb.MemberLive.Show do
{:noreply, assign(socket, :active_tab, :membership_fees)}
end
@impl true
def handle_event("open_delete_modal", _params, socket) do
{:noreply, assign(socket, :show_delete_modal, true)}
end
@impl true
def handle_event("cancel_delete_modal", _params, socket) do
{:noreply, assign(socket, :show_delete_modal, false)}
end
@impl true
def handle_event("delete", %{"id" => id}, socket) do
member = socket.assigns.member
actor = current_actor(socket)
if to_string(id) != to_string(member.id) do
{:noreply, put_flash(socket, :error, gettext("Member not found"))}
{:noreply,
socket
|> put_flash(:error, gettext("Member not found"))
|> assign(:show_delete_modal, false)}
else
case Ash.destroy(member, actor: actor) do
:ok ->
@ -415,16 +457,20 @@ defmodule MvWeb.MemberLive.Show do
{:error, %Ash.Error.Forbidden{}} ->
{:noreply,
put_flash(
socket,
socket
|> put_flash(
:error,
gettext("You do not have permission to delete this member")
)}
)
|> assign(:show_delete_modal, false)}
{:error, error} ->
require Logger
Logger.warning("Member delete failed: member_id=#{member.id} error=#{inspect(error)}")
{:noreply, put_flash(socket, :error, format_error(error))}
{:noreply,
socket
|> put_flash(:error, format_error(error))
|> assign(:show_delete_modal, false)}
end
end
end

View file

@ -288,11 +288,18 @@ defmodule MvWeb.MemberLive.Show.MembershipFeesComponent do
<% end %>
</.section_box>
<%!-- Edit Cycle Amount Modal --%>
<%!-- Edit Cycle Amount Modal (WCAG: focus in modal, aria-labelledby) --%>
<%= if @editing_cycle do %>
<dialog id="edit-cycle-amount-modal" class="modal modal-open">
<dialog
id="edit-cycle-amount-modal"
class="modal modal-open"
role="dialog"
aria-labelledby="edit-cycle-amount-modal-title"
>
<div class="modal-box">
<h3 class="text-lg font-bold">{gettext("Edit Cycle Amount")}</h3>
<h3 id="edit-cycle-amount-modal-title" class="text-lg font-bold">
{gettext("Edit Cycle Amount")}
</h3>
<form phx-submit="save_cycle_amount" phx-target={@myself}>
<input type="hidden" name="cycle_id" value={@editing_cycle.id} />
<div class="form-control w-full mt-4">
@ -308,6 +315,7 @@ defmodule MvWeb.MemberLive.Show.MembershipFeesComponent do
value={Decimal.to_string(@editing_cycle.amount) |> String.replace(".", ",")}
class="input input-bordered w-full"
required
phx-mounted={JS.focus()}
/>
</div>
<div class="modal-action">
@ -326,11 +334,16 @@ defmodule MvWeb.MemberLive.Show.MembershipFeesComponent do
</dialog>
<% end %>
<%!-- Delete Cycle Confirmation Modal --%>
<%!-- Delete Cycle Confirmation Modal (WCAG: focus in modal, aria-labelledby) --%>
<%= if @deleting_cycle do %>
<dialog id="delete-cycle-modal" class="modal modal-open">
<dialog
id="delete-cycle-modal"
class="modal modal-open"
role="dialog"
aria-labelledby="delete-cycle-modal-title"
>
<div class="modal-box">
<h3 class="text-lg font-bold">{gettext("Delete Cycle")}</h3>
<h3 id="delete-cycle-modal-title" class="text-lg font-bold">{gettext("Delete Cycle")}</h3>
<p class="py-4">
{gettext("Are you sure you want to delete this cycle?")}
</p>
@ -341,7 +354,12 @@ defmodule MvWeb.MemberLive.Show.MembershipFeesComponent do
)} - {MembershipFeeHelpers.format_currency(@deleting_cycle.amount)}
</p>
<div class="modal-action">
<.button variant="neutral" phx-click="cancel_delete_cycle" phx-target={@myself}>
<.button
variant="neutral"
phx-click="cancel_delete_cycle"
phx-target={@myself}
phx-mounted={JS.focus()}
>
{gettext("Cancel")}
</.button>
<.button
@ -357,11 +375,18 @@ defmodule MvWeb.MemberLive.Show.MembershipFeesComponent do
</dialog>
<% end %>
<%!-- Delete All Cycles Confirmation Modal --%>
<%!-- Delete All Cycles Confirmation Modal (WCAG: focus in modal, aria-labelledby) --%>
<%= if @deleting_all_cycles do %>
<dialog id="delete-all-cycles-modal" class="modal modal-open">
<dialog
id="delete-all-cycles-modal"
class="modal modal-open"
role="dialog"
aria-labelledby="delete-all-cycles-modal-title"
>
<div class="modal-box">
<h3 class="text-lg font-bold text-error">{gettext("Delete All Cycles")}</h3>
<h3 id="delete-all-cycles-modal-title" class="text-lg font-bold text-error">
{gettext("Delete All Cycles")}
</h3>
<div class="alert alert-warning mt-4">
<.icon name="hero-exclamation-triangle" class="size-5" />
<div>
@ -389,6 +414,7 @@ defmodule MvWeb.MemberLive.Show.MembershipFeesComponent do
value={@delete_all_confirmation || ""}
class="input input-bordered w-full"
placeholder={gettext("Yes")}
phx-mounted={JS.focus()}
/>
</div>
<div class="modal-action">
@ -411,11 +437,16 @@ defmodule MvWeb.MemberLive.Show.MembershipFeesComponent do
</dialog>
<% end %>
<%!-- Create Cycle Modal --%>
<%!-- Create Cycle Modal (WCAG: focus in modal, aria-labelledby) --%>
<%= if @creating_cycle do %>
<dialog id="create-cycle-modal" class="modal modal-open">
<dialog
id="create-cycle-modal"
class="modal modal-open"
role="dialog"
aria-labelledby="create-cycle-modal-title"
>
<div class="modal-box">
<h3 class="text-lg font-bold">{gettext("Create Cycle")}</h3>
<h3 id="create-cycle-modal-title" class="text-lg font-bold">{gettext("Create Cycle")}</h3>
<form phx-submit="create_cycle" phx-target={@myself}>
<div class="form-control w-full mt-4">
<label class="label" for="create-cycle-date">
@ -431,6 +462,7 @@ defmodule MvWeb.MemberLive.Show.MembershipFeesComponent do
class="input input-bordered w-full"
required
aria-label={gettext("Date")}
phx-mounted={JS.focus()}
/>
<label class="label">
<span class="label-text-alt">

View file

@ -35,7 +35,8 @@ defmodule MvWeb.RoleLive.Show do
socket
|> assign(:page_title, gettext("Show Role"))
|> assign(:role, role)
|> assign(:user_count, user_count)}
|> assign(:user_count, user_count)
|> assign(:show_delete_modal, false)}
{:error, %Ash.Error.Invalid{errors: [%Ash.Error.Query.NotFound{} | _]}} ->
{:ok,
@ -84,35 +85,45 @@ defmodule MvWeb.RoleLive.Show do
error_message = format_error(error)
{:noreply,
put_flash(
socket,
socket
|> put_flash(
:error,
gettext("Failed to delete role: %{error}", error: error_message)
)}
)
|> assign(:show_delete_modal, false)}
end
end
@impl true
def handle_event("open_delete_modal", _params, socket) do
{:noreply, assign(socket, :show_delete_modal, true)}
end
@impl true
def handle_event("cancel_delete_modal", _params, socket) do
{:noreply, assign(socket, :show_delete_modal, false)}
end
defp handle_delete_role(role, socket) do
if role.is_system_role do
{:noreply,
put_flash(
socket,
:error,
gettext("System roles cannot be deleted.")
)}
socket
|> put_flash(:error, gettext("System roles cannot be deleted."))
|> assign(:show_delete_modal, false)}
else
user_count = recalculate_user_count(role, socket.assigns.current_user)
if user_count > 0 do
{:noreply,
put_flash(
socket,
socket
|> put_flash(
:error,
gettext(
"Cannot delete role. %{count} user(s) are still assigned to this role. Please assign them to another role first.",
count: user_count
)
)}
)
|> assign(:show_delete_modal, false)}
else
perform_role_deletion(role, socket)
end
@ -225,13 +236,7 @@ defmodule MvWeb.RoleLive.Show do
</p>
<.button
variant="danger"
phx-click={JS.push("delete", value: %{id: @role.id})}
data-confirm={
gettext(
"Are you sure you want to delete the role %{name}? This action cannot be undone.",
name: @role.name
)
}
phx-click="open_delete_modal"
data-testid="role-delete"
aria-label={gettext("Delete role %{name}", name: @role.name)}
>
@ -241,6 +246,46 @@ defmodule MvWeb.RoleLive.Show do
</div>
</section>
<% end %>
<%!-- Delete Role Confirmation Modal (WCAG: focus moves into modal, keyboard confirm/cancel) --%>
<%= if assigns[:show_delete_modal] do %>
<dialog
id="delete-role-modal"
class="modal modal-open"
role="dialog"
aria-labelledby="delete-role-modal-title"
>
<div class="modal-box">
<h3 id="delete-role-modal-title" class="text-lg font-bold">{gettext("Delete Role")}</h3>
<p class="py-4">
{gettext(
"Are you sure you want to delete the role %{name}? This action cannot be undone.",
name: @role.name
)}
</p>
<div class="modal-action">
<.button
type="button"
variant="neutral"
phx-click="cancel_delete_modal"
phx-mounted={JS.focus()}
id="delete-role-modal-cancel"
aria-label={gettext("Cancel")}
>
{gettext("Cancel")}
</.button>
<.button
type="button"
variant="danger"
phx-click={JS.push("delete", value: %{id: @role.id})}
aria-label={gettext("Delete role")}
>
{gettext("Delete")}
</.button>
</div>
</div>
</dialog>
<% end %>
</Layouts.app>
"""
end

View file

@ -313,14 +313,7 @@ defmodule MvWeb.UserLive.Form do
<.button
type="button"
variant="danger"
phx-click="delete"
phx-value-id={@user.id}
data-confirm={
gettext(
"Are you sure you want to delete the user %{email}? This action cannot be undone.",
email: @user.email
)
}
phx-click="open_delete_modal"
data-testid="user-delete"
aria-label={gettext("Delete user %{email}", email: @user.email)}
>
@ -331,6 +324,40 @@ defmodule MvWeb.UserLive.Form do
</section>
<% end %>
<%!-- Delete User Confirmation Modal (WCAG: focus in modal, keyboard confirm/cancel) --%>
<%= if @user && assigns[:show_delete_modal] do %>
<dialog id="delete-user-form-modal" class="modal modal-open" role="dialog" aria-labelledby="delete-user-form-modal-title">
<div class="modal-box">
<h3 id="delete-user-form-modal-title" class="text-lg font-bold">{gettext("Delete User")}</h3>
<p class="py-4">
{gettext("Are you sure you want to delete the user %{email}? This action cannot be undone.",
email: @user.email
)}
</p>
<div class="modal-action">
<.button
type="button"
variant="neutral"
phx-click="cancel_delete_modal"
phx-mounted={JS.focus()}
id="delete-user-form-modal-cancel"
aria-label={gettext("Cancel")}
>
{gettext("Cancel")}
</.button>
<.button
type="button"
variant="danger"
phx-click={JS.push("delete", value: %{id: @user.id})}
aria-label={gettext("Delete user")}
>
{gettext("Delete")}
</.button>
</div>
</div>
</dialog>
<% end %>
<div class="mt-4">
<.button navigate={return_path(@return_to, @user)} variant="neutral">
{gettext("Cancel")}
@ -399,6 +426,7 @@ defmodule MvWeb.UserLive.Form do
|> assign(:selected_member_name, nil)
|> assign(:unlink_member, false)
|> assign(:focused_member_index, nil)
|> assign_new(:show_delete_modal, fn -> false end)
|> load_initial_members()
|> assign_form()}
end
@ -454,6 +482,17 @@ defmodule MvWeb.UserLive.Form do
end
end
@impl true
@impl true
def handle_event("open_delete_modal", _params, socket) do
{:noreply, assign(socket, :show_delete_modal, true)}
end
@impl true
def handle_event("cancel_delete_modal", _params, socket) do
{:noreply, assign(socket, :show_delete_modal, false)}
end
@impl true
def handle_event("delete", %{"id" => id}, socket) do
user = socket.assigns.user
@ -461,13 +500,22 @@ defmodule MvWeb.UserLive.Form do
cond do
is_nil(user) ->
{:noreply, put_flash(socket, :error, gettext("User not found"))}
{:noreply,
socket
|> put_flash(:error, gettext("User not found"))
|> assign(:show_delete_modal, false)}
to_string(id) != to_string(user.id) ->
{:noreply, put_flash(socket, :error, gettext("User not found"))}
{:noreply,
socket
|> put_flash(:error, gettext("User not found"))
|> assign(:show_delete_modal, false)}
Mv.Helpers.SystemActor.system_user?(user) ->
{:noreply, put_flash(socket, :error, gettext("System user cannot be deleted."))}
{:noreply,
socket
|> put_flash(:error, gettext("System user cannot be deleted."))
|> assign(:show_delete_modal, false)}
true ->
handle_user_delete_destroy(socket, user, actor)
@ -594,10 +642,15 @@ defmodule MvWeb.UserLive.Form do
{:error, %Ash.Error.Forbidden{}} ->
{:noreply,
put_flash(socket, :error, gettext("You do not have permission to delete this user"))}
socket
|> put_flash(:error, gettext("You do not have permission to delete this user"))
|> assign(:show_delete_modal, false)}
{:error, error} ->
{:noreply, put_flash(socket, :error, format_ash_error(error))}
{:noreply,
socket
|> put_flash(:error, format_ash_error(error))
|> assign(:show_delete_modal, false)}
end
end

View file

@ -102,14 +102,7 @@ defmodule MvWeb.UserLive.Show do
</p>
<.button
variant="danger"
phx-click="delete"
phx-value-id={@user.id}
data-confirm={
gettext(
"Are you sure you want to delete the user %{email}? This action cannot be undone.",
email: @user.email
)
}
phx-click="open_delete_modal"
data-testid="user-delete"
aria-label={gettext("Delete user %{email}", email: @user.email)}
>
@ -119,6 +112,40 @@ defmodule MvWeb.UserLive.Show do
</div>
</section>
<% end %>
<%!-- Delete User Confirmation Modal (WCAG: focus in modal, keyboard confirm/cancel) --%>
<%= if assigns[:show_delete_modal] do %>
<dialog id="delete-user-modal" class="modal modal-open" role="dialog" aria-labelledby="delete-user-modal-title">
<div class="modal-box">
<h3 id="delete-user-modal-title" class="text-lg font-bold">{gettext("Delete User")}</h3>
<p class="py-4">
{gettext("Are you sure you want to delete the user %{email}? This action cannot be undone.",
email: @user.email
)}
</p>
<div class="modal-action">
<.button
type="button"
variant="neutral"
phx-click="cancel_delete_modal"
phx-mounted={JS.focus()}
id="delete-user-modal-cancel"
aria-label={gettext("Cancel")}
>
{gettext("Cancel")}
</.button>
<.button
type="button"
variant="danger"
phx-click={JS.push("delete", value: %{id: @user.id})}
aria-label={gettext("Delete user")}
>
{gettext("Delete")}
</.button>
</div>
</div>
</dialog>
<% end %>
</Layouts.app>
"""
end
@ -139,10 +166,21 @@ defmodule MvWeb.UserLive.Show do
{:ok,
socket
|> assign(:page_title, gettext("Show User"))
|> assign(:user, user)}
|> assign(:user, user)
|> assign(:show_delete_modal, false)}
end
end
@impl true
def handle_event("open_delete_modal", _params, socket) do
{:noreply, assign(socket, :show_delete_modal, true)}
end
@impl true
def handle_event("cancel_delete_modal", _params, socket) do
{:noreply, assign(socket, :show_delete_modal, false)}
end
@impl true
def handle_event("delete", %{"id" => id}, socket) do
user = socket.assigns.user
@ -150,10 +188,16 @@ defmodule MvWeb.UserLive.Show do
cond do
to_string(id) != to_string(user.id) ->
{:noreply, put_flash(socket, :error, gettext("User not found"))}
{:noreply,
socket
|> put_flash(:error, gettext("User not found"))
|> assign(:show_delete_modal, false)}
Mv.Helpers.SystemActor.system_user?(user) ->
{:noreply, put_flash(socket, :error, gettext("System user cannot be deleted."))}
{:noreply,
socket
|> put_flash(:error, gettext("System user cannot be deleted."))
|> assign(:show_delete_modal, false)}
true ->
handle_user_delete_destroy(socket, user, actor)
@ -170,10 +214,15 @@ defmodule MvWeb.UserLive.Show do
{:error, %Ash.Error.Forbidden{}} ->
{:noreply,
put_flash(socket, :error, gettext("You do not have permission to delete this user"))}
socket
|> put_flash(:error, gettext("You do not have permission to delete this user"))
|> assign(:show_delete_modal, false)}
{:error, error} ->
{:noreply, put_flash(socket, :error, format_ash_error(error))}
{:noreply,
socket
|> put_flash(:error, format_ash_error(error))
|> assign(:show_delete_modal, false)}
end
end
end