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