mitgliederverwaltung/lib/mv_web/live/member_live/show.ex
Rafael Epplée e6c5a58c65
Some checks reported errors
continuous-integration/drone/push Build was killed
Show dates in european format
2025-12-03 14:20:14 +01:00

128 lines
4.1 KiB
Elixir

defmodule MvWeb.MemberLive.Show do
@moduledoc """
LiveView for displaying a single member's details.
## Features
- Display all member information (personal, contact, address)
- Show linked user account (if exists)
- Display custom field values
- Navigate to edit form
- Return to member list
## Displayed Information
- Basic: name, email, dates (join, exit)
- Contact: phone number
- Address: street, house number, postal code, city
- Status: paid flag
- Relationships: linked user account
- Custom: dynamic custom field values from CustomFields
## Navigation
- Back to member list
- Edit member (with return_to parameter for back navigation)
"""
use MvWeb, :live_view
import Ash.Query
alias MvWeb.Helpers.DateFormatter
@impl true
def render(assigns) do
~H"""
<Layouts.app flash={@flash} current_user={@current_user}>
<.header>
{@member.first_name} {@member.last_name}
<:subtitle>{gettext("This is a member record from your database.")}</:subtitle>
<:actions>
<.button navigate={~p"/members"} aria-label={gettext("Back to members list")}>
<.icon name="hero-arrow-left" />
<span class="sr-only">{gettext("Back to members list")}</span>
</.button>
<.button variant="primary" navigate={~p"/members/#{@member}/edit?return_to=show"}>
<.icon name="hero-pencil-square" /> {gettext("Edit Member")}
</.button>
</:actions>
</.header>
<.list>
<:item title={gettext("Id")}>{@member.id}</:item>
<:item title={gettext("First Name")}>{@member.first_name}</:item>
<:item title={gettext("Last Name")}>{@member.last_name}</:item>
<:item title={gettext("Email")}>{@member.email}</:item>
<:item title={gettext("Paid")}>
{if @member.paid, do: gettext("Yes"), else: gettext("No")}
</:item>
<:item title={gettext("Phone Number")}>{@member.phone_number}</:item>
<:item title={gettext("Join Date")}>{DateFormatter.format_date(@member.join_date)}</:item>
<:item title={gettext("Exit Date")}>{DateFormatter.format_date(@member.exit_date)}</:item>
<:item title={gettext("Notes")}>{@member.notes}</:item>
<:item title={gettext("City")}>{@member.city}</:item>
<:item title={gettext("Street")}>{@member.street}</:item>
<:item title={gettext("House Number")}>{@member.house_number}</:item>
<:item title={gettext("Postal Code")}>{@member.postal_code}</:item>
<:item title={gettext("Linked User")}>
<%= if @member.user do %>
<.link
navigate={~p"/users/#{@member.user}"}
class="text-blue-600 hover:text-blue-800 underline"
>
<.icon name="hero-user" class="h-4 w-4 inline mr-1" />
{@member.user.email}
</.link>
<% else %>
<span class="text-gray-500 italic">{gettext("No user linked")}</span>
<% end %>
</:item>
</.list>
<h3 class="mt-8 mb-2 text-lg font-semibold">{gettext("Custom Field Values")}</h3>
<.generic_list items={
Enum.map(@member.custom_field_values, fn cfv ->
{
# name
cfv.custom_field && cfv.custom_field.name,
# value
format_custom_field_value(cfv)
}
end)
} />
</Layouts.app>
"""
end
@impl true
def mount(_params, _session, socket) do
{:ok, socket}
end
@impl true
def handle_params(%{"id" => id}, _, socket) do
query =
Mv.Membership.Member
|> filter(id == ^id)
|> load([:user, custom_field_values: [:custom_field]])
member = Ash.read_one!(query)
{:noreply,
socket
|> assign(:page_title, page_title(socket.assigns.live_action))
|> assign(:member, member)}
end
defp page_title(:show), do: gettext("Show Member")
defp page_title(:edit), do: gettext("Edit Member")
defp format_custom_field_value(cfv) do
value =
case cfv.value do
%{value: v} -> v
v -> v
end
case value do
%Date{} = date -> DateFormatter.format_date(date)
other -> other
end
end
end