(null)
-
-
/**
* Computes and return the segments edition points
* @param parentBase
diff --git a/front/components/editor/BasketCourt.tsx b/front/components/editor/BasketCourt.tsx
index e57d669..e59bdb7 100644
--- a/front/components/editor/BasketCourt.tsx
+++ b/front/components/editor/BasketCourt.tsx
@@ -8,6 +8,7 @@ import {
useState,
} from "react"
import CourtPlayer from "./CourtPlayer"
+
import { Player } from "../../tactic/Player"
import { Action, ActionKind } from "../../tactic/Action"
import ArrowAction from "../actions/ArrowAction"
diff --git a/front/style/ball.css b/front/style/ball.css
index c14c196..5169ec7 100644
--- a/front/style/ball.css
+++ b/front/style/ball.css
@@ -9,3 +9,6 @@
height: 20px;
cursor: pointer;
}
+
+.ball-div:focus-within {
+}
diff --git a/front/style/colors.css b/front/style/colors.css
deleted file mode 100644
index db7edfe..0000000
--- a/front/style/colors.css
+++ /dev/null
@@ -1,13 +0,0 @@
-:root {
- --main-color: #ffffff;
- --second-color: #ccde54;
-
- --background-color: #d2cdd3;
-
- --selected-team-primarycolor: #ffffff;
- --selected-team-secondarycolor: #000000;
-
- --selection-color: #3f7fc4;
-
- --arrows-color: #676767;
-}
diff --git a/front/style/home/home.css b/front/style/home/home.css
new file mode 100644
index 0000000..455e3af
--- /dev/null
+++ b/front/style/home/home.css
@@ -0,0 +1,43 @@
+@import url(../theme/dark.css);
+@import url(personnal_space.css);
+@import url(side_menu.css);
+@import url(../template/header.css);
+
+body {
+ /* background-color: #303030; */
+}
+#main {
+ /* margin-left : 10%;
+ margin-right: 10%; */
+ /* border : solid 1px #303030; */
+ display: flex;
+ flex-direction: column;
+ font-family: var(--font-content);
+ height: 100%;
+}
+
+#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;
+}
+
+.set-button {
+ width: 80%;
+ margin-left: 5%;
+ margin-top: 5%;
+}
diff --git a/front/style/home/personnal_space.css b/front/style/home/personnal_space.css
new file mode 100644
index 0000000..173098e
--- /dev/null
+++ b/front/style/home/personnal_space.css
@@ -0,0 +1,40 @@
+#personal-space {
+ display: flex;
+ flex-direction: column;
+}
+
+#title-personal-space h2 {
+ text-align: center;
+ color: var(--main-contrast-color);
+ /* font-family: Helvetica;
+ font-weight: bold; */
+}
+
+#body-personal-space {
+ width: 95%;
+ /* background-color: #ccc2b7; */
+ border: 3px var(--main-color) solid;
+ border-radius: 0.5cap;
+ align-self: center;
+}
+
+#body-personal-space table {
+ width: 100%;
+ border-collapse: separate;
+ border-spacing: 1em;
+ table-layout: fixed;
+ overflow: hidden;
+}
+
+#body-personal-space td {
+ width: 80px !important;
+ padding-bottom: 1%;
+ padding-top: 1%;
+ height: fit-content;
+ text-align: center;
+ overflow: hidden;
+}
+
+tbody p {
+ text-align: center;
+}
diff --git a/front/style/home/side_menu.css b/front/style/home/side_menu.css
new file mode 100644
index 0000000..3a23947
--- /dev/null
+++ b/front/style/home/side_menu.css
@@ -0,0 +1,53 @@
+@import url(../theme/dark.css);
+
+#side-menu {
+ background-color: var(--third-color);
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ overflow: hidden;
+}
+
+#side-menu h2 {
+ display: inline-block;
+ margin-right: 5%;
+}
+
+#side-menu-content {
+ width: 90%;
+}
+.titre-side-menu {
+ border-bottom: var(--main-color) solid 3px;
+ width: 100%;
+ margin-bottom: 3%;
+}
+
+#side-menu .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%;
+}
+
+.button-side-menu {
+ /* border : black solid 1px; */
+ border-radius: 0.5cap;
+ width: fit-content;
+ padding: 2%;
+ margin-top: 3%;
+ overflow: hidden;
+}
+
+.button-side-menu:hover {
+ /* background-color: #c9d1e0; */
+ cursor: pointer;
+}
diff --git a/front/style/template/header.css b/front/style/template/header.css
new file mode 100644
index 0000000..2ea8d2f
--- /dev/null
+++ b/front/style/template/header.css
@@ -0,0 +1,65 @@
+#header {
+ text-align: center;
+ background-color: var(--main-color);
+ margin: 0px;
+ /* border : var(--accent-color) 1px solid; */
+ display: flex;
+ flex-direction: row;
+ font-family: var(--font-title);
+ /* border-radius: 0.75cap; */
+}
+
+#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%;
+}
+
+#iqball {
+ color: var(--accent-color);
+ font-weight: bold;
+ font-size: 45px;
+}
diff --git a/front/style/theme/dark.css b/front/style/theme/dark.css
new file mode 100644
index 0000000..bdd4824
--- /dev/null
+++ b/front/style/theme/dark.css
@@ -0,0 +1,9 @@
+:root {
+ --main-color: #191a21;
+ --second-color: #282a36;
+ --third-color: #303341;
+ --accent-color: #ffa238;
+ --main-contrast-color: #e6edf3;
+ --font-title: Helvetica;
+ --font-content: Helvetica;
+}
diff --git a/front/views/Home.tsx b/front/views/Home.tsx
new file mode 100644
index 0000000..44803a3
--- /dev/null
+++ b/front/views/Home.tsx
@@ -0,0 +1,267 @@
+import "../style/home/home.css"
+
+// import AccountSvg from "../assets/account.svg?react"
+import { CSSProperties, useRef } from "react"
+import { Header } from "./template/Header"
+
+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 (
+
+
+
+
+ )
+}
+
+function Body({
+ lastTactics,
+ allTactics,
+ teams,
+}: {
+ lastTactics: Tactic[]
+ allTactics: Tactic[]
+ teams: Team[]
+}) {
+ const widthPersonalSpace = 78
+ const widthSideMenu = 100 - widthPersonalSpace
+ return (
+
+ )
+}
+
+function SideMenu({
+ width,
+ lastTactics,
+ teams,
+}: {
+ width: number
+ lastTactics: Tactic[]
+ teams: Team[]
+}) {
+ return (
+
+ )
+}
+
+function PersonalSpace({
+ width,
+ allTactics,
+}: {
+ width: number
+ allTactics: Tactic[]
+}) {
+ return (
+
+
+
+
+ )
+}
+
+function TitlePersonalSpace() {
+ return (
+
+
Espace Personnel
+
+ )
+}
+
+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) => (
+ {
+ location.pathname = "/tactic/" + tactic.id + "/edit"
+ }}>
+ {truncateString(tactic.name, 25)}
+ |
+ ))
+ i++
+ }
+ if (nbRow == 1) {
+ if (listTactic[0].length < 3) {
+ for (let i = 0; i <= 3 - listTactic[0].length; i++) {
+ listTactic[0].push( | )
+ }
+ }
+ }
+
+ const data = listTactic.map((tactic, rowIndex) => (
+ {tactic}
+ ))
+ return data
+}
+
+function BodyPersonalSpace({ allTactics }: { allTactics: Tactic[] }) {
+ let data
+ if (allTactics.length == 0) {
+ data = Aucune tactique créé !
+ } else {
+ data =
+ }
+
+ return (
+
+ )
+}
+
+function Team({ teams }: { teams: Team[] }) {
+ const listTeam = teams.map((team, rowIndex) => (
+
+ {team.name}
+
+
+ ))
+ return (
+
+
+
Mes équipes
+
+
+
+
+ )
+}
+
+function Tactic({ lastTactics }: { lastTactics: Tactic[] }) {
+ return (
+
+
+
Mes dernières stratégies
+
+
+
+
+ )
+}
+
+function SetButtonTactic({ tactics }: { tactics: Tactic[] }) {
+ const lastTactics = tactics.map((tactic) => (
+
+ ))
+ return {lastTactics}
+}
+
+function SetButtonTeam({ teams }: { teams: Team[] }) {
+ const listTeam = teams.map((teams) => )
+ return {listTeam}
+}
+
+function ButtonTeam({ team }: { team: Team }) {
+ const name = truncateString(team.name, 20)
+ return (
+
+
{
+ location.pathname = "/team/" + team.id
+ }}>
+ {name}
+
+
+ )
+}
+
+function ButtonLastTactic({ tactic }: { tactic: Tactic }) {
+ const name = truncateString(tactic.name, 20)
+ return (
+ {
+ location.pathname = "/tactic/" + tactic.id + "/edit"
+ }}>
+ {name}
+
+ )
+}
+
+function truncateString(name: string, limit: number): string {
+ if (name.length > limit) {
+ name = name.substring(0, limit) + "..."
+ }
+ return name
+}
diff --git a/front/views/template/Header.tsx b/front/views/template/Header.tsx
new file mode 100644
index 0000000..7129153
--- /dev/null
+++ b/front/views/template/Header.tsx
@@ -0,0 +1,36 @@
+/**
+ *
+ * @param param0 username
+ * @returns Header
+ */
+export function Header({ username }: { username: string }) {
+ return (
+
+ )
+}
diff --git a/public/account.svg b/public/account.svg
new file mode 100644
index 0000000..70d7391
--- /dev/null
+++ b/public/account.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/public/index.php b/public/index.php
index 8c9a62b..935e2f2 100644
--- a/public/index.php
+++ b/public/index.php
@@ -1,6 +1,5 @@
tactics = $tactics;
+ $this->teams = $teams;
}
/**
@@ -23,16 +27,34 @@ class UserController {
* @return ViewHttpResponse the home page view
*/
public function home(SessionHandle $session): ViewHttpResponse {
- //TODO use session's account to get the last 5 tactics of the logged-in account
- $listTactic = $this->tactics->getLast(5);
- return ViewHttpResponse::twig("home.twig", ["recentTactic" => $listTactic]);
+ $limitNbTactics = 5;
+ $lastTactics = $this->tactics->getLast($limitNbTactics, $session->getAccount()->getId());
+ $allTactics = $this->tactics->getAll($session->getAccount()->getId());
+ $name = $session->getAccount()->getName();
+
+ 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,
+ ]);
+ }
+
+ public function homeTwig(SessionHandle $session): ViewHttpResponse {
+ return ViewHttpResponse::twig("home.twig", []);
}
/**
* @return ViewHttpResponse account settings page
*/
public function settings(SessionHandle $session): ViewHttpResponse {
- return ViewHttpResponse::twig("account_settings.twig", []);
+ return ViewHttpResponse::react("views/Settings.tsx", []);
}
public function disconnect(MutableSessionHandle $session): HttpResponse {
diff --git a/src/Core/Gateway/TacticInfoGateway.php b/src/Core/Gateway/TacticInfoGateway.php
index 67cffc4..08302c9 100644
--- a/src/Core/Gateway/TacticInfoGateway.php
+++ b/src/Core/Gateway/TacticInfoGateway.php
@@ -45,13 +45,40 @@ class TacticInfoGateway {
* @param integer $nb
* @return array>
*/
- public function getLast(int $nb): ?array {
+ public function getLast(int $nb, int $ownerId): ?array {
$res = $this->con->fetch(
- "SELECT * FROM Tactic ORDER BY creation_date DESC LIMIT :nb ",
- [":nb" => [$nb, PDO::PARAM_INT]]
+ "SELECT *
+ 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) {
- return null;
+ return [];
+ }
+ return $res;
+ }
+
+ /**
+ * Get all the tactics of the owner
+ *
+ * @return array>
+ */
+ 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;
}
diff --git a/src/Core/Gateway/TeamGateway.php b/src/Core/Gateway/TeamGateway.php
index d775eda..bc1da94 100644
--- a/src/Core/Gateway/TeamGateway.php
+++ b/src/Core/Gateway/TeamGateway.php
@@ -81,5 +81,14 @@ class TeamGateway {
)[0]['id'] ?? null;
}
+ /**
+ * Get all the user's teams
+ *
+ * @param integer $user
+ * @return array>
+ */
+ public function getAll(int $user): array {
+ return $this->con->fetch("SELECT * FROM Team", []);
+ }
}
diff --git a/src/Core/Model/TacticModel.php b/src/Core/Model/TacticModel.php
index 51e5eb8..7057e7f 100644
--- a/src/Core/Model/TacticModel.php
+++ b/src/Core/Model/TacticModel.php
@@ -3,6 +3,7 @@
namespace IQBall\Core\Model;
use IQBall\Core\Data\CourtType;
+use IQBall\App\Session\SessionHandle;
use IQBall\Core\Data\TacticInfo;
use IQBall\Core\Gateway\TacticInfoGateway;
use IQBall\Core\Validation\ValidationFail;
@@ -57,10 +58,27 @@ class TacticModel {
* @param integer $nb
* @return array>
*/
- public function getLast(int $nb): ?array {
- return $this->tactics->getLast($nb);
+
+ /**
+ * Return the nb last tactics
+ *
+ * @param integer $nb
+ * @param integer $ownerId
+ * @return array>
+ */
+ 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>
+ */
+ public function getAll(int $ownerId): ?array {
+ return $this->tactics->getAll($ownerId);
+ }
/**
* Update the name of a tactic
* @param int $id the tactic identifier
diff --git a/src/Core/Model/TeamModel.php b/src/Core/Model/TeamModel.php
index f6af837..a5ba84b 100644
--- a/src/Core/Model/TeamModel.php
+++ b/src/Core/Model/TeamModel.php
@@ -79,4 +79,14 @@ class TeamModel {
return $teamId;
}
+ /**
+ * Get all user's teams
+ *
+ * @param integer $user
+ * @return array>
+ */
+ public function getAll(int $user): array {
+ return $this->teams->getAll($user);
+ }
+
}