feat(list group): show when you're captain and add doc

This commit is contained in:
rick 2022-11-26 20:38:51 +01:00
parent ebeb1c63ad
commit 4e2d63ec64
Signed by: Rick
GPG key ID: 4A6223D66294EB20
2 changed files with 146 additions and 26 deletions

View file

@ -1,23 +1,37 @@
use gloo_net::http::Request;
use gloo_net::Error;
use gloo_storage::errors::StorageError;
use gloo_storage::{LocalStorage, Storage};
use patternfly_yew::{
Button, Card, Flex, FlexModifier, Gallery, Icon, Modal, ModalVariant, Title, ToFlexItems,
ToastViewer, Variant, WithBreakpointExt,
ActionGroup, Button, Card, Color, Flex, FlexModifier, Form, FormGroup, FormGroupValidated, Gallery, Icon, Label, Modal, ModalVariant, TextInput, Title, ToFlexItems,
ToastViewer, Validator, ValidationContext, ValidationResult, Variant, WithBreakpointExt,
};
use yew::prelude::*;
use crate::components::{Group, Home, TestMessage, ToastFields, ToastType};
#[derive(Default)]
pub struct ListGroups {
/// Id de l'utilisateur connecté
id_user: String,
/// Ses groupes
groups: Vec<Group>,
/// Les groupes où il n'y est pas
free_groups: Vec<Group>,
/// Nombre de groupes à afficher
nb_show: usize,
/// Groupe choisi dans la fenetre "rejoindre"
selected_group: usize,
quit_group: Option<usize>,
/// Which modal we must show
/// Quel fenetre modal on affiche
modal: ModalGroup,
/// Le groupe à créer
new_group: Option<Group>,
/// Nom du nouveau groupe
new_name: String,
/// Nom du jeu
form_game: String,
/// Jeu pour le nouveau groupe.
new_game: Option<Game>,
}
#[derive(PartialEq, Properties)]
@ -25,7 +39,7 @@ pub struct PropGroups {
pub id: String,
}
/// Which modal we show
/// Quel modal il faut afficher
enum ModalGroup {
None,
Create,
@ -38,7 +52,7 @@ impl Default for ModalGroup {
}
}
#[derive(PartialEq)]
#[derive(Eq, PartialEq)]
pub enum MsgListGroups {
/// Rafraichi la page
Refresh,
@ -62,16 +76,60 @@ pub enum MsgListGroups {
/// Lorsque l'utilisateur clique sur un groupe, on l'enregistre au vu de
/// son ajout futur
SelectGroup(usize),
/// Update the name for the new group
OnChangeName(String),
/// Sélection du nouveau groupe faite, envoie d'un requete en back
SendJoin,
/// Requete en back fini
FinishJoin,
/// Envoie de la requete pour la création de groupe
SendCreate,
/// Requete en back finie
Finish(TypeFinish),
/// Popup d'informations
Info(String, String),
/// Popup d'erreur
Error(String, String),
}
/// Type de retour du back
#[derive(Eq, PartialEq)]
enum TypeFinish {
Join,
Create,
}
impl ListGroups {
/// Appelé lorsque le champs `name` est changé.
fn on_change_name(&mut self, name: String) {
self.new_name = name;
}
/// Appelé lorsque le champs `name` est changé.
fn on_change_game(&mut self, game: String) {
}
/// Check si le groupe est vide ou pas. Si oui, en créer un avec l'utilisateur actuel en
/// capitaine.
fn check_group(&mut self) {
if self.new_group.is_none() {
let mut group = Group::default();
let user: Result<User, StorageError> = LocalStorage::get("auth");
if let Ok(user) = user {
group.captain = user.id;
}
self.new_group = Some(group);
}
}
fn update_group(&mut self) {
if let Some(group) = &mut self.new_group {
group.name = self.new_name.clone();
//group.game = Groups::;
}
}
}
impl Component for ListGroups {
type Message = MsgListGroups;
type Properties = PropGroups;
@ -147,14 +205,27 @@ impl Component for ListGroups {
let more = ctx.link().callback(|_| MsgListGroups::More);
let join = ctx.link().callback(|_| MsgListGroups::ToggleJoin);
let create = ctx.link().callback(|_| MsgListGroups::ToggleCreate);
let cancel_join = ctx.link().callback(|_| MsgListGroups::CloseModal);
let close_modal = ctx.link().callback(|_| MsgListGroups::CloseModal);
let finish_join = ctx.link().callback(|_| MsgListGroups::SendJoin);
let change_name = ctx.link().callback(|name: String| MsgListGroups::OnChangeName(name));
let groups: Vec<Html> = self.groups[..self.nb_show].iter().enumerate().map(|(id, group)| { html!{
let groups: Vec<Html> = self.groups[..self.nb_show].iter().enumerate().map(|(id, group)| {
html!{
<Card>
<h1>{ group.name.clone() }</h1>
<h2>{ group.game.clone() }</h2>
<Button onclick={ ctx.link().callback(move |_| MsgListGroups::Leave(id)) }variant={Variant::DangerSecondary}>{ "Quitter" }</Button>
if self.id_user == group.captain {
<Label
color={Color::Blue}
label={ "Capitaine" }
/>
}
<Button
disabled={self.id_user == group.captain}
onclick={ ctx.link().callback(move |_| MsgListGroups::Leave(id)) }variant={Variant::DangerSecondary}
>
{ "Quitter" }
</Button>
</Card>
}}).collect::<Vec<Html>>();
@ -165,7 +236,7 @@ impl Component for ListGroups {
let modal = match self.modal {
ModalGroup::Join => html! {
<Modal onclose={cancel_join} variant={ ModalVariant::Medium }>
<Modal onclose={close_modal} variant={ ModalVariant::Medium }>
<br />
<Gallery gutter=true>
{ self.free_groups.iter().enumerate().map(|(id, group)| {
@ -191,7 +262,7 @@ impl Component for ListGroups {
<>
<ToastViewer />
<Title>{ "Vos groupes" }</Title>
<Button onclick={create} icon={Some(Icon::PlusCircleIcon)}>{ "Créer un groupe" }</Button>
<Button disabled=true onclick={create} variant={Variant::Control} icon={Some(Icon::PlusCircleIcon)}>{ "Créer un groupe" }</Button>
<Button onclick={join} icon={Some(Icon::PlusCircleIcon)}>{ "Rejoindre un groupe" }</Button>
{ modal }
@ -248,13 +319,10 @@ impl Component for ListGroups {
let len = groups.len();
self.groups = groups;
self.nb_show = if len < 3 { len } else { 3 };
true
}
MsgListGroups::DoneFree(groups) => {
let len = groups.len();
self.free_groups = groups;
true
}
MsgListGroups::ToggleJoin => {
@ -291,7 +359,7 @@ impl Component for ListGroups {
{
Ok(resp) => {
if resp.ok() {
MsgListGroups::FinishJoin
MsgListGroups::Finish(TypeFinish::Join)
} else {
MsgListGroups::Error(
String::from("Erreur"),
@ -313,13 +381,50 @@ impl Component for ListGroups {
false
}
MsgListGroups::FinishJoin => {
self.groups
.push(self.free_groups.remove(self.selected_group));
if self.nb_show < 3 {
self.nb_show += 1;
MsgListGroups::SendCreate => {
return false;
if let Some(group) = self.free_groups.get(self.selected_group) {
let id = group.id.clone();
ctx.link().send_future(async move {
match Request::put(&format!("/api/groups/{}/create", id))
.send()
.await
{
Ok(resp) => {
if resp.ok() {
MsgListGroups::Finish(TypeFinish::Join)
} else {
MsgListGroups::Error(
String::from("Erreur"),
String::from("Pas de réponse 200"),
)
}
}
Err(_) => {
MsgListGroups::Error(String::from("Erreur"), String::from("Bruh"))
}
}
});
} else {
ctx.link().send_message(MsgListGroups::Error(
String::from("Erreur"),
String::from("Contactez nous si vous êtes tombés sur cette erreur."),
));
}
true
false
}
MsgListGroups::Finish(t) => match t {
TypeFinish::Join => {
self.groups
.push(self.free_groups.remove(self.selected_group));
if self.nb_show < 3 {
self.nb_show += 1;
}
true
}
TypeFinish::Create => false,
}
MsgListGroups::FinishLeave(id) => {
let group = self.groups.remove(id);
@ -371,6 +476,10 @@ impl Component for ListGroups {
false
}
MsgListGroups::Refresh => true,
MsgListGroups::OnChangeName(name) => {
self.on_change_name(name);
true
}
MsgListGroups::More => {
self.nb_show += 3;
if self.nb_show > self.groups.len() {

View file

@ -22,19 +22,21 @@ pub struct User {
discordname: String,
}
#[derive(Deserialize, Serialize)]
#[derive(Default, Deserialize, Serialize)]
struct Game {
name: String,
}
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
pub struct Group {
pub id: String,
pub captain: String,
pub name: String,
pub game: String,
}
impl Group {
/// Change le champs `game` pour son nom et non son ID.
pub async fn get_game_name(&mut self) {
match Request::get(&format!("/api/games/{}", self.game))
.send()
@ -52,4 +54,13 @@ impl Group {
Err(_) => (),
}
}
/// Retourne l'id en BDD d'un jeu. None si le jeu n'existe pas.
pub async fn get_id_from_name(game: String) -> Option<String> {
match Request::get(&format!("/api/games/id?name={}", game)).send().await {
_ => ()
}
None
}
}