refactor(membership-fees): share fee-type delete handling between LiveViews

This commit is contained in:
Moritz 2026-06-16 15:30:56 +02:00 committed by moritz
parent 18bf4dab2b
commit 3f073d4365
4 changed files with 74 additions and 105 deletions

View file

@ -9,8 +9,10 @@ defmodule MvWeb.Helpers.MembershipFeeHelpers do
use Gettext, backend: MvWeb.Gettext
alias Mv.Membership.Member
alias Mv.MembershipFees
alias Mv.MembershipFees.CalendarCycles
alias Mv.MembershipFees.MembershipFeeCycle
alias Mv.MembershipFees.MembershipFeeType
alias MvWeb.Helpers.DateFormatter
@doc """
@ -249,4 +251,69 @@ defmodule MvWeb.Helpers.MembershipFeeHelpers do
def status_icon(:paid), do: "hero-check-circle"
def status_icon(:unpaid), do: "hero-x-circle"
def status_icon(:suspended), do: "hero-pause-circle"
@doc """
Handles a membership-fee-type "delete" event for the fee-type list and the
fee-settings LiveViews.
Loads the fee type, attempts to destroy it, and returns the updated socket
with the matching flash. On success the deleted type and its member count are
dropped from the `:membership_fee_types` and `:member_counts` assigns. The
NotFound, Forbidden (delete and access), and generic error branches preserve
the exact messages both views used before they shared this block.
"""
@spec delete_fee_type(Phoenix.LiveView.Socket.t(), String.t(), term()) ::
{:noreply, Phoenix.LiveView.Socket.t()}
def delete_fee_type(socket, id, actor) do
case Ash.get(MembershipFeeType, id, domain: MembershipFees, actor: actor) do
{:ok, fee_type} ->
destroy_fee_type(socket, fee_type, id, actor)
{:error, %Ash.Error.Query.NotFound{}} ->
{:noreply,
Phoenix.LiveView.put_flash(socket, :error, gettext("Membership fee type not found"))}
{:error, %Ash.Error.Forbidden{}} ->
{:noreply,
Phoenix.LiveView.put_flash(
socket,
:error,
gettext("You do not have permission to access this membership fee type")
)}
{:error, error} ->
{:noreply, Phoenix.LiveView.put_flash(socket, :error, fee_error_message(error))}
end
end
defp destroy_fee_type(socket, fee_type, id, actor) do
case Ash.destroy(fee_type, domain: MembershipFees, actor: actor) do
:ok ->
updated_types = Enum.reject(socket.assigns.membership_fee_types, &(&1.id == id))
updated_counts = Map.delete(socket.assigns.member_counts, id)
{:noreply,
socket
|> Phoenix.Component.assign(:membership_fee_types, updated_types)
|> Phoenix.Component.assign(:member_counts, updated_counts)
|> Phoenix.LiveView.put_flash(:success, gettext("Membership fee type deleted"))}
{:error, %Ash.Error.Forbidden{}} ->
{:noreply,
Phoenix.LiveView.put_flash(
socket,
:error,
gettext("You do not have permission to delete this membership fee type")
)}
{:error, error} ->
{:noreply, Phoenix.LiveView.put_flash(socket, :error, fee_error_message(error))}
end
end
defp fee_error_message(%Ash.Error.Invalid{} = error) do
Enum.map_join(error.errors, ", ", fn e -> e.message end)
end
defp fee_error_message(_error), do: gettext("An error occurred")
end

View file

@ -15,7 +15,6 @@ defmodule MvWeb.MembershipFeeSettingsLive do
alias Mv.Membership
alias Mv.Membership.Member
alias Mv.MembershipFees
alias Mv.MembershipFees.MembershipFeeType
alias MvWeb.Helpers.MembershipFeeHelpers
@ -92,47 +91,7 @@ defmodule MvWeb.MembershipFeeSettingsLive do
@impl true
def handle_event("delete", %{"id" => id}, socket) do
actor = current_actor(socket)
case Ash.get(MembershipFeeType, id, domain: MembershipFees, actor: actor) do
{:ok, fee_type} ->
case Ash.destroy(fee_type, domain: MembershipFees, actor: actor) do
:ok ->
updated_types = Enum.reject(socket.assigns.membership_fee_types, &(&1.id == id))
updated_counts = Map.delete(socket.assigns.member_counts, id)
{:noreply,
socket
|> assign(:membership_fee_types, updated_types)
|> assign(:member_counts, updated_counts)
|> put_flash(:success, gettext("Membership fee type deleted"))}
{:error, %Ash.Error.Forbidden{}} ->
{:noreply,
put_flash(
socket,
:error,
gettext("You do not have permission to delete this membership fee type")
)}
{:error, error} ->
{:noreply, put_flash(socket, :error, format_error(error))}
end
{:error, %Ash.Error.Query.NotFound{}} ->
{:noreply, put_flash(socket, :error, gettext("Membership fee type not found"))}
{:error, %Ash.Error.Forbidden{}} ->
{:noreply,
put_flash(
socket,
:error,
gettext("You do not have permission to access this membership fee type")
)}
{:error, error} ->
{:noreply, put_flash(socket, :error, format_error(error))}
end
MembershipFeeHelpers.delete_fee_type(socket, id, current_actor(socket))
end
@impl true
@ -465,12 +424,6 @@ defmodule MvWeb.MembershipFeeSettingsLive do
Map.get(member_counts, fee_type.id, 0)
end
defp format_error(%Ash.Error.Invalid{} = error) do
Enum.map_join(error.errors, ", ", fn e -> e.message end)
end
defp format_error(_error), do: gettext("An error occurred")
defp assign_form(%{assigns: %{settings: settings}} = socket) do
form =
AshPhoenix.Form.for_update(

View file

@ -141,47 +141,7 @@ defmodule MvWeb.MembershipFeeTypeLive.Index do
@impl true
def handle_event("delete", %{"id" => id}, socket) do
actor = current_actor(socket)
case Ash.get(MembershipFeeType, id, domain: MembershipFees, actor: actor) do
{:ok, fee_type} ->
case Ash.destroy(fee_type, domain: MembershipFees, actor: actor) do
:ok ->
updated_types = Enum.reject(socket.assigns.membership_fee_types, &(&1.id == id))
updated_counts = Map.delete(socket.assigns.member_counts, id)
{:noreply,
socket
|> assign(:membership_fee_types, updated_types)
|> assign(:member_counts, updated_counts)
|> put_flash(:success, gettext("Membership fee type deleted"))}
{:error, %Ash.Error.Forbidden{}} ->
{:noreply,
put_flash(
socket,
:error,
gettext("You do not have permission to delete this membership fee type")
)}
{:error, error} ->
{:noreply, put_flash(socket, :error, format_error(error))}
end
{:error, %Ash.Error.Query.NotFound{}} ->
{:noreply, put_flash(socket, :error, gettext("Membership fee type not found"))}
{:error, %Ash.Error.Forbidden{} = _error} ->
{:noreply,
put_flash(
socket,
:error,
gettext("You do not have permission to access this membership fee type")
)}
{:error, error} ->
{:noreply, put_flash(socket, :error, format_error(error))}
end
MembershipFeeHelpers.delete_fee_type(socket, id, current_actor(socket))
end
# Helper functions
@ -215,12 +175,6 @@ defmodule MvWeb.MembershipFeeTypeLive.Index do
Map.get(member_counts, fee_type.id, 0)
end
defp format_error(%Ash.Error.Invalid{} = error) do
Enum.map_join(error.errors, ", ", fn e -> e.message end)
end
defp format_error(_error), do: gettext("An error occurred")
# Info card explaining the membership fee type concept
defp info_card(assigns) do
~H"""

