Merge branch 'home-page' of codefirst.iut.uca.fr:IQBall/Application-Web
continuous-integration/drone/push Build is passing Details

pull/81/head
DahmaneYanis 1 year ago
commit 76141f86ee

@ -0,0 +1,38 @@
{
// Utilisez IntelliSense pour en savoir plus sur les attributs possibles.
// Pointez pour afficher la description des attributs existants.
// Pour plus d'informations, visitez : https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Launch built-in server and debug",
"type": "php",
"request": "launch",
"runtimeArgs": [
"-S",
"localhost:8080",
"-t",
"./public"
],
"port": 8080,
"serverReadyAction": {
"action": "openExternally"
}
},
{
"name": "Debug current script in console",
"type": "php",
"request": "launch",
"program": "${file}",
"cwd": "${fileDirname}",
"externalConsole": false,
"port": 9003
},
{
"name": "Listen for Xdebug",
"type": "php",
"request": "launch",
"port": 9003
}
]
}

@ -10,7 +10,6 @@ const SUPPORTS_FAST_REFRESH = _SUPPORTS_FAST_REFRESH;
/** /**
* Maps the given relative source uri (relative to the `/front` folder) to its actual location depending on imported profile. * Maps the given relative source uri (relative to the `/front` folder) to its actual location depending on imported profile.
* @param string $assetURI relative uri path from `/front` folder * @param string $assetURI relative uri path from `/front` folder
* @return string valid url that points to the given uri
*/ */
function asset(string $assetURI): string { function asset(string $assetURI): string {
return _asset($assetURI); return _asset($assetURI);

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24"><path d="M234-276q51-39 114-61.5T480-360q69 0 132 22.5T726-276q35-41 54.5-93T800-480q0-133-93.5-226.5T480-800q-133 0-226.5 93.5T160-480q0 59 19.5 111t54.5 93Zm246-164q-59 0-99.5-40.5T340-580q0-59 40.5-99.5T480-720q59 0 99.5 40.5T620-580q0 59-40.5 99.5T480-440Zm0 360q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Zm0-80q53 0 100-15.5t86-44.5q-39-29-86-44.5T480-280q-53 0-100 15.5T294-220q39 29 86 44.5T480-160Zm0-360q26 0 43-17t17-43q0-26-17-43t-43-17q-26 0-43 17t-17 43q0 26 17 43t43 17Zm0-60Zm0 360Z" fill="#e6edf3"/></svg>

After

Width:  |  Height:  |  Size: 747 B

@ -0,0 +1,63 @@
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
version="1.1"
width="100"
height="50"
viewBox="7.5 18.5 85.5 56"
style="enable-background:new 7.5 18.5 85.5 56;"
xml:space="preserve">
<style type="text/css">
.st0{fill:none;stroke:#000000;stroke-miterlimit:10;}
.st1{fill:none;stroke:#000000;stroke-miterlimit:10;stroke-dasharray:1.4358,1.4358;}
.st2{fill:none;stroke:#000000;stroke-width:0.5;stroke-miterlimit:10;}
.st3{fill:none;stroke:#000000;stroke-miterlimit:10;stroke-dasharray:1.4407,1.4407;}
</style>
<polygon class="st0" points="92.1,72.1 50.1,72.1 8.1,72.1 8.1,21.2 50.1,21.2 92.1,21.2 "/>
<line class="st0" x1="50.1" y1="21.2" x2="50.1" y2="72.1"/>
<circle class="st0" cx="50.1" cy="46.6" r="6.4"/>
<path class="st0" d="M8.1,66h7.2c10.1,0,18.2-8.7,18.2-19.3s-8.2-19.3-18.2-19.3H8.1"/>
<path class="st0" d="M8.1,40.2h19c3.6,0,6.4,2.9,6.4,6.4s-2.9,6.4-6.4,6.4h-19"/>
<line class="st0" x1="27.1" y1="40.2" x2="27.1" y2="53.1"/>
<g>
<g><path class="st0" d="M27.4,40.3c-0.3,0-0.5,0-0.7,0"/>
<path class="st1"
d="M25.3,40.7c-2.5,0.9-4.3,3.3-4.3,6.1c0,3,2.2,5.6,5,6.2"/>
<path
class="st0" d="M26.7,53c0.2,0,0.5,0,0.7,0"/>
</g>
</g>
<line class="st0" x1="16.2" y1="53.1" x2="16.2" y2="54.1"/>
<line class="st2" x1="19.3" y1="53.1" x2="19.3" y2="54.1"/>
<line class="st2" x1="22.4" y1="53.1" x2="22.4" y2="54.1"/>
<line class="st2" x1="25.7" y1="53.1" x2="25.7" y2="54.1"/>
<line class="st0" x1="16.1" y1="39.2" x2="16.1" y2="40.2"/>
<line class="st2" x1="19.2" y1="39.2" x2="19.2" y2="40.2"/>
<line class="st2" x1="22.3" y1="39.2" x2="22.3" y2="40.2"/>
<line class="st2" x1="25.6" y1="39.2" x2="25.6" y2="40.2"/>
<line class="st0" x1="27.1" y1="40.2" x2="27.1" y2="53.1"/>
<path class="st0" d="M92.1,66.1h-7.2c-10.1,0-18.2-8.7-18.2-19.3s8.2-19.3,18.2-19.3h7.2"/>
<path class="st0" d="M92.1,40.3h-19c-3.6,0-6.4,2.9-6.4,6.4s2.9,6.4,6.4,6.4h19"/>
<line class="st0" x1="84" y1="53.2" x2="84" y2="54.1"/>
<line class="st2" x1="80.9" y1="53.2" x2="80.9" y2="54.1"/>
<line class="st2" x1="77.9" y1="53.2" x2="77.9" y2="54.1"/>
<line class="st2" x1="74.5" y1="53.2" x2="74.5" y2="54.1"/>
<line class="st0" x1="84.1" y1="39.3" x2="84.1" y2="40.3"/>
<line class="st2" x1="81" y1="39.3" x2="81" y2="40.3"/>
<line class="st2" x1="77.9" y1="39.3" x2="77.9" y2="40.3"/>
<line class="st2" x1="74.6" y1="39.3" x2="74.6" y2="40.3"/>
<line class="st0" x1="73.1" y1="40.3" x2="73.1" y2="53.2"/>
<line class="st2" x1="36.2" y1="70" x2="36.2" y2="74.1"/>
<line class="st2" x1="63.5" y1="70" x2="63.5" y2="74.1"/>
<line class="st2" x1="36.2" y1="19.1" x2="36.2" y2="23.2"/>
<line class="st2" x1="63.5" y1="19.1" x2="63.5" y2="23.2"/>
<g xmlns="http://www.w3.org/2000/svg">
<g>
<path class="st0" d="M72.9,40.3c0.3,0,0.5,0,0.7,0"/>
<path class="st3"
d="M75,40.7c2.5,0.9,4.3,3.3,4.3,6.1c0,3-2.2,5.6-5.1,6.2"/>
<path
class="st0" d="M73.5,53.1c-0.2,0-0.5,0-0.7,0"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.2 KiB

@ -8,6 +8,7 @@ import {
useState, useState,
} from "react" } from "react"
import CourtPlayer from "./CourtPlayer" import CourtPlayer from "./CourtPlayer"
import { Player } from "../../tactic/Player" import { Player } from "../../tactic/Player"
import { Action, ActionKind } from "../../tactic/Action" import { Action, ActionKind } from "../../tactic/Action"
import ArrowAction from "../actions/ArrowAction" import ArrowAction from "../actions/ArrowAction"

@ -9,3 +9,6 @@
height: 20px; height: 20px;
cursor: pointer; cursor: pointer;
} }
.ball-div:focus-within {
}

@ -0,0 +1,114 @@
@import url(variable.css);
body {
/* background-color: #303030; */
}
#main {
/* margin-left : 10%;
margin-right: 10%; */
/* border : solid 1px #303030; */
display: flex;
flex-direction: column;
font-family: Helvetica;
height: 100%;
}
#header {
text-align: center;
background-color: var(--main-color);
margin: 0px;
/* border : var(--accent-color) 1px ésolid; */
display: flex;
flex-direction: row;
/* border-radius: 0.75cap; */
}
#IQBall {
color: var(--accent-color);
font-weight: bold;
font-size: 45px;
}
#IQBall {
color: #ffa238;
font-weight: bold;
font-size: 45px;
}
#body {
display: flex;
flex-direction: row;
margin: 0px;
height: 100%;
background-color: var(--second-color);
}
.data {
border: 1.5px solid var(--main-contrast-color);
background-color: var(--main-color);
border-radius: 0.75cap;
color: var(--main-contrast-color);
}
.data:hover {
border-color: var(--accent-color);
cursor: pointer;
}
.listTactic {
display: block;
}
.SetButton {
width: 80%;
margin-left: 5%;
margin-top: 5%;
}
#img-account {
width: 100%;
cursor: pointer;
}
#header-right,
#header-left {
width: 10%;
/* border: yellow 2px solid; */
}
#header-right {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
#username {
color: var(--main-contrast-color);
margin: 0;
}
#clickable-header-right:hover #username {
color: var(--accent-color);
}
#header-center {
width: 80%;
}
#clickable-header-right {
width: 40%;
border-radius: 1cap;
padding: 2%;
}
#clickable-header-right:hover {
border: orange 1px solid;
}
.clickable {
cursor: pointer;
}
#img-account {
width: 100%;
}

