feat: improve field order for approvals and add seeds
Some checks failed
continuous-integration/drone/push Build is failing

This commit is contained in:
Simon 2026-03-12 16:15:57 +01:00
parent a5ce7cb921
commit a7481f6ab1
Signed by: simon
GPG key ID: 40E7A58C4AA1EDB2
8 changed files with 245 additions and 109 deletions

View file

@ -93,6 +93,7 @@
- **Placement:** Own section **"Onboarding / Join"** in global settings, **above** "Custom fields", **below** "Vereinsdaten" (club data). - **Placement:** Own section **"Onboarding / Join"** in global settings, **above** "Custom fields", **below** "Vereinsdaten" (club data).
- **Join form enabled:** Checkbox (e.g. `join_form_enabled`). When set, the public `/join` page is active and the following config applies. - **Join form enabled:** Checkbox (e.g. `join_form_enabled`). When set, the public `/join` page is active and the following config applies.
- **Copyable join link:** When the join form is enabled, a copyable full URL to the `/join` page is shown below the checkbox (above the field list), with a short hint so admins can share it with applicants.
- **Field selection:** From **all existing** member fields (from `Mv.Constants.member_fields()`) and **custom fields**, the admin selects which fields appear on the join form. Stored as a list/set of field identifiers (no separate table); display in settings as a simple list, e.g. **badges with X to remove** (similar to the groups overview). Adding fields: e.g. dropdown or modal to pick from remaining fields. Detailed UX for this subsection is to be specified in a **separate subtask**. - **Field selection:** From **all existing** member fields (from `Mv.Constants.member_fields()`) and **custom fields**, the admin selects which fields appear on the join form. Stored as a list/set of field identifiers (no separate table); display in settings as a simple list, e.g. **badges with X to remove** (similar to the groups overview). Adding fields: e.g. dropdown or modal to pick from remaining fields. Detailed UX for this subsection is to be specified in a **separate subtask**.
- **Technically required fields:** The only field that must always be required for the join flow is **email**. All other fields can be optional or marked as required per admin choice; implementation should support a "required" flag per selected join-form field. - **Technically required fields:** The only field that must always be required for the join flow is **email**. All other fields can be optional or marked as required per admin choice; implementation should support a "required" flag per selected join-form field.
- **Other:** Which entry paths are enabled, approval workflow (who can approve) to be detailed in Step 2 and later specs. - **Other:** Which entry paths are enabled, approval workflow (who can approve) to be detailed in Step 2 and later specs.
@ -115,7 +116,7 @@ Implementation spec for Subtask 5.
#### Route and pages #### Route and pages
- **List:** **`/join_requests`** list of join requests. Filter by status (default or primary view: status `submitted`); optional view for "all" or "approved/rejected" for audit. - **List:** **`/join_requests`** list of join requests. Filter by status (default or primary view: status `submitted`); optional view for "all" or "approved/rejected" for audit.
- **Detail:** **`/join_requests/:id`** single join request with all data (typed fields + `form_data`), actions Approve / Reject. - **Detail:** **`/join_requests/:id`** single join request. **Two blocks:** (1) **Applicant data** all form fields (typed + `form_data`) merged and shown in join-form order; (2) **Status and review** submitted_at, status, and when decided: approved_at/rejected_at, reviewed by. Actions Approve / Reject when status is `submitted`.
#### Backend (JoinRequest) #### Backend (JoinRequest)

View file

