regalade/app/src/sidebar.rs

149 lines
6 KiB
Rust

use yew::prelude::*;
use crate::{Route, HouseholdInfo};
#[derive(PartialEq)]
struct MenuEntry {
icon: &'static str,
label: &'static str,
page: Route,
}
#[derive(Properties, PartialEq)]
struct SidebarProps {
entries: Vec<MenuEntry>,
current: Route,
household: HouseholdInfo,
children: Children,
}
#[function_component]
fn Sidebar(props: &SidebarProps) -> Html {
html! {
<div class="container-fluid">
<div class={classes!("row", "flex-nowrap")}>
<div class={classes!(
"col-auto",
"col-md-3",
"col-xl-2",
"px-sm-2",
"px-0",
"bg-dark-subtle"
)}>
<div class={classes!(
"d-flex",
"flex-column",
"align-items-center",
"align-items-sm-start",
"px-3",
"pt-2",
"text-white",
"min-vh-100"
)}>
<a href="/" class={classes!(
"d-flex",
"align-items-center",
"pb-3",
"mb-md-0",
"me-md-auto",
"text-white",
"text-decoration-none"
)}>
<span class="fs-5 d-none d-sm-inline">{"Menu"}</span>
</a>
<hr class={classes!("w-100", "d-none", "d-sm-inline")} />
<ul id="menu" class={classes!(
"nav",
"nav-pills",
"flex-column",
"mb-sm-auto",
"mb-0",
"align-items-center",
"align-items-sm-start",
"w-100",
)}>
{
for props.entries.iter().map(|e| {
let active = if e.page == props.current {
Some("active")
} else {
None
};
html! {
<li class="nav-item w-100">
<a href="#" class={classes!(
"nav-link",
"text-white",
active,
)}>
<i class={classes!("fs-4", e.icon)}></i>
<span class={classes!("ms-2", "d-none", "d-sm-inline")}>
{e.label}
</span>
</a>
</li>
}
})
}
</ul>
<hr class="w-100" />
<div class={classes!("dropdown")}>
<a href="#"
data-bs-toggle="dropdown"
aria-expanded="false"
class={classes!(
"d-flex",
"align-items-center",
"text-white",
"text-decoration-none",
"dropdown-toggle",
)}
>
<i class={classes!("fs-4", "bi-house-door-fill")}></i>
<strong class={classes!("ms-2", "d-none", "d-sm-inline")}>
{&props.household.name}
</strong>
</a>
<ul class="dropdown-menu">
<hr />
<li><a class="dropdown-item" href="#">{"New household"}</a></li>
</ul>
</div>
</div>
</div>
<div class={classes!("col", "py-3")}>
{ for props.children.iter() }
</div>
</div>
</div>
}
}
#[derive(Properties, PartialEq)]
pub(crate) struct RegaladeSidebarProps {
pub(crate) current: Route,
pub(crate) household: HouseholdInfo,
pub(crate) children: Children,
}
#[function_component]
pub(crate) fn RegaladeSidebar(props: &RegaladeSidebarProps) -> Html {
let entries = vec![
MenuEntry {
label: "Home",
icon: "bi-house",
page: Route::Index,
},
MenuEntry {
label: "Ingredients",
icon: "bi-egg-fill",
page: Route::Ingredients,
},
];
html! {
<Sidebar {entries} current={props.current} household={props.household.clone()}>
{ for props.children.iter() }
</Sidebar>
}
}