@ -0,0 +1,94 @@
#main {
margin-left : 10%;
margin-right: 10%;
border : solid 2px purple;
display: flex;
flex-direction: column;
font-family: Helvetica,;
}
.new {
border-radius: 100%;
}
#header {
text-align: center;
<<<<<<< HEAD:front/style/home.css
background-color: green;
margin : 0px;
}
#body {
display: flex;
flex-direction: row;
border : solid 10px violet;
margin:0px
}
#personal-space {
background-color: orange;
display: flex;
flex-direction: column;
}
#sideMenu {
background-color: grey;
}
#titlePersonalSpace h2 {
text-align: center;
}
#sideMenu h2 {
display: inline-block;
margin-right : 5%;
}
.titreSideMenu {
border-bottom: black solid 2px;
width: 95%;
}
#sideMenu .title {
font-size: 13px;
font-weight: bold;
color : #FFFFFF;
letter-spacing: 1px;
text-transform: uppercase;
background-color: black;
padding : 1.5%;
margin-bottom: 0px;
}
#bodyPersonalSpace {
width: 95%;
border : 1px red solid;
align-self: center;
}
#bodyPersonalSpace table{
width: 100%;
border-collapse : separate;
border-spacing : 1em;
}
td {
border : 3px solid black;
padding-bottom : 1%;
padding-top : 1%;
margin: 80px;
text-align: center;
}
td:hover {
background-color: red;
=======
}
#title {
background-color: aqua;
>>>>>>> 6d36115 (WIP page home):front/style/home/titre.css
}