View file

@ -193,8 +193,7 @@ msgid "An account with this email already exists. Please verify your password to
msgstr ""
#: lib/mv_web/helpers/ash_error_helpers.ex
#: lib/mv_web/live/membership_fee_settings_live.ex
#: lib/mv_web/live/membership_fee_type_live/index.ex
#: lib/mv_web/helpers/membership_fee_helpers.ex
#: lib/mv_web/live/role_live/helpers.ex
#, elixir-autogen, elixir-format
msgid "An error occurred"
@ -2289,14 +2288,12 @@ msgstr ""
msgid "Membership fee start"
msgstr ""
#: lib/mv_web/live/membership_fee_settings_live.ex
#: lib/mv_web/live/membership_fee_type_live/index.ex
#: lib/mv_web/helpers/membership_fee_helpers.ex
#, elixir-autogen, elixir-format
msgid "Membership fee type deleted"
msgstr ""
#: lib/mv_web/live/membership_fee_settings_live.ex
#: lib/mv_web/live/membership_fee_type_live/index.ex
#: lib/mv_web/helpers/membership_fee_helpers.ex
#, elixir-autogen, elixir-format
msgid "Membership fee type not found"
msgstr ""
@ -3956,8 +3953,7 @@ msgstr ""
msgid "You do not have permission to %{action} members."
msgstr ""
#: lib/mv_web/live/membership_fee_settings_live.ex
#: lib/mv_web/live/membership_fee_type_live/index.ex
#: lib/mv_web/helpers/membership_fee_helpers.ex
#, elixir-autogen, elixir-format
msgid "You do not have permission to access this membership fee type"
msgstr ""
@ -3973,8 +3969,7 @@ msgstr ""
msgid "You do not have permission to delete this member"
msgstr ""
#: lib/mv_web/live/membership_fee_settings_live.ex
#: lib/mv_web/live/membership_fee_type_live/index.ex
#: lib/mv_web/helpers/membership_fee_helpers.ex
#, elixir-autogen, elixir-format
msgid "You do not have permission to delete this membership fee type"
msgstr ""