login.ex (4000B)
1 defmodule DailyTrackerWeb.UserLive.Login do 2 use DailyTrackerWeb, :live_view 3 4 alias DailyTracker.Accounts 5 6 @impl true 7 def render(assigns) do 8 ~H""" 9 <Layouts.app flash={@flash} current_scope={@current_scope}> 10 <div class="mx-auto max-w-sm space-y-4"> 11 <div class="text-center"> 12 <.header> 13 <p>Log in</p> 14 <:subtitle> 15 <%= if @current_scope do %> 16 You need to reauthenticate to perform sensitive actions on your account. 17 <% else %> 18 Don't have an account? <.link 19 navigate={~p"/users/register"} 20 class="font-semibold text-brand hover:underline" 21 phx-no-format 22 >Sign up</.link> for an account now. 23 <% end %> 24 </:subtitle> 25 </.header> 26 </div> 27 28 <div :if={local_mail_adapter?()} class="alert alert-info"> 29 <.icon name="hero-information-circle" class="size-6 shrink-0" /> 30 <div> 31 <p>You are running the local mail adapter.</p> 32 <p> 33 To see sent emails, visit <.link href="/dev/mailbox" class="underline">the mailbox page</.link>. 34 </p> 35 </div> 36 </div> 37 38 <.form 39 :let={f} 40 for={@form} 41 id="login_form_magic" 42 action={~p"/users/log-in"} 43 phx-submit="submit_magic" 44 > 45 <.input 46 readonly={!!@current_scope} 47 field={f[:email]} 48 type="email" 49 label="Email" 50 autocomplete="username" 51 spellcheck="false" 52 required 53 phx-mounted={JS.focus()} 54 /> 55 <.button class="btn btn-primary w-full"> 56 Log in with email <span aria-hidden="true">→</span> 57 </.button> 58 </.form> 59 60 <div class="divider">or</div> 61 62 <.form 63 :let={f} 64 for={@form} 65 id="login_form_password" 66 action={~p"/users/log-in"} 67 phx-submit="submit_password" 68 phx-trigger-action={@trigger_submit} 69 > 70 <.input 71 readonly={!!@current_scope} 72 field={f[:email]} 73 type="email" 74 label="Email" 75 autocomplete="username" 76 spellcheck="false" 77 required 78 /> 79 <.input 80 field={@form[:password]} 81 type="password" 82 label="Password" 83 autocomplete="current-password" 84 spellcheck="false" 85 /> 86 <.button class="btn btn-primary w-full" name={@form[:remember_me].name} value="true"> 87 Log in and stay logged in <span aria-hidden="true">→</span> 88 </.button> 89 <.button class="btn btn-primary btn-soft w-full mt-2"> 90 Log in only this time 91 </.button> 92 </.form> 93 </div> 94 </Layouts.app> 95 """ 96 end 97 98 @impl true 99 def mount(_params, _session, socket) do 100 email = 101 Phoenix.Flash.get(socket.assigns.flash, :email) || 102 get_in(socket.assigns, [:current_scope, Access.key(:user), Access.key(:email)]) 103 104 form = to_form(%{"email" => email}, as: "user") 105 106 {:ok, assign(socket, form: form, trigger_submit: false)} 107 end 108 109 @impl true 110 def handle_event("submit_password", _params, socket) do 111 {:noreply, assign(socket, :trigger_submit, true)} 112 end 113 114 def handle_event("submit_magic", %{"user" => %{"email" => email}}, socket) do 115 if user = Accounts.get_user_by_email(email) do 116 Accounts.deliver_login_instructions( 117 user, 118 &url(~p"/users/log-in/#{&1}") 119 ) 120 end 121 122 info = 123 "If your email is in our system, you will receive instructions for logging in shortly." 124 125 {:noreply, 126 socket 127 |> put_flash(:info, info) 128 |> push_navigate(to: ~p"/users/log-in")} 129 end 130 131 defp local_mail_adapter? do 132 Application.get_env(:daily_tracker, DailyTracker.Mailer)[:adapter] == Swoosh.Adapters.Local 133 end 134 end