134 lines
4.0 KiB
Elixir
134 lines
4.0 KiB
Elixir
defmodule DexiWeb.ProfileLive do
|
|
use DexiWeb, :live_view
|
|
|
|
alias Dexi.Accounts
|
|
alias Dexi.Accounts.Scope
|
|
alias DexiWeb.AccountComponents
|
|
|
|
@impl true
|
|
def mount(_params, _session, socket) do
|
|
{:ok,
|
|
socket
|
|
|> assign(:page_title, "Account")
|
|
|> assign(:editing?, false)
|
|
|> assign_account(socket.assigns.current_scope.user)}
|
|
end
|
|
|
|
@impl true
|
|
def handle_event("edit-profile", _params, socket) do
|
|
{:noreply, assign(socket, :editing?, true)}
|
|
end
|
|
|
|
def handle_event("cancel-edit", _params, socket) do
|
|
{:noreply,
|
|
socket
|
|
|> assign(:editing?, false)
|
|
|> assign(:form, to_form(Accounts.change_profile(socket.assigns.current_scope.user)))}
|
|
end
|
|
|
|
def handle_event("validate", %{"user" => params}, socket) do
|
|
form =
|
|
socket.assigns.current_scope.user
|
|
|> Accounts.change_profile(params)
|
|
|> Map.put(:action, :validate)
|
|
|> to_form()
|
|
|
|
{:noreply, assign(socket, :form, form)}
|
|
end
|
|
|
|
def handle_event("save", %{"user" => params}, socket) do
|
|
case Accounts.update_profile(socket.assigns.current_scope.user, params) do
|
|
{:ok, user} ->
|
|
{:noreply,
|
|
socket
|
|
|> assign_account(user)
|
|
|> assign(:editing?, false)
|
|
|> put_flash(:info, "Account saved.")}
|
|
|
|
{:error, changeset} ->
|
|
{:noreply, assign(socket, :form, to_form(changeset))}
|
|
end
|
|
end
|
|
|
|
def handle_event("send-confirmation", _params, socket) do
|
|
user = socket.assigns.current_scope.user
|
|
{:noreply, send_confirmation(socket, user)}
|
|
end
|
|
|
|
def handle_event("confirm-email", %{"confirmation" => %{"code" => code}}, socket) do
|
|
case Accounts.confirm_email(socket.assigns.current_scope.user, code) do
|
|
{:ok, user} ->
|
|
{:noreply,
|
|
socket
|
|
|> assign_account(user)
|
|
|> put_flash(:info, "Email confirmed.")}
|
|
|
|
{:error, :expired} ->
|
|
{:noreply, put_flash(socket, :error, "That code expired. Request a new one.")}
|
|
|
|
{:error, _reason} ->
|
|
{:noreply, put_flash(socket, :error, "That confirmation code is invalid.")}
|
|
end
|
|
end
|
|
|
|
@impl true
|
|
def render(assigns) do
|
|
~H"""
|
|
<Layouts.app flash={@flash} current_scope={@current_scope}>
|
|
<section class={["mx-auto max-w-2xl px-5 py-16 sm:py-24"]}>
|
|
<p class={["text-xs font-black uppercase tracking-[0.28em] text-blue-grey"]}>Account</p>
|
|
<h1 class={["mt-3 text-4xl font-black tracking-[-0.05em] sm:text-5xl"]}>Your details</h1>
|
|
<p class={["mt-4 text-blue-grey"]}>
|
|
Your public key is your identity. Email and name are optional.
|
|
</p>
|
|
|
|
<div class={[
|
|
"mt-8 rounded-3xl border border-muted-steel bg-slate-blue p-6 shadow-cyan-glow sm:p-8"
|
|
]}>
|
|
<AccountComponents.account_preview
|
|
:if={!@editing?}
|
|
user={@current_scope.user}
|
|
/>
|
|
<AccountComponents.profile_editor :if={@editing?} form={@form} />
|
|
<AccountComponents.email_confirmation_panel
|
|
user={@current_scope.user}
|
|
form={@confirmation_form}
|
|
/>
|
|
</div>
|
|
</section>
|
|
</Layouts.app>
|
|
"""
|
|
end
|
|
|
|
defp assign_account(socket, user) do
|
|
user =
|
|
case Accounts.clear_expired_email_confirmation(user) do
|
|
{:ok, refreshed_user} -> refreshed_user
|
|
{:error, _reason} -> user
|
|
end
|
|
|
|
socket
|
|
|> assign(:current_scope, Scope.for_user(user))
|
|
|> assign(:form, to_form(Accounts.change_profile(user)))
|
|
|> assign(:confirmation_form, to_form(%{"code" => ""}, as: :confirmation))
|
|
end
|
|
|
|
defp send_confirmation(socket, user) do
|
|
case Accounts.request_email_confirmation(user) do
|
|
{:ok, updated_user} ->
|
|
socket
|
|
|> assign_account(updated_user)
|
|
|> put_flash(:info, "Confirmation code sent.")
|
|
|
|
{:error, :rate_limited} ->
|
|
put_flash(socket, :error, "Please wait one minute before requesting another code.")
|
|
|
|
{:error, :already_confirmed} ->
|
|
put_flash(socket, :info, "That email is already confirmed.")
|
|
|
|
{:error, _reason} ->
|
|
put_flash(socket, :error, "The confirmation email could not be sent.")
|
|
end
|
|
end
|
|
end
|