fully implemented the add of members + added style on the page + almost done implementing the remove of members
continuous-integration/drone/push Build is failing Details

pull/84/head
Maël DAIM 1 year ago
parent c0a02c91c5
commit d2ac21a906

@ -1,8 +1,22 @@
#mainDiv { #mainDiv {
background-color: lightblue;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
height: 100%;
}
header{
display: flex;
justify-content: center;
background-color: #525252;
width: 100%;
margin-bottom: 5px;
}
header h1 a{
color: orange;
text-decoration: none;
font-size: 1.5em;
} }
.square { .square {
@ -14,23 +28,51 @@
border: solid; border: solid;
} }
section { #teamInfo{
background-color: #fff;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
width: 60%; width: 60%;
background-color: #8F8F8F;
padding-bottom: 10px;
border-radius: 10px;
}
#firstPart{
display: flex;
flex-direction: column;
align-items: center;
}
#teamName{
font-size: 2.8em;
} }
#colors{ #colors{
display: flex; display: flex;
flex-direction: row; flex-direction: column;
} }
.color { .color {
flex-direction: row; flex-direction: row;
justify-content: space-between; justify-content: space-between;
} }
#colorsTitle{
width: 110%;
display: flex;
flex-direction: row;
justify-content: space-between;
font-size: 1.3em;
color: white;
}
#actualColors{
display: flex;
flex-direction: row;
justify-content: space-around;
}
#logo { #logo {
width: 90%; width: 90%;
aspect-ratio: 3/2; aspect-ratio: 3/2;
@ -42,84 +84,49 @@ section {
border-radius:10px ; border-radius:10px ;
background-color: red; background-color: red;
color: white; color: white;
margin-top: 10px;
margin-bottom: 10px;
} }
.player{ #headMembers{
width: 33%;
display: flex;
flex-direction: row; flex-direction: row;
justify-content: space-evenly; justify-content: space-evenly;
} }
#profilePicture{ #addMember{
height:40px; height: 30px;
width:40px; aspect-ratio: 1/1;
border-radius: 100%;
align-self: center;
} }
#Members{ #Members{
display: flex; display: flex;
flex-direction: column; flex-direction: column;
background-color: lightcoral; background-color: #BCBCBC;
width: 60%; width: 60%;
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-around;
border-radius: 10px;
} }
.Member{ .Member{
width: 60%; width: 60%;
background-color: red; background-color: white;
display: flex; display: flex;
flex-direction: row; flex-direction: row;
justify-content: space-evenly; justify-content: space-evenly;
}
#teamInfo{
display: flex;
flex-direction: column;
align-items: center; align-items: center;
border-radius: 10px;
margin-top: 5px;
margin-bottom: 5px;
width: 60%;
align-items: center;
background-color: #666666;
} }
#headMembers{ #profilePicture{
width: 33%; height:40px;
display: flex; width:40px;
flex-direction: row;
justify-content: space-between;
}
#addMember{
height: 30px;
aspect-ratio: 1/1;
border-radius: 100%;
align-self: center;
} }
.popup {
display: none;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0,0,0,0.7);
}
.popup-content {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background-color: #fff;
padding: 20px;
text-align: center;
}
.close {
position: absolute;
top: 10px;
right: 10px;
font-size: 20px;
cursor: pointer;
}

