update controllers and auth
This commit is contained in:
parent
8e36c96c33
commit
80708d9be3
23
lib/lokal_web/controllers/email_controller.ex
Normal file
23
lib/lokal_web/controllers/email_controller.ex
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
defmodule LokalWeb.EmailController do
|
||||||
|
@moduledoc """
|
||||||
|
A dev controller used to develop on emails
|
||||||
|
"""
|
||||||
|
|
||||||
|
use LokalWeb, :controller
|
||||||
|
alias Lokal.Accounts.User
|
||||||
|
|
||||||
|
plug :put_layout, {LokalWeb.LayoutView, :email}
|
||||||
|
|
||||||
|
@sample_assigns %{
|
||||||
|
email: %{subject: "Example subject"},
|
||||||
|
url: "https://lokal.bubbletea.dev/sample_url",
|
||||||
|
user: %User{email: "sample@email.com"}
|
||||||
|
}
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Debug route used to preview emails
|
||||||
|
"""
|
||||||
|
def preview(conn, %{"id" => template}) do
|
||||||
|
render(conn, "#{template |> to_string()}.html", @sample_assigns)
|
||||||
|
end
|
||||||
|
end
|
@ -1,12 +1,13 @@
|
|||||||
defmodule LokalWeb.UserAuth do
|
defmodule LokalWeb.UserAuth do
|
||||||
@moduledoc """
|
@moduledoc """
|
||||||
Module for any user authentication functions
|
Functions for user session and authentication
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import Plug.Conn
|
import Plug.Conn
|
||||||
import Phoenix.Controller
|
import Phoenix.Controller
|
||||||
import LokalWeb.Gettext
|
import LokalWeb.Gettext
|
||||||
alias Lokal.{Accounts, Accounts.User}
|
alias Lokal.{Accounts, Accounts.User}
|
||||||
|
alias LokalWeb.PageLive
|
||||||
alias LokalWeb.Router.Helpers, as: Routes
|
alias LokalWeb.Router.Helpers, as: Routes
|
||||||
|
|
||||||
# Make the remember me cookie valid for 60 days.
|
# Make the remember me cookie valid for 60 days.
|
||||||
@ -32,6 +33,7 @@ defmodule LokalWeb.UserAuth do
|
|||||||
|
|
||||||
def log_in_user(conn, %User{confirmed_at: nil}, _params) do
|
def log_in_user(conn, %User{confirmed_at: nil}, _params) do
|
||||||
conn
|
conn
|
||||||
|
|> fetch_flash()
|
||||||
|> put_flash(
|
|> put_flash(
|
||||||
:error,
|
:error,
|
||||||
dgettext("errors", "You must confirm your account and log in to access this page.")
|
dgettext("errors", "You must confirm your account and log in to access this page.")
|
||||||
@ -53,6 +55,11 @@ defmodule LokalWeb.UserAuth do
|
|||||||
|> redirect(to: user_return_to || signed_in_path(conn))
|
|> redirect(to: user_return_to || signed_in_path(conn))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@spec maybe_write_remember_me_cookie(
|
||||||
|
Plug.Conn.t(),
|
||||||
|
String.t() | any(),
|
||||||
|
%{required(String.t()) => String.t()} | any()
|
||||||
|
) :: Plug.Conn.t()
|
||||||
defp maybe_write_remember_me_cookie(conn, token, %{"remember_me" => "true"}) do
|
defp maybe_write_remember_me_cookie(conn, token, %{"remember_me" => "true"}) do
|
||||||
put_resp_cookie(conn, @remember_me_cookie, token, @remember_me_options)
|
put_resp_cookie(conn, @remember_me_cookie, token, @remember_me_options)
|
||||||
end
|
end
|
||||||
@ -149,13 +156,31 @@ defmodule LokalWeb.UserAuth do
|
|||||||
conn
|
conn
|
||||||
else
|
else
|
||||||
conn
|
conn
|
||||||
|> put_flash(:error, "You must confirm your account and log in to access this page.")
|
|> put_flash(
|
||||||
|
:error,
|
||||||
|
dgettext("errors", "You must confirm your account and log in to access this page.")
|
||||||
|
)
|
||||||
|> maybe_store_return_to()
|
|> maybe_store_return_to()
|
||||||
|> redirect(to: Routes.user_session_path(conn, :new))
|
|> redirect(to: Routes.user_session_path(conn, :new))
|
||||||
|> halt()
|
|> halt()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Used for routes that require the user to be an admin.
|
||||||
|
"""
|
||||||
|
def require_role(conn, role: role_atom) do
|
||||||
|
if conn.assigns[:current_user] && conn.assigns.current_user.role == role_atom do
|
||||||
|
conn
|
||||||
|
else
|
||||||
|
conn
|
||||||
|
|> put_flash(:error, dgettext("errors", "You are not authorized to view this page."))
|
||||||
|
|> maybe_store_return_to()
|
||||||
|
|> redirect(to: Routes.live_path(conn, PageLive))
|
||||||
|
|> halt()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
defp maybe_store_return_to(%{method: "GET"} = conn) do
|
defp maybe_store_return_to(%{method: "GET"} = conn) do
|
||||||
put_session(conn, :user_return_to, current_path(conn))
|
put_session(conn, :user_return_to, current_path(conn))
|
||||||
end
|
end
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
defmodule LokalWeb.UserConfirmationController do
|
defmodule LokalWeb.UserConfirmationController do
|
||||||
use LokalWeb, :controller
|
use LokalWeb, :controller
|
||||||
|
|
||||||
|
import LokalWeb.Gettext
|
||||||
alias Lokal.Accounts
|
alias Lokal.Accounts
|
||||||
|
|
||||||
def new(conn, _params) do
|
def new(conn, _params) do
|
||||||
render(conn, "new.html")
|
render(conn, "new.html", page_title: gettext("Confirm your account"))
|
||||||
end
|
end
|
||||||
|
|
||||||
def create(conn, %{"user" => %{"email" => email}}) do
|
def create(conn, %{"user" => %{"email" => email}}) do
|
||||||
@ -19,8 +20,11 @@ defmodule LokalWeb.UserConfirmationController do
|
|||||||
conn
|
conn
|
||||||
|> put_flash(
|
|> put_flash(
|
||||||
:info,
|
:info,
|
||||||
"If your email is in our system and it has not been confirmed yet, " <>
|
dgettext(
|
||||||
"you will receive an email with instructions shortly."
|
"prompts",
|
||||||
|
"If your email is in our system and it has not been confirmed yet, " <>
|
||||||
|
"you will receive an email with instructions shortly."
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|> redirect(to: "/")
|
|> redirect(to: "/")
|
||||||
end
|
end
|
||||||
@ -29,9 +33,9 @@ defmodule LokalWeb.UserConfirmationController do
|
|||||||
# leaked token giving the user access to the account.
|
# leaked token giving the user access to the account.
|
||||||
def confirm(conn, %{"token" => token}) do
|
def confirm(conn, %{"token" => token}) do
|
||||||
case Accounts.confirm_user(token) do
|
case Accounts.confirm_user(token) do
|
||||||
{:ok, _} ->
|
{:ok, %{email: email}} ->
|
||||||
conn
|
conn
|
||||||
|> put_flash(:info, "User confirmed successfully.")
|
|> put_flash(:info, dgettext("prompts", "%{email} confirmed successfully.", email: email))
|
||||||
|> redirect(to: "/")
|
|> redirect(to: "/")
|
||||||
|
|
||||||
:error ->
|
:error ->
|
||||||
@ -45,7 +49,10 @@ defmodule LokalWeb.UserConfirmationController do
|
|||||||
|
|
||||||
%{} ->
|
%{} ->
|
||||||
conn
|
conn
|
||||||
|> put_flash(:error, "User confirmation link is invalid or it has expired.")
|
|> put_flash(
|
||||||
|
:error,
|
||||||
|
dgettext("errors", "User confirmation link is invalid or it has expired.")
|
||||||
|
)
|
||||||
|> redirect(to: "/")
|
|> redirect(to: "/")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -1,30 +1,81 @@
|
|||||||
defmodule LokalWeb.UserRegistrationController do
|
defmodule LokalWeb.UserRegistrationController do
|
||||||
use LokalWeb, :controller
|
use LokalWeb, :controller
|
||||||
|
import LokalWeb.Gettext
|
||||||
alias Lokal.Accounts
|
alias Lokal.{Accounts, Invites}
|
||||||
alias Lokal.Accounts.User
|
alias Lokal.Accounts.User
|
||||||
alias LokalWeb.UserAuth
|
alias LokalWeb.{Endpoint, PageLive}
|
||||||
|
|
||||||
def new(conn, _params) do
|
def new(conn, %{"invite" => invite_token}) do
|
||||||
changeset = Accounts.change_user_registration(%User{})
|
invite = Invites.get_invite_by_token(invite_token)
|
||||||
render(conn, "new.html", changeset: changeset)
|
|
||||||
|
if invite do
|
||||||
|
conn |> render_new(invite)
|
||||||
|
else
|
||||||
|
conn
|
||||||
|
|> put_flash(:error, dgettext("errors", "Sorry, this invite was not found or expired"))
|
||||||
|
|> redirect(to: Routes.live_path(Endpoint, PageLive))
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def create(conn, %{"user" => user_params}) do
|
def new(conn, _params) do
|
||||||
|
if Accounts.allow_registration?() do
|
||||||
|
conn |> render_new()
|
||||||
|
else
|
||||||
|
conn
|
||||||
|
|> put_flash(:error, dgettext("errors", "Sorry, public registration is disabled"))
|
||||||
|
|> redirect(to: Routes.live_path(Endpoint, PageLive))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# renders new user registration page
|
||||||
|
defp render_new(conn, invite \\ nil) do
|
||||||
|
render(conn, "new.html",
|
||||||
|
changeset: Accounts.change_user_registration(%User{}),
|
||||||
|
invite: invite,
|
||||||
|
page_title: gettext("Register")
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
def create(conn, %{"user" => %{"invite_token" => invite_token}} = attrs) do
|
||||||
|
invite = Invites.get_invite_by_token(invite_token)
|
||||||
|
|
||||||
|
if invite do
|
||||||
|
conn |> create_user(attrs, invite)
|
||||||
|
else
|
||||||
|
conn
|
||||||
|
|> put_flash(:error, dgettext("errors", "Sorry, this invite was not found or expired"))
|
||||||
|
|> redirect(to: Routes.live_path(Endpoint, PageLive))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def create(conn, attrs) do
|
||||||
|
if Accounts.allow_registration?() do
|
||||||
|
conn |> create_user(attrs)
|
||||||
|
else
|
||||||
|
conn
|
||||||
|
|> put_flash(:error, dgettext("errors", "Sorry, public registration is disabled"))
|
||||||
|
|> redirect(to: Routes.live_path(Endpoint, PageLive))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp create_user(conn, %{"user" => user_params}, invite \\ nil) do
|
||||||
case Accounts.register_user(user_params) do
|
case Accounts.register_user(user_params) do
|
||||||
{:ok, user} ->
|
{:ok, user} ->
|
||||||
{:ok, _} =
|
unless invite |> is_nil() do
|
||||||
Accounts.deliver_user_confirmation_instructions(
|
invite |> Invites.use_invite!()
|
||||||
user,
|
end
|
||||||
&Routes.user_confirmation_url(conn, :confirm, &1)
|
|
||||||
)
|
Accounts.deliver_user_confirmation_instructions(
|
||||||
|
user,
|
||||||
|
&Routes.user_confirmation_url(conn, :confirm, &1)
|
||||||
|
)
|
||||||
|
|
||||||
conn
|
conn
|
||||||
|> put_flash(:info, "User created successfully.")
|
|> put_flash(:info, dgettext("prompts", "Please check your email to verify your account"))
|
||||||
|> UserAuth.log_in_user(user)
|
|> redirect(to: Routes.user_session_path(Endpoint, :new))
|
||||||
|
|
||||||
{:error, %Ecto.Changeset{} = changeset} ->
|
{:error, %Ecto.Changeset{} = changeset} ->
|
||||||
render(conn, "new.html", changeset: changeset)
|
conn |> render("new.html", changeset: changeset, invite: invite)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -6,7 +6,7 @@ defmodule LokalWeb.UserResetPasswordController do
|
|||||||
plug :get_user_by_reset_password_token when action in [:edit, :update]
|
plug :get_user_by_reset_password_token when action in [:edit, :update]
|
||||||
|
|
||||||
def new(conn, _params) do
|
def new(conn, _params) do
|
||||||
render(conn, "new.html")
|
render(conn, "new.html", page_title: gettext("Forgot your password?"))
|
||||||
end
|
end
|
||||||
|
|
||||||
def create(conn, %{"user" => %{"email" => email}}) do
|
def create(conn, %{"user" => %{"email" => email}}) do
|
||||||
@ -21,13 +21,20 @@ defmodule LokalWeb.UserResetPasswordController do
|
|||||||
conn
|
conn
|
||||||
|> put_flash(
|
|> put_flash(
|
||||||
:info,
|
:info,
|
||||||
"If your email is in our system, you will receive instructions to reset your password shortly."
|
dgettext(
|
||||||
|
"prompts",
|
||||||
|
"If your email is in our system, you will receive instructions to " <>
|
||||||
|
"reset your password shortly."
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|> redirect(to: "/")
|
|> redirect(to: "/")
|
||||||
end
|
end
|
||||||
|
|
||||||
def edit(conn, _params) do
|
def edit(conn, _params) do
|
||||||
render(conn, "edit.html", changeset: Accounts.change_user_password(conn.assigns.user))
|
render(conn, "edit.html",
|
||||||
|
changeset: Accounts.change_user_password(conn.assigns.user),
|
||||||
|
page_title: gettext("Reset your password")
|
||||||
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Do not log in the user after reset password to avoid a
|
# Do not log in the user after reset password to avoid a
|
||||||
@ -36,7 +43,7 @@ defmodule LokalWeb.UserResetPasswordController do
|
|||||||
case Accounts.reset_user_password(conn.assigns.user, user_params) do
|
case Accounts.reset_user_password(conn.assigns.user, user_params) do
|
||||||
{:ok, _} ->
|
{:ok, _} ->
|
||||||
conn
|
conn
|
||||||
|> put_flash(:info, "Password reset successfully.")
|
|> put_flash(:info, dgettext("prompts", "Password reset successfully."))
|
||||||
|> redirect(to: Routes.user_session_path(conn, :new))
|
|> redirect(to: Routes.user_session_path(conn, :new))
|
||||||
|
|
||||||
{:error, changeset} ->
|
{:error, changeset} ->
|
||||||
@ -51,7 +58,10 @@ defmodule LokalWeb.UserResetPasswordController do
|
|||||||
conn |> assign(:user, user) |> assign(:token, token)
|
conn |> assign(:user, user) |> assign(:token, token)
|
||||||
else
|
else
|
||||||
conn
|
conn
|
||||||
|> put_flash(:error, "Reset password link is invalid or it has expired.")
|
|> put_flash(
|
||||||
|
:error,
|
||||||
|
dgettext("errors", "Reset password link is invalid or it has expired.")
|
||||||
|
)
|
||||||
|> redirect(to: "/")
|
|> redirect(to: "/")
|
||||||
|> halt()
|
|> halt()
|
||||||
end
|
end
|
||||||
|
@ -5,7 +5,7 @@ defmodule LokalWeb.UserSessionController do
|
|||||||
alias LokalWeb.UserAuth
|
alias LokalWeb.UserAuth
|
||||||
|
|
||||||
def new(conn, _params) do
|
def new(conn, _params) do
|
||||||
render(conn, "new.html", error_message: nil)
|
render(conn, "new.html", error_message: nil, page_title: gettext("Log in"))
|
||||||
end
|
end
|
||||||
|
|
||||||
def create(conn, %{"user" => user_params}) do
|
def create(conn, %{"user" => user_params}) do
|
||||||
@ -14,13 +14,13 @@ defmodule LokalWeb.UserSessionController do
|
|||||||
if user = Accounts.get_user_by_email_and_password(email, password) do
|
if user = Accounts.get_user_by_email_and_password(email, password) do
|
||||||
UserAuth.log_in_user(conn, user, user_params)
|
UserAuth.log_in_user(conn, user, user_params)
|
||||||
else
|
else
|
||||||
render(conn, "new.html", error_message: "Invalid email or password")
|
render(conn, "new.html", error_message: dgettext("errors", "Invalid email or password"))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def delete(conn, _params) do
|
def delete(conn, _params) do
|
||||||
conn
|
conn
|
||||||
|> put_flash(:info, "Logged out successfully.")
|
|> put_flash(:info, dgettext("prompts", "Logged out successfully."))
|
||||||
|> UserAuth.log_out_user()
|
|> UserAuth.log_out_user()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
defmodule LokalWeb.UserSettingsController do
|
defmodule LokalWeb.UserSettingsController do
|
||||||
use LokalWeb, :controller
|
use LokalWeb, :controller
|
||||||
|
import LokalWeb.Gettext
|
||||||
alias Lokal.Accounts
|
alias Lokal.Accounts
|
||||||
alias LokalWeb.UserAuth
|
alias LokalWeb.{PageLive, UserAuth}
|
||||||
|
|
||||||
plug :assign_email_and_password_changesets
|
plug :assign_email_and_password_changesets
|
||||||
|
|
||||||
def edit(conn, _params) do
|
def edit(conn, _params) do
|
||||||
render(conn, "edit.html")
|
render(conn, "edit.html", page_title: gettext("Settings"))
|
||||||
end
|
end
|
||||||
|
|
||||||
def update(conn, %{"action" => "update_email"} = params) do
|
def update(conn, %{"action" => "update_email"} = params) do
|
||||||
@ -25,7 +25,10 @@ defmodule LokalWeb.UserSettingsController do
|
|||||||
conn
|
conn
|
||||||
|> put_flash(
|
|> put_flash(
|
||||||
:info,
|
:info,
|
||||||
"A link to confirm your email change has been sent to the new address."
|
dgettext(
|
||||||
|
"prompts",
|
||||||
|
"A link to confirm your email change has been sent to the new address."
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|> redirect(to: Routes.user_settings_path(conn, :edit))
|
|> redirect(to: Routes.user_settings_path(conn, :edit))
|
||||||
|
|
||||||
@ -41,7 +44,7 @@ defmodule LokalWeb.UserSettingsController do
|
|||||||
case Accounts.update_user_password(user, password, user_params) do
|
case Accounts.update_user_password(user, password, user_params) do
|
||||||
{:ok, user} ->
|
{:ok, user} ->
|
||||||
conn
|
conn
|
||||||
|> put_flash(:info, "Password updated successfully.")
|
|> put_flash(:info, dgettext("prompts", "Password updated successfully."))
|
||||||
|> put_session(:user_return_to, Routes.user_settings_path(conn, :edit))
|
|> put_session(:user_return_to, Routes.user_settings_path(conn, :edit))
|
||||||
|> UserAuth.log_in_user(user)
|
|> UserAuth.log_in_user(user)
|
||||||
|
|
||||||
@ -54,16 +57,33 @@ defmodule LokalWeb.UserSettingsController do
|
|||||||
case Accounts.update_user_email(conn.assigns.current_user, token) do
|
case Accounts.update_user_email(conn.assigns.current_user, token) do
|
||||||
:ok ->
|
:ok ->
|
||||||
conn
|
conn
|
||||||
|> put_flash(:info, "Email changed successfully.")
|
|> put_flash(:info, dgettext("prompts", "Email changed successfully."))
|
||||||
|> redirect(to: Routes.user_settings_path(conn, :edit))
|
|> redirect(to: Routes.user_settings_path(conn, :edit))
|
||||||
|
|
||||||
:error ->
|
:error ->
|
||||||
conn
|
conn
|
||||||
|> put_flash(:error, "Email change link is invalid or it has expired.")
|
|> put_flash(
|
||||||
|
:error,
|
||||||
|
dgettext("errors", "Email change link is invalid or it has expired.")
|
||||||
|
)
|
||||||
|> redirect(to: Routes.user_settings_path(conn, :edit))
|
|> redirect(to: Routes.user_settings_path(conn, :edit))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def delete(%{assigns: %{current_user: current_user}} = conn, %{"id" => user_id}) do
|
||||||
|
if user_id == current_user.id do
|
||||||
|
current_user |> Accounts.delete_user!(current_user)
|
||||||
|
|
||||||
|
conn
|
||||||
|
|> put_flash(:error, dgettext("prompts", "Your account has been deleted"))
|
||||||
|
|> redirect(to: Routes.live_path(conn, PageLive))
|
||||||
|
else
|
||||||
|
conn
|
||||||
|
|> put_flash(:error, dgettext("errors", "Unable to delete user"))
|
||||||
|
|> redirect(to: Routes.user_settings_path(conn, :edit))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
defp assign_email_and_password_changesets(conn, _opts) do
|
defp assign_email_and_password_changesets(conn, _opts) do
|
||||||
user = conn.assigns.current_user
|
user = conn.assigns.current_user
|
||||||
|
|
||||||
|
@ -4,22 +4,31 @@ defmodule LokalWeb.ErrorHelpers do
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
use Phoenix.HTML
|
use Phoenix.HTML
|
||||||
|
import Phoenix.LiveView.Helpers
|
||||||
|
alias Ecto.Changeset
|
||||||
|
alias Phoenix.{HTML.Form, LiveView.Rendered}
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Generates tag for inlined form input errors.
|
Generates tag for inlined form input errors.
|
||||||
"""
|
"""
|
||||||
def error_tag(form, field) do
|
@spec error_tag(Form.t(), Form.field()) :: Rendered.t()
|
||||||
Enum.map(Keyword.get_values(form.errors, field), fn error ->
|
@spec error_tag(Form.t(), Form.field(), String.t()) :: Rendered.t()
|
||||||
content_tag(:span, translate_error(error),
|
def error_tag(form, field, extra_class \\ "") do
|
||||||
class: "invalid-feedback",
|
assigns = %{extra_class: extra_class, form: form, field: field}
|
||||||
phx_feedback_for: input_name(form, field)
|
|
||||||
)
|
~H"""
|
||||||
end)
|
<%= for error <- Keyword.get_values(@form.errors, @field) do %>
|
||||||
|
<span class={"invalid-feedback #{@extra_class}"} phx-feedback-for={input_name(@form, @field)}>
|
||||||
|
<%= translate_error(error) %>
|
||||||
|
</span>
|
||||||
|
<% end %>
|
||||||
|
"""
|
||||||
end
|
end
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Translates an error message using gettext.
|
Translates an error message using gettext.
|
||||||
"""
|
"""
|
||||||
|
@spec translate_error({String.t(), keyword() | map()}) :: String.t()
|
||||||
def translate_error({msg, opts}) do
|
def translate_error({msg, opts}) do
|
||||||
# When using gettext, we typically pass the strings we want
|
# When using gettext, we typically pass the strings we want
|
||||||
# to translate as a static argument:
|
# to translate as a static argument:
|
||||||
@ -44,4 +53,30 @@ defmodule LokalWeb.ErrorHelpers do
|
|||||||
Gettext.dgettext(LokalWeb.Gettext, "errors", msg, opts)
|
Gettext.dgettext(LokalWeb.Gettext, "errors", msg, opts)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Displays all errors from a changeset, or just for a single key
|
||||||
|
"""
|
||||||
|
@spec changeset_errors(Changeset.t()) :: String.t()
|
||||||
|
@spec changeset_errors(Changeset.t(), key :: atom()) :: [String.t()] | nil
|
||||||
|
def changeset_errors(changeset) do
|
||||||
|
changeset
|
||||||
|
|> changeset_error_map()
|
||||||
|
|> Enum.map_join(". ", fn {key, errors} ->
|
||||||
|
"#{key |> humanize()}: #{errors |> Enum.join(", ")}"
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
def changeset_errors(changeset, key) do
|
||||||
|
changeset |> changeset_error_map() |> Map.get(key)
|
||||||
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Displays all errors from a changeset in a key value map
|
||||||
|
"""
|
||||||
|
@spec changeset_error_map(Changeset.t()) :: %{atom() => [String.t()]}
|
||||||
|
def changeset_error_map(changeset) do
|
||||||
|
changeset
|
||||||
|
|> Changeset.traverse_errors(fn error -> error |> translate_error() end)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
@ -1,16 +1,16 @@
|
|||||||
defmodule LokalWeb.ErrorView do
|
defmodule LokalWeb.ErrorView do
|
||||||
use LokalWeb, :view
|
use LokalWeb, :view
|
||||||
|
import LokalWeb.Components.Topbar
|
||||||
|
alias LokalWeb.{Endpoint, PageLive}
|
||||||
|
|
||||||
# If you want to customize a particular status code
|
def template_not_found(error_path, _assigns) do
|
||||||
# for a certain format, you may uncomment below.
|
error_string =
|
||||||
# def render("500.html", _assigns) do
|
case error_path do
|
||||||
# "Internal Server Error"
|
"404.html" -> dgettext("errors", "Not found")
|
||||||
# end
|
"401.html" -> dgettext("errors", "Unauthorized")
|
||||||
|
_ -> dgettext("errors", "Internal Server Error")
|
||||||
|
end
|
||||||
|
|
||||||
# By default, Phoenix returns the status message from
|
render("error.html", %{error_string: error_string})
|
||||||
# the template name. For example, "404.html" becomes
|
|
||||||
# "Not Found".
|
|
||||||
def template_not_found(template, _assigns) do
|
|
||||||
Phoenix.Controller.status_message_from_template(template)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
defmodule LokalWeb.UserConfirmationView do
|
defmodule LokalWeb.UserConfirmationView do
|
||||||
use LokalWeb, :view
|
use LokalWeb, :view
|
||||||
|
alias Lokal.Accounts
|
||||||
end
|
end
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
defmodule LokalWeb.UserResetPasswordView do
|
defmodule LokalWeb.UserResetPasswordView do
|
||||||
use LokalWeb, :view
|
use LokalWeb, :view
|
||||||
|
alias Lokal.Accounts
|
||||||
end
|
end
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
defmodule LokalWeb.UserSessionView do
|
defmodule LokalWeb.UserSessionView do
|
||||||
use LokalWeb, :view
|
use LokalWeb, :view
|
||||||
|
alias Lokal.Accounts
|
||||||
end
|
end
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
defmodule LokalWeb.ViewHelpers do
|
defmodule LokalWeb.ViewHelpers do
|
||||||
@moduledoc """
|
@moduledoc """
|
||||||
Contains common helpers that can be used in liveviews and regular views. These
|
Contains common helpers that can be used in liveviews and regular views. These
|
||||||
are automatically imported into any Phoenix View using `use LokalWeb, :view`
|
are automatically imported into any Phoenix View using `use LokalWeb,
|
||||||
|
:view`
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import Phoenix.LiveView.Helpers
|
import Phoenix.LiveView.Helpers
|
||||||
@ -10,24 +11,42 @@ defmodule LokalWeb.ViewHelpers do
|
|||||||
Returns a <time> element that renders the naivedatetime in the user's local
|
Returns a <time> element that renders the naivedatetime in the user's local
|
||||||
timezone with Alpine.js
|
timezone with Alpine.js
|
||||||
"""
|
"""
|
||||||
@spec display_datetime(NaiveDateTime.t()) :: Phoenix.LiveView.Rendered.t()
|
@spec display_datetime(NaiveDateTime.t() | nil) :: Phoenix.LiveView.Rendered.t()
|
||||||
|
def display_datetime(nil), do: ""
|
||||||
|
|
||||||
def display_datetime(datetime) do
|
def display_datetime(datetime) do
|
||||||
assigns = %{
|
assigns = %{
|
||||||
datetime: datetime |> DateTime.from_naive!("Etc/UTC") |> DateTime.to_iso8601(:extended)
|
datetime: datetime |> DateTime.from_naive!("Etc/UTC") |> DateTime.to_iso8601(:extended)
|
||||||
}
|
}
|
||||||
|
|
||||||
~H"""
|
~H"""
|
||||||
<time
|
<time datetime={@datetime} x-data={"{
|
||||||
datetime={@datetime}
|
|
||||||
x-data={"{
|
|
||||||
date:
|
date:
|
||||||
Intl.DateTimeFormat([], {dateStyle: 'short', timeStyle: 'long'})
|
Intl.DateTimeFormat([], {dateStyle: 'short', timeStyle: 'long'})
|
||||||
.format(new Date(\"#{@datetime}\"))
|
.format(new Date(\"#{@datetime}\"))
|
||||||
}"}
|
}"} x-text="date">
|
||||||
x-text="date"
|
|
||||||
>
|
|
||||||
<%= @datetime %>
|
<%= @datetime %>
|
||||||
</time>
|
</time>
|
||||||
"""
|
"""
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Returns a <date> element that renders the Date in the user's local
|
||||||
|
timezone with Alpine.js
|
||||||
|
"""
|
||||||
|
@spec display_date(Date.t() | nil) :: Phoenix.LiveView.Rendered.t()
|
||||||
|
def display_date(nil), do: ""
|
||||||
|
|
||||||
|
def display_date(date) do
|
||||||
|
assigns = %{date: date |> Date.to_iso8601(:extended)}
|
||||||
|
|
||||||
|
~H"""
|
||||||
|
<time datetime={@date} x-data={"{
|
||||||
|
date:
|
||||||
|
Intl.DateTimeFormat([], {timeZone: 'Etc/UTC', dateStyle: 'short'}).format(new Date(\"#{@date}\"))
|
||||||
|
}"} x-text="date">
|
||||||
|
<%= @date %>
|
||||||
|
</time>
|
||||||
|
"""
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
Loading…
Reference in New Issue
Block a user