monorepo/visions/ui/src/main.rs

126 lines
3.3 KiB
Rust

use std::rc::Rc;
use gloo_console::log;
use visions_types::{AuthResponse, SessionId, UserOverview};
use yew::prelude::*;
mod client;
use client::*;
mod views;
use views::Login;
struct AuthInfo {
session_id: Option<SessionId>,
}
impl Default for AuthInfo {
fn default() -> Self {
Self { session_id: None }
}
}
enum AuthAction {
Auth(String),
Unauth,
}
impl Reducible for AuthInfo {
type Action = AuthAction;
fn reduce(self: Rc<Self>, action: Self::Action) -> Rc<Self> {
// log!("reduce", action);
match action {
AuthAction::Auth(session_id) => Self {
session_id: Some(session_id.into()),
}
.into(),
AuthAction::Unauth => Self { session_id: None }.into(),
}
}
}
#[derive(Properties, PartialEq)]
struct LandingProps {
session_id: SessionId,
}
#[function_component]
fn Landing(LandingProps { session_id }: &LandingProps) -> Html {
let user_ref = use_state(|| vec![]);
{
let user_ref = user_ref.clone();
let session_id = session_id.clone();
use_effect(move || {
wasm_bindgen_futures::spawn_local(async move {
let client = Connection::new();
match client.list_users(&session_id).await {
Ok(users) => user_ref.set(users),
Err(ClientError::Unauthorized) => todo!(),
Err(ClientError::Err(status)) => {
log!("error: {:?}", status);
todo!()
}
}
})
});
}
html! {
<div>
{"Landing Page"}
{user_ref.iter().map(|overview| {
let overview = overview.clone();
html! { <UserOverviewComponent overview={overview} /> }}).collect::<Vec<Html>>()
}
</div>
}
}
#[derive(Properties, PartialEq)]
struct UserOverviewProps {
overview: UserOverview,
}
#[function_component]
fn UserOverviewComponent(UserOverviewProps { overview }: &UserOverviewProps) -> Html {
html! {
<div> { overview.name.clone() } </div>
}
}
#[function_component]
fn App() -> Html {
let auth_info = use_reducer(AuthInfo::default);
let on_login = {
let auth_info = auth_info.clone();
Callback::from(move |(username, password)| {
let auth_info = auth_info.clone();
wasm_bindgen_futures::spawn_local(async move {
let client = Connection::new();
match client.auth(username, password).await {
Ok(AuthResponse::Success(session_id)) => {
auth_info.dispatch(AuthAction::Auth(session_id.as_str().to_owned()))
}
Ok(AuthResponse::PasswordReset(session_id)) => {
auth_info.dispatch(AuthAction::Auth(session_id.as_str().to_owned()))
}
Err(ClientError::Unauthorized) => todo!(),
Err(ClientError::Err(status)) => todo!(),
};
})
})
};
match auth_info.session_id {
Some(ref session_id) => html! { <Landing session_id={session_id.clone()} /> },
None => html! { <Login on_login={on_login.clone()} /> },
}
}
fn main() {
yew::Renderer::<App>::new().render();
}