@ -2,7 +2,7 @@ import '../style/team_panel.css';
import {BASE} from "../Constants"; import {BASE} from "../Constants";
import {Team,TeamInfo,Color,User,Member} from "../model/Team/Team" import {Team,TeamInfo,Color,User,Member} from "../model/Team/Team"
export default function TeamPanel({isCoach, team}: {isCoach: boolean, team: Team }){ export default function TeamPanel({isCoach, team,currentUserId}: {isCoach: boolean, team: Team,currentUserId:number}){
return ( return (
<div id="mainDiv"> <div id="mainDiv">
<header> <header>
@ -13,7 +13,7 @@ export default function TeamPanel({isCoach, team}: {isCoach: boolean, team: Team
{isCoach && <CoachOptions id={team.info.id}/>} {isCoach && <CoachOptions id={team.info.id}/>}
<MembersDisplay members={team.members}/> <MembersDisplay members={team.members} isCoach={isCoach} idTeam={team.info.id} currentUserId={currentUserId}/>
</div> </div>
) )
} }
@ -21,15 +21,19 @@ export default function TeamPanel({isCoach, team}: {isCoach: boolean, team: Team
function TeamDisplay({ team}: {team : TeamInfo}) { function TeamDisplay({ team}: {team : TeamInfo}) {
return ( return (
<div id="teamInfo"> <div id="teamInfo">
<div> <div id="firstPart">
<h1>{team.name}</h1> <h1 id="teamName">{team.name}</h1>
<img id="logo" src={team.picture} alt="Logo d'équipe" /> <img id="logo" src={team.picture} alt="Logo d'équipe" />
</div> </div>
<div id="colors"> <div id="colors">
<p>Couleur principale</p> <div id="colorsTitle">
<ColorDisplay color={team.mainColor}/> <p>Couleur principale</p>
<p>Couleur secondaire</p> <p>Couleur secondaire</p>
<ColorDisplay color={team.secondColor}/> </div>
<div id="actualColors">
<ColorDisplay color={team.mainColor}/>
<ColorDisplay color={team.secondColor}/>
</div>
</div> </div>
</div> </div>
) )
@ -49,28 +53,31 @@ function CoachOptions ({id}:{id:number}){
) )
} }
function MembersDisplay({members,isCoach}:{members : Member[], isCoach : boolean}){ function MembersDisplay({members,isCoach,idTeam,currentUserId}:{members : Member[], isCoach : boolean,idTeam : number,currentUserId:number}){
const listMember = members.map((member) => const listMember = members.map((member) =>
<MemberDisplay member={member}/> <MemberDisplay member={member} isCoach={isCoach} idTeam={idTeam} currentUserId={currentUserId}/>
); );
return ( return (
<div id="Members"> <div id="Members">
<div id="headMembers"> <div id="headMembers">
<h2>Membres :</h2> <h2>Membres :</h2>
<button id="addMember" onClick={()=> window.location.href=`${BASE}/team//addMember`}>+</button> {isCoach && <button id="addMember" onClick={()=> window.location.href=`${BASE}/team/${idTeam}/addMember`}>+</button>}
</div> </div>
{listMember} {listMember}
</div> </div>
) )
} }
function MemberDisplay({member}: {member : Member}){ function MemberDisplay({member,isCoach,idTeam,currentUserId}: {member : Member,isCoach : boolean,idTeam:number,currentUserId:number}){
return ( return (
<div className="Member"> <div className="Member">
<img id="profilePicture" src={member.user.profilePicture} alt="Photo de profile"/> <img id="profilePicture" src={member.user.profilePicture} alt="Photo de profile"/>
<p>{member.user.name}</p> <p>{member.user.name}</p>
<p>{member.role}</p> <p>{member.role}</p>
<p>{member.user.email}</p> <p>{member.user.email}</p>
{isCoach && currentUserId !== member.user.id && <button id="delete" onClick={()=>confirm("Êtes-vous sûr de retirer ce membre de l'équipe?") ? window.location.href=`${BASE}/team/${idTeam}/remove/${member.user.id}` : {}}>Retirer</button>}
{isCoach && currentUserId == member.user.id && <button id="delete" onClick={()=>confirm("Êtes-vous sûr de quitter cette équipe?") ? window.location.href=`${BASE}/team/${idTeam}/remove/${member.user.id}` : {}}>Quitter</button>}
</div> </div>
) )
} }

@ -104,10 +104,9 @@ function getRoutes(): AltoRouter {
$ar->map("POST", "/team/search", Action::auth(fn(SessionHandle $s) => getTeamController()->listTeamByName($_POST, $s))); $ar->map("POST", "/team/search", Action::auth(fn(SessionHandle $s) => getTeamController()->listTeamByName($_POST, $s)));
$ar->map("GET", "/team/[i:id]", Action::auth(fn(int $id, SessionHandle $s) => getTeamController()->displayTeam($id, $s))); $ar->map("GET", "/team/[i:id]", Action::auth(fn(int $id, SessionHandle $s) => getTeamController()->displayTeam($id, $s)));
$ar->map("GET", "/team/[i:id]/delete", Action::auth(fn(int $id,SessionHandle $s) => getTeamController()->deleteTeamById($id,$s))); $ar->map("GET", "/team/[i:id]/delete", Action::auth(fn(int $id,SessionHandle $s) => getTeamController()->deleteTeamById($id,$s)));
$ar->map("GET", "/team/members/add", Action::auth(fn(SessionHandle $s) => getTeamController()->displayAddMember($s))); $ar->map("GET", "/team/[i:id]/addMember", Action::auth(fn(int $id,SessionHandle $s) => getTeamController()->displayAddMember($id,$s)));
$ar->map("POST", "/team/[i:id]/addMember", Action::auth(fn(int $id,SessionHandle $s) => getTeamController()->addMember($id,$_POST, $s))); $ar->map("POST", "/team/[i:id]/addMember", Action::auth(fn(int $id,SessionHandle $s) => getTeamController()->addMember($id,$_POST, $s)));
$ar->map("GET", "/team/members/remove", Action::auth(fn(SessionHandle $s) => getTeamController()->displayDeleteMember($s))); $ar->map("POST", "/team/[i:idTeam]/remove/[i:idMember]", Action::auth(fn(int $idTeam,int $idMember,SessionHandle $s) => getTeamController()->deleteMember($idTeam,$idMember, $s)));
$ar->map("POST", "/team/members/remove", Action::auth(fn(SessionHandle $s) => getTeamController()->deleteMember($_POST, $s)));
return $ar; return $ar;
} }

@ -31,10 +31,6 @@ class TeamController {
return ViewHttpResponse::twig("insert_team.html.twig", []); return ViewHttpResponse::twig("insert_team.html.twig", []);
} }
/** /**
* @param SessionHandle $session * @param SessionHandle $session
* @return ViewHttpResponse the team panel to delete a member * @return ViewHttpResponse the team panel to delete a member
@ -137,7 +133,10 @@ class TeamController {
'team' => [ 'team' => [
"info" => $result->getInfo(), "info" => $result->getInfo(),
"members" => $result->listMembers() "members" => $result->listMembers()
], 'isCoach' => $role]); ],
'isCoach' => $role,
'currentUserId'=>$session->getAccount()->getUser()->getId()]
);
} }
} }
@ -145,8 +144,8 @@ class TeamController {
* @param SessionHandle $session * @param SessionHandle $session
* @return ViewHttpResponse the team panel to add a member * @return ViewHttpResponse the team panel to add a member
*/ */
public function displayAddMember(SessionHandle $session): ViewHttpResponse { public function displayAddMember(int $idTeam,SessionHandle $session): ViewHttpResponse {
return ViewHttpResponse::twig("add_member.html.twig", []); return ViewHttpResponse::twig("add_member.html.twig", ['idTeam'=> $idTeam]);
} }
/** /**
@ -159,12 +158,21 @@ class TeamController {
$errors = []; $errors = [];
$request = HttpRequest::from($request, $errors, [ $request = HttpRequest::from($request, $errors, [
"team" => [Validators::isInteger()],
"email" => [Validators::email(), Validators::lenBetween(5, 256)], "email" => [Validators::email(), Validators::lenBetween(5, 256)],
]); ]);
if(!empty($errors)){
$this->model->addMember($request['email'], $idTeam, $request['role']); return ViewHttpResponse::twig('add_member.html.twig',['badEmail' => true,'idTeam'=> $idTeam]);
return ViewHttpResponse::redirect('/team/'.$idTeam); }
$ret = $this->model->addMember($request['email'], $idTeam, $request['role']);
switch($ret){
case -1:
return ViewHttpResponse::twig('add_member.html.twig',['notFound' => true,'idTeam'=> $idTeam]);
case -2:
return ViewHttpResponse::twig('add_member.html.twig',['alreadyExisting' => true,'idTeam'=> $idTeam]);
default:
return ViewHttpResponse::redirect('/team/'.$idTeam);
}
} }
/** /**
@ -173,13 +181,12 @@ class TeamController {
* @param SessionHandle $session * @param SessionHandle $session
* @return HttpResponse * @return HttpResponse
*/ */
public function deleteMember(array $request, SessionHandle $session): HttpResponse { public function deleteMember(int $idTeam,int $idMember, SessionHandle $session): HttpResponse {
$errors = []; $ret = $this->model->deleteMember($idMember,$idTeam);
$request = HttpRequest::from($request, $errors, [ if($ret == -1 || $session->getAccount()->getUser()->getId() == $idMember ){
"team" => [Validators::isInteger()], return ViewHttpResponse::redirect('/');
"email" => [Validators::email(), Validators::lenBetween(5, 256)], }
]); return $this->displayTeam($ret,$session);
return $this->displayTeam($this->model->deleteMember($request['email'], intval($request['team'])), $session);
} }
} }