@ -93,6 +93,7 @@ defmodule MvWeb.GlobalSettingsLive do
|> assign(:smtp_test_result, nil) |> assign(:smtp_test_result, nil)
|> assign(:smtp_test_to_email, "") |> assign(:smtp_test_to_email, "")
|> assign_join_form_state(settings, custom_fields) |> assign_join_form_state(settings, custom_fields)
|> assign(:join_url, url(socket.endpoint, ~p"/join"))
|> assign_form() |> assign_form()
{:ok, socket} {:ok, socket}
@ -153,6 +154,33 @@ defmodule MvWeb.GlobalSettingsLive do
</div> </div>
<div :if={@join_form_enabled}> <div :if={@join_form_enabled}>
<%!-- Copyable join page link (below checkbox, above field list) --%>
<div class="mb-4 p-3 max-w-2xl rounded-lg border border-base-300 bg-base-200/50">
<p class="text-sm text-base-content/70 mb-2">
{gettext("Link to the public join page (share this with applicants):")}
</p>
<div class="flex flex-wrap items-center gap-2">
<input
type="text"
readonly
value={@join_url}
class="input input-bordered input-sm flex-1 min-w-0 font-mono text-sm"
aria-label={gettext("Join page URL")}
/>
<.button
variant="secondary"
size="sm"
id="copy-join-url-btn"
phx-hook="CopyToClipboard"
phx-click="copy_join_url"
aria-label={gettext("Copy join page URL")}
>
<.icon name="hero-clipboard-document" class="size-4" />
{gettext("Copy")}
</.button>
</div>
</div>
<%!-- Field list header + Add button (left-aligned) --%> <%!-- Field list header + Add button (left-aligned) --%>
<h3 class="font-medium mb-3">{gettext("Fields on the join form")}</h3> <h3 class="font-medium mb-3">{gettext("Fields on the join form")}</h3>
<div class="relative mb-3 w-fit" phx-click-away="hide_add_field_dropdown"> <div class="relative mb-3 w-fit" phx-click-away="hide_add_field_dropdown">
@ -796,6 +824,16 @@ defmodule MvWeb.GlobalSettingsLive do
# ---- Join form event handlers ---- # ---- Join form event handlers ----
@impl true
def handle_event("copy_join_url", _params, socket) do
socket =
socket
|> push_event("copy_to_clipboard", %{text: socket.assigns.join_url})
|> put_flash(:success, gettext("Join page URL copied to clipboard."))
{:noreply, socket}
end
@impl true @impl true
def handle_event("toggle_join_form_enabled", _params, socket) do def handle_event("toggle_join_form_enabled", _params, socket) do
socket = assign(socket, :join_form_enabled, not socket.assigns.join_form_enabled) socket = assign(socket, :join_form_enabled, not socket.assigns.join_form_enabled)

View file

