2023-06-19 10:53:14 +02:00

92 lines
2.6 KiB
Rust

use crate::components::error::error_component::ErrorComponent;
use crate::components::error::error_provider::ErrorProvider;
use crate::event_bus::EventBus;
use crate::services::websocket::WebsocketService;
use components::admin::Admin;
use components::create_achievement::CreateAchievementComponent;
use components::create_milestone::CreateMilestoneComponent;
use components::root::Root;
use std::rc::Rc;
use yew::prelude::*;
use yew_agent::Bridged;
use yew_router::BrowserRouter;
use yew_router::Routable;
use yew_router::Switch;
mod components;
pub mod event_bus;
mod services;
pub mod util;
#[derive(Debug, Clone, Copy, PartialEq, Routable)]
enum Route {
#[at("/")]
Root,
#[at("/create-achievement")]
CreateAchievement,
#[at("/create-milestone")]
CreateMilestone,
#[at("/en-lille-nisse-rejste")]
Admin,
#[not_found]
#[at("/404")]
NotFound,
}
fn switch(selected_route: Route) -> Html {
match selected_route {
Route::Root => html! {<Root />},
Route::Admin => html! {<Admin/>},
Route::CreateAchievement => html! {<CreateAchievementComponent/>},
Route::CreateMilestone => html! {<CreateMilestoneComponent/>},
Route::NotFound => html! {<h1>{"404 not found"}</h1>},
}
}
#[derive(Default, Clone, Debug, PartialEq, Eq)]
struct AppStateInner {
/// The part of the state that comes from the server
state: common::State,
}
impl Reducible for AppStateInner {
type Action = common::State;
fn reduce(self: Rc<Self>, action: Self::Action) -> Rc<Self> {
Rc::new(Self { state: action })
}
}
type AppState = Rc<AppStateInner>;
#[function_component]
pub fn App() -> Html {
let app_state = use_reducer(AppStateInner::default);
let app_state_dispatcher = app_state.dispatcher();
let _event_bus = use_memo(
|_| {
log::info!("Creating event bus bridge.");
EventBus::<common::State>::bridge(Rc::new(move |ws_msg: common::State| {
log::debug!("dispatching websocket msg to reducer");
app_state_dispatcher.dispatch(ws_msg);
}))
},
(),
);
let _wss = use_memo(|_| Rc::new(WebsocketService::connect()), ());
let rc_app_state = Rc::new((*app_state).clone());
html! {
<ContextProvider<AppState> context={rc_app_state}>
<ErrorProvider>
<div class="container" style="margin-top: 5%; margin-bottom: 25%">
<ErrorComponent />
<BrowserRouter>
<Switch<Route> render={switch}/>
</BrowserRouter>
</div>
</ErrorProvider>
</ContextProvider<AppState>>
}
}