diff --git a/lib/who_need_help/help.ex b/lib/who_need_help/help.ex index 49267c9..cff2fd0 100644 --- a/lib/who_need_help/help.ex +++ b/lib/who_need_help/help.ex @@ -175,22 +175,27 @@ defmodule WhoNeedHelp.Help do end def create_request(%Scope{user: user}, attrs) do + changeset = + %HelpRequest{requester_id: user.id} + |> HelpRequest.create_changeset(attrs) + |> validate_structured_data() + result = - with {:ok, _limit} <- Trust.authorize_action(Scope.for_user(user), :create_request) do - Repo.transact(fn -> - with {:ok, request} <- - %HelpRequest{requester_id: user.id} - |> HelpRequest.create_changeset(attrs) - |> validate_structured_data() - |> Repo.insert(), - {:ok, _audit} <- - Trust.audit(user.id, "request.created", "request", request.id, %{ - "urgency" => to_string(request.urgency), - "category_id" => request.category_id - }) do - {:ok, request} - end - end) + if changeset.valid? do + with {:ok, _limit} <- Trust.authorize_action(Scope.for_user(user), :create_request) do + Repo.transact(fn -> + with {:ok, request} <- Repo.insert(changeset), + {:ok, _audit} <- + Trust.audit(user.id, "request.created", "request", request.id, %{ + "urgency" => to_string(request.urgency), + "category_id" => request.category_id + }) do + {:ok, request} + end + end) + end + else + {:error, changeset} end with {:ok, request} <- result do diff --git a/lib/who_need_help_web/live/request_live/new.ex b/lib/who_need_help_web/live/request_live/new.ex index 9b45498..300ef40 100644 --- a/lib/who_need_help_web/live/request_live/new.ex +++ b/lib/who_need_help_web/live/request_live/new.ex @@ -24,6 +24,7 @@ defmodule WhoNeedHelpWeb.RequestLive.New do |> assign(:categories, Catalog.list_categories()) |> assign(:selected_category, nil) |> assign(:structured_fields, []) + |> assign(:submission_errors, []) |> assign(:form, to_form(changeset))} end @@ -39,6 +40,7 @@ defmodule WhoNeedHelpWeb.RequestLive.New do {:noreply, socket |> assign(:form, to_form(changeset)) + |> maybe_refresh_submission_errors(changeset) |> assign_category(params)} end @@ -57,6 +59,7 @@ defmodule WhoNeedHelpWeb.RequestLive.New do {:noreply, socket |> assign(:form, to_form(changeset)) + |> assign(:submission_errors, submission_errors(changeset)) |> assign_category(params)} else {:noreply, put_flash(socket, :error, error_message(changeset))} @@ -78,6 +81,34 @@ defmodule WhoNeedHelpWeb.RequestLive.New do defp normalize_expiry(params), do: params + defp maybe_refresh_submission_errors(%{assigns: %{submission_errors: []}} = socket, _changeset), + do: socket + + defp maybe_refresh_submission_errors(socket, changeset), + do: assign(socket, :submission_errors, submission_errors(changeset)) + + defp submission_errors(changeset) do + changeset.errors + |> Enum.map(fn + {:location, _error} -> + {:location, + gettext("Choose a location using the button or enter both latitude and longitude.")} + + {:expires_at, _error} -> + {:expires_at, gettext("Choose an expiry time in the future.")} + + {field, error} -> + {field, "#{Phoenix.Naming.humanize(field)}: #{translate_error(error)}"} + end) + |> Enum.uniq() + end + + defp minimum_expiry_value do + DateTime.utc_now(:second) + |> DateTime.add(60, :second) + |> Calendar.strftime("%Y-%m-%dT%H:%M") + end + defp assign_category(socket, params) do category = Enum.find(socket.assigns.categories, &(&1.id == params["category_id"])) @@ -304,6 +335,7 @@ defmodule WhoNeedHelpWeb.RequestLive.New do field={@form[:expires_at]} type="datetime-local" label={gettext("Request expires (UTC)")} + min={minimum_expiry_value()} /> <.input @@ -323,18 +355,21 @@ defmodule WhoNeedHelpWeb.RequestLive.New do ]} />
- {gettext("You can also enter coordinates manually for local testing.")} + {gettext( + "Use the button or enter both coordinates. Public map precision follows the visibility choice above." + )}
+ <.icon name="hero-exclamation-circle" class="size-5" /> + {message} +
{gettext("Fix the following details and publish again:")}
+