Packages
phoenix_kit
1.2.10
1.7.208
1.7.207
1.7.206
1.7.205
1.7.204
1.7.203
1.7.202
1.7.201
1.7.200
1.7.199
1.7.198
1.7.197
1.7.196
1.7.194
1.7.193
1.7.192
1.7.191
1.7.190
1.7.189
1.7.187
1.7.186
1.7.185
1.7.184
1.7.183
1.7.182
1.7.181
1.7.180
1.7.179
1.7.178
1.7.177
1.7.176
1.7.175
1.7.174
1.7.173
1.7.172
1.7.171
1.7.170
1.7.169
1.7.168
1.7.167
1.7.166
1.7.165
1.7.164
1.7.162
1.7.161
1.7.160
1.7.159
1.7.157
1.7.156
1.7.155
1.7.154
1.7.153
1.7.152
1.7.151
1.7.150
1.7.149
1.7.146
1.7.145
1.7.144
1.7.143
1.7.138
1.7.133
1.7.132
1.7.131
1.7.130
1.7.128
1.7.126
1.7.125
1.7.121
1.7.120
1.7.119
1.7.118
1.7.117
1.7.116
1.7.115
1.7.114
1.7.113
1.7.112
1.7.111
1.7.110
1.7.109
1.7.108
1.7.107
1.7.106
1.7.105
1.7.104
1.7.103
1.7.102
1.7.101
1.7.100
1.7.99
1.7.98
1.7.97
1.7.96
1.7.95
1.7.94
1.7.93
1.7.92
1.7.91
1.7.90
1.7.89
1.7.88
1.7.87
1.7.86
1.7.85
1.7.84
1.7.83
1.7.82
1.7.81
1.7.80
1.7.79
1.7.78
1.7.77
1.7.76
1.7.75
1.7.74
1.7.71
1.7.70
1.7.69
1.7.66
1.7.65
1.7.64
1.7.63
1.7.62
1.7.61
1.7.59
1.7.58
1.7.57
1.7.56
1.7.55
1.7.54
1.7.53
1.7.52
1.7.51
1.7.49
1.7.44
1.7.43
1.7.42
1.7.41
1.7.39
1.7.38
1.7.37
1.7.36
1.7.34
1.7.33
1.7.31
1.7.30
1.7.29
1.7.28
1.7.27
1.7.26
1.7.25
1.7.24
1.7.23
1.7.22
1.7.21
1.7.20
1.7.19
1.7.18
1.7.17
1.7.16
1.7.15
1.7.14
1.7.13
1.7.12
1.7.11
1.7.10
1.7.9
1.7.8
1.7.7
1.7.6
1.7.5
1.7.4
1.7.3
1.7.2
1.7.1
1.7.0
1.6.20
1.6.19
1.6.18
1.6.17
1.6.16
1.6.15
1.6.14
1.6.13
1.6.12
1.6.11
1.6.10
1.6.9
1.6.8
1.6.7
1.6.6
1.6.5
1.6.4
1.6.3
1.5.2
1.5.1
1.5.0
1.4.9
1.4.8
1.4.7
1.4.6
1.4.5
1.4.4
1.4.3
1.4.2
1.4.1
1.4.0
1.3.2
1.3.1
1.3.0
1.2.10
1.2.9
1.2.8
1.2.7
1.2.5
1.2.4
1.2.2
1.2.1
1.2.0
1.1.0
1.0.0
A foundation for building Elixir Phoenix apps — SaaS, social networks, ERP systems, marketplaces, and more
Current section
Files
Jump to
Current section
Files
lib/phoenix_kit_web/users/settings_live.ex
defmodule PhoenixKitWeb.Users.SettingsLive do
use PhoenixKitWeb, :live_view
alias PhoenixKit.Users.Auth
alias PhoenixKit.Utils.Routes
def render(assigns) do
~H"""
<PhoenixKitWeb.Components.LayoutWrapper.app_layout
flash={@flash}
phoenix_kit_current_scope={assigns[:phoenix_kit_current_scope]}
page_title="Account Settings"
>
<div class="flex items-center justify-center py-8 min-h-[80vh]">
<div class="w-full max-w-lg px-4">
<div class="text-center mb-8">
<div class="flex items-center justify-center mb-4">
<PhoenixKitWeb.Components.Core.Icons.icon_settings class="w-12 h-12 text-primary" />
</div>
<h1 class="text-3xl font-bold mb-2">Account Settings</h1>
<p class="text-base-content/60 text-sm">
Manage your account email address and password settings
</p>
</div>
<div class="space-y-8">
<!-- Email Settings Card -->
<div class="card bg-base-100 shadow-2xl">
<div class="card-body">
<div class="flex items-center mb-4">
<PhoenixKitWeb.Components.Core.Icons.icon_email class="w-6 h-6 text-primary mr-3" />
<div>
<h2 class="text-xl font-bold">Email Address</h2>
<p class="text-sm text-base-content/60">Change your account email address</p>
</div>
</div>
<.simple_form
for={@email_form}
id="email_form"
phx-submit="update_email"
phx-change="validate_email"
>
<.input
field={@email_form[:email]}
type="email"
label="Email"
required
>
<:icon>
<PhoenixKitWeb.Components.Core.Icons.icon_email class="w-4 h-4 mr-2" />
</:icon>
</.input>
<.input
field={@email_form[:current_password]}
name="current_password"
id="current_password_for_email"
type="password"
label="Current password"
value={@email_form_current_password}
required
>
<:icon>
<PhoenixKitWeb.Components.Core.Icons.icon_lock class="w-4 h-4 mr-2" />
</:icon>
</.input>
<:actions>
<.button
phx-disable-with="Changing..."
class="btn-primary transition-all hover:scale-[1.02] active:scale-[0.98]"
>
<PhoenixKitWeb.Components.Core.Icons.icon_email class="w-5 h-5 mr-2" />
Change Email
</.button>
</:actions>
</.simple_form>
</div>
</div>
<!-- Profile Settings Card -->
<div class="card bg-base-100 shadow-2xl">
<div class="card-body">
<div class="flex items-center mb-4">
<PhoenixKitWeb.Components.Core.Icons.icon_user_profile class="w-6 h-6 text-primary mr-3" />
<div>
<h2 class="text-xl font-bold">Profile Information</h2>
<p class="text-sm text-base-content/60">Update your personal information</p>
</div>
</div>
<.simple_form
for={@profile_form}
id="profile_form"
phx-submit="update_profile"
phx-change="validate_profile"
>
<.input
field={@profile_form[:first_name]}
type="text"
label="First Name"
>
<:icon>
<PhoenixKitWeb.Components.Core.Icons.icon_user_profile class="w-4 h-4 mr-2" />
</:icon>
</.input>
<.input field={@profile_form[:last_name]} type="text" label="Last Name">
<:icon>
<PhoenixKitWeb.Components.Core.Icons.icon_user_profile class="w-4 h-4 mr-2" />
</:icon>
</.input>
<:actions>
<.button
phx-disable-with="Updating..."
class="btn-primary transition-all hover:scale-[1.02] active:scale-[0.98]"
>
<PhoenixKitWeb.Components.Core.Icons.icon_user_profile class="w-5 h-5 mr-2" />
Update Profile
</.button>
</:actions>
</.simple_form>
</div>
</div>
<!-- Password Settings Card -->
<div class="card bg-base-100 shadow-2xl">
<div class="card-body">
<div class="flex items-center mb-4">
<PhoenixKitWeb.Components.Core.Icons.icon_lock class="w-6 h-6 text-primary mr-3" />
<div>
<h2 class="text-xl font-bold">Password</h2>
<p class="text-sm text-base-content/60">Update your account password</p>
</div>
</div>
<.simple_form
for={@password_form}
id="password_form"
action={Routes.path("/users/log-in?_action=password_updated")}
method="post"
phx-change="validate_password"
phx-submit="update_password"
phx-trigger-action={@trigger_submit}
>
<input
name={@password_form[:email].name}
type="hidden"
id="hidden_user_email"
value={@current_email}
/>
<.input
field={@password_form[:password]}
type="password"
label="New password"
required
>
<:icon>
<PhoenixKitWeb.Components.Core.Icons.icon_lock class="w-4 h-4 mr-2" />
</:icon>
</.input>
<.input
field={@password_form[:password_confirmation]}
type="password"
label="Confirm new password"
>
<:icon>
<PhoenixKitWeb.Components.Core.Icons.icon_lock class="w-4 h-4 mr-2" />
</:icon>
</.input>
<.input
field={@password_form[:current_password]}
name="current_password"
type="password"
label="Current password"
id="current_password_for_password"
value={@current_password}
required
>
<:icon>
<PhoenixKitWeb.Components.Core.Icons.icon_lock class="w-4 h-4 mr-2" />
</:icon>
</.input>
<:actions>
<.button
phx-disable-with="Changing..."
class="btn-primary transition-all hover:scale-[1.02] active:scale-[0.98]"
>
<PhoenixKitWeb.Components.Core.Icons.icon_lock class="w-5 h-5 mr-2" />
Change Password
</.button>
</:actions>
</.simple_form>
</div>
</div>
<!-- Development Mode Notice -->
<div :if={show_dev_notice?()} class="alert alert-info">
<PhoenixKitWeb.Components.Core.Icons.icon_info class="stroke-current shrink-0 h-6 w-6" />
<span>
Development mode: Check
<.link href="/dev/mailbox" class="font-semibold underline">mailbox</.link>
for confirmation emails
</span>
</div>
</div>
</div>
</div>
</PhoenixKitWeb.Components.LayoutWrapper.app_layout>
"""
end
def mount(%{"token" => token}, _session, socket) do
socket =
case Auth.update_user_email(socket.assigns.phoenix_kit_current_user, token) do
:ok ->
put_flash(socket, :info, "Email changed successfully.")
:error ->
put_flash(socket, :error, "Email change link is invalid or it has expired.")
end
{:ok, push_navigate(socket, to: Routes.path("/users/settings"))}
end
def mount(_params, _session, socket) do
user = socket.assigns.phoenix_kit_current_user
email_changeset = Auth.change_user_email(user)
password_changeset = Auth.change_user_password(user)
profile_changeset = Auth.change_user_profile(user)
socket =
socket
|> assign(:current_password, nil)
|> assign(:email_form_current_password, nil)
|> assign(:current_email, user.email)
|> assign(:email_form, to_form(email_changeset))
|> assign(:password_form, to_form(password_changeset))
|> assign(:profile_form, to_form(profile_changeset))
|> assign(:trigger_submit, false)
{:ok, socket}
end
def handle_event("validate_email", params, socket) do
%{"current_password" => password, "user" => user_params} = params
email_form =
socket.assigns.phoenix_kit_current_user
|> Auth.change_user_email(user_params)
|> Map.put(:action, :validate)
|> to_form()
{:noreply, assign(socket, email_form: email_form, email_form_current_password: password)}
end
def handle_event("update_email", params, socket) do
%{"current_password" => password, "user" => user_params} = params
user = socket.assigns.phoenix_kit_current_user
case Auth.apply_user_email(user, password, user_params) do
{:ok, applied_user} ->
Auth.deliver_user_update_email_instructions(
applied_user,
user.email,
&Routes.url("/users/settings/confirm-email/#{&1}")
)
info = "A link to confirm your email change has been sent to the new address."
{:noreply, socket |> put_flash(:info, info) |> assign(email_form_current_password: nil)}
{:error, changeset} ->
{:noreply, assign(socket, :email_form, to_form(Map.put(changeset, :action, :insert)))}
end
end
def handle_event("validate_password", params, socket) do
%{"current_password" => password, "user" => user_params} = params
password_form =
socket.assigns.phoenix_kit_current_user
|> Auth.change_user_password(user_params)
|> Map.put(:action, :validate)
|> to_form()
{:noreply, assign(socket, password_form: password_form, current_password: password)}
end
def handle_event("update_password", params, socket) do
%{"current_password" => password, "user" => user_params} = params
user = socket.assigns.phoenix_kit_current_user
case Auth.update_user_password(user, password, user_params) do
{:ok, user} ->
password_form =
user
|> Auth.change_user_password(user_params)
|> to_form()
{:noreply, assign(socket, trigger_submit: true, password_form: password_form)}
{:error, changeset} ->
{:noreply, assign(socket, password_form: to_form(changeset))}
end
end
def handle_event("validate_profile", params, socket) do
%{"user" => user_params} = params
profile_form =
socket.assigns.phoenix_kit_current_user
|> Auth.change_user_profile(user_params)
|> Map.put(:action, :validate)
|> to_form()
{:noreply, assign(socket, profile_form: profile_form)}
end
def handle_event("update_profile", params, socket) do
%{"user" => user_params} = params
user = socket.assigns.phoenix_kit_current_user
case Auth.update_user_profile(user, user_params) do
{:ok, _user} ->
{:noreply, socket |> put_flash(:info, "Profile updated successfully")}
{:error, changeset} ->
{:noreply, assign(socket, :profile_form, to_form(Map.put(changeset, :action, :insert)))}
end
end
defp show_dev_notice? do
case Application.get_env(:phoenix_kit, PhoenixKit.Mailer)[:adapter] do
Swoosh.Adapters.Local -> true
_ -> false
end
end
end