Merge branch '22-create-home-page-2' into 'main'
Created initial home page outline Closes #22 See merge request libretunes/libretunes!20
This commit is contained in:
commit
6c74220458
18
src/app.rs
18
src/app.rs
@ -8,6 +8,7 @@ use crate::pages::login::*;
|
|||||||
use crate::pages::signup::*;
|
use crate::pages::signup::*;
|
||||||
use crate::error_template::{AppError, ErrorTemplate};
|
use crate::error_template::{AppError, ErrorTemplate};
|
||||||
|
|
||||||
|
|
||||||
#[component]
|
#[component]
|
||||||
pub fn App() -> impl IntoView {
|
pub fn App() -> impl IntoView {
|
||||||
// Provides context that manages stylesheets, titles, meta tags, etc.
|
// Provides context that manages stylesheets, titles, meta tags, etc.
|
||||||
@ -41,15 +42,32 @@ pub fn App() -> impl IntoView {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
use crate::components::sidebar::*;
|
||||||
|
use crate::components::dashboard::*;
|
||||||
|
use crate::components::search::*;
|
||||||
|
use crate::components::personal::*;
|
||||||
|
|
||||||
/// Renders the home page of your application.
|
/// Renders the home page of your application.
|
||||||
#[component]
|
#[component]
|
||||||
fn HomePage() -> impl IntoView {
|
fn HomePage() -> impl IntoView {
|
||||||
let play_status = PlayStatus::default();
|
let play_status = PlayStatus::default();
|
||||||
let play_status = create_rw_signal(play_status);
|
let play_status = create_rw_signal(play_status);
|
||||||
|
|
||||||
|
let (dashboard_open, set_dashboard_open) = create_signal(true);
|
||||||
|
|
||||||
view! {
|
view! {
|
||||||
|
<div class="home-container">
|
||||||
|
<Sidebar setter=set_dashboard_open active=dashboard_open />
|
||||||
|
<Show
|
||||||
|
when=move || {dashboard_open() == true}
|
||||||
|
fallback=move || view! { <Search /> }
|
||||||
|
>
|
||||||
|
<Dashboard />
|
||||||
|
</Show>
|
||||||
|
<Personal />
|
||||||
<PlayBar status=play_status/>
|
<PlayBar status=play_status/>
|
||||||
<Queue status=play_status/>
|
<Queue status=play_status/>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
4
src/components.rs
Normal file
4
src/components.rs
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
pub mod sidebar;
|
||||||
|
pub mod dashboard;
|
||||||
|
pub mod search;
|
||||||
|
pub mod personal;
|
10
src/components/dashboard.rs
Normal file
10
src/components/dashboard.rs
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
use leptos::*;
|
||||||
|
|
||||||
|
#[component]
|
||||||
|
pub fn Dashboard() -> impl IntoView {
|
||||||
|
view! {
|
||||||
|
<div class="dashboard-container home-component">
|
||||||
|
<h1 class="dashboard-header">Dashboard</h1>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
42
src/components/personal.rs
Normal file
42
src/components/personal.rs
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
use leptos::leptos_dom::*;
|
||||||
|
use leptos::*;
|
||||||
|
use leptos_icons::*;
|
||||||
|
|
||||||
|
#[component]
|
||||||
|
pub fn Personal() -> impl IntoView {
|
||||||
|
view! {
|
||||||
|
<div class=" personal-container">
|
||||||
|
<Profile />
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[component]
|
||||||
|
pub fn Profile() -> impl IntoView {
|
||||||
|
let (dropdown_open, set_dropdown_open) = create_signal(false);
|
||||||
|
|
||||||
|
let open_dropdown = move |_| {
|
||||||
|
set_dropdown_open.update(|value| *value = !*value);
|
||||||
|
log!("opened dropdown");
|
||||||
|
};
|
||||||
|
view! {
|
||||||
|
<div class="profile-container">
|
||||||
|
<div class="profile-icon" on:click=open_dropdown>
|
||||||
|
<Icon icon=icondata::CgProfile />
|
||||||
|
</div>
|
||||||
|
<div class="dropdown-container" style={move || if dropdown_open() {"display: flex"} else {"display: none"}}>
|
||||||
|
<DropDownNotLoggedIn />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[component]
|
||||||
|
pub fn DropDownNotLoggedIn() -> impl IntoView {
|
||||||
|
view! {
|
||||||
|
<div class="dropdown-not-logged">
|
||||||
|
<h1>Not Logged in!</h1>
|
||||||
|
<a href="/login"><button class="auth-button">Log In</button></a>
|
||||||
|
<a href="/signup"><button class="auth-button">Sign up</button></a>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
10
src/components/search.rs
Normal file
10
src/components/search.rs
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
use leptos::*;
|
||||||
|
|
||||||
|
#[component]
|
||||||
|
pub fn Search() -> impl IntoView {
|
||||||
|
view! {
|
||||||
|
<div class="search-container home-component">
|
||||||
|
<h1>Searching...</h1>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
50
src/components/sidebar.rs
Normal file
50
src/components/sidebar.rs
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
use leptos::leptos_dom::*;
|
||||||
|
use leptos::*;
|
||||||
|
use leptos_icons::*;
|
||||||
|
|
||||||
|
#[component]
|
||||||
|
pub fn Sidebar(setter: WriteSignal<bool>, active: ReadSignal<bool>) -> impl IntoView {
|
||||||
|
let open_dashboard = move |_| {
|
||||||
|
setter.update(|value| *value = true);
|
||||||
|
log!("open dashboard");
|
||||||
|
};
|
||||||
|
let open_search = move |_| {
|
||||||
|
setter.update(|value| *value = false);
|
||||||
|
log!("open search");
|
||||||
|
};
|
||||||
|
|
||||||
|
view! {
|
||||||
|
<div class="sidebar-container">
|
||||||
|
<div class="sidebar-top-container">
|
||||||
|
<h2 class="header">LibreTunes</h2>
|
||||||
|
<div class="buttons" on:click=open_dashboard style={move || if active() {"color: #e1e3e1"} else {""}} >
|
||||||
|
<Icon icon=icondata::OcHomeFillLg />
|
||||||
|
<h1>Dashboard</h1>
|
||||||
|
</div>
|
||||||
|
<div class="buttons" on:click=open_search style={move || if !active() {"color: #e1e3e1"} else {""}}>
|
||||||
|
<Icon icon=icondata::BiSearchRegular />
|
||||||
|
<h1>Search</h1>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<Bottom />
|
||||||
|
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[component]
|
||||||
|
pub fn Bottom() -> impl IntoView {
|
||||||
|
view! {
|
||||||
|
<div class="sidebar-bottom-container">
|
||||||
|
<div class="heading">
|
||||||
|
<h1 class="header">Playlists</h1>
|
||||||
|
<button class="add-playlist">
|
||||||
|
<div class="add-sign">
|
||||||
|
<Icon icon=icondata::IoAddSharp />
|
||||||
|
</div>
|
||||||
|
New Playlist
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
@ -8,6 +8,7 @@ pub mod queue;
|
|||||||
pub mod song;
|
pub mod song;
|
||||||
pub mod models;
|
pub mod models;
|
||||||
pub mod pages;
|
pub mod pages;
|
||||||
|
pub mod components;
|
||||||
pub mod users;
|
pub mod users;
|
||||||
pub mod search;
|
pub mod search;
|
||||||
pub mod fileserv;
|
pub mod fileserv;
|
||||||
|
10
style/dashboard.scss
Normal file
10
style/dashboard.scss
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
@import "theme.scss";
|
||||||
|
|
||||||
|
.dashboard-container {
|
||||||
|
width: calc(100% - 22rem - 16rem);
|
||||||
|
.dashboard-header {
|
||||||
|
font-size: 1.2rem;
|
||||||
|
font-weight: 300;
|
||||||
|
border-bottom: 2px solid white;
|
||||||
|
}
|
||||||
|
}
|
16
style/home.scss
Normal file
16
style/home.scss
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
@import "theme.scss";
|
||||||
|
|
||||||
|
.home-container {
|
||||||
|
margin-top: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100vh;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
}
|
||||||
|
.home-component {
|
||||||
|
background: #1c1c1c;
|
||||||
|
height: 100vh;
|
||||||
|
margin: 2px;
|
||||||
|
padding: 0.2rem 1.5rem 1.5rem 1rem;
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
}
|
@ -1,8 +1,13 @@
|
|||||||
@import 'playbar.scss';
|
@import "playbar.scss";
|
||||||
@import 'theme.scss';
|
@import "theme.scss";
|
||||||
@import 'queue.scss';
|
@import "queue.scss";
|
||||||
@import 'login.scss';
|
@import "login.scss";
|
||||||
@import 'signup.scss';
|
@import "signup.scss";
|
||||||
|
@import "sidebar.scss";
|
||||||
|
@import "dashboard.scss";
|
||||||
|
@import 'home.scss';
|
||||||
|
@import 'search.scss';
|
||||||
|
@import 'personal.scss';
|
||||||
|
|
||||||
body {
|
body {
|
||||||
font-family: sans-serif;
|
font-family: sans-serif;
|
||||||
|
74
style/personal.scss
Normal file
74
style/personal.scss
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
@import "theme.scss";
|
||||||
|
|
||||||
|
.personal-container {
|
||||||
|
width: 16rem;
|
||||||
|
background: #1c1c1c;
|
||||||
|
height: 100vh;
|
||||||
|
margin: 2px;
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
|
||||||
|
.profile-container {
|
||||||
|
display: flex;
|
||||||
|
border-radius: 0.4rem;
|
||||||
|
margin: 0.2rem;
|
||||||
|
min-height: 6rem;
|
||||||
|
border: 2px solid rgba(89, 89, 89, 0.199);
|
||||||
|
padding: 0.5rem;
|
||||||
|
|
||||||
|
.profile-icon {
|
||||||
|
display: inline-flex;
|
||||||
|
padding: 0.2rem;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 2rem;
|
||||||
|
border-radius: 50%;
|
||||||
|
transition: all 0.3s;
|
||||||
|
height: max-content;
|
||||||
|
margin-left: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.profile-icon:hover {
|
||||||
|
transform: scale(1.1);
|
||||||
|
background-color: rgba(255, 255, 255, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.profile-icon:active {
|
||||||
|
transform: scale(0.8);
|
||||||
|
}
|
||||||
|
.dropdown-container {
|
||||||
|
position: absolute;
|
||||||
|
top: 3.8rem;
|
||||||
|
right: 0.8rem;
|
||||||
|
background: #1c1c1c;
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
width: 10rem;
|
||||||
|
z-index: 1;
|
||||||
|
background-color: red;
|
||||||
|
border: 1px solid grey;
|
||||||
|
|
||||||
|
.dropdown-not-logged {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
width: 100%;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
h1 {
|
||||||
|
font-size: 1.2rem;
|
||||||
|
}
|
||||||
|
.auth-button {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
6
style/search.scss
Normal file
6
style/search.scss
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
@import "theme.scss";
|
||||||
|
|
||||||
|
.search-container {
|
||||||
|
width: calc(100% - 22rem - 16rem);
|
||||||
|
|
||||||
|
}
|
91
style/sidebar.scss
Normal file
91
style/sidebar.scss
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
@import "theme.scss";
|
||||||
|
|
||||||
|
.sidebar-container {
|
||||||
|
background-color: transparent;
|
||||||
|
width: 22rem;
|
||||||
|
height: calc(100% - 75px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-top-container {
|
||||||
|
border-radius: 1rem;
|
||||||
|
background-color: #1c1c1c;
|
||||||
|
height: 9rem;
|
||||||
|
margin: 3px;
|
||||||
|
padding: 0.1rem 1rem 1rem 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-top-container .header {
|
||||||
|
font-size: 1.2rem;
|
||||||
|
}
|
||||||
|
.sidebar-top-container .buttons {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
font-size: 1.8rem;
|
||||||
|
align-items: center;
|
||||||
|
transition: all 0.5s;
|
||||||
|
cursor: pointer;
|
||||||
|
color: grey;
|
||||||
|
}
|
||||||
|
.sidebar-top-container .buttons:hover {
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-top-container .buttons:last-child {
|
||||||
|
margin-left: 0.02rem;
|
||||||
|
margin-top: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-top-container h1 {
|
||||||
|
font-size: 0.95rem;
|
||||||
|
margin-left: 0.9rem;
|
||||||
|
font-weight: 400;
|
||||||
|
font-style: $standard-font;
|
||||||
|
letter-spacing: 0.5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-bottom-container {
|
||||||
|
border-radius: 1rem;
|
||||||
|
background-color: #1c1c1c;
|
||||||
|
margin: 3px;
|
||||||
|
margin-top: 6px;
|
||||||
|
padding: 0.2rem 1rem 1rem 1rem;
|
||||||
|
height: calc(100% - 9rem);
|
||||||
|
|
||||||
|
.heading {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.header {
|
||||||
|
font-size: 1.2rem;
|
||||||
|
font-weight: 200;
|
||||||
|
}
|
||||||
|
|
||||||
|
.add-playlist {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
border-radius: 50px;
|
||||||
|
border: none;
|
||||||
|
height: 2.2rem;
|
||||||
|
padding-right: 2rem;
|
||||||
|
padding-left: 2rem;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background-color 0.3s ease;
|
||||||
|
.add-sign {
|
||||||
|
font-size: 1.5rem;
|
||||||
|
margin-top: auto;
|
||||||
|
margin-right: 5px;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.add-playlist:hover {
|
||||||
|
background-color: #9e9e9e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,3 +1,7 @@
|
|||||||
|
@import url('https://fonts.googleapis.com/css2?family=Open+Sans:ital,wght@0,300..800;1,300..800&display=swap');
|
||||||
|
|
||||||
|
$standard-font: 'Open Sans', sans-serif;
|
||||||
|
|
||||||
$background-color: #030303;
|
$background-color: #030303;
|
||||||
$accent-color: #4032a8;
|
$accent-color: #4032a8;
|
||||||
$text-controls-color: #e0e0e0;
|
$text-controls-color: #e0e0e0;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user