140 lines
3.6 KiB
Elixir
140 lines
3.6 KiB
Elixir
defmodule MvWeb.GlobalSettingsLive do
|
|
@moduledoc """
|
|
LiveView for managing global application settings (Vereinsdaten).
|
|
|
|
## Features
|
|
- Edit the association/club name
|
|
- Manage custom fields
|
|
- Real-time form validation
|
|
- Success/error feedback
|
|
|
|
## Settings
|
|
- `club_name` - The name of the association/club (required)
|
|
|
|
## Events
|
|
- `validate` - Real-time form validation
|
|
- `save` - Save settings changes
|
|
|
|
## Note
|
|
Settings is a singleton resource - there is only one settings record.
|
|
The club_name can also be set via the `ASSOCIATION_NAME` environment variable.
|
|
"""
|
|
use MvWeb, :live_view
|
|
|
|
alias Mv.Membership
|
|
|
|
@impl true
|
|
def mount(_params, _session, socket) do
|
|
{:ok, settings} = Membership.get_settings()
|
|
|
|
{:ok,
|
|
socket
|
|
|> assign(:page_title, gettext("Settings"))
|
|
|> assign(:settings, settings)
|
|
|> assign_form()}
|
|
end
|
|
|
|
@impl true
|
|
def render(assigns) do
|
|
~H"""
|
|
<Layouts.app flash={@flash} current_user={@current_user}>
|
|
<.header>
|
|
{gettext("Settings")}
|
|
<:subtitle>
|
|
{gettext("Manage global settings for the association.")}
|
|
</:subtitle>
|
|
</.header>
|
|
|
|
<%!-- Club Settings Section --%>
|
|
<.header>
|
|
{gettext("Club Settings")}
|
|
</.header>
|
|
<.form for={@form} id="settings-form" phx-change="validate" phx-submit="save">
|
|
<.input
|
|
field={@form[:club_name]}
|
|
type="text"
|
|
label={gettext("Association Name")}
|
|
required
|
|
/>
|
|
|
|
<.button phx-disable-with={gettext("Saving...")} variant="primary">
|
|
{gettext("Save Settings")}
|
|
</.button>
|
|
</.form>
|
|
|
|
<%!-- Custom Fields Section --%>
|
|
<.live_component
|
|
module={MvWeb.CustomFieldLive.IndexComponent}
|
|
id="custom-fields-component"
|
|
/>
|
|
</Layouts.app>
|
|
"""
|
|
end
|
|
|
|
@impl true
|
|
def handle_event("validate", %{"setting" => setting_params}, socket) do
|
|
{:noreply,
|
|
assign(socket, form: AshPhoenix.Form.validate(socket.assigns.form, setting_params))}
|
|
end
|
|
|
|
@impl true
|
|
def handle_event("save", %{"setting" => setting_params}, socket) do
|
|
case AshPhoenix.Form.submit(socket.assigns.form, params: setting_params) do
|
|
{:ok, updated_settings} ->
|
|
socket =
|
|
socket
|
|
|> assign(:settings, updated_settings)
|
|
|> put_flash(:info, gettext("Settings updated successfully"))
|
|
|> assign_form()
|
|
|
|
{:noreply, socket}
|
|
|
|
{:error, form} ->
|
|
{:noreply, assign(socket, form: form)}
|
|
end
|
|
end
|
|
|
|
@impl true
|
|
def handle_info({:custom_field_saved, _custom_field, action}, socket) do
|
|
send_update(MvWeb.CustomFieldLive.IndexComponent,
|
|
id: "custom-fields-component",
|
|
show_form: false
|
|
)
|
|
|
|
{:noreply,
|
|
put_flash(socket, :info, gettext("Custom field %{action} successfully", action: action))}
|
|
end
|
|
|
|
@impl true
|
|
def handle_info({:custom_field_deleted, _custom_field}, socket) do
|
|
{:noreply, put_flash(socket, :info, gettext("Custom field deleted successfully"))}
|
|
end
|
|
|
|
@impl true
|
|
def handle_info({:custom_field_delete_error, error}, socket) do
|
|
{:noreply,
|
|
put_flash(
|
|
socket,
|
|
:error,
|
|
gettext("Failed to delete custom field: %{error}", error: inspect(error))
|
|
)}
|
|
end
|
|
|
|
@impl true
|
|
def handle_info(:custom_field_slug_mismatch, socket) do
|
|
{:noreply, put_flash(socket, :error, gettext("Slug does not match. Deletion cancelled."))}
|
|
end
|
|
|
|
defp assign_form(%{assigns: %{settings: settings}} = socket) do
|
|
form =
|
|
AshPhoenix.Form.for_update(
|
|
settings,
|
|
:update,
|
|
api: Membership,
|
|
as: "setting",
|
|
forms: [auto?: true]
|
|
)
|
|
|
|
assign(socket, form: to_form(form))
|
|
end
|
|
end
|