can now share tactic with account
continuous-integration/drone/push Build is failing Details

shareTactic
Vivien DUFOUR 1 year ago
parent bd244c8dde
commit 8315b79ba1

@ -15,7 +15,6 @@ body {
height: 100vh; height: 100vh;
} }
#content-container { #content-container {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
@ -57,7 +56,12 @@ header h1 a {
font-size: 1.4em; font-size: 1.4em;
} }
html, body, #main-div, #content-container, #right-panel, #tactics { html,
body,
#main-div,
#content-container,
#right-panel,
#tactics {
height: 100%; height: 100%;
} }

@ -2,14 +2,14 @@ import "../style/home/home.css"
import { Header } from "./template/Header" import { Header } from "./template/Header"
import { BASE } from "../Constants" import { BASE } from "../Constants"
import Draggable from "react-draggable"; import Draggable from "react-draggable"
import {NULL_POS} from "../components/arrows/Pos"; import { NULL_POS } from "../components/arrows/Pos"
import {contains} from "../components/arrows/Box"; import { contains } from "../components/arrows/Box"
import React, {useRef, useState} from "react"; import React, { useRef, useState } from "react"
import { fetchAPI } from "../Fetcher" import { fetchAPI } from "../Fetcher"
import {User} from "../model/User"; import { User } from "../model/User"
import { FaShare } from "react-icons/fa"; import { FaShare } from "react-icons/fa"
import {SaveStates} from "../components/editor/SavingState"; import { SaveStates } from "../components/editor/SavingState"
interface Tactic { interface Tactic {
id: number id: number
@ -64,7 +64,12 @@ function Body({
const widthSideMenu = 100 - widthPersonalSpace const widthSideMenu = 100 - widthPersonalSpace
return ( return (
<div id="body"> <div id="body">
<PersonalSpace width={widthPersonalSpace} allTactics={allTactics} teams={teams} user={user}/> <PersonalSpace
width={widthPersonalSpace}
allTactics={allTactics}
teams={teams}
user={user}
/>
<SideMenu <SideMenu
width={widthSideMenu} width={widthSideMenu}
lastTactics={lastTactics} lastTactics={lastTactics}
@ -84,7 +89,9 @@ function SideMenu({
teams: Team[] teams: Team[]
}) { }) {
return ( return (
<div id="side-menu" style={{ <div
id="side-menu"
style={{
width: width + "%", width: width + "%",
}}> }}>
<div id="side-menu-content"> <div id="side-menu-content">
@ -113,7 +120,11 @@ function PersonalSpace({
width: width + "%", width: width + "%",
}}> }}>
<TitlePersonalSpace /> <TitlePersonalSpace />
<BodyPersonalSpace allTactics={allTactics} teams={teams} user={user}/> <BodyPersonalSpace
allTactics={allTactics}
teams={teams}
user={user}
/>
</div> </div>
) )
} }
@ -153,8 +164,12 @@ function TableData({
i = 0 i = 0
while (i < nbRow) { while (i < nbRow) {
listTactic[i] = listTactic[i].map((tactic: Tactic, i) => ( listTactic[i] = listTactic[i].map((tactic: Tactic, index: number) => (
<DraggableTableDataElement key={i} tactic={tactic} teams={teams}/> <DraggableTableDataElement
key={index}
tactic={tactic}
teams={teams}
/>
)) ))
i++ i++
} }
@ -172,7 +187,6 @@ function TableData({
return data return data
} }
function DraggableTableDataElement({ function DraggableTableDataElement({
tactic, tactic,
teams, teams,
@ -182,47 +196,58 @@ function DraggableTableDataElement({
}) { }) {
const ref = useRef<HTMLDivElement>(null) const ref = useRef<HTMLDivElement>(null)
const [dragging, setDragging] = useState(false) const [dragging, setDragging] = useState(false)
const [hovered, setHovered] = useState(false); const [hovered, setHovered] = useState(false)
const handleButtonClick = (event: React.MouseEvent<HTMLButtonElement>) => { const handleButtonClick = (event: React.MouseEvent<HTMLButtonElement>) => {
event.stopPropagation(); event.stopPropagation()
if (!dragging) { if (!dragging) {
const userEmail = window.prompt("Entrez l'email à qui partager la tactique :"); const userEmail = window.prompt(
"Entrez l'email à qui partager la tactique :",
)
if (userEmail != null) { if (userEmail != null) {
onShareTactic(userEmail, tactic); onShareTactic(userEmail, tactic)
} }
} else { } else {
setDragging(false); setDragging(false)
}
} }
};
return ( return (
<Draggable position={NULL_POS} <Draggable
position={NULL_POS}
nodeRef={ref} nodeRef={ref}
onDrag={() => setDragging(true)} onDrag={() => setDragging(true)}
onStop={() => { if(dragging) { onStop={() => {
onDropTactic(ref.current.getBoundingClientRect(), tactic, teams) if (dragging) {
if (ref.current) {
onDropTactic(
ref.current.getBoundingClientRect(),
tactic,
teams,
)
} }
}}
>
<td key={tactic.id}
ref={ref}
className="data"
onClick={() => { if(!dragging) {
location.pathname = BASE + "/tactic/" + tactic.id + "/edit"
} }
else { }}>
<td
key={tactic.id}
ref={ref as React.RefObject<HTMLTableDataCellElement>}
className="data"
onClick={() => {
if (!dragging) {
location.pathname =
BASE + "/tactic/" + tactic.id + "/edit"
} else {
setDragging(false) setDragging(false)
} }
}} }}
onMouseEnter={() => setHovered(true)} onMouseEnter={() => setHovered(true)}
onMouseLeave={() => setHovered(false)} onMouseLeave={() => setHovered(false)}>
>
{truncateString(tactic.name, 25)} {truncateString(tactic.name, 25)}
{hovered && ( {hovered && (
<div className="share-icon-container"> <div className="share-icon-container">
<button className="share-button share-icon-button" onClick={handleButtonClick}> <button
className="share-button share-icon-button"
onClick={handleButtonClick}>
<FaShare className="share-icon" /> <FaShare className="share-icon" />
</button> </button>
</div> </div>
@ -298,7 +323,9 @@ function SetButtonTactic({ tactics }: { tactics: Tactic[] }) {
} }
function SetButtonTeam({ teams }: { teams: Team[] }) { function SetButtonTeam({ teams }: { teams: Team[] }) {
const listTeam = teams.map((teams, i) => <ButtonTeam key={i} team={teams} />) const listTeam = teams.map((teams, i) => (
<ButtonTeam key={i} team={teams} />
))
return <div className="set-button">{listTeam}</div> return <div className="set-button">{listTeam}</div>
} }
@ -340,33 +367,58 @@ function truncateString(name: string, limit: number): string {
} }
function onDropTactic(ref: DOMRect, tactic: Tactic, teams: Team[]) { function onDropTactic(ref: DOMRect, tactic: Tactic, teams: Team[]) {
let shared = false; let shared = false
for (const team of teams) { for (const team of teams) {
if (contains(ref, document.getElementById(`button-team-${team.id}`)!.getBoundingClientRect())) { if (
contains(
ref,
document
.getElementById(`button-team-${team.id}`)!
.getBoundingClientRect(),
)
) {
if (!shared) { if (!shared) {
shareTacticToTeam(tactic, team); shareTacticToTeam(tactic, team)
shared = true; shared = true
} }
} }
} }
} }
async function onShareTactic(email: string, tactic: Tactic) { async function onShareTactic(email: string, tactic: Tactic) {
const canShareResponse = await fetchAPI(`tactic/${tactic.id}/can-share`, tactic); const canShareResponse = await fetchAPI(
`tactic/${tactic.id}/can-share`,
tactic,
)
if (canShareResponse.ok) { if (canShareResponse.ok) {
const shareToAccountResponse = await fetchAPI(`tactic/${tactic.id}/share-to-account`, email); const shareToAccountResponse = await fetchAPI(
`tactic/${tactic.id}/share-to-account`,
{ email },
)
if (!shareToAccountResponse.ok) { if (!shareToAccountResponse.ok) {
alert("Une erreur s'est produite lors du partage de la tactique avec ce compte"); alert(
"Une erreur s'est produite lors du partage de la tactique avec ce compte",
)
} }
} else { } else {
alert("Vous ne pouvez pas partager cette tactique"); alert("Vous ne pouvez pas partager cette tactique")
} }
} }
async function shareTacticToTeam(tactic: Tactic, team: Team) { async function shareTacticToTeam(tactic: Tactic, team: Team) {
const canShare = await fetchAPI(`tactic/${tactic.id}/can-share-to-team`, team).then((r) => r.ok) const canShare = await fetchAPI(
if(canShare && confirm("Etes-vous sûr de vouloir partager la tactique " + tactic.name + " avec l'équipe " + team.name)) { `tactic/${tactic.id}/can-share-to-team`,
team,
).then((r) => r.ok)
if (
canShare &&
confirm(
"Etes-vous sûr de vouloir partager la tactique " +
tactic.name +
" avec l'équipe " +
team.name,
)
) {
fetchAPI(`tactic/${tactic.id}/share-to-team`, team) fetchAPI(`tactic/${tactic.id}/share-to-team`, team)
} }
if (!canShare) { if (!canShare) {

@ -1,9 +1,9 @@
import "../style/team_panel.css" import "../style/team_panel.css"
import { BASE } from "../Constants" import { BASE } from "../Constants"
import { Team, TeamInfo, Member } from "../model/Team" import { Team, TeamInfo, Member } from "../model/Team"
import {Tactic} from "../model/tactic/Tactic"; import { Tactic } from "../model/tactic/Tactic"
import {fetchAPI} from "../Fetcher"; import { fetchAPI } from "../Fetcher"
import {useState} from "react"; import { useState } from "react"
export default function TeamPanel({ export default function TeamPanel({
isCoach, isCoach,
@ -16,15 +16,16 @@ export default function TeamPanel({
currentUserId: number currentUserId: number
tactics: Tactic[] tactics: Tactic[]
}) { }) {
const [teamTactics, setTeamTactics] = useState(tactics); const [teamTactics, setTeamTactics] = useState(tactics)
function handleTacticDelete(tacticId) { function handleTacticDelete(tacticId: number) {
fetchAPI(`tactic/${tacticId}/unshare-to-team`, team.info) fetchAPI(`tactic/${tacticId}/unshare-to-team`, team.info)
const updatedTactics = teamTactics.filter((tactic) => tactic.id !== tacticId); const updatedTactics = teamTactics.filter(
setTeamTactics(updatedTactics); (tactic) => tactic.id !== tacticId,
)
setTeamTactics(updatedTactics)
} }
return ( return (
<div id="main-div"> <div id="main-div">
<div id="header-div"> <div id="header-div">
@ -46,7 +47,13 @@ export default function TeamPanel({
/> />
</div> </div>
<div id="right-panel"> <div id="right-panel">
<TacticsDisplay tactics={teamTactics} isCoach={isCoach} onTacticDelete={(tacticId) => handleTacticDelete(tacticId)}/> <TacticsDisplay
tactics={teamTactics}
isCoach={isCoach}
onTacticDelete={(tacticId) =>
handleTacticDelete(tacticId)
}
/>
</div> </div>
</div> </div>
</div> </div>
@ -199,7 +206,12 @@ function TacticsDisplay({
onTacticDelete: (tacticId: number) => void onTacticDelete: (tacticId: number) => void
}) { }) {
const listTactic = tactics.map((tactic) => ( const listTactic = tactics.map((tactic) => (
<TacticDisplay key={tactic.id} tactic={tactic} isCoach={isCoach} onTacticDelete={() => onTacticDelete(tactic.id)}/> <TacticDisplay
key={tactic.id}
tactic={tactic}
isCoach={isCoach}
onTacticDelete={() => onTacticDelete(tactic.id)}
/>
)) ))
return ( return (
<div id="tactics"> <div id="tactics">
@ -221,16 +233,21 @@ function TacticDisplay({
onTacticDelete: () => void onTacticDelete: () => void
}) { }) {
return ( return (
<div className="tactic" onClick={() => location.pathname = BASE + "/tactic/" + tactic.id + "/edit"}> <div
className="tactic"
onClick={() =>
(location.pathname = BASE + "/tactic/" + tactic.id + "/edit")
}>
<p>{tactic.name}</p> <p>{tactic.name}</p>
{isCoach && ( {isCoach && (
<button <button
id="delete" id="delete"
onClick={(event) => { onClick={(event) => {
event.stopPropagation(); event.stopPropagation()
confirm("Êtes-vous sûr de vouloir supprimer le partage cette tactique ?") && onTacticDelete(); confirm(
}} "Êtes-vous sûr de vouloir supprimer le partage cette tactique ?",
> ) && onTacticDelete()
}}>
Retirer Retirer
</button> </button>
)} )}

@ -1,5 +1,5 @@
import { BASE } from "../../Constants" import { BASE } from "../../Constants"
import {User} from "../../model/User"; import { User } from "../../model/User"
/** /**
* *
@ -11,7 +11,8 @@ export function Header({ user }: { user: User }) {
<div id="header"> <div id="header">
<div id="header-left"></div> <div id="header-left"></div>
<div id="header-center"> <div id="header-center">
<h1 id="iqball" <h1
id="iqball"
className="clickable" className="clickable"
onClick={() => { onClick={() => {
location.pathname = "/" location.pathname = "/"
@ -28,7 +29,8 @@ export function Header({ user }: { user: User }) {
onClick={() => { onClick={() => {
location.pathname = BASE + "/settings" location.pathname = BASE + "/settings"
}} }}
alt="photo de profil"/> alt="photo de profil"
/>
<p id="username">{user.name}</p> <p id="username">{user.name}</p>
</div> </div>
</div> </div>

@ -21,8 +21,10 @@ use IQBall\Core\Model\TeamModel;
use IQBall\Core\Gateway\MemberGateway; use IQBall\Core\Gateway\MemberGateway;
function getTacticController(): APITacticController { function getTacticController(): APITacticController {
return new APITacticController(new TacticModel(new TacticInfoGateway(new Connection(get_database())), new AccountGateway(new Connection(get_database()))), return new APITacticController(
new TeamModel(new TeamGateway(new Connection(get_database())), new MemberGateway(new Connection(get_database())), new AccountGateway(new Connection(get_database())))); new TacticModel(new TacticInfoGateway(new Connection(get_database())), new AccountGateway(new Connection(get_database()))),
new TeamModel(new TeamGateway(new Connection(get_database())), new MemberGateway(new Connection(get_database())), new AccountGateway(new Connection(get_database())))
);
} }
function getAuthController(): APIAuthController { function getAuthController(): APIAuthController {

@ -68,6 +68,11 @@ class APITacticController {
} }
/**
* @param int $tacticId
* @param Account $account
* @return HttpResponse
*/
public function canShareTactic(int $tacticId, Account $account): HttpResponse { public function canShareTactic(int $tacticId, Account $account): HttpResponse {
if ($this->tacticModel->canShareTactic($tacticId, $account)) { if ($this->tacticModel->canShareTactic($tacticId, $account)) {
return HttpResponse::fromCode(HttpCodes::OK); return HttpResponse::fromCode(HttpCodes::OK);
@ -75,14 +80,18 @@ class APITacticController {
return new JsonHttpResponse(["message" => "Vous ne pouvez pas partager cette tactique"], HttpCodes::FORBIDDEN); return new JsonHttpResponse(["message" => "Vous ne pouvez pas partager cette tactique"], HttpCodes::FORBIDDEN);
} }
/**
* @param int $tacticId
* @param Account $account
* @return HttpResponse
*/
public function canShareTacticToTeam(int $tacticId, Account $account): HttpResponse { public function canShareTacticToTeam(int $tacticId, Account $account): HttpResponse {
return Control::runChecked([ return Control::runChecked([
"id" => [], "id" => [],
"name" => [], "name" => [],
"picture" => [], "picture" => [],
"main_color" => [], "main_color" => [],
"second_color" => [] "second_color" => [],
], function (HttpRequest $request) use ($tacticId, $account) { ], function (HttpRequest $request) use ($tacticId, $account) {
if ($this->canShareTactic($tacticId, $account)) { if ($this->canShareTactic($tacticId, $account)) {
if ($this->teamModel->canShareTacticToTeam($request["id"], $account->getUser()->getEmail())) { if ($this->teamModel->canShareTacticToTeam($request["id"], $account->getUser()->getEmail())) {
@ -93,36 +102,50 @@ class APITacticController {
}); });
} }
/**
* @param int $tacticId
* @param Account $account
* @return HttpResponse
*/
public function shareTacticToTeam(int $tacticId, Account $account): HttpResponse { public function shareTacticToTeam(int $tacticId, Account $account): HttpResponse {
return Control::runChecked([ return Control::runChecked([
"id" => [], "id" => [],
"name" => [], "name" => [],
"picture" => [], "picture" => [],
"main_color" => [], "main_color" => [],
"second_color" => [] "second_color" => [],
], function (HttpRequest $request) use ($tacticId, $account) { ], function (HttpRequest $request) use ($tacticId) {
$this->teamModel->shareTacticToTeam($request["id"], $tacticId); $this->teamModel->shareTacticToTeam($request["id"], $tacticId);
return HttpResponse::fromCode(HttpCodes::OK); return HttpResponse::fromCode(HttpCodes::OK);
}); });
} }
/**
* @param int $tacticId
* @param Account $account
* @return HttpResponse
*/
public function shareTacticToAccount(int $tacticId, Account $account): HttpResponse { public function shareTacticToAccount(int $tacticId, Account $account): HttpResponse {
return Control::runChecked([ return Control::runChecked([
"email" => [], "email" => [],
], function (HttpRequest $request) use ($tacticId, $account) { ], function (HttpRequest $request) use ($tacticId) {
$this->tacticModel->shareTacticToAccountMail($request["email"], $tacticId); $this->tacticModel->shareTacticToAccountMail($request["email"], $tacticId);
return HttpResponse::fromCode(HttpCodes::OK); return HttpResponse::fromCode(HttpCodes::OK);
}); });
} }
/**
* @param int $tacticId
* @param Account $account
* @return HttpResponse
*/
public function unshareTacticToTeam(int $tacticId, Account $account): HttpResponse { public function unshareTacticToTeam(int $tacticId, Account $account): HttpResponse {
return Control::runChecked([ return Control::runChecked([
"id" => [], "id" => [],
"name" => [], "name" => [],
"picture" => [], "picture" => [],
"mainColor" => [], "mainColor" => [],
"secondColor" => [] "secondColor" => [],
], function (HttpRequest $request) use ($tacticId, $account) { ], function (HttpRequest $request) use ($tacticId, $account) {
if ($this->teamModel->canShareTacticToTeam($request["id"], $account->getUser()->getEmail())) { if ($this->teamModel->canShareTacticToTeam($request["id"], $account->getUser()->getEmail())) {
$this->teamModel->unshareTacticToTeam($tacticId, $request["id"]); $this->teamModel->unshareTacticToTeam($tacticId, $request["id"]);
@ -132,4 +155,3 @@ class APITacticController {
}); });
} }
} }

@ -6,74 +6,112 @@ use IQBall\App\Session\SessionHandle;
use IQBall\App\ViewHttpResponse; use IQBall\App\ViewHttpResponse;
use IQBall\Core\Model\TacticModel; use IQBall\Core\Model\TacticModel;
use IQBall\Core\Model\TeamModel; use IQBall\Core\Model\TeamModel;
use \IQBall\Core\Http\HttpResponse; use IQBall\Core\Http\HttpResponse;
class TacticController class TacticController {
{
private TacticModel $tactics; private TacticModel $tactics;
private ?TeamModel $teams; private ?TeamModel $teams;
public function __construct(TacticModel $tactics, ?TeamModel $teams = NULL) { public function __construct(TacticModel $tactics, ?TeamModel $teams = null) {
$this->tactics = $tactics; $this->tactics = $tactics;
$this->teams = $teams; $this->teams = $teams;
} }
/**
* @param bool $toShare
* @param SessionHandle $session
* @return ViewHttpResponse
*/
public function displayTactic(bool $toShare, SessionHandle $session): ViewHttpResponse { public function displayTactic(bool $toShare, SessionHandle $session): ViewHttpResponse {
if($toShare) { if($toShare) {
$results = $this->tactics->getAll($session->getAccount()->getUser()->getId()); $results = $this->tactics->getAll($session->getAccount()->getUser()->getId());
} } else {
else {
$results = $this->tactics->getAllTacticSharedOwned($session->getAccount()->getUser()->getId()); $results = $this->tactics->getAllTacticSharedOwned($session->getAccount()->getUser()->getId());
} }
return ViewHttpResponse::twig("display_tactic.html.twig", ['tactics' => $results, 'toShare' => $toShare]); return ViewHttpResponse::twig("display_tactic.html.twig", ['tactics' => $results, 'toShare' => $toShare]);
} }
/**
* @param bool $toShare
* @param int $tacticId
* @param SessionHandle $session
* @return ViewHttpResponse
*/
public function displayTeamAndAccount(bool $toShare, int $tacticId, SessionHandle $session): ViewHttpResponse { public function displayTeamAndAccount(bool $toShare, int $tacticId, SessionHandle $session): ViewHttpResponse {
if($toShare) { if($toShare) {
$results = $this->teams->getAllIsCoach($session->getAccount()->getUser()->getId()); $results = $this->teams->getAllIsCoach($session->getAccount()->getUser()->getId());
} } else {
else {
$results = $this->teams->getAllIsCoach($session->getAccount()->getUser()->getId()); $results = $this->teams->getAllIsCoach($session->getAccount()->getUser()->getId());
} }
return ViewHttpResponse::twig("display_user_teams_accounts.html.twig", ['teams' => $results, 'tactic' => $tacticId, 'toShare' => $toShare]); return ViewHttpResponse::twig("display_user_teams_accounts.html.twig", ['teams' => $results, 'tactic' => $tacticId, 'toShare' => $toShare]);
} }
/**
* @param int $tacticId
* @param int $teamId
* @param SessionHandle $session
* @return ViewHttpResponse
*/
public function displayShareConfirmation(int $tacticId, int $teamId, SessionHandle $session): ViewHttpResponse { public function displayShareConfirmation(int $tacticId, int $teamId, SessionHandle $session): ViewHttpResponse {
return ViewHttpResponse::twig("display_share_confirmation.html.twig", ['team' => $teamId, 'tactic' => $tacticId]); return ViewHttpResponse::twig("display_share_confirmation.html.twig", ['team' => $teamId, 'tactic' => $tacticId]);
} }
public function shareTacticToTeam(array $confirmation, int $tacticId, int $teamId, SessionHandle $session) : HttpResponse /**
{ * @param array<array<string, mixed>> $confirmation
* @param int $tacticId
* @param int $teamId
* @param SessionHandle $session
* @return HttpResponse
*/
public function shareTacticToTeam(array $confirmation, int $tacticId, int $teamId, SessionHandle $session): HttpResponse {
if($confirmation['confirmation'] == "yes") { if($confirmation['confirmation'] == "yes") {
$this->teams->shareTacticToTeam($teamId, $tacticId); $this->teams->shareTacticToTeam($teamId, $tacticId);
} }
return ViewHttpResponse::redirect("/"); return ViewHttpResponse::redirect("/");
} }
public function shareTacticToAccount(array $request, int $tacticId, SessionHandle $session) : HttpResponse /**
{ * @param array<string> $request
* @param int $tacticId
* @param SessionHandle $session
* @return HttpResponse
*/
public function shareTacticToAccount(array $request, int $tacticId, SessionHandle $session): HttpResponse {
$email = $request["email"]; $email = $request["email"];
$this->tactics->shareTacticToAccountMail($email, $tacticId); $this->tactics->shareTacticToAccountMail($email, $tacticId);
return ViewHttpResponse::redirect("/"); return ViewHttpResponse::redirect("/");
} }
public function unshareTactic(int $tacticId, SessionHandle $session) : HttpResponse /**
{ * @param int $tacticId
* @param SessionHandle $session
* @return HttpResponse
*/
public function unshareTactic(int $tacticId, SessionHandle $session): HttpResponse {
$this->tactics->unshareTactic($tacticId); $this->tactics->unshareTactic($tacticId);
$this->teams->unshareTactic($tacticId); $this->teams->unshareTactic($tacticId);
return ViewHttpResponse::redirect("/"); return ViewHttpResponse::redirect("/");
} }
public function unshareTacticToTeam(int $tacticId, int $teamId, SessionHandle $session) : HttpResponse /**
{ * @param int $tacticId
* @param int $teamId
* @param SessionHandle $session
* @return HttpResponse
*/
public function unshareTacticToTeam(int $tacticId, int $teamId, SessionHandle $session): HttpResponse {
$this->teams->unshareTacticToTeam($tacticId, $teamId); $this->teams->unshareTacticToTeam($tacticId, $teamId);
return ViewHttpResponse::redirect("/"); return ViewHttpResponse::redirect("/");
} }
public function unshareTacticToAccount(int $tacticId, int $accountId, SessionHandle $session) : HttpResponse /**
{ * @param int $tacticId
* @param int $accountId
* @param SessionHandle $session
* @return HttpResponse
*/
public function unshareTacticToAccount(int $tacticId, int $accountId, SessionHandle $session): HttpResponse {
$this->tactics->unshareTacticToAccount($tacticId, $accountId); $this->tactics->unshareTacticToAccount($tacticId, $accountId);
return ViewHttpResponse::redirect("/"); return ViewHttpResponse::redirect("/");
} }

@ -140,7 +140,7 @@ class TeamController {
], ],
'isCoach' => $role, 'isCoach' => $role,
'currentUserId' => $session->getAccount()->getUser()->getId(), 'currentUserId' => $session->getAccount()->getUser()->getId(),
'tactics' => $tactics 'tactics' => $tactics,
] ]
); );
} }

@ -60,8 +60,7 @@ class TacticInfo implements \JsonSerializable {
return $this->creationDate; return $this->creationDate;
} }
public function jsonSerialize() public function jsonSerialize() {
{
return get_object_vars($this); return get_object_vars($this);
} }
} }

@ -17,6 +17,14 @@ class AccountGateway {
$this->con = $con; $this->con = $con;
} }
/**
* @param string $name
* @param string $email
* @param string $token
* @param string $hash
* @param string $profilePicture
* @return int
*/
public function insertAccount(string $name, string $email, string $token, string $hash, string $profilePicture): int { public function insertAccount(string $name, string $email, string $token, string $hash, string $profilePicture): int {
$this->con->exec("INSERT INTO Account(username, hash, email, token,profilePicture) VALUES (:username,:hash,:email,:token,:profilePic)", [ $this->con->exec("INSERT INTO Account(username, hash, email, token,profilePicture) VALUES (:username,:hash,:email,:token,:profilePic)", [
':username' => [$name, PDO::PARAM_STR], ':username' => [$name, PDO::PARAM_STR],
@ -69,6 +77,10 @@ class AccountGateway {
return new Account($acc["token"], new User($email, $acc["username"], $acc["id"], $acc["profilePicture"])); return new Account($acc["token"], new User($email, $acc["username"], $acc["id"], $acc["profilePicture"]));
} }
/**
* @param string $email
* @return array<array<string, mixed>>
*/
public function getAccountIdFromMail(string $email): array { public function getAccountIdFromMail(string $email): array {
return $this->con->fetch( return $this->con->fetch(
"SELECT id FROM Account WHERE email = :mail", "SELECT id FROM Account WHERE email = :mail",
@ -91,7 +103,11 @@ class AccountGateway {
return new Account($acc["token"], new User($acc["email"], $acc["username"], $acc["id"], $acc["profilePicture"])); return new Account($acc["token"], new User($acc["email"], $acc["username"], $acc["id"], $acc["profilePicture"]));
} }
/**
* @param int $accountId
* @param int $tacticId
* @return int
*/
public function shareTacticToAccount(int $accountId, int $tacticId): int { public function shareTacticToAccount(int $accountId, int $tacticId): int {
$this->con->exec( $this->con->exec(
"INSERT INTO TacticSharedAccount(id_account, id_tactic) VALUES(:accountId, :tacticId)", "INSERT INTO TacticSharedAccount(id_account, id_tactic) VALUES(:accountId, :tacticId)",
@ -103,6 +119,10 @@ class AccountGateway {
return intval($this->con->lastInsertId()); return intval($this->con->lastInsertId());
} }
/**
* @param int $tacticId
* @return int
*/
public function unshareTactic(int $tacticId): int { public function unshareTactic(int $tacticId): int {
$this->con->exec( $this->con->exec(
"DELETE FROM TacticSharedAccount WHERE id_tactic = :tacticId", "DELETE FROM TacticSharedAccount WHERE id_tactic = :tacticId",
@ -113,6 +133,11 @@ class AccountGateway {
return intval($this->con->lastInsertId()); return intval($this->con->lastInsertId());
} }
/**
* @param int $tacticId
* @param int $accountId
* @return int
*/
public function unshareTacticToAccount(int $tacticId, int $accountId): int { public function unshareTacticToAccount(int $tacticId, int $accountId): int {
$this->con->exec( $this->con->exec(
"DELETE FROM TacticSharedAccount WHERE id_tactic = :tacticId AND id_account = :accountId", "DELETE FROM TacticSharedAccount WHERE id_tactic = :tacticId AND id_account = :accountId",

@ -6,6 +6,7 @@ use IQBall\Core\Connection;
use IQBall\Core\Data\CourtType; use IQBall\Core\Data\CourtType;
use IQBall\Core\Data\TacticInfo; use IQBall\Core\Data\TacticInfo;
use PDO; use PDO;
use function PHPStan\dumpType; use function PHPStan\dumpType;
class TacticInfoGateway { class TacticInfoGateway {
@ -94,7 +95,7 @@ class TacticInfoGateway {
WHERE ts.id_team = m.id_team AND ts.id_tactic = t.id WHERE ts.id_team = m.id_team AND ts.id_tactic = t.id
AND m.id_user = :ownerId", AND m.id_user = :ownerId",
[ [
":ownerId" => [$ownerId, PDO::PARAM_INT] ":ownerId" => [$ownerId, PDO::PARAM_INT],
] ]
); );
if (count($res) == 0) { if (count($res) == 0) {
@ -112,7 +113,7 @@ class TacticInfoGateway {
"SELECT t.* FROM Tactic t, TacticSharedAccount ta "SELECT t.* FROM Tactic t, TacticSharedAccount ta
WHERE t.id = ta.id_tactic AND ta.id_account = :ownerId", WHERE t.id = ta.id_tactic AND ta.id_account = :ownerId",
[ [
":ownerId" => [$ownerId, PDO::PARAM_INT] ":ownerId" => [$ownerId, PDO::PARAM_INT],
] ]
); );
if (count($res) == 0) { if (count($res) == 0) {
@ -121,13 +122,17 @@ class TacticInfoGateway {
return array_map(fn(array $row) => $this->rowToTacticInfo($row), $res); return array_map(fn(array $row) => $this->rowToTacticInfo($row), $res);
} }
/**
* @param int $ownerId
* @return array<TacticInfo>|null
*/
public function getAllTacticSharedTeamOwned(int $ownerId): ?array { public function getAllTacticSharedTeamOwned(int $ownerId): ?array {
$res = $this->con->fetch( $res = $this->con->fetch(
"SELECT t.* FROM Tactic t, TacticSharedTeam ts, Member m "SELECT t.* FROM Tactic t, TacticSharedTeam ts, Member m
WHERE ts.id_team = m.id_team AND ts.id_tactic = t.id WHERE ts.id_team = m.id_team AND ts.id_tactic = t.id
AND m.id_user = :ownerId AND t.owner = :ownerId", AND m.id_user = :ownerId AND t.owner = :ownerId",
[ [
":ownerId" => [$ownerId, PDO::PARAM_INT] ":ownerId" => [$ownerId, PDO::PARAM_INT],
] ]
); );
if (count($res) == 0) { if (count($res) == 0) {
@ -136,12 +141,16 @@ class TacticInfoGateway {
return array_map(fn(array $row) => $this->rowToTacticInfo($row), $res); return array_map(fn(array $row) => $this->rowToTacticInfo($row), $res);
} }
/**
* @param int $ownerId
* @return array<TacticInfo>|null
*/
public function getAllTacticSharedAccountOwned(int $ownerId): ?array { public function getAllTacticSharedAccountOwned(int $ownerId): ?array {
$res = $this->con->fetch( $res = $this->con->fetch(
"SELECT t.* FROM Tactic t, TacticSharedAccount ta "SELECT t.* FROM Tactic t, TacticSharedAccount ta
WHERE t.id = ta.id_tactic AND t.owner = :ownerId", WHERE t.id = ta.id_tactic AND t.owner = :ownerId",
[ [
":ownerId" => [$ownerId, PDO::PARAM_INT] ":ownerId" => [$ownerId, PDO::PARAM_INT],
] ]
); );
if (count($res) == 0) { if (count($res) == 0) {
@ -150,7 +159,11 @@ class TacticInfoGateway {
return array_map(fn(array $row) => $this->rowToTacticInfo($row), $res); return array_map(fn(array $row) => $this->rowToTacticInfo($row), $res);
} }
/**
* @param int $tacticId
* @param int $accountId
* @return array<array<string, mixed>>|null
*/
public function getOwnerIdTacticSharedTeam(int $tacticId, int $accountId): ?array { public function getOwnerIdTacticSharedTeam(int $tacticId, int $accountId): ?array {
return $this->con->fetch( return $this->con->fetch(
"SELECT t.owner "SELECT t.owner
@ -161,11 +174,16 @@ class TacticInfoGateway {
WHERE tt.id_tactic = :tacticId AND m.id_user = :accountId", WHERE tt.id_tactic = :tacticId AND m.id_user = :accountId",
[ [
":tacticId" => [$tacticId, PDO::PARAM_INT], ":tacticId" => [$tacticId, PDO::PARAM_INT],
":accountId" => [$accountId, PDO::PARAM_INT] ":accountId" => [$accountId, PDO::PARAM_INT],
] ]
); );
} }
/**
* @param int $tacticId
* @param int $accountId
* @return array<array<string, mixed>>|null
*/
public function getOwnerIdTacticSharedAccount(int $tacticId, int $accountId): ?array { public function getOwnerIdTacticSharedAccount(int $tacticId, int $accountId): ?array {
return $this->con->fetch( return $this->con->fetch(
"SELECT t.owner FROM Account a "SELECT t.owner FROM Account a
@ -174,7 +192,7 @@ class TacticInfoGateway {
WHERE ta.id_tactic = :tacticId AND ta.id_account = :accountId", WHERE ta.id_tactic = :tacticId AND ta.id_account = :accountId",
[ [
":tacticId" => [$tacticId, PDO::PARAM_INT], ":tacticId" => [$tacticId, PDO::PARAM_INT],
":accountId" => [$accountId, PDO::PARAM_INT] ":accountId" => [$accountId, PDO::PARAM_INT],
] ]
); );
} }
@ -227,6 +245,10 @@ class TacticInfoGateway {
return $stmnt->rowCount() == 1; return $stmnt->rowCount() == 1;
} }
/**
* @param array<mixed> $row
* @return TacticInfo
*/
private function rowToTacticInfo(array $row): TacticInfo { private function rowToTacticInfo(array $row): TacticInfo {
$type = CourtType::fromName($row['court_type']); $type = CourtType::fromName($row['court_type']);
return new TacticInfo($row['id'], $row["name"], strtotime($row["creation_date"]), $row["owner"], $type, $row['content']); return new TacticInfo($row['id'], $row["name"], strtotime($row["creation_date"]), $row["owner"], $type, $row['content']);

@ -3,6 +3,7 @@
namespace IQBall\Core\Gateway; namespace IQBall\Core\Gateway;
use IQBall\Core\Connection; use IQBall\Core\Connection;
use IQBall\Core\Data\TacticInfo;
use IQBall\Core\Data\TeamInfo; use IQBall\Core\Data\TeamInfo;
use PDO; use PDO;
@ -33,6 +34,11 @@ class TeamGateway {
return intval($this->con->lastInsertId()); return intval($this->con->lastInsertId());
} }
/**
* @param int $teamId
* @param int $tacticId
* @return int
*/
public function shareTacticToTeam(int $teamId, int $tacticId): int { public function shareTacticToTeam(int $teamId, int $tacticId): int {
$this->con->exec( $this->con->exec(
"INSERT INTO TacticSharedTeam(id_team, id_tactic) VALUES(:teamId, :tacticId)", "INSERT INTO TacticSharedTeam(id_team, id_tactic) VALUES(:teamId, :tacticId)",
@ -44,6 +50,10 @@ class TeamGateway {
return intval($this->con->lastInsertId()); return intval($this->con->lastInsertId());
} }
/**
* @param int $tacticId
* @return int
*/
public function unshareTactic(int $tacticId): int { public function unshareTactic(int $tacticId): int {
$this->con->exec( $this->con->exec(
"DELETE FROM TacticSharedTeam WHERE id_tactic = :tacticId", "DELETE FROM TacticSharedTeam WHERE id_tactic = :tacticId",
@ -54,6 +64,11 @@ class TeamGateway {
return intval($this->con->lastInsertId()); return intval($this->con->lastInsertId());
} }
/**
* @param int $tacticId
* @param int $teamId
* @return int
*/
public function unshareTacticToTeam(int $tacticId, int $teamId): int { public function unshareTacticToTeam(int $tacticId, int $teamId): int {
$this->con->exec( $this->con->exec(
"DELETE FROM TacticSharedTeam WHERE id_tactic = :tacticId AND id_team = :teamId", "DELETE FROM TacticSharedTeam WHERE id_tactic = :tacticId AND id_team = :teamId",
@ -170,6 +185,10 @@ class TeamGateway {
); );
} }
/**
* @param int $user
* @return array<array<string, mixed>>
*/
public function getAllIsCoach(int $user): array { public function getAllIsCoach(int $user): array {
return $this->con->fetch( return $this->con->fetch(
"SELECT t.* FROM team t,Member m WHERE m.id_team = t.id AND m.id_user= :idUser AND m.role = 'COACH'", "SELECT t.* FROM team t,Member m WHERE m.id_team = t.id AND m.id_user= :idUser AND m.role = 'COACH'",
@ -179,6 +198,10 @@ class TeamGateway {
); );
} }
/**
* @param int $team
* @return array<array<string, mixed>>
*/
public function getAllTeamTactic(int $team): array { public function getAllTeamTactic(int $team): array {
return $this->con->fetch( return $this->con->fetch(
"SELECT t.* FROM Tactic t, TacticSharedTeam tt WHERE t.id = tt.id_tactic AND tt.id_team = :idTeam", "SELECT t.* FROM Tactic t, TacticSharedTeam tt WHERE t.id = tt.id_tactic AND tt.id_team = :idTeam",

@ -55,19 +55,12 @@ class TacticModel {
return $this->tactics->get($id); return $this->tactics->get($id);
} }
/**
* Return the nb last tactics created
*
* @param integer $nb
* @return array<array<string,mixed>>
*/
/** /**
* Return the nb last tactics * Return the nb last tactics
* *
* @param integer $nb * @param integer $nb
* @param integer $ownerId * @param integer $ownerId
* @return array<array<string,mixed>> * @return array<TacticInfo>
*/ */
public function getLast(int $nb, int $ownerId): array { public function getLast(int $nb, int $ownerId): array {
return $this->tactics->getLastOwnedBy($nb, $ownerId); return $this->tactics->getLastOwnedBy($nb, $ownerId);
@ -77,21 +70,35 @@ class TacticModel {
* Get all the tactics of the owner * Get all the tactics of the owner
* *
* @param integer $ownerId * @param integer $ownerId
* @return array|null * @return array<TacticInfo>|null
*/ */
public function getAll(int $ownerId): ?array { public function getAll(int $ownerId): ?array {
return $this->tactics->getAllOwnedBy($ownerId); return $this->tactics->getAllOwnedBy($ownerId);
} }
public function getAllTacticSharedTeam(int $ownerId) : ?array /**
{ * Get all the tactics shared to a user via team share
* @param int $ownerId
* @return array<TacticInfo>|null
*/
public function getAllTacticSharedTeam(int $ownerId): ?array {
return $this->tactics->getAllTacticSharedTeam($ownerId); return $this->tactics->getAllTacticSharedTeam($ownerId);
} }
/**
* Get all the tactics shared to a user via account share
* @param int $ownerId
* @return array<TacticInfo>|null
*/
public function getAllTacticSharedAccount(int $ownerId): ?array { public function getAllTacticSharedAccount(int $ownerId): ?array {
return $this->tactics->getAllTacticSharedAccount($ownerId); return $this->tactics->getAllTacticSharedAccount($ownerId);
} }
/**
* Get all the tactics shared to a user via team or account share
* @param int $ownerId
* @return array<TacticInfo>|null
*/
public function getAllTacticShared(int $ownerId): ?array { public function getAllTacticShared(int $ownerId): ?array {
$allTactics = []; $allTactics = [];
$allTacticsSharedTeam = $this->tactics->getAllTacticSharedTeam($ownerId); $allTacticsSharedTeam = $this->tactics->getAllTacticSharedTeam($ownerId);
@ -114,6 +121,11 @@ class TacticModel {
return $allTactics; return $allTactics;
} }
/**
* Get all the tactics a user shared and own
* @param int $ownerId
* @return array<TacticInfo>|null
*/
public function getAllTacticSharedOwned(int $ownerId): ?array { public function getAllTacticSharedOwned(int $ownerId): ?array {
$allTactics = []; $allTactics = [];
$allTacticsSharedTeamOwned = $this->tactics->getAllTacticSharedTeamOwned($ownerId); $allTacticsSharedTeamOwned = $this->tactics->getAllTacticSharedTeamOwned($ownerId);
@ -136,34 +148,54 @@ class TacticModel {
return $allTactics; return $allTactics;
} }
public function shareTacticToAccount(int $accountId, int $tacticId): int /**
{ * Share tactic to an account
* @param int $accountId
* @param int $tacticId
* @return int
*/
public function shareTacticToAccount(int $accountId, int $tacticId): int {
return $this->users->shareTacticToAccount($accountId, $tacticId); return $this->users->shareTacticToAccount($accountId, $tacticId);
} }
public function shareTacticToAccountMail(string $email, int $tacticId): ?int /**
{ * Share tactic to an account email
* @param string $email
* @param int $tacticId
* @return int|null
*/
public function shareTacticToAccountMail(string $email, int $tacticId): ?int {
$account = $this->users->getAccountFromMail($email); $account = $this->users->getAccountFromMail($email);
var_dump($account);
$accountId = $account->getUser()->getId(); $accountId = $account->getUser()->getId();
var_dump($accountId);
if(isset($accountId)) {
return $this->shareTacticToAccount($accountId, $tacticId); return $this->shareTacticToAccount($accountId, $tacticId);
} }
return null;
}
public function unshareTactic(int $tacticId): int /**
{ * Unshare a tactic to every account
* @param int $tacticId
* @return int
*/
public function unshareTactic(int $tacticId): int {
return $this->users->unshareTactic($tacticId); return $this->users->unshareTactic($tacticId);
} }
public function unshareTacticToAccount(int $tacticId, int $accountId): int /**
{ * Unshare a tactic to an account
* @param int $tacticId
* @param int $accountId
* @return int
*/
public function unshareTacticToAccount(int $tacticId, int $accountId): int {
return $this->users->unshareTacticToAccount($tacticId, $accountId); return $this->users->unshareTacticToAccount($tacticId, $accountId);
} }
/**
* Get the owner of a shared tactic
* @param int $tactidId
* @param int $accountId
* @return array<int>|null
*/
public function getOwnerIdTacticShared(int $tactidId, int $accountId): ?array { public function getOwnerIdTacticShared(int $tactidId, int $accountId): ?array {
$ids = []; $ids = [];
$idT = $this->tactics->getOwnerIdTacticSharedTeam($tactidId, $accountId); $idT = $this->tactics->getOwnerIdTacticSharedTeam($tactidId, $accountId);
@ -215,6 +247,7 @@ class TacticModel {
return []; return [];
} }
public function updateContent(int $id, string $json): ?ValidationFail { public function updateContent(int $id, string $json): ?ValidationFail {
if (!$this->tactics->updateContent($id, $json)) { if (!$this->tactics->updateContent($id, $json)) {
return ValidationFail::error("Could not update content"); return ValidationFail::error("Could not update content");
@ -222,6 +255,12 @@ class TacticModel {
return null; return null;
} }
/**
* Verify if tactic can be shared by user
* @param int $id
* @param Account $account
* @return bool
*/
public function canShareTactic(int $id, Account $account): bool { public function canShareTactic(int $id, Account $account): bool {
if($this->get($id)->getOwnerId() != $account->getUser()->getId()) { if($this->get($id)->getOwnerId() != $account->getUser()->getId()) {
return false; return false;

@ -78,20 +78,41 @@ class TeamModel {
return new Team($teamInfo, $members); return new Team($teamInfo, $members);
} }
/**
public function shareTacticToTeam(int $teamId, int $tacticId): int * Share tactic to a team
{ * @param int $teamId
* @param int $tacticId
* @return int
*/
public function shareTacticToTeam(int $teamId, int $tacticId): int {
return $this->teams->shareTacticToTeam($teamId, $tacticId); return $this->teams->shareTacticToTeam($teamId, $tacticId);
} }
/**
* Unshare tactic from every team
* @param int $tacticId
* @return int
*/
public function unshareTactic(int $tacticId): int { public function unshareTactic(int $tacticId): int {
return $this->teams->unshareTactic($tacticId); return $this->teams->unshareTactic($tacticId);
} }
/**
* Unshare team-shared tactic
* @param int $tacticId
* @param int $teamId
* @return int
*/
public function unshareTacticToTeam(int $tacticId, int $teamId): int { public function unshareTacticToTeam(int $tacticId, int $teamId): int {
return $this->teams->unshareTacticToTeam($tacticId, $teamId); return $this->teams->unshareTacticToTeam($tacticId, $teamId);
} }
/**
* Verify if user can share tactic to a team
* @param int $teamId
* @param string $email
* @return bool
*/
public function canShareTacticToTeam(int $teamId, string $email): bool { public function canShareTacticToTeam(int $teamId, string $email): bool {
if($this->isCoach($teamId, $email)) { if($this->isCoach($teamId, $email)) {
return true; return true;
@ -161,10 +182,20 @@ class TeamModel {
return $this->teams->getAll($user); return $this->teams->getAll($user);
} }
/**
* Get all user's teams where user is coach
* @param int $user
* @return array<array<string, mixed>>
*/
public function getAllIsCoach(int $user): array { public function getAllIsCoach(int $user): array {
return $this->teams->getAllIsCoach($user); return $this->teams->getAllIsCoach($user);
} }
/**
* Get all tactic shared with a team
* @param int $team
* @return array<array<string, mixed>>
*/
public function getAllTeamTactic(int $team): array { public function getAllTeamTactic(int $team): array {
return $this->teams->getAllTeamTactic($team); return $this->teams->getAllTeamTactic($team);
} }

Loading…
Cancel
Save