@ -128,20 +128,20 @@ defmodule MvWeb.JoinRequestLive.Show do
<%= if @join_request do %> <%= if @join_request do %>
<div class="mt-6 space-y-6 max-w-2xl"> <div class="mt-6 space-y-6 max-w-2xl">
<%!-- Single block: all applicant-provided data in join form order --%>
<div> <div>
<h2 class="text-lg font-semibold mb-2">{gettext("Request data")}</h2> <h2 class="text-lg font-semibold mb-2">{gettext("Applicant data")}</h2>
<div class="border border-base-300 rounded-lg p-4 bg-base-100 space-y-2">
<%= for {label, value} <- applicant_data_rows(@join_request, @join_form_field_ids || []) do %>
<.field_row label={label} value={value} empty_text={gettext("Not specified")} />
<% end %>
</div>
</div>
<%!-- Status and review (submitted_at, status; if decided: approved/rejected at, reviewed by) --%>
<div>
<h2 class="text-lg font-semibold mb-2">{gettext("Status and review")}</h2>
<div class="border border-base-300 rounded-lg p-4 bg-base-100 space-y-2"> <div class="border border-base-300 rounded-lg p-4 bg-base-100 space-y-2">
<.field_row label={gettext("Email")} value={@join_request.email} />
<.field_row
label={gettext("First name")}
value={@join_request.first_name}
empty_text={gettext("Not specified")}
/>
<.field_row
label={gettext("Last name")}
value={@join_request.last_name}
empty_text={gettext("Not specified")}
/>
<.field_row <.field_row
label={gettext("Submitted at")} label={gettext("Submitted at")}
value={DateFormatter.format_datetime(@join_request.submitted_at)} value={DateFormatter.format_datetime(@join_request.submitted_at)}
@ -154,24 +154,7 @@ defmodule MvWeb.JoinRequestLive.Show do
</.badge> </.badge>
</span> </span>
</div> </div>
</div>
</div>
<%= if map_size(@join_request.form_data || %{}) > 0 do %>
<div>
<h2 class="text-lg font-semibold mb-2">{gettext("Additional form data")}</h2>
<div class="border border-base-300 rounded-lg p-4 bg-base-100 space-y-2">
<%= for {key, value} <- format_form_data(@join_request.form_data, @join_form_field_ids || []) do %>
<.field_row label={key} value={to_string(value)} />
<% end %>
</div>
</div>
<% end %>
<%= if @join_request.status in [:approved, :rejected] do %> <%= if @join_request.status in [:approved, :rejected] do %>
<div>
<h2 class="text-lg font-semibold mb-2">{gettext("Review information")}</h2>
<div class="border border-base-300 rounded-lg p-4 bg-base-100 space-y-2">
<%= if @join_request.approved_at do %> <%= if @join_request.approved_at do %>
<.field_row <.field_row
label={gettext("Approved at")} label={gettext("Approved at")}
@ -189,9 +172,9 @@ defmodule MvWeb.JoinRequestLive.Show do
value={JoinRequestHelpers.reviewer_display(@join_request)} value={JoinRequestHelpers.reviewer_display(@join_request)}
empty_text="-" empty_text="-"
/> />
</div>
</div>
<% end %> <% end %>
</div>
</div>
<%= if @join_request.status == :submitted do %> <%= if @join_request.status == :submitted do %>
<div class="flex flex-wrap items-center justify-between gap-3 pt-2"> <div class="flex flex-wrap items-center justify-between gap-3 pt-2">
@ -240,40 +223,71 @@ defmodule MvWeb.JoinRequestLive.Show do
""" """
end end
# Formats form_data for display in join-form order; legacy keys (not in current # Builds a single list of {label, display_value} for all applicant-provided data in join form
# join_form_field_ids) are appended at the end, sorted by label for stability. # order. Typed fields (email, first_name, last_name) and form_data are merged; legacy
# Labels: member field keys → human-readable; UUID keys kept as-is (custom field IDs). # form_data keys (not in current join form config) are appended at the end.
defp format_form_data(nil, _ordered_field_ids), do: [] defp applicant_data_rows(join_request, ordered_field_ids) do
defp format_form_data(form_data, ordered_field_ids) when is_map(form_data) do
member_field_strings = Constants.member_fields() |> Enum.map(&Atom.to_string/1) member_field_strings = Constants.member_fields() |> Enum.map(&Atom.to_string/1)
form_data = join_request.form_data || %{}
typed = %{
"email" => join_request.email,
"first_name" => join_request.first_name,
"last_name" => join_request.last_name
}
# First: entries in current join form order (only keys present in form_data)
in_order = in_order =
ordered_field_ids ordered_field_ids
|> Enum.filter(&Map.has_key?(form_data, &1))
|> Enum.map(fn key -> |> Enum.map(fn key ->
value = form_data[key] value = Map.get(typed, key) || Map.get(form_data, key)
label = field_key_to_label(key, member_field_strings) label = field_key_to_label(key, member_field_strings)
{label, value} {label, format_applicant_value(value)}
end) end)
# Then: keys in form_data that are not in current settings (e.g. removed fields on old requests)
legacy_keys = legacy_keys =
form_data form_data
|> Map.keys() |> Map.keys()
|> Enum.reject(&(&1 in ordered_field_ids)) |> Enum.reject(fn k ->
k in ordered_field_ids or k in ["email", "first_name", "last_name"]
end)
|> Enum.sort() |> Enum.sort()
legacy_entries = legacy_entries =
Enum.map(legacy_keys, fn key -> Enum.map(legacy_keys, fn key ->
label = field_key_to_label(key, member_field_strings) label = field_key_to_label(key, member_field_strings)
{label, form_data[key]} {label, format_applicant_value(form_data[key])}
end) end)
in_order ++ legacy_entries in_order ++ legacy_entries
end end
defp format_applicant_value(nil), do: nil
defp format_applicant_value(""), do: nil
defp format_applicant_value(%Date{} = date), do: DateFormatter.format_date(date)
defp format_applicant_value(value) when is_map(value), do: format_applicant_value_from_map(value)
defp format_applicant_value(value) when is_boolean(value),
do: if(value, do: gettext("Yes"), else: gettext("No"))
defp format_applicant_value(value) when is_binary(value) or is_number(value),
do: to_string(value)
defp format_applicant_value(value), do: to_string(value)
defp format_applicant_value_from_map(value) do
raw = Map.get(value, "_union_value") || Map.get(value, "value")
type = Map.get(value, "_union_type") || Map.get(value, "type")
if raw && type in ["date", :date] do
format_applicant_value(raw)
else
format_applicant_value_simple(raw, value)
end
end
defp format_applicant_value_simple(raw, _value) when is_binary(raw), do: raw
defp format_applicant_value_simple(raw, _value) when is_boolean(raw),
do: if(raw, do: gettext("Yes"), else: gettext("No"))
defp format_applicant_value_simple(raw, _value) when is_integer(raw), do: to_string(raw)
defp format_applicant_value_simple(_raw, value), do: to_string(value)
defp field_key_to_label(key, member_field_strings) when is_binary(key) do defp field_key_to_label(key, member_field_strings) when is_binary(key) do
if key in member_field_strings, if key in member_field_strings,
do: MemberFieldsTranslations.label(String.to_existing_atom(key)), do: MemberFieldsTranslations.label(String.to_existing_atom(key)),