@ -0,0 +1,40 @@
#personal-space {
display: flex;
flex-direction: column;
}
#titlePersonalSpace h2 {
text-align: center;
color: var(--main-contrast-color);
/* font-family: Helvetica;
font-weight: bold; */
}
#bodyPersonalSpace {
width: 95%;
/* background-color: #ccc2b7; */
border: 3px var(--main-color) solid;
border-radius: 0.5cap;
align-self: center;
}
#bodyPersonalSpace table {
width: 100%;
border-collapse: separate;
border-spacing: 1em;
table-layout: fixed;
overflow: hidden;
}
#bodyPersonalSpace td {
width: 80px !important;
padding-bottom: 1%;
padding-top: 1%;
height: fit-content;
text-align: center;
overflow: hidden;
}
tbody p {
text-align: center;
}

@ -0,0 +1,53 @@
@import url(variable.css);
#sideMenu {
background-color: var(--third-color);
display: flex;
flex-direction: column;
align-items: center;
overflow: hidden;
}
#sideMenu h2 {
display: inline-block;
margin-right: 5%;
}
#sideMenuContent {
width: 90%;
}
.titreSideMenu {
border-bottom: var(--main-color) solid 3px;
width: 100%;
margin-bottom: 3%;
}
#sideMenu .title {
font-size: 12px;
font-weight: bold;
color: var(--main-contrast-color);
letter-spacing: 1px;
text-transform: uppercase;
background-color: var(--main-color);
padding: 3%;
margin-bottom: 0px;
margin-right: 3%;
}
.new {
border-radius: 100%;
}
.buttonSideMenu {
/* border : black solid 1px; */
border-radius: 0.5cap;
width: fit-content;
padding: 2%;
margin-top: 3%;
overflow: hidden;
}
.buttonSideMenu:hover {
/* background-color: #c9d1e0; */
cursor: pointer;
}

