daily-tracker

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

settings.ex (4851B)


      1 defmodule DailyTrackerWeb.UserLive.Settings do
      2   use DailyTrackerWeb, :live_view
      3 
      4   on_mount {DailyTrackerWeb.UserAuth, :require_sudo_mode}
      5 
      6   alias DailyTracker.Accounts
      7 
      8   @impl true
      9   def render(assigns) do
     10     ~H"""
     11     <Layouts.app flash={@flash} current_scope={@current_scope}>
     12       <div class="text-center">
     13         <.header>
     14           Account Settings
     15           <:subtitle>Manage your account email address and password settings</:subtitle>
     16         </.header>
     17       </div>
     18 
     19       <.form for={@email_form} id="email_form" phx-submit="update_email" phx-change="validate_email">
     20         <.input
     21           field={@email_form[:email]}
     22           type="email"
     23           label="Email"
     24           autocomplete="username"
     25           spellcheck="false"
     26           required
     27         />
     28         <.button variant="primary" phx-disable-with="Changing...">Change Email</.button>
     29       </.form>
     30 
     31       <div class="divider" />
     32 
     33       <.form
     34         for={@password_form}
     35         id="password_form"
     36         action={~p"/users/update-password"}
     37         method="post"
     38         phx-change="validate_password"
     39         phx-submit="update_password"
     40         phx-trigger-action={@trigger_submit}
     41       >
     42         <input
     43           name={@password_form[:email].name}
     44           type="hidden"
     45           id="hidden_user_email"
     46           spellcheck="false"
     47           value={@current_email}
     48         />
     49         <.input
     50           field={@password_form[:password]}
     51           type="password"
     52           label="New password"
     53           autocomplete="new-password"
     54           spellcheck="false"
     55           required
     56         />
     57         <.input
     58           field={@password_form[:password_confirmation]}
     59           type="password"
     60           label="Confirm new password"
     61           autocomplete="new-password"
     62           spellcheck="false"
     63         />
     64         <.button variant="primary" phx-disable-with="Saving...">
     65           Save Password
     66         </.button>
     67       </.form>
     68     </Layouts.app>
     69     """
     70   end
     71 
     72   @impl true
     73   def mount(%{"token" => token}, _session, socket) do
     74     socket =
     75       case Accounts.update_user_email(socket.assigns.current_scope.user, token) do
     76         {:ok, _user} ->
     77           put_flash(socket, :info, "Email changed successfully.")
     78 
     79         {:error, _} ->
     80           put_flash(socket, :error, "Email change link is invalid or it has expired.")
     81       end
     82 
     83     {:ok, push_navigate(socket, to: ~p"/users/settings")}
     84   end
     85 
     86   def mount(_params, _session, socket) do
     87     user = socket.assigns.current_scope.user
     88     email_changeset = Accounts.change_user_email(user, %{}, validate_unique: false)
     89     password_changeset = Accounts.change_user_password(user, %{}, hash_password: false)
     90 
     91     socket =
     92       socket
     93       |> assign(:current_email, user.email)
     94       |> assign(:email_form, to_form(email_changeset))
     95       |> assign(:password_form, to_form(password_changeset))
     96       |> assign(:trigger_submit, false)
     97 
     98     {:ok, socket}
     99   end
    100 
    101   @impl true
    102   def handle_event("validate_email", params, socket) do
    103     %{"user" => user_params} = params
    104 
    105     email_form =
    106       socket.assigns.current_scope.user
    107       |> Accounts.change_user_email(user_params, validate_unique: false)
    108       |> Map.put(:action, :validate)
    109       |> to_form()
    110 
    111     {:noreply, assign(socket, email_form: email_form)}
    112   end
    113 
    114   def handle_event("update_email", params, socket) do
    115     %{"user" => user_params} = params
    116     user = socket.assigns.current_scope.user
    117     true = Accounts.sudo_mode?(user)
    118 
    119     case Accounts.change_user_email(user, user_params) do
    120       %{valid?: true} = changeset ->
    121         Accounts.deliver_user_update_email_instructions(
    122           Ecto.Changeset.apply_action!(changeset, :insert),
    123           user.email,
    124           &url(~p"/users/settings/confirm-email/#{&1}")
    125         )
    126 
    127         info = "A link to confirm your email change has been sent to the new address."
    128         {:noreply, socket |> put_flash(:info, info)}
    129 
    130       changeset ->
    131         {:noreply, assign(socket, :email_form, to_form(changeset, action: :insert))}
    132     end
    133   end
    134 
    135   def handle_event("validate_password", params, socket) do
    136     %{"user" => user_params} = params
    137 
    138     password_form =
    139       socket.assigns.current_scope.user
    140       |> Accounts.change_user_password(user_params, hash_password: false)
    141       |> Map.put(:action, :validate)
    142       |> to_form()
    143 
    144     {:noreply, assign(socket, password_form: password_form)}
    145   end
    146 
    147   def handle_event("update_password", params, socket) do
    148     %{"user" => user_params} = params
    149     user = socket.assigns.current_scope.user
    150     true = Accounts.sudo_mode?(user)
    151 
    152     case Accounts.change_user_password(user, user_params) do
    153       %{valid?: true} = changeset ->
    154         {:noreply, assign(socket, trigger_submit: true, password_form: to_form(changeset))}
    155 
    156       changeset ->
    157         {:noreply, assign(socket, password_form: to_form(changeset, action: :insert))}
    158     end
    159   end
    160 end