cds-web/front/src/main.rs

364 lines
11 KiB
Rust

use gloo_net::http::Request;
use gloo_net::Error;
use gloo_storage::errors::StorageError;
use gloo_storage::{LocalStorage, Storage};
use patternfly_yew::{Toast, ToastDispatcher, ToastViewer, Type};
use serde::{Deserialize, Serialize};
use yew::prelude::*;
use yew_router::prelude::*;
#[derive(Clone, Deserialize, PartialEq, Serialize)]
struct User {
id: String,
banned: bool,
blacklisted: bool,
experience: u32,
level: u32,
money: u32,
moneylimit: u32,
discordname: String,
}
#[derive(Clone, Routable, PartialEq)]
enum Route {
#[at("/")]
Home,
#[at("/about")]
About,
#[at("/test")]
Test,
#[at("/404")]
NotFound,
}
#[function_component(About)]
fn about() -> Html {
let _history = use_history().unwrap();
//LocalStorage::set("test", "coucou");
let test: String = LocalStorage::get("test").unwrap_or(String::from("nop"));
//let onclick = Callback::once(move |_| history.push(Route::Home));
html! {
<>
<h1>{ "À propos" }</h1>
<p>{ test }</p>
//<a {onclick}>{ "Index" }</a>
</>
}
}
struct Home {
value: String,
user: Option<User>,
}
#[derive(PartialEq)]
enum TestMessage {
Test,
Toast(ToastType),
ConnexionOk(User),
}
#[derive(PartialEq)]
struct ToastFields {
pub title: String,
pub body: String,
}
#[derive(PartialEq)]
enum ToastType {
Info(ToastFields),
Error(ToastFields),
}
impl Component for Home {
type Message = TestMessage;
type Properties = ();
fn create(_ctx: &Context<Self>) -> Self {
Self {
value: String::from("coucou"),
user: None,
}
}
fn view(&self, ctx: &Context<Self>) -> Html {
let user: Result<User, StorageError> = LocalStorage::get("auth");
if let Ok(user) = user {
if let None = self.user {
ctx.link().send_message(TestMessage::ConnexionOk(user));
}
} else {
ctx.link().send_future_batch(async {
match Request::get("/api/users/current").send().await {
Ok(resp) => {
if resp.ok() {
let json: Result<User, Error> = resp.json().await;
match json {
Ok(json) => {
let user = json.clone();
match LocalStorage::set("auth", json) {
Ok(_) => vec![
TestMessage::Toast(ToastType::Info(ToastFields {
title: String::from("Connexion réussie !"),
body: String::new(),
})),
TestMessage::ConnexionOk(user),
],
Err(err) => vec![TestMessage::Toast(ToastType::Error(
ToastFields {
title: String::from("Error from the promise"),
body: err.to_string(),
},
))],
}
}
Err(err) => {
LocalStorage::delete("auth");
vec![TestMessage::Toast(ToastType::Error(ToastFields {
title: String::from("Error from the promise"),
body: err.to_string(),
}))]
}
}
} else {
vec![TestMessage::Toast(ToastType::Error(ToastFields {
title: String::from("Error from the promise"),
body: String::from("L'API ne retourne pas un code 200."),
}))]
}
}
Err(err) => vec![TestMessage::Toast(ToastType::Error(ToastFields {
title: String::from("Error from the promise"),
body: err.to_string(),
}))],
}
});
}
let onclick = ctx.link().callback(|_| TestMessage::Test);
html! {
<>
<ToastViewer />
if let Some(user) = &self.user {
<h1>{ format!("Bienvenue {} !", user.discordname) }</h1>
} else {
<p><a href="/login/discord">{ "SE CONNECTER VIA DISCORD ICI" }</a></p>
<p><a href="/login/steam">{ "SE CONNECTER VIA STEAM ICI" }</a></p>
}
<button {onclick}>{"test"}</button>
</>
}
}
fn update(&mut self, _ctx: &Context<Self>, msg: Self::Message) -> bool {
match msg {
TestMessage::ConnexionOk(user) => {
self.user = Some(user);
return true;
}
TestMessage::Toast(toast) => match toast {
ToastType::Info(infos) => ToastDispatcher::new().toast(Toast {
title: infos.title,
r#type: Type::Info,
..Default::default()
}),
ToastType::Error(infos) => ToastDispatcher::new().toast(Toast {
title: infos.title,
r#type: Type::Danger,
body: html! { <p>{ infos.body }</p> },
..Default::default()
}),
},
//_ => ToastDispatcher::new().toast(html! {<Alert title="Coucou"></Alert>}),
_ => ToastDispatcher::new().toast(Toast {
title: String::from("Un callback n'a pas été implémenté !"),
r#type: Type::Warning,
..Default::default()
}),
}
false
/*
if msg == TestMessage::Test {
self.value = String::from("nouveau");
true
} else if let TestMessage::StatusConnection(_) = msg {
self.value = String::from("yes ça marche");
true
} else {
false
}
*/
}
}
/*
#[function_component(Home)]
fn home() -> Html {
// check if the cookie is set
let state = use_state(|| StatusConnection::NotConnected);
//let connected = use_state_eq(|| false);
{
let state = state.clone();
use_effect(move || {
//let connected = connected.clone();
wasm_bindgen_futures::spawn_local(async move {
if let Ok(resp) = Request::get("/api/users/current").send().await {
if resp.ok() {
let json: Result<User, Error> = resp.json().await;
if let Ok(json) = json {
LocalStorage::set("auth", json);
state.set(StatusConnection::UpdateConnection);
} else if let Err(err) = json {
LocalStorage::delete("auth");
state.set(StatusConnection::Error(err.to_string()));
}
} else {
state.set(StatusConnection::NotConnected);
}
}
});
|| ()
});
}
/*
let client = Client::new();
if let Ok(resp) = client.get("/users/current").send() {
if resp.status() == StatusCode::OK {
if let Ok(json) = resp.json::<User>() {
LocalStorage::set("auth", json);
}
}
}
*/
let _user: Result<User, StorageError> = LocalStorage::get("auth");
if let Ok(user) = LocalStorage::get("auth") {
if *state == StatusConnection::UpdateConnection {
let state = state.clone();
state.set(StatusConnection::Connected(user));
}
}
match &*state {
StatusConnection::NotConnected => {
html! {
<>
<p><a href="/login/discord">{ "SE CONNECTER VIA DISCORD ICI" }</a></p>
<p><a href="/login/steam">{ "SE CONNECTER VIA STEAM ICI" }</a></p>
</>
}
},
StatusConnection::UpdateConnection => {
html!{ <p>{ "Connexion en cours..." }</p> }
},
StatusConnection::Connected(user) => html!{ <h1>{ format!("Bienvenue {} !", user.discordname) }</h1> },
StatusConnection::Error(err) => {
html! {
<>
<h1>{ "Erreur !!" }</h1>
<p>{ err }</p>
</>
}
}
}
/*
let tmp: Result<User, StorageError> = LocalStorage::get("auth");
if let Ok(o) = tmp {
} else {
let check_auth = use_state(|| None::<User>);
wasm_bindgen_futures::spawn_local(async move {
if let Ok(resp) = Request::get("/users/current").send().await {
if let Ok(user) = resp.json().await {
check_auth.set(Some(user))
}
};
});
if let Some(user) = (*check_auth).clone() {
LocalStorage::set("auth", user);
}
//html! { "Vous êtes connecté !" }
}
*/
}
*/
fn switch(route: &Route) -> Html {
match route {
Route::Home => html! { <Home /> },
Route::About => html! { <About /> },
Route::NotFound => html! { <h1>{"404, déso"}</h1> },
Route::Test => html! { <Test /> },
}
}
#[function_component(App)]
fn app() -> Html {
html! {
<BrowserRouter>
<Switch<Route> render={Switch::render(switch)} />
</BrowserRouter>
}
/*
html! {
<div>
<h1>{ "Chasseurs De Succès" }</h1>
<h2>{ "Bienvenue sur le site pour gérer les groupes de chasses" }</h2>
</div>
}
*/
}
fn main() {
yew::start_app::<App>();
}
/*
#[derive(Clone, Deserialize, PartialEq, Serialize)]
struct Group {
name: String,
}
struct ListGroups {
list: Vec<Group>,
}
impl Component for ListGroups {
fn create(_ctx: &Context<Self>) -> Self {
Self {
}
}
}
*/
#[function_component(Test)]
fn test() -> Html {
let test = use_state(|| String::from(""));
{
let test = test.clone();
wasm_bindgen_futures::spawn_local(async move {
if let Ok(o) = Request::get("/test").send().await {
test.set(o.text().await.unwrap())
} else {
test.set(String::from("Pas de connexion !!"))
};
});
}
html! {
<>
<h1>{ "Moi !!!" }</h1>
<p>{ (*test).clone() }</p>
</>
}
}