@ -0,0 +1,7 @@
:root {
--main-color: #191a21;
--second-color: #282a36;
--third-color: #303341;
--accent-color: #ffa238;
--main-contrast-color: #e6edf3;
}

@ -0,0 +1,306 @@
import "../style/home.css"
import "../style/personnal_space.css"
import "../style/side_menu.css"
// import AccountSvg from "../assets/account.svg?react"
import { CSSProperties, useRef } from "react"
interface Tactic {
id: number
name: string
creation_date: string
}
interface Team {
id: number
name: string
picture: string
main_color: string
second_color: string
}
export default function Home({
lastTactics,
allTactics,
teams,
username,
}: {
lastTactics: Tactic[]
allTactics: Tactic[]
teams: Team[]
username: string
}) {
return (
<div id="main">
<Title username={username} />
<Body
lastTactics={lastTactics}
allTactics={allTactics}
teams={teams}
/>
</div>
)
}
/**
*
* @param param0 username
* @returns Header
*/
export function Title({ username }: { username: string }) {
return (
<div id="header">
<div id="header-left"></div>
<div id="header-center">
<h1
id="IQBall"
className="clickable"
onClick={() => {
location.pathname = "/"
}}>
<span id="IQ">IQ</span>
<span id="Ball">Ball</span>
</h1>
</div>
<div id="header-right">
<div className="clickable" id="clickable-header-right">
{/* <AccountSvg id="img-account" /> */}
<img
id="img-account"
src="account.svg"
onClick={() => {
location.pathname = "/settings"
}}
/>
<p id="username">{username}</p>
</div>
</div>
</div>
)
}
export function Body({
lastTactics,
allTactics,
teams,
}: {
lastTactics: Tactic[]
allTactics: Tactic[]
teams: Team[]
}) {
const widthPersonalSpace = 78
const widthSideMenu = 100 - widthPersonalSpace
return (
<div id="body">
<PersonalSpace width={widthPersonalSpace} allTactics={allTactics} />
<SideMenu
width={widthSideMenu}
lastTactics={lastTactics}
teams={teams}
/>
</div>
)
}
export function SideMenu({
width,
lastTactics,
teams,
}: {
width: number
lastTactics: Tactic[]
teams: Team[]
}) {
return (
<div
id="sideMenu"
style={{
width: width + "%",
}}>
<div id="sideMenuContent">
<Team teams={teams} />
<Tactic lastTactics={lastTactics} />
</div>
</div>
)
}
export function PersonalSpace({
width,
allTactics,
}: {
width: number
allTactics: Tactic[]
}) {
return (
<div
id="personal-space"
style={{
width: width + "%",
}}>
<TitlePersonalSpace />
<BodyPersonalSpace allTactics={allTactics} />
</div>
)
}
function TitlePersonalSpace() {
return (
<div id="titlePersonalSpace">
<h2>Espace Personnel</h2>
</div>
)
}
function TableData({ allTactics }: { allTactics: Tactic[] }) {
const nbRow = Math.floor(allTactics.length / 3) + 1
let listTactic = Array(nbRow)
for (let i = 0; i < nbRow; i++) {
listTactic[i] = Array(0)
}
let i = 0
let j = 0
allTactics.forEach((tactic) => {
listTactic[i].push(tactic)
j++
if (j === 3) {
i++
j = 0
}
})
i = 0
while (i < nbRow) {
listTactic[i] = listTactic[i].map((tactic: Tactic) => (
<td
key={tactic.id}
className="data"
onClick={() => {
location.pathname = "/tactic/" + tactic.id + "/edit"
}}>
{troncName(tactic.name, 25)}
</td>
))
i++
}
if (nbRow == 1) {
if (listTactic[0].length < 3) {
for (let i = 0; i <= 3 - listTactic[0].length; i++) {
listTactic[0].push(<td key={"tdNone" + i}></td>)
}
}
}
const data = listTactic.map((tactic, rowIndex) => (
<tr key={rowIndex + "row"}>{tactic}</tr>
))
return data
}
function BodyPersonalSpace({ allTactics }: { allTactics: Tactic[] }) {
let data
if (allTactics.length == 0) {
data = <p>Aucune tactique créé !</p>
} else {
data = <TableData allTactics={allTactics} />
}
return (
<div id="bodyPersonalSpace">
<table>
<tbody key="tbody">{data}</tbody>
</table>
</div>
)
}
export function Team({ teams }: { teams: Team[] }) {
const listTeam = teams.map((team, rowIndex) => (
<li key={"team" + rowIndex}>
{team.name}
<button onClick={() => (location.pathname = "/team/" + team.id)}>
open
</button>
</li>
))
return (
<div id="teams">
<div className="titreSideMenu">
<h2 className="title">Mes équipes</h2>
<button
className="new"
onClick={() => (location.pathname = "/team/new")}>
+
</button>
</div>
<SetButtonTeam teams={teams} />
</div>
)
}
export function Tactic({ lastTactics }: { lastTactics: Tactic[] }) {
return (
<div id="tactic">
<div className="titreSideMenu">
<h2 className="title">Mes dernières stratégies</h2>
<button
className="new"
id="createTactic"
onClick={() => (location.pathname = "/tactic/new")}>
+
</button>
</div>
<SetButtonTactic tactics={lastTactics} />
</div>
)
}
function SetButtonTactic({ tactics }: { tactics: Tactic[] }) {
const lastTactics = tactics.map((tactic) => (
<ButtonLastTactic tactic={tactic} />
))
return <div className="SetButton">{lastTactics}</div>
}
function SetButtonTeam({ teams }: { teams: Team[] }) {
const listTeam = teams.map((teams) => <ButtonTeam team={teams} />)
return <div className="SetButton">{listTeam}</div>
}
function ButtonTeam({ team }: { team: Team }) {
const name = troncName(team.name, 20)
return (
<div>
<div
id={"ButtonTeam" + team.id}
className="buttonSideMenu data"
onClick={() => {
location.pathname = "/team/" + team.id
}}>
{name}
</div>
</div>
)
}
function ButtonLastTactic({ tactic }: { tactic: Tactic }) {
const name = troncName(tactic.name, 20)
return (
<div
id={"Button" + tactic.id}
className="buttonSideMenu data"
onClick={() => {
location.pathname = "/tactic/" + tactic.id + "/edit"
}}>
{name}
</div>
)
}
function troncName(name: string, limit: number): string {
if (name.length > limit) {
name = name.substring(0, limit) + "..."
} else {
name = name
}
return name
}

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24"><path d="M234-276q51-39 114-61.5T480-360q69 0 132 22.5T726-276q35-41 54.5-93T800-480q0-133-93.5-226.5T480-800q-133 0-226.5 93.5T160-480q0 59 19.5 111t54.5 93Zm246-164q-59 0-99.5-40.5T340-580q0-59 40.5-99.5T480-720q59 0 99.5 40.5T620-580q0 59-40.5 99.5T480-440Zm0 360q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Zm0-80q53 0 100-15.5t86-44.5q-39-29-86-44.5T480-280q-53 0-100 15.5T294-220q39 29 86 44.5T480-160Zm0-360q26 0 43-17t17-43q0-26-17-43t-43-17q-26 0-43 17t-17 43q0 26 17 43t43 17Zm0-60Zm0 360Z" fill="#e6edf3"/></svg>

