Merge branch '14-create-login-signup-page' into 'main'

Create login and signup pages

Closes #14

See merge request libretunes/libretunes!10
This commit is contained in:
2024-02-29 20:47:16 -05:00
11 changed files with 533 additions and 1 deletions

View File

@ -1,6 +1,8 @@
use leptos::*;
use leptos_meta::*;
use leptos_router::*;
use crate::pages::login::*;
use crate::pages::signup::*;
#[component]
pub fn App() -> impl IntoView {
@ -21,6 +23,8 @@ pub fn App() -> impl IntoView {
<Routes>
<Route path="" view=HomePage/>
<Route path="/*any" view=NotFound/>
<Route path="/login" view=Login />
<Route path="/signup" view=Signup />
</Routes>
</main>
</Router>

View File

@ -5,6 +5,7 @@ pub mod playstatus;
pub mod playbar;
pub mod database;
pub mod models;
pub mod pages;
pub mod users;
pub mod search;
use cfg_if::cfg_if;

2
src/pages.rs Normal file
View File

@ -0,0 +1,2 @@
pub mod login;
pub mod signup;

91
src/pages/login.rs Normal file
View File

@ -0,0 +1,91 @@
use crate::auth::login;
use leptos::leptos_dom::*;
use leptos::*;
use leptos_icons::AiIcon::*;
use leptos_icons::IoIcon::*;
use leptos_icons::*;
#[component]
pub fn Login() -> impl IntoView {
let (username_or_email, set_username_or_email) = create_signal("".to_string());
let (password, set_password) = create_signal("".to_string());
let (show_password, set_show_password) = create_signal(false);
let toggle_password = move |_| {
set_show_password.update(|show_password| *show_password = !*show_password);
log!("showing password");
};
let on_submit = move |ev: leptos::ev::SubmitEvent| {
ev.prevent_default();
let username_or_email1 = username_or_email.get();
let password1 = password.get();
spawn_local(async move {
let login_result = login(username_or_email1, password1).await;
if let Err(err) = login_result {
// Handle the error here, e.g., log it or display to the user
log!("Error logging in: {:?}", err);
} else if let Ok(true) = login_result {
// Redirect to the login page
log!("Logged in Successfully!");
leptos_router::use_navigate()("/", Default::default());
log!("Navigated to home page after login");
} else if let Ok(false) = login_result {
log!("Invalid username or password");
}
});
};
view! {
<div class="auth-page-container">
<div class="login-container">
<a class="return" href="/"><Icon icon=Icon::from(IoReturnUpBackSharp) /></a>
<div class="header">
<h1>LibreTunes</h1>
</div>
<form class="login-form" action="POST" on:submit=on_submit>
<div class="input-box">
<input class="login-info" type="text" required
on:input = move |ev| {
set_username_or_email(event_target_value(&ev));
log!("username/email changed to: {}", username_or_email.get());
}
prop:value=username_or_email
/>
<span>Username/Email</span>
<i></i>
</div>
<div class="input-box">
<input class="login-password" type={move || if show_password() { "text" } else { "password"} } required
on:input = move |ev| {
set_password(event_target_value(&ev));
log!("password changed to: {}", password.get());
}
/>
<span>Password</span>
<i></i>
<Show
when=move || {show_password() == false}
fallback=move || view!{ <button on:click=toggle_password class="login-password-visibility">
<Icon icon=Icon::from(AiEyeInvisibleFilled) />
</button> /> }
>
<button on:click=toggle_password class="login-password-visibility">
<Icon icon=Icon::from(AiEyeFilled) />
</button>
</Show>
</div>
<a href="" class="forgot-pw">Forgot Password?</a>
<input type="submit" value="Login" />
<span class="go-to-signup">
New here? <a href="/signup">Create an Account</a>
</span>
</form>
</div>
</div>
}
}

104
src/pages/signup.rs Normal file
View File

@ -0,0 +1,104 @@
use crate::auth::signup;
use crate::models::User;
use leptos::ev::input;
use leptos::leptos_dom::*;
use leptos::*;
use leptos_icons::AiIcon::*;
use leptos_icons::IoIcon::*;
use leptos_icons::*;
#[component]
pub fn Signup() -> impl IntoView {
let (username, set_username) = create_signal("".to_string());
let (email, set_email) = create_signal("".to_string());
let (password, set_password) = create_signal("".to_string());
let (show_password, set_show_password) = create_signal(false);
let navigate = leptos_router::use_navigate();
let toggle_password = move |_| {
set_show_password.update(|show_password| *show_password = !*show_password);
log!("showing password");
};
let on_submit = move |ev: leptos::ev::SubmitEvent| {
ev.prevent_default();
let new_user = User {
id: None,
username: username.get(),
email: email.get(),
password: Some(password.get()),
created_at: None,
};
log!("new user: {:?}", new_user);
spawn_local(async move {
if let Err(err) = signup(new_user).await {
// Handle the error here, e.g., log it or display to the user
log!("Error signing up: {:?}", err);
} else {
// Redirect to the login page
log!("Signed up successfully!");
leptos_router::use_navigate()("/", Default::default());
log!("Navigated to home page after signup")
}
});
};
view! {
<div class="auth-page-container">
<div class="signup-container">
<a class="return" href="/"><Icon icon=Icon::from(IoReturnUpBackSharp) /></a>
<div class="header">
<h1>LibreTunes</h1>
</div>
<form class="signup-form" action="POST" on:submit=on_submit>
<div class="input-box">
<input class="signup-email" type="text" required
on:input = move |ev| {
set_email(event_target_value(&ev));
log!("email changed to: {}", email.get());
}
prop:value=email
/>
<span>Email</span>
<i></i>
</div>
<div class="input-box">
<input class="signup-username" type="text" required
on:input = move |ev| {
set_username(event_target_value(&ev));
log!("username changed to: {}", username.get());
}
/>
<span>Username</span>
<i></i>
</div>
<div class="input-box">
<input class="signup-password" type={move || if show_password() { "text" } else { "password"} } required style="width: 90%;"
on:input = move |ev| {
set_password(event_target_value(&ev));
log!("password changed to: {}", password.get());
}
/>
<span>Password</span>
<i></i>
<Show
when=move || {show_password() == false}
fallback=move || view!{ <button on:click=toggle_password class="password-visibility"> <Icon icon=Icon::from(AiEyeInvisibleFilled) /></button> /> }
>
<button on:click=toggle_password class="password-visibility">
<Icon icon=Icon::from(AiEyeFilled) />
</button>
</Show>
</div>
<input type="submit" value="Sign Up" />
<span class="go-to-login">
Already Have an Account? <a href="/login" class="link" >Go to Login</a>
</span>
</form>
</div>
</div>
}
}