cds-web/front/src/components/list_groups.rs
2022-10-29 13:39:11 +02:00

243 lines
8.4 KiB
Rust

use gloo_net::http::Request;
use gloo_net::Error;
use patternfly_yew::{Button, Card, Flex, FlexModifier, Icon, Modal, ModalVariant, Title, ToastViewer, ToFlexItems, Variant, WithBreakpointExt}; use yew::prelude::*;
use crate::components::{Group, Home, TestMessage, ToastFields, ToastType};
#[derive(Default)]
pub struct ListGroups {
idUser: String,
groups: Vec<Group>,
free_groups: Vec<Group>,
nb_show: usize,
selected_group: usize,
join: bool,
}
#[derive(PartialEq, Properties)]
pub struct PropGroups {
pub id: String,
}
#[derive(PartialEq)]
pub enum MsgListGroups {
/// Tous les groupes ont été récupéré
Done(Vec<Group>),
/// Tous les groupes sans l'utilisateur ont été récupéré
DoneFree(Vec<Group>),
/// Afficher plus de groupes
More,
/// Afficher ou cacher la fenetre pour rejoindre des groupes
ToggleJoin,
/// Annuler la sélection de nouveaux groupes
CancelJoin,
/// Lorsque l'utilisateur clique sur un groupe, on l'enregistre au vu de
/// son ajout futur
SelectGroup(usize),
/// Sélection du nouveau groupe faite, envoie d'un requete en back
FinishJoin,
/// Popup d'informations
Info(String, String),
/// Popup d'erreur
Error(String, String),
}
impl Component for ListGroups {
type Message = MsgListGroups;
type Properties = PropGroups;
fn create(ctx: &Context<Self>) -> Self {
Self {
idUser: ctx.props().id.clone(),
..Default::default()
}
}
fn view(&self, ctx: &Context<Self>) -> Html {
if self.groups.len() == 0 {
let id = self.idUser.clone();
ctx.link().send_future(async move {
match Request::get(&format!("/api/users/{}/groups", id))
.send()
.await
{
Ok(resp) => {
if resp.ok() {
let json: Result<Vec<Group>, Error> = resp.json().await;
match json {
Ok(mut json) => {
for item in json.iter_mut() {
item.get_game_name().await;
}
return MsgListGroups::Done(json);
}
Err(err) => {
log::info!("{}", err.to_string());
()
}
}
}
}
Err(_) => (),
};
MsgListGroups::Info(String::from("Ok"), String::new())
});
}
if self.free_groups.len() == 0 {
let id = self.idUser.clone();
ctx.link().send_future(async move {
match Request::get(&format!("/api/users/{}/not/groups", id))
.send()
.await
{
Ok(resp) => {
if resp.ok() {
let json: Result<Vec<Group>, Error> = resp.json().await;
match json {
Ok(mut json) => {
for item in json.iter_mut() {
item.get_game_name().await;
}
return MsgListGroups::DoneFree(json);
}
Err(err) => {
log::info!("{}", err.to_string());
()
}
}
}
}
Err(_) => (),
};
MsgListGroups::Info(String::from("Ok"), String::new())
});
}
let more = ctx.link().callback(|_| MsgListGroups::More);
let join = ctx.link().callback(|_| MsgListGroups::ToggleJoin);
let cancel_join = ctx.link().callback(|_| MsgListGroups::CancelJoin);
let finish_join = ctx.link().callback(|_| MsgListGroups::FinishJoin);
let groups: Vec<Html> = self.groups[..self.nb_show].iter().map(|group| { html!{
<div>
<h1>{ group.name.clone() }</h1>
<h2>{ group.game.clone() }</h2>
</div>
}}).collect::<Vec<Html>>();
let mut groups_final: Vec<Html> = Vec::new();
for g in groups.chunks(3) {
groups_final.push(html!{ <Flex> { g.to_vec().into_flex_items() } </Flex> });
}
html! {
<>
<ToastViewer />
<Title>{ "Vos groupes" }</Title>
<Button onclick={join} icon={Some(Icon::PlusCircleIcon)}>{ "Rejoindre un groupe" }</Button>
if self.join {
<Modal onclose={cancel_join} variant={ ModalVariant::Medium }>
{ self.free_groups.iter().enumerate().map(|(id, group)| {
html! {
<Card
onclick={ctx.link().callback(move |_| MsgListGroups::SelectGroup(id))}
selectable=true
selected={self.selected_group == id}
>
{group.name.clone()}
</Card>
}
}).collect::<Html>() }
<Button onclick={finish_join}>{ "Valider" }</Button>
</Modal>
}
if self.groups.len() > 0 {
{
html!{
<div>
<Flex modifiers={[FlexModifier::Column.all()]}>
{ groups_final.into_flex_items() }
</Flex>
if self.nb_show < self.groups.len() {
<Button variant={Variant::Primary} onclick={more}>{ "Plus de groupes" }</Button>
}
</div>
}
}
} else {
<p>{ "Vous n'êtes dans aucun groupe." }</p>
}
</>
}
}
fn update(&mut self, ctx: &Context<Self>, msg: Self::Message) -> bool {
match msg {
MsgListGroups::Info(title, body) => {
if let Some(parent) = ctx.link().get_parent() {
(parent.clone())
.downcast::<Home>()
.send_message(TestMessage::Toast(ToastType::Info(ToastFields {
title,
body,
})))
}
}
MsgListGroups::Error(title, body) => {
if let Some(parent) = ctx.link().get_parent() {
(parent.clone())
.downcast::<Home>()
.send_message(TestMessage::Toast(ToastType::Error(ToastFields {
title,
body,
})))
}
}
MsgListGroups::Done(groups) => {
let len = groups.len();
self.groups = groups;
self.nb_show = if len < 3 {
len
} else {
3
};
return true;
}
MsgListGroups::DoneFree(groups) => {
let len = groups.len();
self.free_groups = groups;
return true;
}
MsgListGroups::ToggleJoin => {
self.join = !self.join;
return true;
}
MsgListGroups::CancelJoin => {
self.join = false;
return true;
}
MsgListGroups::FinishJoin => {
return false;
}
MsgListGroups::SelectGroup(id) => {
self.selected_group = id;
return true;
}
MsgListGroups::More => {
self.nb_show += 3;
if self.nb_show > self.groups.len() {
self.nb_show -= self.nb_show - self.groups.len();
}
return true;
}
}
false
}
}