After

Width:  |  Height:  |  Size: 747 B

@ -1,6 +1,5 @@
<?php <?php
require "../vendor/autoload.php"; require "../vendor/autoload.php";
require "../config.php"; require "../config.php";
require "../sql/database.php"; require "../sql/database.php";
@ -39,7 +38,7 @@ function getConnection(): Connection {
} }
function getUserController(): UserController { function getUserController(): UserController {
return new UserController(new TacticModel(new TacticInfoGateway(getConnection()))); return new UserController(new TacticModel(new TacticInfoGateway(getConnection())), new TeamModel(new TeamGateway(getConnection()), new MemberGateway(getConnection()), new AccountGateway(getConnection())));
} }
function getVisualizerController(): VisualizerController { function getVisualizerController(): VisualizerController {
@ -122,7 +121,6 @@ function runMatch($match, MutableSessionHandle $session): HttpResponse {
return App::runAction($basePath . '/login', $match['target'], $match['params'], $session); return App::runAction($basePath . '/login', $match['target'], $match['params'], $session);
} }
//this is a global variable //this is a global variable
$basePath = get_public_path(__DIR__); $basePath = get_public_path(__DIR__);

@ -7,15 +7,19 @@ use IQBall\App\Session\SessionHandle;
use IQBall\App\ViewHttpResponse; use IQBall\App\ViewHttpResponse;
use IQBall\Core\Http\HttpResponse; use IQBall\Core\Http\HttpResponse;
use IQBall\Core\Model\TacticModel; use IQBall\Core\Model\TacticModel;
use IQBall\Core\Model\TeamModel;
class UserController { class UserController {
private TacticModel $tactics; private TacticModel $tactics;
private ?TeamModel $teams;
/** /**
* @param TacticModel $tactics * @param TacticModel $tactics
*/ */
public function __construct(TacticModel $tactics) { public function __construct(TacticModel $tactics, ?TeamModel $teams = null) {
$this->tactics = $tactics; $this->tactics = $tactics;
$this->teams = $teams;
} }
/** /**
@ -23,9 +27,29 @@ class UserController {
* @return ViewHttpResponse the home page view * @return ViewHttpResponse the home page view
*/ */
public function home(SessionHandle $session): ViewHttpResponse { public function home(SessionHandle $session): ViewHttpResponse {
//TODO use session's account to get the last 5 tactics of the logged-in account $limitNbTactics = 5;
$listTactic = $this->tactics->getLast(5); $lastTactics = $this->tactics->getLast($limitNbTactics, $session->getAccount()->getId());
return ViewHttpResponse::twig("home.twig", ["recentTactic" => $listTactic]); $allTactics = $this->tactics->getAll($session->getAccount()->getId());
$name = $session->getAccount()->getName();
//TODO
if ($this->teams != null) {
$teams = $this->teams->getAll($session->getAccount()->getId());
} else {
$teams = [];
}
return ViewHttpResponse::react("views/Home.tsx", [
"lastTactics" => $lastTactics,
"allTactics" => $allTactics,
"teams" => $teams,
"username" => $name,
]);
// return ViewHttpResponse::react("views/Home.tsx", []);
}
public function homeTwig(SessionHandle $session): ViewHttpResponse {
return ViewHttpResponse::twig("home.twig", []);
} }
/** /**

@ -45,13 +45,40 @@ class TacticInfoGateway {
* @param integer $nb * @param integer $nb
* @return array<array<string,mixed>> * @return array<array<string,mixed>>
*/ */
public function getLast(int $nb): ?array { public function getLast(int $nb, int $ownerId): ?array {
$res = $this->con->fetch( $res = $this->con->fetch(
"SELECT * FROM Tactic ORDER BY creation_date DESC LIMIT :nb ", "SELECT *
[":nb" => [$nb, PDO::PARAM_INT]] FROM Tactic
WHERE owner = :ownerId
ORDER BY creation_date DESC
LIMIT :nb",
[
":ownerId" => [$ownerId, PDO::PARAM_INT],":nb" => [$nb, PDO::PARAM_INT],
]
); );
if (count($res) == 0) { if (count($res) == 0) {
return null; return [];
}
return $res;
}
/**
* Get all the tactics of the owner
*
* @return array<array<string,mixed>>
*/
public function getAll(int $ownerId): ?array {
$res = $this->con->fetch(
"SELECT *
FROM Tactic
WHERE owner = :ownerId
ORDER BY name DESC",
[
":ownerId" => [$ownerId, PDO::PARAM_INT],
]
);
if (count($res) == 0) {
return [];
} }
return $res; return $res;
} }

@ -81,5 +81,14 @@ class TeamGateway {
)[0]['id'] ?? null; )[0]['id'] ?? null;
} }
/**
* Undocumented function
*
* @param integer $user
* @return array<array<string, mixed>>
*/
public function getAll(int $user): array {
return $this->con->fetch("SELECT * FROM Team", []);
}
} }

