mentorenwahl/frontend/src/components/navbar.rs

142 lines
5.1 KiB
Rust

use graphql_client::reqwest::post_graphql;
use yew::prelude::*;
use yew_agent::{Dispatched, Dispatcher};
use yew_router::prelude::*;
use crate::agents;
use crate::components;
use crate::graphql;
use crate::routes;
pub enum Msg {
LogoutClicked,
Logout(graphql::Errors),
BurgerClicked,
}
#[derive(Properties, PartialEq)]
pub struct NavbarProps {
pub token: Option<String>,
pub logged_in: bool,
#[prop_or(true)]
pub default_theme: bool,
}
pub struct Navbar {
logged_in: bool,
logged_in_event_bus: Dispatcher<agents::logged_in::EventBus>,
errors: Option<Vec<String>>,
burger_active: bool,
}
impl Component for Navbar {
type Message = Msg;
type Properties = NavbarProps;
fn create(ctx: &Context<Self>) -> Self {
Self {
logged_in: ctx.props().logged_in,
logged_in_event_bus: agents::logged_in::EventBus::dispatcher(),
errors: None,
burger_active: false,
}
}
fn update(&mut self, ctx: &Context<Self>, msg: Self::Message) -> bool {
match msg {
Msg::LogoutClicked => {
let client = graphql::client(ctx.props().token.as_ref()).unwrap();
ctx.link().send_future(async move {
let response = post_graphql::<graphql::mutations::logout::Logout, _>(
&client,
graphql::URL.as_str(),
graphql::mutations::logout::logout::Variables,
)
.await
.unwrap();
Msg::Logout(graphql::convert(response.errors))
});
false
}
Msg::Logout(errors) => {
if errors.is_none() {
self.logged_in_event_bus
.send(agents::logged_in::Request::LoggedIn(false));
false
} else {
self.errors = errors;
true
}
}
Msg::BurgerClicked => {
self.burger_active = !self.burger_active;
true
}
}
}
fn view(&self, ctx: &Context<Self>) -> Html {
html! {
<header>
<nav class={classes!("navbar", "is-success")}
role="navigation"
aria-label="main navigation"
>
<div class={classes!("navbar-brand")}>
<Link<routes::Route> to={routes::Route::Index} classes={classes!("navbar-item")}>
<strong>{ "Mentorenwahl" }</strong>
</Link<routes::Route>>
<a role="button"
onclick={ctx.link().callback(|_| Msg::BurgerClicked)}
class={classes!("navbar-burger")}
aria-label="menu"
aria-expandable="false"
>
<span aria-hidden="true" />
<span aria-hidden="true" />
<span aria-hidden="true" />
</a>
</div>
<div class={classes!("navbar-menu", if self.burger_active { Some("is-active") } else { None })}>
<div class={classes!("navbar-start")}>
<Link<routes::Route> to={routes::Route::Home} classes={classes!("navbar-item")}>
<strong>{ "Home" }</strong>
</Link<routes::Route>>
<Link<routes::Route> to={routes::Route::Settings} classes={classes!("navbar-item")}>
{ "Settings" }
</Link<routes::Route>>
</div>
<div class={classes!("navbar-end")}>
<Link<routes::Route> to={routes::Route::Info} classes={classes!("navbar-item")}>
{ "Info" }
</Link<routes::Route>>
<div class={classes!("navbar-item")}>
<div class={classes!("buttons")}>
if self.logged_in {
<a onclick={ctx.link().callback(|_| Msg::LogoutClicked)} class={classes!("button")}>
{ "Logout" }
</a>
} else {
<Link<routes::Route> to={routes::Route::Login} classes={classes!("button")}>
{ "Login" }
</Link<routes::Route>>
}
</div>
</div>
</div>
</div>
<components::graphql_errors::GraphQLErrors errors={self.errors.to_owned()} />
</nav>
</header>
}
}
}