add links
This commit is contained in:
parent
3842798968
commit
e2b802f968
54 changed files with 4984 additions and 6 deletions
82
lib/zoeyscomputer_web/live/link_live/form_component.ex
Normal file
82
lib/zoeyscomputer_web/live/link_live/form_component.ex
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
defmodule ZoeyscomputerWeb.LinkLive.FormComponent do
|
||||
use ZoeyscomputerWeb, :live_component
|
||||
|
||||
alias Zoeyscomputer.Links
|
||||
|
||||
@impl true
|
||||
def render(assigns) do
|
||||
~H"""
|
||||
<div>
|
||||
<.header>
|
||||
<%= @title %>
|
||||
<:subtitle>Use this form to manage link records in your database.</:subtitle>
|
||||
</.header>
|
||||
|
||||
<.simple_form
|
||||
for={@form}
|
||||
id="link-form"
|
||||
phx-target={@myself}
|
||||
phx-change="validate"
|
||||
phx-submit="save"
|
||||
>
|
||||
<.input field={@form[:url]} type="text" label="Url" />
|
||||
<:actions>
|
||||
<.button phx-disable-with="Saving...">Save Link</.button>
|
||||
</:actions>
|
||||
</.simple_form>
|
||||
</div>
|
||||
"""
|
||||
end
|
||||
|
||||
@impl true
|
||||
def update(%{link: link} = assigns, socket) do
|
||||
{:ok,
|
||||
socket
|
||||
|> assign(assigns)
|
||||
|> assign_new(:form, fn ->
|
||||
to_form(Links.change_link(link))
|
||||
end)}
|
||||
end
|
||||
|
||||
@impl true
|
||||
def handle_event("validate", %{"link" => link_params}, socket) do
|
||||
changeset = Links.change_link(socket.assigns.link, link_params)
|
||||
{:noreply, assign(socket, form: to_form(changeset, action: :validate))}
|
||||
end
|
||||
|
||||
def handle_event("save", %{"link" => link_params}, socket) do
|
||||
save_link(socket, socket.assigns.action, link_params)
|
||||
end
|
||||
|
||||
defp save_link(socket, :edit, link_params) do
|
||||
case Links.update_link(socket.assigns.link, link_params) do
|
||||
{:ok, link} ->
|
||||
notify_parent({:saved, link})
|
||||
|
||||
{:noreply,
|
||||
socket
|
||||
|> put_flash(:info, "Link updated successfully")
|
||||
|> push_patch(to: socket.assigns.patch)}
|
||||
|
||||
{:error, %Ecto.Changeset{} = changeset} ->
|
||||
{:noreply, assign(socket, form: to_form(changeset))}
|
||||
end
|
||||
end
|
||||
|
||||
defp save_link(socket, :new, link_params) do
|
||||
case Links.create_link(link_params) do
|
||||
{:ok, link} ->
|
||||
notify_parent({:saved, link})
|
||||
|
||||
{:noreply,
|
||||
socket
|
||||
|> put_flash(:info, "Link created successfully")
|
||||
|> push_patch(to: socket.assigns.patch)}
|
||||
|
||||
{:error, %Ecto.Changeset{} = changeset} ->
|
||||
{:noreply, assign(socket, form: to_form(changeset))}
|
||||
end
|
||||
end
|
||||
|
||||
defp notify_parent(msg), do: send(self(), {__MODULE__, msg})
|
||||
end
|
||||
39
lib/zoeyscomputer_web/live/link_live/index.ex
Normal file
39
lib/zoeyscomputer_web/live/link_live/index.ex
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
defmodule ZoeyscomputerWeb.LinkLive.Index do
|
||||
use ZoeyscomputerWeb, :live_view
|
||||
|
||||
alias Zoeyscomputer.Links
|
||||
|
||||
def mount(_params, _session, socket) do
|
||||
user_id = socket.assigns.current_user.id
|
||||
|
||||
changeset = Links.Link.changeset(%Links.Link{})
|
||||
|
||||
socket =
|
||||
socket
|
||||
|> assign(:links, Links.list_links(user_id))
|
||||
|> assign(:form, to_form(changeset))
|
||||
|
||||
{:ok, socket}
|
||||
end
|
||||
|
||||
def handle_event("submit", %{"link" => link_params}, socket) do
|
||||
params =
|
||||
link_params
|
||||
|> Map.put("user_id", socket.assigns.current_user.id)
|
||||
|
||||
case Links.create_link(params) do
|
||||
{:ok, link} ->
|
||||
socket =
|
||||
socket
|
||||
|> assign(:links, [link | socket.assigns.links])
|
||||
|
||||
{:noreply, socket}
|
||||
|
||||
{:error, changeset} ->
|
||||
socket
|
||||
|> assign(:form, to_form(changeset))
|
||||
|
||||
{:noreply, socket}
|
||||
end
|
||||
end
|
||||
end
|
||||
30
lib/zoeyscomputer_web/live/link_live/index.html.heex
Normal file
30
lib/zoeyscomputer_web/live/link_live/index.html.heex
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
<div class="flex gap-2">
|
||||
<h1 class="text-2xl grow font-bold">Links</h1>
|
||||
|
||||
<.link
|
||||
navigate={~p"/links/new"}
|
||||
class="bg-black border border-black hover:bg-gray-700 text-white font-bold py-2 px-3 rounded-md"
|
||||
>
|
||||
Add Link
|
||||
</.link>
|
||||
</div>
|
||||
|
||||
<div class="divide-y">
|
||||
<div :for={link <- @links}>
|
||||
<div>
|
||||
<div class="font-bold"><%= link.url %></div>
|
||||
<div class="text-sm"><%= link.inserted_at %></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<.form for={@form} phx-submit="submit">
|
||||
<div class="flex gap-2 items-end">
|
||||
<div class="grow">
|
||||
<.input field={@form[:url]} type="text" label="url" />
|
||||
</div>
|
||||
<button class="bg-black border border-black hover:bg-gray-700 text-white font-bold py-2 px-3 rounded-md">
|
||||
Create
|
||||
</button>
|
||||
</div>
|
||||
</.form>
|
||||
37
lib/zoeyscomputer_web/live/link_live/new.ex
Normal file
37
lib/zoeyscomputer_web/live/link_live/new.ex
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
defmodule ZoeyscomputerWeb.LinkLive.New do
|
||||
use ZoeyscomputerWeb, :live_view
|
||||
|
||||
alias Zoeyscomputer.Links
|
||||
|
||||
def mount(_params, _session, socket) do
|
||||
changeset = Links.Link.changeset(%Links.Link{})
|
||||
|
||||
socket =
|
||||
socket
|
||||
|> assign(:form, to_form(changeset))
|
||||
|
||||
{:ok, socket}
|
||||
end
|
||||
|
||||
def handle_event("submit", %{"link" => link_params}, socket) do
|
||||
params =
|
||||
link_params
|
||||
|> Map.put("user_id", socket.assigns.current_user.id)
|
||||
|
||||
case Links.create_link(params) do
|
||||
{:ok, _link} ->
|
||||
socket =
|
||||
socket
|
||||
|> put_flash(:info, "Link created successfully")
|
||||
|> push_navigate(to: ~p"/links")
|
||||
|
||||
{:noreply, socket}
|
||||
|
||||
{:error, changeset} ->
|
||||
socket
|
||||
|> assign(:form, to_form(changeset))
|
||||
|
||||
{:noreply, socket}
|
||||
end
|
||||
end
|
||||
end
|
||||
12
lib/zoeyscomputer_web/live/link_live/new.html.heex
Normal file
12
lib/zoeyscomputer_web/live/link_live/new.html.heex
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
<h1 class="text-2xl grow font-bold mb-6">Create a new link</h1>
|
||||
|
||||
<.form for={@form} phx-submit="submit">
|
||||
<div class="flex gap-2 items-end">
|
||||
<div class="grow">
|
||||
<.input field={@form[:url]} type="text" label="url" />
|
||||
</div>
|
||||
<button class="bg-black border border-black hover:bg-gray-700 text-white font-bold py-2 px-3 rounded-md">
|
||||
Create
|
||||
</button>
|
||||
</div>
|
||||
</.form>
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
defmodule ZoeyscomputerWeb.UserConfirmationInstructionsLive do
|
||||
use ZoeyscomputerWeb, :live_view
|
||||
|
||||
alias Zoeyscomputer.Users
|
||||
|
||||
def render(assigns) do
|
||||
~H"""
|
||||
<div class="mx-auto max-w-sm">
|
||||
<.header class="text-center">
|
||||
No confirmation instructions received?
|
||||
<:subtitle>We'll send a new confirmation link to your inbox</:subtitle>
|
||||
</.header>
|
||||
|
||||
<.simple_form for={@form} id="resend_confirmation_form" phx-submit="send_instructions">
|
||||
<.input field={@form[:email]} type="email" placeholder="Email" required />
|
||||
<:actions>
|
||||
<.button phx-disable-with="Sending..." class="w-full">
|
||||
Resend confirmation instructions
|
||||
</.button>
|
||||
</:actions>
|
||||
</.simple_form>
|
||||
|
||||
<p class="text-center mt-4">
|
||||
<.link href={~p"/users/register"}>Register</.link>
|
||||
| <.link href={~p"/users/log_in"}>Log in</.link>
|
||||
</p>
|
||||
</div>
|
||||
"""
|
||||
end
|
||||
|
||||
def mount(_params, _session, socket) do
|
||||
{:ok, assign(socket, form: to_form(%{}, as: "user"))}
|
||||
end
|
||||
|
||||
def handle_event("send_instructions", %{"user" => %{"email" => email}}, socket) do
|
||||
if user = Users.get_user_by_email(email) do
|
||||
Users.deliver_user_confirmation_instructions(
|
||||
user,
|
||||
&url(~p"/users/confirm/#{&1}")
|
||||
)
|
||||
end
|
||||
|
||||
info =
|
||||
"If your email is in our system and it has not been confirmed yet, you will receive an email with instructions shortly."
|
||||
|
||||
{:noreply,
|
||||
socket
|
||||
|> put_flash(:info, info)
|
||||
|> redirect(to: ~p"/")}
|
||||
end
|
||||
end
|
||||
58
lib/zoeyscomputer_web/live/user_confirmation_live.ex
Normal file
58
lib/zoeyscomputer_web/live/user_confirmation_live.ex
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
defmodule ZoeyscomputerWeb.UserConfirmationLive do
|
||||
use ZoeyscomputerWeb, :live_view
|
||||
|
||||
alias Zoeyscomputer.Users
|
||||
|
||||
def render(%{live_action: :edit} = assigns) do
|
||||
~H"""
|
||||
<div class="mx-auto max-w-sm">
|
||||
<.header class="text-center">Confirm Account</.header>
|
||||
|
||||
<.simple_form for={@form} id="confirmation_form" phx-submit="confirm_account">
|
||||
<input type="hidden" name={@form[:token].name} value={@form[:token].value} />
|
||||
<:actions>
|
||||
<.button phx-disable-with="Confirming..." class="w-full">Confirm my account</.button>
|
||||
</:actions>
|
||||
</.simple_form>
|
||||
|
||||
<p class="text-center mt-4">
|
||||
<.link href={~p"/users/register"}>Register</.link>
|
||||
| <.link href={~p"/users/log_in"}>Log in</.link>
|
||||
</p>
|
||||
</div>
|
||||
"""
|
||||
end
|
||||
|
||||
def mount(%{"token" => token}, _session, socket) do
|
||||
form = to_form(%{"token" => token}, as: "user")
|
||||
{:ok, assign(socket, form: form), temporary_assigns: [form: nil]}
|
||||
end
|
||||
|
||||
# Do not log in the user after confirmation to avoid a
|
||||
# leaked token giving the user access to the account.
|
||||
def handle_event("confirm_account", %{"user" => %{"token" => token}}, socket) do
|
||||
case Users.confirm_user(token) do
|
||||
{:ok, _} ->
|
||||
{:noreply,
|
||||
socket
|
||||
|> put_flash(:info, "User confirmed successfully.")
|
||||
|> redirect(to: ~p"/")}
|
||||
|
||||
:error ->
|
||||
# If there is a current user and the account was already confirmed,
|
||||
# then odds are that the confirmation link was already visited, either
|
||||
# by some automation or by the user themselves, so we redirect without
|
||||
# a warning message.
|
||||
case socket.assigns do
|
||||
%{current_user: %{confirmed_at: confirmed_at}} when not is_nil(confirmed_at) ->
|
||||
{:noreply, redirect(socket, to: ~p"/")}
|
||||
|
||||
%{} ->
|
||||
{:noreply,
|
||||
socket
|
||||
|> put_flash(:error, "User confirmation link is invalid or it has expired.")
|
||||
|> redirect(to: ~p"/")}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
50
lib/zoeyscomputer_web/live/user_forgot_password_live.ex
Normal file
50
lib/zoeyscomputer_web/live/user_forgot_password_live.ex
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
defmodule ZoeyscomputerWeb.UserForgotPasswordLive do
|
||||
use ZoeyscomputerWeb, :live_view
|
||||
|
||||
alias Zoeyscomputer.Users
|
||||
|
||||
def render(assigns) do
|
||||
~H"""
|
||||
<div class="mx-auto max-w-sm">
|
||||
<.header class="text-center">
|
||||
Forgot your password?
|
||||
<:subtitle>We'll send a password reset link to your inbox</:subtitle>
|
||||
</.header>
|
||||
|
||||
<.simple_form for={@form} id="reset_password_form" phx-submit="send_email">
|
||||
<.input field={@form[:email]} type="email" placeholder="Email" required />
|
||||
<:actions>
|
||||
<.button phx-disable-with="Sending..." class="w-full">
|
||||
Send password reset instructions
|
||||
</.button>
|
||||
</:actions>
|
||||
</.simple_form>
|
||||
<p class="text-center text-sm mt-4">
|
||||
<.link href={~p"/users/register"}>Register</.link>
|
||||
| <.link href={~p"/users/log_in"}>Log in</.link>
|
||||
</p>
|
||||
</div>
|
||||
"""
|
||||
end
|
||||
|
||||
def mount(_params, _session, socket) do
|
||||
{:ok, assign(socket, form: to_form(%{}, as: "user"))}
|
||||
end
|
||||
|
||||
def handle_event("send_email", %{"user" => %{"email" => email}}, socket) do
|
||||
if user = Users.get_user_by_email(email) do
|
||||
Users.deliver_user_reset_password_instructions(
|
||||
user,
|
||||
&url(~p"/users/reset_password/#{&1}")
|
||||
)
|
||||
end
|
||||
|
||||
info =
|
||||
"If your email is in our system, you will receive instructions to reset your password shortly."
|
||||
|
||||
{:noreply,
|
||||
socket
|
||||
|> put_flash(:info, info)
|
||||
|> redirect(to: ~p"/")}
|
||||
end
|
||||
end
|
||||
43
lib/zoeyscomputer_web/live/user_login_live.ex
Normal file
43
lib/zoeyscomputer_web/live/user_login_live.ex
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
defmodule ZoeyscomputerWeb.UserLoginLive do
|
||||
use ZoeyscomputerWeb, :live_view
|
||||
|
||||
def render(assigns) do
|
||||
~H"""
|
||||
<div class="mx-auto max-w-sm">
|
||||
<.header class="text-center">
|
||||
Log in to account
|
||||
<:subtitle>
|
||||
Don't have an account?
|
||||
<.link navigate={~p"/users/register"} class="font-semibold text-brand hover:underline">
|
||||
Sign up
|
||||
</.link>
|
||||
for an account now.
|
||||
</:subtitle>
|
||||
</.header>
|
||||
|
||||
<.simple_form for={@form} id="login_form" action={~p"/users/log_in"} phx-update="ignore">
|
||||
<.input field={@form[:email]} type="email" label="Email" required />
|
||||
<.input field={@form[:password]} type="password" label="Password" required />
|
||||
|
||||
<:actions>
|
||||
<.input field={@form[:remember_me]} type="checkbox" label="Keep me logged in" />
|
||||
<.link href={~p"/users/reset_password"} class="text-sm font-semibold">
|
||||
Forgot your password?
|
||||
</.link>
|
||||
</:actions>
|
||||
<:actions>
|
||||
<.button phx-disable-with="Logging in..." class="w-full">
|
||||
Log in <span aria-hidden="true">→</span>
|
||||
</.button>
|
||||
</:actions>
|
||||
</.simple_form>
|
||||
</div>
|
||||
"""
|
||||
end
|
||||
|
||||
def mount(_params, _session, socket) do
|
||||
email = Phoenix.Flash.get(socket.assigns.flash, :email)
|
||||
form = to_form(%{"email" => email}, as: "user")
|
||||
{:ok, assign(socket, form: form), temporary_assigns: [form: form]}
|
||||
end
|
||||
end
|
||||
87
lib/zoeyscomputer_web/live/user_registration_live.ex
Normal file
87
lib/zoeyscomputer_web/live/user_registration_live.ex
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
defmodule ZoeyscomputerWeb.UserRegistrationLive do
|
||||
use ZoeyscomputerWeb, :live_view
|
||||
|
||||
alias Zoeyscomputer.Users
|
||||
alias Zoeyscomputer.Users.User
|
||||
|
||||
def render(assigns) do
|
||||
~H"""
|
||||
<div class="mx-auto max-w-sm">
|
||||
<.header class="text-center">
|
||||
Register for an account
|
||||
<:subtitle>
|
||||
Already registered?
|
||||
<.link navigate={~p"/users/log_in"} class="font-semibold text-brand hover:underline">
|
||||
Log in
|
||||
</.link>
|
||||
to your account now.
|
||||
</:subtitle>
|
||||
</.header>
|
||||
|
||||
<.simple_form
|
||||
for={@form}
|
||||
id="registration_form"
|
||||
phx-submit="save"
|
||||
phx-change="validate"
|
||||
phx-trigger-action={@trigger_submit}
|
||||
action={~p"/users/log_in?_action=registered"}
|
||||
method="post"
|
||||
>
|
||||
<.error :if={@check_errors}>
|
||||
Oops, something went wrong! Please check the errors below.
|
||||
</.error>
|
||||
|
||||
<.input field={@form[:email]} type="email" label="Email" required />
|
||||
<.input field={@form[:password]} type="password" label="Password" required />
|
||||
|
||||
<:actions>
|
||||
<.button phx-disable-with="Creating account..." class="w-full">Create an account</.button>
|
||||
</:actions>
|
||||
</.simple_form>
|
||||
</div>
|
||||
"""
|
||||
end
|
||||
|
||||
def mount(_params, _session, socket) do
|
||||
changeset = Users.change_user_registration(%User{})
|
||||
|
||||
socket =
|
||||
socket
|
||||
|> assign(trigger_submit: false, check_errors: false)
|
||||
|> assign_form(changeset)
|
||||
|
||||
{:ok, socket, temporary_assigns: [form: nil]}
|
||||
end
|
||||
|
||||
def handle_event("save", %{"user" => user_params}, socket) do
|
||||
case Users.register_user(user_params) do
|
||||
{:ok, user} ->
|
||||
{:ok, _} =
|
||||
Users.deliver_user_confirmation_instructions(
|
||||
user,
|
||||
&url(~p"/users/confirm/#{&1}")
|
||||
)
|
||||
|
||||
changeset = Users.change_user_registration(user)
|
||||
{:noreply, socket |> assign(trigger_submit: true) |> assign_form(changeset)}
|
||||
|
||||
{:error, %Ecto.Changeset{} = changeset} ->
|
||||
{:noreply, socket |> assign(check_errors: true) |> assign_form(changeset)}
|
||||
end
|
||||
end
|
||||
|
||||
def handle_event("validate", %{"user" => user_params}, socket) do
|
||||
changeset = Users.change_user_registration(%User{}, user_params)
|
||||
{:noreply, assign_form(socket, Map.put(changeset, :action, :validate))}
|
||||
end
|
||||
|
||||
defp assign_form(socket, %Ecto.Changeset{} = changeset) do
|
||||
form = to_form(changeset, as: "user")
|
||||
|
||||
if changeset.valid? do
|
||||
assign(socket, form: form, check_errors: false)
|
||||
else
|
||||
assign(socket, form: form)
|
||||
end
|
||||
end
|
||||
end
|
||||
89
lib/zoeyscomputer_web/live/user_reset_password_live.ex
Normal file
89
lib/zoeyscomputer_web/live/user_reset_password_live.ex
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
defmodule ZoeyscomputerWeb.UserResetPasswordLive do
|
||||
use ZoeyscomputerWeb, :live_view
|
||||
|
||||
alias Zoeyscomputer.Users
|
||||
|
||||
def render(assigns) do
|
||||
~H"""
|
||||
<div class="mx-auto max-w-sm">
|
||||
<.header class="text-center">Reset Password</.header>
|
||||
|
||||
<.simple_form
|
||||
for={@form}
|
||||
id="reset_password_form"
|
||||
phx-submit="reset_password"
|
||||
phx-change="validate"
|
||||
>
|
||||
<.error :if={@form.errors != []}>
|
||||
Oops, something went wrong! Please check the errors below.
|
||||
</.error>
|
||||
|
||||
<.input field={@form[:password]} type="password" label="New password" required />
|
||||
<.input
|
||||
field={@form[:password_confirmation]}
|
||||
type="password"
|
||||
label="Confirm new password"
|
||||
required
|
||||
/>
|
||||
<:actions>
|
||||
<.button phx-disable-with="Resetting..." class="w-full">Reset Password</.button>
|
||||
</:actions>
|
||||
</.simple_form>
|
||||
|
||||
<p class="text-center text-sm mt-4">
|
||||
<.link href={~p"/users/register"}>Register</.link>
|
||||
| <.link href={~p"/users/log_in"}>Log in</.link>
|
||||
</p>
|
||||
</div>
|
||||
"""
|
||||
end
|
||||
|
||||
def mount(params, _session, socket) do
|
||||
socket = assign_user_and_token(socket, params)
|
||||
|
||||
form_source =
|
||||
case socket.assigns do
|
||||
%{user: user} ->
|
||||
Users.change_user_password(user)
|
||||
|
||||
_ ->
|
||||
%{}
|
||||
end
|
||||
|
||||
{:ok, assign_form(socket, form_source), temporary_assigns: [form: nil]}
|
||||
end
|
||||
|
||||
# Do not log in the user after reset password to avoid a
|
||||
# leaked token giving the user access to the account.
|
||||
def handle_event("reset_password", %{"user" => user_params}, socket) do
|
||||
case Users.reset_user_password(socket.assigns.user, user_params) do
|
||||
{:ok, _} ->
|
||||
{:noreply,
|
||||
socket
|
||||
|> put_flash(:info, "Password reset successfully.")
|
||||
|> redirect(to: ~p"/users/log_in")}
|
||||
|
||||
{:error, changeset} ->
|
||||
{:noreply, assign_form(socket, Map.put(changeset, :action, :insert))}
|
||||
end
|
||||
end
|
||||
|
||||
def handle_event("validate", %{"user" => user_params}, socket) do
|
||||
changeset = Users.change_user_password(socket.assigns.user, user_params)
|
||||
{:noreply, assign_form(socket, Map.put(changeset, :action, :validate))}
|
||||
end
|
||||
|
||||
defp assign_user_and_token(socket, %{"token" => token}) do
|
||||
if user = Users.get_user_by_reset_password_token(token) do
|
||||
assign(socket, user: user, token: token)
|
||||
else
|
||||
socket
|
||||
|> put_flash(:error, "Reset password link is invalid or it has expired.")
|
||||
|> redirect(to: ~p"/")
|
||||
end
|
||||
end
|
||||
|
||||
defp assign_form(socket, %{} = source) do
|
||||
assign(socket, :form, to_form(source, as: "user"))
|
||||
end
|
||||
end
|
||||
167
lib/zoeyscomputer_web/live/user_settings_live.ex
Normal file
167
lib/zoeyscomputer_web/live/user_settings_live.ex
Normal file
|
|
@ -0,0 +1,167 @@
|
|||
defmodule ZoeyscomputerWeb.UserSettingsLive do
|
||||
use ZoeyscomputerWeb, :live_view
|
||||
|
||||
alias Zoeyscomputer.Users
|
||||
|
||||
def render(assigns) do
|
||||
~H"""
|
||||
<.header class="text-center">
|
||||
Account Settings
|
||||
<:subtitle>Manage your account email address and password settings</:subtitle>
|
||||
</.header>
|
||||
|
||||
<div class="space-y-12 divide-y">
|
||||
<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 />
|
||||
<.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
|
||||
/>
|
||||
<:actions>
|
||||
<.button phx-disable-with="Changing...">Change Email</.button>
|
||||
</:actions>
|
||||
</.simple_form>
|
||||
</div>
|
||||
<div>
|
||||
<.simple_form
|
||||
for={@password_form}
|
||||
id="password_form"
|
||||
action={~p"/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 />
|
||||
<.input
|
||||
field={@password_form[:password_confirmation]}
|
||||
type="password"
|
||||
label="Confirm new password"
|
||||
/>
|
||||
<.input
|
||||
field={@password_form[:current_password]}
|
||||
name="current_password"
|
||||
type="password"
|
||||
label="Current password"
|
||||
id="current_password_for_password"
|
||||
value={@current_password}
|
||||
required
|
||||
/>
|
||||
<:actions>
|
||||
<.button phx-disable-with="Changing...">Change Password</.button>
|
||||
</:actions>
|
||||
</.simple_form>
|
||||
</div>
|
||||
</div>
|
||||
"""
|
||||
end
|
||||
|
||||
def mount(%{"token" => token}, _session, socket) do
|
||||
socket =
|
||||
case Users.update_user_email(socket.assigns.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: ~p"/users/settings")}
|
||||
end
|
||||
|
||||
def mount(_params, _session, socket) do
|
||||
user = socket.assigns.current_user
|
||||
email_changeset = Users.change_user_email(user)
|
||||
password_changeset = Users.change_user_password(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(: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.current_user
|
||||
|> Users.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.current_user
|
||||
|
||||
case Users.apply_user_email(user, password, user_params) do
|
||||
{:ok, applied_user} ->
|
||||
Users.deliver_user_update_email_instructions(
|
||||
applied_user,
|
||||
user.email,
|
||||
&url(~p"/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.current_user
|
||||
|> Users.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.current_user
|
||||
|
||||
case Users.update_user_password(user, password, user_params) do
|
||||
{:ok, user} ->
|
||||
password_form =
|
||||
user
|
||||
|> Users.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
|
||||
end
|
||||
Loading…
Add table
Add a link
Reference in a new issue