@ -3,6 +3,7 @@
namespace IQBall\Core\Model; namespace IQBall\Core\Model;
use IQBall\Core\Data\CourtType; use IQBall\Core\Data\CourtType;
use IQBall\App\Session\SessionHandle;
use IQBall\Core\Data\TacticInfo; use IQBall\Core\Data\TacticInfo;
use IQBall\Core\Gateway\TacticInfoGateway; use IQBall\Core\Gateway\TacticInfoGateway;
use IQBall\Core\Validation\ValidationFail; use IQBall\Core\Validation\ValidationFail;
@ -57,10 +58,27 @@ class TacticModel {
* @param integer $nb * @param integer $nb
* @return array<array<string,mixed>> * @return array<array<string,mixed>>
*/ */
public function getLast(int $nb): ?array {
return $this->tactics->getLast($nb); /**
* Return the nb last tactics
*
* @param integer $nb
* @param integer $ownerId
* @return array<array<string,mixed>>
*/
public function getLast(int $nb, int $ownerId): array {
return $this->tactics->getLast($nb, $ownerId);
} }
/**
* Get all the tactics of the owner
*
* @param integer $ownerId
* @return array<array<string,mixed>>
*/
public function getAll(int $ownerId): ?array {
return $this->tactics->getAll($ownerId);
}
/** /**
* Update the name of a tactic * Update the name of a tactic
* @param int $id the tactic identifier * @param int $id the tactic identifier

@ -79,4 +79,14 @@ class TeamModel {
return $teamId; return $teamId;
} }
/**
* Get all user's teams
*
* @param integer $user
* @return array<array<string, mixed>>
*/
public function getAll(int $user) : array {
return $this->teams->getAll($user);
}
} }

Loading…
Cancel
Save