View file

@ -110,11 +110,6 @@ msgstr "Feld hinzufügen"
msgid "Add members" msgid "Add members"
msgstr "Mitglieder hinzufügen" msgstr "Mitglieder hinzufügen"
#: lib/mv_web/live/join_request_live/show.ex
#, elixir-autogen, elixir-format
msgid "Additional form data"
msgstr "Weitere Formulardaten"
#: lib/mv_web/live/member_live/show.ex #: lib/mv_web/live/member_live/show.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Address" msgid "Address"
@ -1121,7 +1116,6 @@ msgstr "Rolle bearbeiten"
#: lib/mv_web/live/group_live/show.ex #: lib/mv_web/live/group_live/show.ex
#: lib/mv_web/live/join_request_live/index.ex #: lib/mv_web/live/join_request_live/index.ex
#: lib/mv_web/live/join_request_live/show.ex
#: lib/mv_web/live/member_live/form.ex #: lib/mv_web/live/member_live/form.ex
#: lib/mv_web/live/member_live/index.html.heex #: lib/mv_web/live/member_live/index.html.heex
#: lib/mv_web/live/member_live/show.ex #: lib/mv_web/live/member_live/show.ex
@ -1374,7 +1368,6 @@ msgid "First Name"
msgstr "Vorname" msgstr "Vorname"
#: lib/mv_web/live/join_request_live/index.ex #: lib/mv_web/live/join_request_live/index.ex
#: lib/mv_web/live/join_request_live/show.ex
#: lib/mv_web/live/member_live/index.html.heex #: lib/mv_web/live/member_live/index.html.heex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "First name" msgid "First name"
@ -1792,7 +1785,6 @@ msgid "Last Name"
msgstr "Nachname" msgstr "Nachname"
#: lib/mv_web/live/join_request_live/index.ex #: lib/mv_web/live/join_request_live/index.ex
#: lib/mv_web/live/join_request_live/show.ex
#: lib/mv_web/live/member_live/index.html.heex #: lib/mv_web/live/member_live/index.html.heex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Last name" msgid "Last name"
@ -2178,6 +2170,7 @@ msgstr "Neuer Betrag"
#: lib/mv_web/live/components/member_filter_component.ex #: lib/mv_web/live/components/member_filter_component.ex
#: lib/mv_web/live/custom_field_live/index_component.ex #: lib/mv_web/live/custom_field_live/index_component.ex
#: lib/mv_web/live/join_request_live/show.ex
#: lib/mv_web/live/member_field_live/index_component.ex #: lib/mv_web/live/member_field_live/index_component.ex
#: lib/mv_web/live/member_live/index/formatter.ex #: lib/mv_web/live/member_live/index/formatter.ex
#: lib/mv_web/live/member_live/show.ex #: lib/mv_web/live/member_live/show.ex
@ -2681,11 +2674,6 @@ msgstr "Mitglied aus Gruppe entfernen"
msgid "Reorder" msgid "Reorder"
msgstr "Umordnen" msgstr "Umordnen"
#: lib/mv_web/live/join_request_live/show.ex
#, elixir-autogen, elixir-format
msgid "Request data"
msgstr "Antragsdaten"
#: lib/mv_web/live/custom_field_live/form_component.ex #: lib/mv_web/live/custom_field_live/form_component.ex
#: lib/mv_web/live/custom_field_live/index_component.ex #: lib/mv_web/live/custom_field_live/index_component.ex
#: lib/mv_web/live/global_settings_live.ex #: lib/mv_web/live/global_settings_live.ex
@ -2711,11 +2699,6 @@ msgstr "Passwort zurücksetzen"
msgid "Review by" msgid "Review by"
msgstr "Geprüft von" msgstr "Geprüft von"
#: lib/mv_web/live/join_request_live/show.ex
#, elixir-autogen, elixir-format
msgid "Review information"
msgstr "Bearbeitungsinformationen"
#: lib/mv_web/live/join_request_live/index.ex #: lib/mv_web/live/join_request_live/index.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Reviewed at" msgid "Reviewed at"
@ -3575,6 +3558,7 @@ msgstr "Jährliches Intervall Beitrittszeitraum einbezogen"
#: lib/mv_web/live/components/member_filter_component.ex #: lib/mv_web/live/components/member_filter_component.ex
#: lib/mv_web/live/custom_field_live/index_component.ex #: lib/mv_web/live/custom_field_live/index_component.ex
#: lib/mv_web/live/join_request_live/show.ex
#: lib/mv_web/live/member_field_live/index_component.ex #: lib/mv_web/live/member_field_live/index_component.ex
#: lib/mv_web/live/member_live/index/formatter.ex #: lib/mv_web/live/member_live/index/formatter.ex
#: lib/mv_web/live/member_live/show.ex #: lib/mv_web/live/member_live/show.ex
@ -3776,3 +3760,38 @@ msgstr "aktualisiert"
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "without %{name}" msgid "without %{name}"
msgstr "ohne %{name}" msgstr "ohne %{name}"
#: lib/mv_web/live/join_request_live/show.ex
#, elixir-autogen, elixir-format
msgid "Applicant data"
msgstr "Angaben des Antragstellers"
#: lib/mv_web/live/global_settings_live.ex
#, elixir-autogen, elixir-format
msgid "Copy"
msgstr "Kopieren"
#: lib/mv_web/live/global_settings_live.ex
#, elixir-autogen, elixir-format
msgid "Copy join page URL"
msgstr "URL der Beitrittsseite kopieren"
#: lib/mv_web/live/global_settings_live.ex
#, elixir-autogen, elixir-format
msgid "Join page URL"
msgstr "URL der Beitrittsseite"
#: lib/mv_web/live/global_settings_live.ex
#, elixir-autogen, elixir-format
msgid "Join page URL copied to clipboard."
msgstr "URL der Beitrittsseite in die Zwischenablage kopiert."
#: lib/mv_web/live/global_settings_live.ex
#, elixir-autogen, elixir-format
msgid "Link to the public join page (share this with applicants):"
msgstr "Link zur öffentlichen Beitrittsseite (diesen Link mit Interessent*innen teilen):"
#: lib/mv_web/live/join_request_live/show.ex
#, elixir-autogen, elixir-format
msgid "Status and review"
msgstr "Status und Prüfung"