@ -67,26 +67,43 @@
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
} }
.failed{
color: red;
}
</style> </style>
</head> </head>
<body> <body>
<header>
<h1><a href="{{ path('/') }}">IQBall</a></h1>
</header>
<div class="container"> <div class="container">
<h2>Ajouter un membre à votre équipe</h2> <h2>Ajouter un membre à votre équipe</h2>
<form action="{{ path('/team/#/addMember') }}" method="POST"> <form action="{{ path("/team/#{idTeam}/addMember") }}" method="POST">
<div class="form-group"> <div class="form-group">
<label for="mail">Email du membre :</label>
<input type="text" id="mail" name="mail" required> <label for="email">Email du membre :</label>
{% if badEmail %}
<p class="failed">Email invalide</p>
{% endif %}
{%if notFound %}
<p class="failed">Cette personne n'a pas été trouvé</p>
{% endif %}
{% if alreadyExisting %}
<p class="failed">Cette personne est déjà dans l'équipe</p>
{% endif %}
<input type="text" id="email" name="email" required>
<fieldset class="role"> <fieldset class="role">
<legend>Rôle du membre dans l'équipe :</legend> <legend>Rôle du membre dans l'équipe :</legend>
<div class="radio"> <div class="radio">
<label for="P">Joueur</label> <label for="P">Joueur</label>
<input type="radio" id="P" name="role" value="P" checked /> <input type="radio" id="P" name="role" value="PLAYER" checked />
</div> </div>
<div class="radio"> <div class="radio">
<label for="C">Coach</label> <label for="C">Coach</label>
<input type="radio" id="C" name="role" value="C" /> <input type="radio" id="C" name="role" value="COACH" />
</div> </div>
</fieldset> </fieldset>

