refactor(topbar): refactored TopBar to be a function_component and implemented a second topbar for users that are logged in

This commit is contained in:
antifallobst 2023-09-28 19:49:28 +02:00
parent 0a6e0d78a2
commit dc7f8eeff8
Signed by: antifallobst
GPG Key ID: 2B4F402172791BAF
4 changed files with 114 additions and 59 deletions

View File

@ -1,6 +1,6 @@
#[derive(Clone, PartialEq)]
pub struct State {
auth_token: Option<String>,
pub auth_token: Option<String>,
}
impl Default for State {

81
src/topbar/guest.rs Normal file
View File

@ -0,0 +1,81 @@
use crate::topbar::Tab;
use std::rc::Rc;
use yew::prelude::*;
pub enum Action {
ToggleSignIn,
ToggleSignUp,
}
pub struct State {
sign_in: bool,
sign_up: bool,
}
impl Default for State {
fn default() -> Self {
Self {
sign_in: false,
sign_up: false,
}
}
}
impl Reducible for State {
type Action = Action;
fn reduce(self: Rc<Self>, action: Self::Action) -> Rc<Self> {
let mut state = Self::default();
match action {
Action::ToggleSignIn => {
state.sign_up = false;
state.sign_in = !self.sign_in;
}
Action::ToggleSignUp => {
state.sign_in = false;
state.sign_up = !self.sign_up;
}
}
Rc::new(state)
}
}
#[function_component]
pub fn TopBar() -> Html {
let state = use_reducer(State::default);
let sign_in_onclick = {
let state = state.clone();
Callback::from(move |_| state.dispatch(Action::ToggleSignIn))
};
let sign_up_onclick = {
let state = state.clone();
Callback::from(move |_| state.dispatch(Action::ToggleSignUp))
};
html! {
<nav id="topbar">
<ul id="tabs-main" class="tabs">
<li><a href="/"><Tab text="Home" /></a></li>
<li><a href="/services"><Tab text="Services" /></a></li>
<li><a href="/community"><Tab text="Community" /></a></li>
<li><a href="/about"><Tab text="About" /></a></li>
</ul>
<ul id="tabs-account" class="tabs">
<li><button onclick={sign_in_onclick}><Tab text="Sign In" /></button></li>
<li><button onclick={sign_up_onclick}><Tab text="Sign Up" /></button></li>
</ul>
if state.sign_in {
<h1>{"Sign In"}</h1>
}
if state.sign_up {
<h1>{"Sign Up"}</h1>
}
</nav>
}
}

View File

@ -1,9 +1,9 @@
use yew::prelude::*;
mod guest;
mod user;
pub enum Msg {
ToggleSignIn,
ToggleSignUp,
}
use crate::state::State;
use std::rc::Rc;
use yew::prelude::*;
#[derive(Properties, PartialEq)]
pub struct TabProps {
@ -25,60 +25,15 @@ fn Tab(props: &TabProps) -> Html {
}
}
pub struct TopBar {
sign_in: bool,
sign_up: bool,
}
#[function_component]
pub fn TopBar() -> Html {
let ctx = use_context::<Rc<State>>().expect("No context found!");
impl Component for TopBar {
type Message = Msg;
type Properties = ();
fn create(_ctx: &Context<Self>) -> Self {
Self {
sign_in: false,
sign_up: false,
}
}
fn update(&mut self, _ctx: &Context<Self>, msg: Self::Message) -> bool {
match msg {
Msg::ToggleSignIn => {
self.sign_up = false;
self.sign_in = !self.sign_in;
true
}
Msg::ToggleSignUp => {
self.sign_in = false;
self.sign_up = !self.sign_up;
true
}
}
}
fn view(&self, ctx: &Context<Self>) -> Html {
html! {
<nav id="topbar">
<ul id="tabs-main" class="tabs">
<li><a href="/"><Tab text="Home" /></a></li>
<li><a href="/services"><Tab text="Services" /></a></li>
<li><a href="/community"><Tab text="Community" /></a></li>
<li><a href="/about"><Tab text="About" /></a></li>
</ul>
<ul id="tabs-account" class="tabs">
<li><button onclick={ctx.link().callback(|_| Msg::ToggleSignIn)}><Tab text="Sign In" /></button></li>
<li><button onclick={ctx.link().callback(|_| Msg::ToggleSignUp)}><Tab text="Sign Up" /></button></li>
</ul>
if self.sign_in {
<h1>{"Sign In"}</h1>
}
if self.sign_up {
<h1>{"Sign Up"}</h1>
}
</nav>
html! {
if ctx.auth_token.is_some() {
<user::TopBar/>
} else {
<guest::TopBar/>
}
}
}

19
src/topbar/user.rs Normal file
View File

@ -0,0 +1,19 @@
use crate::topbar::Tab;
use yew::prelude::*;
#[function_component]
pub fn TopBar() -> Html {
html! {
<nav id="topbar">
<ul id="tabs-main" class="tabs">
<li><a href="/"><Tab text="Dashboard" /></a></li>
<li><a href="/services"><Tab text="Services" /></a></li>
<li><a href="/community"><Tab text="Community" /></a></li>
</ul>
<ul id="tabs-account" class="tabs">
<li><a href="#"><Tab text="Profile" /></a></li>
</ul>
</nav>
}
}