View file

@ -111,11 +111,6 @@ msgstr ""
msgid "Add members" msgid "Add members"
msgstr "" msgstr ""
#: lib/mv_web/live/join_request_live/show.ex
#, elixir-autogen, elixir-format
msgid "Additional form data"
msgstr ""
#: lib/mv_web/live/member_live/show.ex #: lib/mv_web/live/member_live/show.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Address" msgid "Address"
@ -1122,7 +1117,6 @@ msgstr ""
#: lib/mv_web/live/group_live/show.ex #: lib/mv_web/live/group_live/show.ex
#: lib/mv_web/live/join_request_live/index.ex #: lib/mv_web/live/join_request_live/index.ex
#: lib/mv_web/live/join_request_live/show.ex
#: lib/mv_web/live/member_live/form.ex #: lib/mv_web/live/member_live/form.ex
#: lib/mv_web/live/member_live/index.html.heex #: lib/mv_web/live/member_live/index.html.heex
#: lib/mv_web/live/member_live/show.ex #: lib/mv_web/live/member_live/show.ex
@ -1375,7 +1369,6 @@ msgid "First Name"
msgstr "" msgstr ""
#: lib/mv_web/live/join_request_live/index.ex #: lib/mv_web/live/join_request_live/index.ex
#: lib/mv_web/live/join_request_live/show.ex
#: lib/mv_web/live/member_live/index.html.heex #: lib/mv_web/live/member_live/index.html.heex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "First name" msgid "First name"
@ -1793,7 +1786,6 @@ msgid "Last Name"
msgstr "" msgstr ""
#: lib/mv_web/live/join_request_live/index.ex #: lib/mv_web/live/join_request_live/index.ex
#: lib/mv_web/live/join_request_live/show.ex
#: lib/mv_web/live/member_live/index.html.heex #: lib/mv_web/live/member_live/index.html.heex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Last name" msgid "Last name"
@ -2179,6 +2171,7 @@ msgstr ""
#: lib/mv_web/live/components/member_filter_component.ex #: lib/mv_web/live/components/member_filter_component.ex
#: lib/mv_web/live/custom_field_live/index_component.ex #: lib/mv_web/live/custom_field_live/index_component.ex
#: lib/mv_web/live/join_request_live/show.ex
#: lib/mv_web/live/member_field_live/index_component.ex #: lib/mv_web/live/member_field_live/index_component.ex
#: lib/mv_web/live/member_live/index/formatter.ex #: lib/mv_web/live/member_live/index/formatter.ex
#: lib/mv_web/live/member_live/show.ex #: lib/mv_web/live/member_live/show.ex
@ -2682,11 +2675,6 @@ msgstr ""
msgid "Reorder" msgid "Reorder"
msgstr "" msgstr ""
#: lib/mv_web/live/join_request_live/show.ex
#, elixir-autogen, elixir-format
msgid "Request data"
msgstr ""
#: lib/mv_web/live/custom_field_live/form_component.ex #: lib/mv_web/live/custom_field_live/form_component.ex
#: lib/mv_web/live/custom_field_live/index_component.ex #: lib/mv_web/live/custom_field_live/index_component.ex
#: lib/mv_web/live/global_settings_live.ex #: lib/mv_web/live/global_settings_live.ex
@ -2712,11 +2700,6 @@ msgstr ""
msgid "Review by" msgid "Review by"
msgstr "" msgstr ""
#: lib/mv_web/live/join_request_live/show.ex
#, elixir-autogen, elixir-format
msgid "Review information"
msgstr ""
#: lib/mv_web/live/join_request_live/index.ex #: lib/mv_web/live/join_request_live/index.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Reviewed at" msgid "Reviewed at"
@ -3575,6 +3558,7 @@ msgstr ""
#: lib/mv_web/live/components/member_filter_component.ex #: lib/mv_web/live/components/member_filter_component.ex
#: lib/mv_web/live/custom_field_live/index_component.ex #: lib/mv_web/live/custom_field_live/index_component.ex
#: lib/mv_web/live/join_request_live/show.ex
#: lib/mv_web/live/member_field_live/index_component.ex #: lib/mv_web/live/member_field_live/index_component.ex
#: lib/mv_web/live/member_live/index/formatter.ex #: lib/mv_web/live/member_live/index/formatter.ex
#: lib/mv_web/live/member_live/show.ex #: lib/mv_web/live/member_live/show.ex
@ -3776,3 +3760,38 @@ msgstr ""
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "without %{name}" msgid "without %{name}"
msgstr "" msgstr ""
#: lib/mv_web/live/join_request_live/show.ex
#, elixir-autogen, elixir-format
msgid "Applicant data"
msgstr ""
#: lib/mv_web/live/global_settings_live.ex
#, elixir-autogen, elixir-format
msgid "Copy"
msgstr ""
#: lib/mv_web/live/global_settings_live.ex
#, elixir-autogen, elixir-format
msgid "Copy join page URL"
msgstr ""
#: lib/mv_web/live/global_settings_live.ex
#, elixir-autogen, elixir-format
msgid "Join page URL"
msgstr ""
#: lib/mv_web/live/global_settings_live.ex
#, elixir-autogen, elixir-format
msgid "Join page URL copied to clipboard."
msgstr ""
#: lib/mv_web/live/global_settings_live.ex
#, elixir-autogen, elixir-format
msgid "Link to the public join page (share this with applicants):"
msgstr ""
#: lib/mv_web/live/join_request_live/show.ex
#, elixir-autogen, elixir-format
msgid "Status and review"
msgstr ""

