diff --git a/lib/mv_web/live/member_live/show.ex b/lib/mv_web/live/member_live/show.ex
index 52b8250..5ac4fee 100644
--- a/lib/mv_web/live/member_live/show.ex
+++ b/lib/mv_web/live/member_live/show.ex
@@ -235,6 +235,19 @@ defmodule MvWeb.MemberLive.Show do
<%= for custom_field <- @custom_fields do %>
<% cfv = find_custom_field_value(@member.custom_field_values, custom_field.id) %>
<.data_field label={custom_field.name}>
+ <:label_suffix :if={custom_field.join_description}>
+ <.tooltip
+ content={"#{gettext("Join form:")} #{custom_field.join_description}"}
+ wrap_class="ml-1 inline-flex items-center"
+ >
+
+ <.icon
+ name="hero-information-circle"
+ class="size-3.5 text-base-content/50"
+ />
+
+
+
{format_custom_field_value(cfv, custom_field.value_type)}
<% end %>
@@ -605,11 +618,14 @@ defmodule MvWeb.MemberLive.Show do
attr :value, :string, default: nil
attr :class, :string, default: ""
slot :inner_block
+ slot :label_suffix
defp data_field(assigns) do
~H"""
- - {@label}
+ -
+ {@label}{render_slot(@label_suffix)}
+
-
<%= if @inner_block != [] do %>
{render_slot(@inner_block)}
diff --git a/priv/gettext/de/LC_MESSAGES/default.po b/priv/gettext/de/LC_MESSAGES/default.po
index 81d91f7..4f895bb 100644
--- a/priv/gettext/de/LC_MESSAGES/default.po
+++ b/priv/gettext/de/LC_MESSAGES/default.po
@@ -3968,7 +3968,7 @@ msgstr "Zeitraum"
msgid "To"
msgstr "Bis"
-#~ #: lib/mv_web/live/group_live/show.ex
-#~ #, elixir-autogen, elixir-format
-#~ msgid "No members selected."
-#~ msgstr "Keine Mitglieder ausgewählt."
+#: lib/mv_web/live/member_live/show.ex
+#, elixir-autogen, elixir-format
+msgid "Join form:"
+msgstr "Beitrittsformular:"
diff --git a/priv/gettext/default.pot b/priv/gettext/default.pot
index 5e9abca..6bdbc40 100644
--- a/priv/gettext/default.pot
+++ b/priv/gettext/default.pot
@@ -3967,3 +3967,8 @@ msgstr ""
#, elixir-autogen, elixir-format
msgid "To"
msgstr ""
+
+#: lib/mv_web/live/member_live/show.ex
+#, elixir-autogen, elixir-format
+msgid "Join form:"
+msgstr ""
diff --git a/priv/gettext/en/LC_MESSAGES/default.po b/priv/gettext/en/LC_MESSAGES/default.po
index 1ae6a49..82a52a6 100644
--- a/priv/gettext/en/LC_MESSAGES/default.po
+++ b/priv/gettext/en/LC_MESSAGES/default.po
@@ -3968,7 +3968,7 @@ msgstr ""
msgid "To"
msgstr ""
-#~ #: lib/mv_web/live/group_live/show.ex
-#~ #, elixir-autogen, elixir-format, fuzzy
-#~ msgid "No members selected."
-#~ msgstr ""
+#: lib/mv_web/live/member_live/show.ex
+#, elixir-autogen, elixir-format, fuzzy
+msgid "Join form:"
+msgstr ""
diff --git a/test/mv_web/member_live/show_test.exs b/test/mv_web/member_live/show_test.exs
index c451be9..2ec5a68 100644
--- a/test/mv_web/member_live/show_test.exs
+++ b/test/mv_web/member_live/show_test.exs
@@ -220,4 +220,59 @@ defmodule MvWeb.MemberLive.ShowTest do
assert html =~ "private@example.com"
end
end
+
+ describe "custom field join_description tooltip" do
+ test "shows a tooltip on the custom field label when join_description is set", %{
+ conn: conn,
+ member: member,
+ actor: actor
+ } do
+ {:ok, custom_field} =
+ CustomField
+ |> Ash.Changeset.for_create(:create, %{
+ name: "DSGVO",
+ value_type: :boolean,
+ join_description: "Accept the privacy policy"
+ })
+ |> Ash.create(actor: actor)
+
+ conn = conn_with_oidc_user(conn)
+ {:ok, view, html} = live(conn, ~p"/members/#{member}")
+
+ assert has_element?(view, "[data-tip*='Accept the privacy policy']")
+ # Tooltip content conveys both the join-form context and the description text.
+ assert has_element?(view, "[data-tip*='Join form:']")
+ assert html =~ "Accept the privacy policy"
+ assert html =~ custom_field.name
+
+ # The info-icon wrapper must center the icon vertically with the label,
+ # matching the flex-items-center idiom used elsewhere (e.g. custom field edit),
+ # so the icon is flush with the label text and not offset downward.
+ assert has_element?(
+ view,
+ "[data-tip*='Accept the privacy policy'].inline-flex.items-center"
+ )
+ end
+
+ test "shows no tooltip on the custom field label when join_description is nil", %{
+ conn: conn,
+ member: member,
+ actor: actor
+ } do
+ {:ok, _custom_field} =
+ CustomField
+ |> Ash.Changeset.for_create(:create, %{
+ name: "Plain field",
+ value_type: :string
+ })
+ |> Ash.create(actor: actor)
+
+ conn = conn_with_oidc_user(conn)
+ {:ok, view, _html} = live(conn, ~p"/members/#{member}")
+
+ assert has_element?(view, "dt", "Plain field")
+ # The info-icon tooltip beside the label is only rendered when join_description is set.
+ refute has_element?(view, "[data-testid='join-description-tooltip']")
+ end
+ end
end