@ -94,9 +94,7 @@ class MemberGateway {
"team" => [$idTeam, PDO::PARAM_INT], "team" => [$idTeam, PDO::PARAM_INT],
"user" => [$idCurrentUser, PDO::PARAM_INT] "user" => [$idCurrentUser, PDO::PARAM_INT]
] ]
)[0]['id_user'] ?? null; );
return $result == null; return !empty($result);
} }
} }

@ -41,11 +41,18 @@ class TeamModel {
* @param string $mail * @param string $mail
* @param int $teamId * @param int $teamId
* @param string $role * @param string $role
* @return void * @return int
*/ */
public function addMember(string $mail, int $teamId, string $role): void { public function addMember(string $mail, int $teamId, string $role): int {
$userId = $this->users->getAccountFromMail($mail)->getUser()->getId(); $user = $this->users->getAccountFromMail($mail);
$this->members->insert($teamId, $userId, $role); if($user == null){
return -1;
}
if(!$this->members->isMemberOfTeam($teamId,$user->getUser()->getId())){
$this->members->insert($teamId, $user->getUser()->getId(), $role);
return 1;
}
return -2;
} }
/** /**
@ -63,7 +70,7 @@ class TeamModel {
* @return ?Team * @return ?Team
*/ */
public function getTeam(int $idTeam, int $idCurrentUser): ?Team { public function getTeam(int $idTeam, int $idCurrentUser): ?Team {
if($this->members->isMemberOfTeam($idTeam,$idCurrentUser)){ if(!$this->members->isMemberOfTeam($idTeam,$idCurrentUser)){
return null; return null;
} }
$teamInfo = $this->teams->getTeamById($idTeam); $teamInfo = $this->teams->getTeamById($idTeam);
@ -77,14 +84,16 @@ class TeamModel {
* @param int $teamId * @param int $teamId
* @return int * @return int
*/ */
public function deleteMember(string $mail, int $teamId): int { public function deleteMember(int $idMember, int $teamId): int {
$userId = $this->users->getAccountFromMail($mail)->getUser()->getId(); $this->members->remove($teamId, $idMember);
$this->members->remove($teamId, $userId); if(empty($this->members->getMembersOfTeam($teamId))){
$this->teams->deleteTeam($teamId);
return -1;
}
return $teamId; return $teamId;
} }
public function deleteTeam(string $email, int $idTeam): int{ public function deleteTeam(string $email, int $idTeam): int{
$this->members->isCoach($email,$idTeam);
if($this->members->isCoach($email,$idTeam)){ if($this->members->isCoach($email,$idTeam)){
$this->teams->deleteTeam($idTeam); $this->teams->deleteTeam($idTeam);
return 0; return 0;

Loading…
Cancel
Save