View file

@ -111,11 +111,6 @@ msgstr ""
msgid "Add members" msgid "Add members"
msgstr "" msgstr ""
#: lib/mv_web/live/join_request_live/show.ex
#, elixir-autogen, elixir-format
msgid "Additional form data"
msgstr "Additional form data"
#: lib/mv_web/live/member_live/show.ex #: lib/mv_web/live/member_live/show.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Address" msgid "Address"
@ -1122,7 +1117,6 @@ msgstr ""
#: lib/mv_web/live/group_live/show.ex #: lib/mv_web/live/group_live/show.ex
#: lib/mv_web/live/join_request_live/index.ex #: lib/mv_web/live/join_request_live/index.ex
#: lib/mv_web/live/join_request_live/show.ex
#: lib/mv_web/live/member_live/form.ex #: lib/mv_web/live/member_live/form.ex
#: lib/mv_web/live/member_live/index.html.heex #: lib/mv_web/live/member_live/index.html.heex
#: lib/mv_web/live/member_live/show.ex #: lib/mv_web/live/member_live/show.ex
@ -1375,7 +1369,6 @@ msgid "First Name"
msgstr "" msgstr ""
#: lib/mv_web/live/join_request_live/index.ex #: lib/mv_web/live/join_request_live/index.ex
#: lib/mv_web/live/join_request_live/show.ex
#: lib/mv_web/live/member_live/index.html.heex #: lib/mv_web/live/member_live/index.html.heex
#, elixir-autogen, elixir-format, fuzzy #, elixir-autogen, elixir-format, fuzzy
msgid "First name" msgid "First name"
@ -1793,7 +1786,6 @@ msgid "Last Name"
msgstr "" msgstr ""
#: lib/mv_web/live/join_request_live/index.ex #: lib/mv_web/live/join_request_live/index.ex
#: lib/mv_web/live/join_request_live/show.ex
#: lib/mv_web/live/member_live/index.html.heex #: lib/mv_web/live/member_live/index.html.heex
#, elixir-autogen, elixir-format, fuzzy #, elixir-autogen, elixir-format, fuzzy
msgid "Last name" msgid "Last name"
@ -2179,6 +2171,7 @@ msgstr ""
#: lib/mv_web/live/components/member_filter_component.ex #: lib/mv_web/live/components/member_filter_component.ex
#: lib/mv_web/live/custom_field_live/index_component.ex #: lib/mv_web/live/custom_field_live/index_component.ex
#: lib/mv_web/live/join_request_live/show.ex
#: lib/mv_web/live/member_field_live/index_component.ex #: lib/mv_web/live/member_field_live/index_component.ex
#: lib/mv_web/live/member_live/index/formatter.ex #: lib/mv_web/live/member_live/index/formatter.ex
#: lib/mv_web/live/member_live/show.ex #: lib/mv_web/live/member_live/show.ex
@ -2682,11 +2675,6 @@ msgstr ""
msgid "Reorder" msgid "Reorder"
msgstr "Reorder" msgstr "Reorder"
#: lib/mv_web/live/join_request_live/show.ex
#, elixir-autogen, elixir-format
msgid "Request data"
msgstr "Request data"
#: lib/mv_web/live/custom_field_live/form_component.ex #: lib/mv_web/live/custom_field_live/form_component.ex
#: lib/mv_web/live/custom_field_live/index_component.ex #: lib/mv_web/live/custom_field_live/index_component.ex
#: lib/mv_web/live/global_settings_live.ex #: lib/mv_web/live/global_settings_live.ex
@ -2712,11 +2700,6 @@ msgstr "Reset your password"
msgid "Review by" msgid "Review by"
msgstr "Review by" msgstr "Review by"
#: lib/mv_web/live/join_request_live/show.ex
#, elixir-autogen, elixir-format
msgid "Review information"
msgstr "Review information"
#: lib/mv_web/live/join_request_live/index.ex #: lib/mv_web/live/join_request_live/index.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Reviewed at" msgid "Reviewed at"
@ -3575,6 +3558,7 @@ msgstr ""
#: lib/mv_web/live/components/member_filter_component.ex #: lib/mv_web/live/components/member_filter_component.ex
#: lib/mv_web/live/custom_field_live/index_component.ex #: lib/mv_web/live/custom_field_live/index_component.ex
#: lib/mv_web/live/join_request_live/show.ex
#: lib/mv_web/live/member_field_live/index_component.ex #: lib/mv_web/live/member_field_live/index_component.ex
#: lib/mv_web/live/member_live/index/formatter.ex #: lib/mv_web/live/member_live/index/formatter.ex
#: lib/mv_web/live/member_live/show.ex #: lib/mv_web/live/member_live/show.ex
@ -3776,3 +3760,38 @@ msgstr ""
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "without %{name}" msgid "without %{name}"
msgstr "without %{name}" msgstr "without %{name}"
#: lib/mv_web/live/join_request_live/show.ex
#, elixir-autogen, elixir-format
msgid "Applicant data"
msgstr "Applicant data"
#: lib/mv_web/live/global_settings_live.ex
#, elixir-autogen, elixir-format
msgid "Copy"
msgstr "Copy"
#: lib/mv_web/live/global_settings_live.ex
#, elixir-autogen, elixir-format
msgid "Copy join page URL"
msgstr "Copy join page URL"
#: lib/mv_web/live/global_settings_live.ex
#, elixir-autogen, elixir-format
msgid "Join page URL"
msgstr "Join page URL"
#: lib/mv_web/live/global_settings_live.ex
#, elixir-autogen, elixir-format
msgid "Join page URL copied to clipboard."
msgstr "Join page URL copied to clipboard."
#: lib/mv_web/live/global_settings_live.ex
#, elixir-autogen, elixir-format
msgid "Link to the public join page (share this with applicants):"
msgstr "Link to the public join page (share this with applicants):"
#: lib/mv_web/live/join_request_live/show.ex
#, elixir-autogen, elixir-format
msgid "Status and review"
msgstr "Status and review"

