Skip to content

Instantly share code, notes, and snippets.

@mplatts
Created November 25, 2021 21:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mplatts/3ddcd839674e99ad581a5aaaaf8ddd3e to your computer and use it in GitHub Desktop.
Save mplatts/3ddcd839674e99ad581a5aaaaf8ddd3e to your computer and use it in GitHub Desktop.
Elixir Phoenix LiveView
defmodule PetalProWeb.RegisterLive do
use PetalProWeb, :live_view
alias PetalPro.{Accounts, Repo}
alias PetalPro.Accounts.{User}
def mount(params, _session, socket) do
socket =
assign(socket, %{
user_return_to: Map.get(params, "user_return_to", nil),
error_message: nil,
changeset: nil,
email: nil,
confirmation_email_sent?: false
})
{:ok, socket}
end
def render(assigns) do
~H"""
<.simple_layout current={:register}>
<div class="flex flex-col justify-center py-12 sm:px-6 lg:px-8">
<div class="text-center sm:mx-auto sm:w-full sm:max-w-md">
<.h2>Register</.h2>
<.p>
Already registered?
<%= live_patch "Sign in", [
to: Routes.live_path(@socket, PetalProWeb.SignInLive, user_return_to: @user_return_to),
class: "text-blue-600 underline"
] %>
</.p>
</div>
</div>
<div class="sm:mx-auto sm:w-full sm:max-w-md">
<div class="px-4 py-8 bg-white shadow sm:rounded-lg sm:px-10 dark:bg-gray-800">
<%= if !@email && !@confirmation_email_sent? do %>
<.form id="email-form" let={f} for={:user} phx-submit="submit_email">
<.form_field type="text_input" form={f} field={:email} placeholder="eg. sarah@gmail.com" />
<.alert state="warning" size="sm" label={@error_message} class="mt-5" />
<div class="flex justify-end mt-6">
<.button label="Next" phx-disable-with="Loading..." />
</div>
</.form>
<% end %>
<%= if @email && @changeset do %>
<.form id="user-details-form" let={f} for={@changeset} phx-submit="register">
<.form_label form={f} field={:email} />
<%= hidden_input f, :email %>
<div class="mb-6 italic text-gray-500"><%= @email %></div>
<.form_field type="text_input" form={f} field={:name} />
<.form_field type="password_input" form={f} field={:password} />
<div class="flex justify-between mt-6">
<.button color="white" label="Back" phx-click="start_over" />
<.button label="Create account" phx-disable-with="Loading..." />
</div>
</.form>
<% end %>
<%= if @confirmation_email_sent? do %>
<.alert type="info">Please check your email for a confirmation link</.alert>
<% end %>
</div>
</div>
</.simple_layout>
"""
end
def handle_event("submit_email", %{"user" => %{"email" => email}}, socket) do
email = Util.trim(email)
socket = with true <- EmailChecker.valid?(email),
nil <- Repo.get_by(User, email: email) do
assign(socket, [
email: email,
changeset: Accounts.change_user_registration(%User{}, %{email: email}),
error_message: nil
])
else
false ->
assign(socket, error_message: "\"#{email}\" is not a valid email.")
%User{} = _user ->
socket
|> push_redirect(to: Routes.live_path(socket, PetalProWeb.SignInLive))
|> put_flash(:info, "You already have an account. Please sign in.")
end
{:noreply, socket}
end
def handle_event("register", %{"user" => user_params}, socket) do
case Accounts.register_user(user_params) do
{:ok, user} ->
PetalPro.Logs.log_async("register", %{user_id: user.id})
{:ok, _} =
Accounts.deliver_user_confirmation_instructions(
user,
&Routes.user_confirmation_url(socket, :edit, &1)
)
{:noreply, assign(socket, %{
changeset: nil,
email: nil,
confirmation_email_sent?: true
})}
{:error, %Ecto.Changeset{} = changeset} ->
{:noreply, assign(socket, %{changeset: changeset})}
end
end
def handle_event("start_over", _, socket) do
{:noreply,
assign(socket, %{
email: nil,
changeset: nil
})}
end
end
defmodule PetalProWeb.SignInLive do
use PetalProWeb, :live_view
def mount(params, _session, socket) do
socket =
assign(socket, %{
user_return_to: Map.get(params, "user_return_to", nil),
sign_in_token: nil,
error: nil
})
{:ok, socket}
end
def render(assigns) do
~H"""
<.simple_layout current={:sign_in}>
<div class="flex flex-col justify-center py-12 sm:px-6 lg:px-8">
<div class="text-center sm:mx-auto sm:w-full sm:max-w-md">
<.h2>Sign in</.h2>
<.p>
Not yet registered?
<.link
type="live_redirect"
label="Register"
class="text-blue-600 underline"
to={Routes.live_path(@socket, PetalProWeb.RegisterLive, user_return_to: @user_return_to)}
/>
</.p>
</div>
</div>
<div class="sm:mx-auto sm:w-full sm:max-w-md">
<div class="px-4 py-8 bg-white shadow sm:rounded-lg sm:px-10 dark:bg-gray-800">
<.form
id="sign-in-form"
let={f}
for={:user}
action={Routes.user_session_path(@socket, :create)}
>
<.alert state="danger" label={@error} class="mb-5" />
<.form_field type="email_input" form={f} field={:email} />
<.form_field type="password_input" form={f} field={:password} />
<.form_field type="checkbox" form={f} field={:remember_me} />
<div class="flex justify-end mt-6">
<.button label="Sign in" />
</div>
</.form>
</div>
</div>
</.simple_layout>
"""
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment