login.rs
⎇
Raw
1use leptos::prelude::*;
2use wasm_bindgen_futures::spawn_local;
3
4use crate::api::{self, input_value, Me};
5use crate::app::AuthPhase;
6
7#[component]
8pub fn LoginView(
9 set_me: WriteSignal<Option<Me>>,
10 set_phase: WriteSignal<AuthPhase>,
11) -> impl IntoView {
12 let (error, set_error) = signal(String::new());
13 let (busy, set_busy) = signal(false);
14
15 let on_submit = move |ev: web_sys::SubmitEvent| {
16 ev.prevent_default();
17 let name = input_value("login-name");
18 let pass = input_value("login-pass");
19 if name.trim().is_empty() || pass.is_empty() {
20 set_error.set("Please enter your name and password.".into());
21 return;
22 }
23 set_error.set(String::new());
24 set_busy.set(true);
25 let name = name.trim().to_string();
26 spawn_local(async move {
27 match api::login(name, pass).await {
28 Ok(_) => match api::me().await {
29 Ok(m) => {
30 set_me.set(Some(m));
31 set_phase.set(AuthPhase::Authed);
32 }
33 Err(e) => {
34 set_error.set(e.to_string());
35 set_busy.set(false);
36 }
37 },
38 Err(e) => {
39 set_error.set(e.to_string());
40 set_busy.set(false);
41 }
42 }
43 });
44 };
45
46 view! {
47 <div class="center-screen">
48 <div class="card auth-card">
49 <h1>"filebrowser-ng"</h1>
50 <p class="muted">"Sign in to continue."</p>
51 <form on:submit=on_submit>
52 <label class="field">
53 <span>"Name"</span>
54 <input
55 id="login-name"
56 type="text"
57 autofocus=true
58 autocomplete="username"
59 />
60 </label>
61 <label class="field">
62 <span>"Password"</span>
63 <input
64 id="login-pass"
65 type="password"
66 autocomplete="current-password"
67 />
68 </label>
69 <p class="error">{move || error.get()}</p>
70 <button class="btn-primary" type="submit" disabled=move || busy.get()>
71 "Sign in"
72 </button>
73 </form>
74 </div>
75 </div>
76 }
77}
78