Merge pull request '95-fix-home-screen-account-button-ui' (#124) from 95-fix-home-screen-account-button-ui into main

Reviewed-on: LibreTunes/LibreTunes#124
This commit is contained in:
Ethan Girouard 2024-11-22 22:32:53 +00:00
commit 9b48fc0204
4 changed files with 126 additions and 28 deletions

View File

@ -87,6 +87,7 @@ pub async fn logout() -> Result<(), ServerFnError> {
auth_session.logout().await auth_session.logout().await
.map_err(|e| ServerFnError::<NoCustomError>::ServerError(format!("Error getting auth session: {}", e)))?; .map_err(|e| ServerFnError::<NoCustomError>::ServerError(format!("Error getting auth session: {}", e)))?;
leptos_axum::redirect("/login");
Ok(()) Ok(())
} }

View File

@ -1,6 +1,8 @@
use leptos::leptos_dom::*; use leptos::leptos_dom::*;
use leptos::*; use leptos::*;
use leptos_icons::*; use leptos_icons::*;
use crate::auth::logout;
use crate::util::state::GlobalState;
#[component] #[component]
pub fn Personal() -> impl IntoView { pub fn Personal() -> impl IntoView {
@ -14,18 +16,66 @@ pub fn Personal() -> impl IntoView {
#[component] #[component]
pub fn Profile() -> impl IntoView { pub fn Profile() -> impl IntoView {
let (dropdown_open, set_dropdown_open) = create_signal(false); let (dropdown_open, set_dropdown_open) = create_signal(false);
let user = GlobalState::logged_in_user();
let open_dropdown = move |_| { let open_dropdown = move |_| {
set_dropdown_open.update(|value| *value = !*value); set_dropdown_open.update(|value| *value = !*value);
log!("opened dropdown");
}; };
let user_profile_picture = move || {
user.get().and_then(|user| {
if let Some(user) = user {
if user.id.is_none() {
return None;
}
Some(format!("/assets/images/profile/{}.webp", user.id.unwrap()))
} else {
None
}
})
};
view! { view! {
<div class="profile-container"> <div class="profile-container">
<div class="profile-name">
<Suspense
fallback=|| view!{
<h1>Not Logged In</h1>
}>
<Show
when=move || user.get().map(|user| user.is_some()).unwrap_or(false)
fallback=|| view!{
<h1>Not Logged In</h1>
}>
<h1>{move || user.get().map(|user| user.map(|user| user.username))}</h1>
</Show>
</Suspense>
</div>
<div class="profile-icon" on:click=open_dropdown> <div class="profile-icon" on:click=open_dropdown>
<Icon icon=icondata::CgProfile /> <Suspense fallback=|| view! { <Icon icon=icondata::CgProfile width="45" height="45"/> }>
<Show
when=move || user.get().map(|user| user.is_some()).unwrap_or(false)
fallback=|| view! { <Icon icon=icondata::CgProfile width="45" height="45"/> }
>
<object class="profile-image" data={user_profile_picture} type="image/webp">
<Icon class="profile-image" icon=icondata::CgProfile width="45" height="45"/>
</object>
</Show>
</Suspense>
</div> </div>
<div class="dropdown-container" style={move || if dropdown_open() {"display: flex"} else {"display: none"}}> <div class="dropdown-container" style={move || if dropdown_open() {"display: flex"} else {"display: none"}}>
<Suspense
fallback=|| view!{
<DropDownNotLoggedIn /> <DropDownNotLoggedIn />
}>
<Show
when=move || user.get().map(|user| user.is_some()).unwrap_or(false)
fallback=|| view!{
<DropDownNotLoggedIn />
}>
<DropDownLoggedIn />
</Show>
</Suspense>
</div> </div>
</div> </div>
} }
@ -33,10 +83,33 @@ pub fn Profile() -> impl IntoView {
#[component] #[component]
pub fn DropDownNotLoggedIn() -> impl IntoView { pub fn DropDownNotLoggedIn() -> impl IntoView {
view! { view! {
<div class="dropdown-not-logged"> <div class="dropdown-logged">
<h1>Not Logged in!</h1> <h1>Not Logged In</h1>
<a href="/login"><button class="auth-button">Log In</button></a> <a href="/login"><button class="auth-button">Log In</button></a>
<a href="/signup"><button class="auth-button">Sign up</button></a> <a href="/signup"><button class="auth-button">Sign Up</button></a>
</div>
}
}
#[component]
pub fn DropDownLoggedIn() -> impl IntoView {
let logout = move |_| {
spawn_local(async move {
let result = logout().await;
if let Err(err) = result {
log!("Error logging out: {:?}", err);
} else {
let user = GlobalState::logged_in_user();
user.refetch();
log!("Logged out successfully");
}
});
};
view! {
<div class="dropdown-logged">
<h1>"Logged In"</h1>
<button on:click=logout class="auth-button">Log Out</button>
</div> </div>
} }
} }

View File

@ -117,7 +117,7 @@ pub async fn validate_user(credentials: UserCredentials) -> Result<Option<User>,
/// Get a user from the database by username or email /// Get a user from the database by username or email
/// Returns a Result with the user if found, None if not found, or an error if there was a problem /// Returns a Result with the user if found, None if not found, or an error if there was a problem
#[server(endpoint = "get_user")] #[server(endpoint = "find_user")]
pub async fn get_user(username_or_email: String) -> Result<Option<User>, ServerFnError> { pub async fn get_user(username_or_email: String) -> Result<Option<User>, ServerFnError> {
let mut user = find_user(username_or_email).await?; let mut user = find_user(username_or_email).await?;

View File

@ -11,9 +11,19 @@
border-radius: 0.4rem; border-radius: 0.4rem;
margin: 0.2rem; margin: 0.2rem;
min-height: 6rem; min-height: 6rem;
border: 2px solid rgba(89, 89, 89, 0.199); border: 0.2rem solid rgba(89, 89, 89, 0.199);
padding: 0.5rem; padding: 0.5rem;
.profile-name {
display: flex;
flex-direction: column;
margin-left: 0.5rem;
h1 {
font-size: 1.2rem;
margin: 0;
}
}
.profile-icon { .profile-icon {
display: inline-flex; display: inline-flex;
padding: 0.2rem; padding: 0.2rem;
@ -21,17 +31,23 @@
font-size: 2rem; font-size: 2rem;
border-radius: 50%; border-radius: 50%;
transition: all 0.3s; transition: all 0.3s;
height: max-content; height: 45;
width: 45;
margin-left: auto; margin-left: auto;
.profile-image {
width: 100%;
height: 100%;
border-radius: 50%;
}
} }
.profile-icon:hover { .profile-icon:hover {
transform: scale(1.1); transform: scale(1.05);
background-color: rgba(255, 255, 255, 0.1); background-color: rgba(255, 255, 255, 0.1);
} }
.profile-icon:active { .profile-icon:active {
transform: scale(0.8); transform: scale(0.95);
} }
.dropdown-container { .dropdown-container {
position: absolute; position: absolute;
@ -41,10 +57,10 @@
border-radius: 0.5rem; border-radius: 0.5rem;
width: 10rem; width: 10rem;
z-index: 1; z-index: 1;
background-color: red; background-color: #1c1c1c;
border: 1px solid grey; border: 0.2rem solid rgba(89, 89, 89, 0.199);
.dropdown-not-logged { .dropdown-logged {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
width: 100%; width: 100%;
@ -53,21 +69,29 @@
h1 { h1 {
font-size: 1.2rem; font-size: 1.2rem;
} }
.profile-info {
display: flex;
width: 100%;
justify-content: center;
border-top: 0.2rem solid rgba(89, 89, 89, 0.199);
border-bottom: 0.2rem solid rgba(89, 89, 89, 0.199);
h1 {
font-size: 1rem;
margin-top: 0.5rem;
}
}
.auth-button { .auth-button {
margin-top: 0.5rem;
padding: 0.5rem;
border-radius: 0.5rem;
background-color: #1c1c1c;
border: 0.2rem solid rgba(89, 89, 89, 0.199);
color: white;
cursor: pointer;
transition: all 0.3s;
margin-bottom: 0.5rem;
} }
} }
} }
.dropdown-container:before {
content: "";
position: absolute;
top: -0.4rem;
right: 0.92rem;
width: 10px;
height: 10px;
transform: rotate(45deg);
background-color: red;
border-left: 1px solid grey;
border-top: 1px solid grey;
}
} }
} }