View file

@ -263,6 +263,21 @@ default_hidden_in_overview = %{
"membership_fee_start_date" => false "membership_fee_start_date" => false
} }
# Default join form field selection (email + name + address + join_date); join form stays disabled.
default_join_form_field_ids = [
"email",
"first_name",
"last_name",
"street",
"house_number",
"postal_code",
"city",
"country",
"join_date"
]
default_join_form_field_required = %{"email" => true}
case Membership.get_settings() do case Membership.get_settings() do
{:ok, existing_settings} -> {:ok, existing_settings} ->
updates = updates =
@ -304,7 +319,9 @@ case Membership.get_settings() do
|> Ash.Changeset.for_create(:create, %{ |> Ash.Changeset.for_create(:create, %{
club_name: default_club_name, club_name: default_club_name,
member_field_visibility: default_hidden_in_overview, member_field_visibility: default_hidden_in_overview,
default_membership_fee_type_id: default_fee_type.id default_membership_fee_type_id: default_fee_type.id,
join_form_field_ids: default_join_form_field_ids,
join_form_field_required: default_join_form_field_required
}) })
|> Ash.create!() |> Ash.create!()
end end

View file

@ -481,19 +481,28 @@ for {email, values} <- custom_value_assignments do
end end
end end
# Join form: enable so membership application list is visible in dev # Join form: enable so membership application list is visible in dev; default field list includes address + join_date
default_join_form_field_ids = [
"email",
"first_name",
"last_name",
"street",
"house_number",
"postal_code",
"city",
"country",
"join_date"
]
default_join_form_field_required = %{"email" => true}
case Membership.get_settings() do case Membership.get_settings() do
{:ok, settings} -> {:ok, settings} ->
unless settings.join_form_enabled do unless settings.join_form_enabled do
Membership.update_settings(settings, %{ Membership.update_settings(settings, %{
join_form_enabled: true, join_form_enabled: true,
join_form_field_ids: settings.join_form_field_ids || ["email", "first_name", "last_name", "city"], join_form_field_ids: settings.join_form_field_ids || default_join_form_field_ids,
join_form_field_required: settings.join_form_field_required || %{ join_form_field_required: settings.join_form_field_required || default_join_form_field_required
"email" => true,
"first_name" => false,
"last_name" => false,
"city" => false
}
}) })
end end
_ -> _ ->