diff --git a/.eslintrc.cjs b/.eslintrc.cjs
new file mode 100644
index 0000000..d6c9537
--- /dev/null
+++ b/.eslintrc.cjs
@@ -0,0 +1,18 @@
+module.exports = {
+ root: true,
+ env: { browser: true, es2020: true },
+ extends: [
+ 'eslint:recommended',
+ 'plugin:@typescript-eslint/recommended',
+ 'plugin:react-hooks/recommended',
+ ],
+ ignorePatterns: ['dist', '.eslintrc.cjs'],
+ parser: '@typescript-eslint/parser',
+ plugins: ['react-refresh'],
+ rules: {
+ 'react-refresh/only-export-components': [
+ 'warn',
+ { allowConstantExport: true },
+ ],
+ },
+}
diff --git a/.gitignore b/.gitignore
index e5a863d..265f50c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,46 +1,26 @@
-.vs
-.vscode
-.idea
-.code
-.vite
+# Logs
+logs
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+pnpm-debug.log*
+lerna-debug.log*
-vendor
-.nfs*
-composer.lock
-*.phar
+node_modules
dist
-.guard
-outputs
-
-# sqlite database files
-*.sqlite
-
-views-mappings.php
-.env.PROD
-
-# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
-
-# dependencies
-/node_modules
-/.pnp
-.pnp.js
-package-lock.json
+dist-ssr
+*.local
-# testing
-/coverage
-
-# production
-/build
-
-# misc
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
.DS_Store
-.env.local
-.env.development.local
-.env.test.local
-.env.production.local
-
-npm-debug.log*
-yarn-debug.log*
-yarn-error.log*
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
-.php-cs-fixer.cache
\ No newline at end of file
+package-lock.json
\ No newline at end of file
diff --git a/README.md b/README.md
index 9a0df84..17f2ded 100644
--- a/README.md
+++ b/README.md
@@ -4,4 +4,3 @@ This repository hosts the IQBall application for web
## Read the docs !
You can find some additional documentation in the [Documentation](Documentation) folder,
and in the [wiki](https://codefirst.iut.uca.fr/git/IQBall/Application-Web/wiki).
-
diff --git a/composer.json b/composer.json
deleted file mode 100644
index 1d3a4d7..0000000
--- a/composer.json
+++ /dev/null
@@ -1,18 +0,0 @@
-{
- "autoload": {
- "psr-4": {
- "IQBall\\": "src/"
- }
- },
- "require": {
- "altorouter/altorouter": "1.2.0",
- "ext-json": "*",
- "ext-pdo": "*",
- "ext-pdo_sqlite": "*",
- "twig/twig":"^2.0",
- "phpstan/phpstan": "*"
- },
- "require-dev": {
- "friendsofphp/php-cs-fixer": "^3.38"
- }
-}
diff --git a/config.php b/config.php
deleted file mode 100644
index a3871c6..0000000
--- a/config.php
+++ /dev/null
@@ -1,33 +0,0 @@
-
-
- ,
- )
-}
diff --git a/front/style/theme/dark.css b/front/style/theme/dark.css
deleted file mode 100644
index bdd4824..0000000
--- a/front/style/theme/dark.css
+++ /dev/null
@@ -1,9 +0,0 @@
-: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/index.html b/index.html
new file mode 100644
index 0000000..73324da
--- /dev/null
+++ b/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ Vite + React + TS
+
+
+
+
+
+
diff --git a/package.json b/package.json
index 966a0e9..9904fe4 100644
--- a/package.json
+++ b/package.json
@@ -3,6 +3,7 @@
"version": "0.1.0",
"private": true,
"dependencies": {
+ "@loadable/component": "^5.16.3",
"@testing-library/jest-dom": "^5.17.0",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
@@ -10,9 +11,11 @@
"@types/node": "^16.18.59",
"@types/react": "^18.2.31",
"@types/react-dom": "^18.2.14",
+ "eslint-plugin-react-refresh": "^0.4.5",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-draggable": "^4.4.6",
+ "react-router-dom": "^6.22.0",
"typescript": "^5.2.2",
"vite": "^4.5.0",
"vite-plugin-css-injected-by-js": "^3.3.0"
@@ -25,14 +28,14 @@
"tsc": "tsc"
},
"devDependencies": {
- "@vitejs/plugin-react": "^4.1.0",
- "prettier": "^3.1.0",
- "typescript": "^5.2.2",
- "vite-plugin-svgr": "^4.1.0",
"@typescript-eslint/eslint-plugin": "^6.11.0",
"@typescript-eslint/parser": "^6.11.0",
+ "@vitejs/plugin-react": "^4.1.0",
"eslint": "^8.53.0",
"eslint-plugin-react": "^7.33.2",
- "eslint-plugin-react-hooks": "^4.6.0"
+ "eslint-plugin-react-hooks": "^4.6.0",
+ "prettier": "^3.1.0",
+ "typescript": "^5.2.2",
+ "vite-plugin-svgr": "^4.1.0"
}
}
diff --git a/phpstan.neon b/phpstan.neon
deleted file mode 100644
index 346baaa..0000000
--- a/phpstan.neon
+++ /dev/null
@@ -1,12 +0,0 @@
-parameters:
- phpVersion: 70400
- level: 6
- paths:
- - src
- scanFiles:
- - config.php
- - sql/database.php
- - profiles/dev-config-profile.php
- - profiles/prod-config-profile.php
- excludePaths:
- - src/App/react-display-file.php
diff --git a/profiles/dev-config-profile.php b/profiles/dev-config-profile.php
deleted file mode 100644
index b8a50be..0000000
--- a/profiles/dev-config-profile.php
+++ /dev/null
@@ -1,43 +0,0 @@
-insertAccount($name, $email, AuthModel::generateToken(), password_hash("123456", PASSWORD_DEFAULT), "https://cdn.pixabay.com/photo/2015/10/05/22/37/blank-profile-picture-973460_960_720.png");
- $accounts->setIsAdmin($id, true);
- }
-
- foreach ($defaultTeams as $name) {
- $id = $teams->insert($name, "https://lebasketographe.fr/wp-content/uploads/2019/11/nom-equipes-nba.jpg", "#1a2b3c", "#FF00AA");
- }
-}
-
-function _get_base_path(): string {
- return "";
-}
diff --git a/profiles/prod-config-profile.php b/profiles/prod-config-profile.php
deleted file mode 100644
index 224f8de..0000000
--- a/profiles/prod-config-profile.php
+++ /dev/null
@@ -1,32 +0,0 @@
-setBasePath($basePath);
-
- $router->map("OPTIONS", "*", Action::noAuth(fn() => HttpResponse::fromCode(HttpCodes::OK)));
-
- $router->map("POST", "/auth", Action::noAuth(fn() => getAuthController()->authorize()));
- $router->map("POST", "/tactic/[i:id]/edit/name", Action::auth(fn(int $id, Account $acc) => getTacticController()->updateName($id, $acc)));
- $router->map("POST", "/tactic/[i:id]/save", Action::auth(fn(int $id, Account $acc) => getTacticController()->saveContent($id, $acc)));
- $router->map("GET", "/admin/list-users", Action::noAuth(fn() => getAccountController()->listUsers($_GET)));
- $router->map("GET", "/admin/user/[i:id]", Action::noAuth(fn(int $id) => getAccountController()->getUser($id)));
- $router->map("GET", "/admin/user/[i:id]/space", Action::noAuth(fn(int $id) => getTacticController()->getUserTactics($id)));
- $router->map("POST", "/admin/user/add", Action::noAuth(fn() => getAccountController()->addUser()));
- $router->map("POST", "/admin/user/remove-all", Action::noAuth(fn() => getAccountController()->removeUsers()));
- $router->map("POST", "/admin/user/[i:id]/update", Action::noAuth(fn(int $id) => getAccountController()->updateUser($id)));
- $router->map("GET", "/admin/server-info", Action::noAuth(fn() => getServerController()->getServerInfo()));
- $router->map("GET", "/admin/list-team", Action::noAuth(fn() => getAPITeamController()->listTeams($_GET)));
- $router->map("POST", "/admin/add-team", Action::noAuth(fn() => getAPITeamController()->addTeam()));
- $router->map("POST", "/admin/delete-teams", Action::noAuth(fn() => getAPITeamController()->deleteTeamSelected()));
- $router->map("POST", "/admin/team/[i:id]/update", Action::noAuth(fn(int $id) => getAPITeamController()->updateTeam($id)));
-
- return $router;
-}
-
-/**
- * Defines the way of being authorised through the API
- * By checking if an Authorisation header is set, and by expecting its value to be a valid token of an account.
- * If the header is not set, fallback to the App's PHP session system, and try to extract the account from it.
- * @return Account|null
- * @throws Exception
- */
-function tryGetAuthorization(): ?Account {
- $headers = getallheaders();
-
- // If no authorization header is set, try fallback to php session.
- if (!isset($headers['Authorization'])) {
- $session = PhpSessionHandle::init();
- return $session->getAccount();
- }
- $token = $headers['Authorization'];
- $gateway = new AccountGateway(new Connection(get_database()));
- return $gateway->getAccountFromToken($token);
-}
-
-Api::consume(API::handleMatch(getRoutes()->match(), fn() => tryGetAuthorization()));
diff --git a/public/assets b/public/assets
deleted file mode 120000
index 7b299d9..0000000
--- a/public/assets
+++ /dev/null
@@ -1 +0,0 @@
-../front/assets
\ No newline at end of file
diff --git a/public/front b/public/front
deleted file mode 120000
index c1394c9..0000000
--- a/public/front
+++ /dev/null
@@ -1 +0,0 @@
-../front
\ No newline at end of file
diff --git a/public/index.php b/public/index.php
deleted file mode 100644
index 5d93c4c..0000000
--- a/public/index.php
+++ /dev/null
@@ -1,129 +0,0 @@
-addFunction(new TwigFunction('path', fn(string $str) => "$basePath$str"));
-
- return $twig;
-}
-
-function getRoutes(): AltoRouter {
- global $basePath;
-
- $ar = new AltoRouter();
- $ar->setBasePath($basePath);
-
- //authentication
- $ar->map("GET", "/login", Action::noAuth(fn() => getAuthController()->displayLogin()));
- $ar->map("GET", "/register", Action::noAuth(fn() => getAuthController()->displayRegister()));
- $ar->map("POST", "/login", Action::noAuth(fn(SessionHandle $s) => getAuthController()->login($_POST, $s)));
- $ar->map("POST", "/register", Action::noAuth(fn(SessionHandle $s) => getAuthController()->register($_POST, $s)));
-
- //user-related
- $ar->map("GET", "/", Action::auth(fn(SessionHandle $s) => getUserController()->home($s)));
- $ar->map("GET", "/home", Action::auth(fn(SessionHandle $s) => getUserController()->home($s)));
- $ar->map("GET", "/settings", Action::auth(fn(SessionHandle $s) => getUserController()->settings($s)));
- $ar->map("GET", "/disconnect", Action::auth(fn(MutableSessionHandle $s) => getUserController()->disconnect($s)));
-
-
- //tactic-related
- $ar->map("GET", "/tactic/[i:id]/view", Action::auth(fn(int $id, SessionHandle $s) => getVisualizerController()->openVisualizer($id, $s)));
- $ar->map("GET", "/tactic/[i:id]/edit", Action::auth(fn(int $id, SessionHandle $s) => getEditorController()->openEditor($id, $s)));
- // don't require an authentication to run this action.
- // If the user is not connected, the tactic will never save.
- $ar->map("GET", "/tactic/new", Action::noAuth(fn() => getEditorController()->createNew()));
- $ar->map("GET", "/tactic/new/plain", Action::noAuth(fn(SessionHandle $s) => getEditorController()->createNewOfKind(CourtType::plain(), $s)));
- $ar->map("GET", "/tactic/new/half", Action::noAuth(fn(SessionHandle $s) => getEditorController()->createNewOfKind(CourtType::half(), $s)));
-
- //team-related
- $ar->map("GET", "/team/new", Action::auth(fn(SessionHandle $s) => getTeamController()->displayCreateTeam($s)));
- $ar->map("POST", "/team/new", Action::auth(fn(SessionHandle $s) => getTeamController()->submitTeam($_POST, $s)));
- $ar->map("GET", "/team/search", Action::auth(fn(SessionHandle $s) => getTeamController()->displayListTeamByName($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]/delete", Action::auth(fn(int $id, SessionHandle $s) => getTeamController()->deleteTeamById($id, $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("GET", "/team/[i:idTeam]/remove/[i:idMember]", Action::auth(fn(int $idTeam, int $idMember, SessionHandle $s) => getTeamController()->deleteMember($idTeam, $idMember, $s)));
- $ar->map("GET", "/team/[i:id]/edit", Action::auth(fn(int $idTeam, SessionHandle $s) => getTeamController()->displayEditTeam($idTeam, $s)));
- $ar->map("POST", "/team/[i:id]/edit", Action::auth(fn(int $idTeam, SessionHandle $s) => getTeamController()->editTeam($idTeam, $_POST, $s)));
-
-
- return $ar;
-}
-
-function runMatch($match, MutableSessionHandle $session): HttpResponse {
- global $basePath;
- if (!$match) {
- return ViewHttpResponse::twig("error.html.twig", [
- 'failures' => [ValidationFail::notFound("Could not find page {$_SERVER['REQUEST_URI']}.")],
- ], HttpCodes::NOT_FOUND);
- }
-
- return App::runAction($basePath . '/login', $match['target'], $match['params'], $session);
-}
-
-//this is a global variable
-$basePath = get_base_path();
-
-App::render(runMatch(getRoutes()->match(), PhpSessionHandle::init()), fn() => getTwig());
diff --git a/sql/database.php b/sql/database.php
deleted file mode 100644
index 7dcd5fc..0000000
--- a/sql/database.php
+++ /dev/null
@@ -1,32 +0,0 @@
-query("SELECT COUNT(*) FROM sqlite_master WHERE type = 'table'")->fetchColumn() > 0;
-
- if ($database_exists) {
- return $pdo;
- }
-
- foreach (scandir(__DIR__) as $file) {
- if (preg_match("/.*\.sql$/i", $file)) {
- $content = file_get_contents(__DIR__ . "/" . $file);
-
- $pdo->exec($content);
- }
- }
-
- init_database($pdo);
-
- return $pdo;
-}
diff --git a/sql/setup-tables.sql b/sql/setup-tables.sql
deleted file mode 100644
index 2971de9..0000000
--- a/sql/setup-tables.sql
+++ /dev/null
@@ -1,50 +0,0 @@
--- drop tables here
-DROP TABLE IF EXISTS Account;
-DROP TABLE IF EXISTS Tactic;
-DROP TABLE IF EXISTS Team;
-DROP TABLE IF EXISTS User;
-DROP TABLE IF EXISTS Member;
-
-CREATE TABLE Admins
-(
- id integer PRIMARY KEY REFERENCES Account
-);
-
-CREATE TABLE Account
-(
- id integer PRIMARY KEY AUTOINCREMENT,
- email varchar UNIQUE NOT NULL,
- username varchar NOT NULL,
- token varchar UNIQUE NOT NULL,
- hash varchar NOT NULL,
- profile_picture varchar NOT NULL
-);
-
-CREATE TABLE Tactic
-(
- id integer PRIMARY KEY AUTOINCREMENT,
- name varchar NOT NULL,
- creation_date timestamp DEFAULT CURRENT_TIMESTAMP NOT NULL,
- owner integer NOT NULL,
- content varchar DEFAULT '{"components": []}' NOT NULL,
- court_type varchar CHECK ( court_type IN ('HALF', 'PLAIN')) NOT NULL,
- FOREIGN KEY (owner) REFERENCES Account
-);
-
-CREATE TABLE Team
-(
- id integer PRIMARY KEY AUTOINCREMENT NOT NULL,
- name varchar NOT NULL,
- picture varchar NOT NULL,
- main_color varchar NOT NULL,
- second_color varchar NOT NULL
-);
-
-CREATE TABLE Member
-(
- id_team integer NOT NULL,
- id_user integer NOT NULL,
- role text CHECK (role IN ('COACH', 'PLAYER')) NOT NULL,
- FOREIGN KEY (id_team) REFERENCES Team (id),
- FOREIGN KEY (id_user) REFERENCES Account (id)
-);
diff --git a/src/Api/API.php b/src/Api/API.php
deleted file mode 100644
index 6893eaa..0000000
--- a/src/Api/API.php
+++ /dev/null
@@ -1,65 +0,0 @@
-getCode());
-
- header('Access-Control-Allow-Origin: *');
- header('Access-Control-Allow-Headers: *');
-
-
- foreach ($response->getHeaders() as $header => $value) {
- header("$header: $value");
- }
-
- if ($response instanceof JsonHttpResponse) {
- header('Content-type: application/json');
- echo $response->getJson();
- } elseif (get_class($response) != HttpResponse::class) {
- throw new Exception("API returned unknown Http Response");
- }
- }
-
-
- /**
- * @param array|false $match
- * @param callable(): Account $tryGetAuthorization function to return account authorisation for the given action (if required)
- * @return HttpResponse
- * @throws Exception
- */
- public static function handleMatch($match, callable $tryGetAuthorization): HttpResponse {
- if (!$match) {
- return new JsonHttpResponse([ValidationFail::notFound("not found")], HttpCodes::NOT_FOUND);
- }
-
- $action = $match['target'];
- if (!$action instanceof Action) {
- throw new Exception("routed action is not an AppAction object.");
- }
-
- $account = null;
-
- if ($action->getAuthType() != Action::NO_AUTH) {
- $account = call_user_func($tryGetAuthorization);
- if ($account == null) {
- return new JsonHttpResponse([ValidationFail::unauthorized("Missing or invalid 'Authorization' header.")], HttpCodes::UNAUTHORIZED);
- }
-
- if ($action->getAuthType() == Action::AUTH_ADMIN && !$account->getUser()->isAdmin()) {
- return new JsonHttpResponse([ValidationFail::unauthorized()], HttpCodes::UNAUTHORIZED);
- }
- }
-
- return $action->run($match['params'], $account);
- }
-}
diff --git a/src/Api/APIControl.php b/src/Api/APIControl.php
deleted file mode 100644
index 751fbfb..0000000
--- a/src/Api/APIControl.php
+++ /dev/null
@@ -1,45 +0,0 @@
- $schema an array of `fieldName => DefaultValidators` which represents the request object schema
- * @param callable(HttpRequest): HttpResponse $run the callback to run if the request is valid according to the given schema.
- * The callback must accept an HttpRequest, and return an HttpResponse object.
- * @return HttpResponse
- */
- public static function runChecked(array $schema, callable $run): HttpResponse {
- return Control::runChecked($schema, $run, self::errorFactory());
- }
-
- /**
- * Runs given callback, if the given request data array validates the given schema.
- * @param array $data the request's data array.
- * @param array $schema an array of `fieldName => DefaultValidators` which represents the request object schema
- * @param callable(HttpRequest): HttpResponse $run the callback to run if the request is valid according to the given schema.
- * The callback must accept an HttpRequest, and return an HttpResponse object.
- * @return HttpResponse
- */
- public static function runCheckedFrom(array $data, array $schema, callable $run): HttpResponse {
- return Control::runCheckedFrom($data, $schema, $run, self::errorFactory());
- }
-
-}
diff --git a/src/Api/Controller/APIAccountsController.php b/src/Api/Controller/APIAccountsController.php
deleted file mode 100644
index fd7e88e..0000000
--- a/src/Api/Controller/APIAccountsController.php
+++ /dev/null
@@ -1,109 +0,0 @@
-accounts = $accounts;
- $this->authModel = $model;
-
- }
-
-
- /**
- * @param array $request
- * @return HttpResponse
- */
- public function listUsers(array $request): HttpResponse {
- return APIControl::runCheckedFrom($request, [
- 'start' => [DefaultValidators::isUnsignedInteger()],
- 'n' => [DefaultValidators::isIntInRange(0, 250)],
- 'search' => [DefaultValidators::lenBetween(0, 256)],
- ], function (HttpRequest $req) {
- $accounts = $this->accounts->searchAccounts(intval($req['start']), intval($req['n']), $req["search"]);
- $users = array_map(fn(Account $acc) => $acc->getUser(), $accounts);
- return new JsonHttpResponse([
- "users" => $users,
- "totalCount" => $this->accounts->totalCount(),
- ]);
- });
- }
-
- /**
- * @param int $userId
- * @return HttpResponse given user information.
- */
- public function getUser(int $userId): HttpResponse {
- $acc = $this->accounts->getAccount($userId);
-
- if ($acc == null) {
- return new JsonHttpResponse([ValidationFail::notFound("User not found")], HttpCodes::NOT_FOUND);
- }
-
- return new JsonHttpResponse($acc->getUser());
- }
-
- public function addUser(): HttpResponse {
- return APIControl::runChecked([
- "username" => [DefaultValidators::name()],
- "email" => [DefaultValidators::email()],
- "password" => [DefaultValidators::password()],
- "isAdmin" => [DefaultValidators::bool()],
- ], function (HttpRequest $req) {
- $model = new AuthModel($this->accounts);
-
- $account = $model->register($req["username"], $req["password"], $req["email"]);
- if ($account == null) {
- return new JsonHttpResponse([new ValidationFail("already exists", "An account with provided email ")], HttpCodes::FORBIDDEN);
- }
-
- return new JsonHttpResponse([
- "id" => $account->getUser()->getId(),
- ]);
- });
- }
-
- public function removeUsers(): HttpResponse {
- return APIControl::runChecked([
- "identifiers" => [DefaultValidators::array(), DefaultValidators::forall(DefaultValidators::isUnsignedInteger())],
- ], function (HttpRequest $req) {
- $this->accounts->removeAccounts($req["identifiers"]);
- return HttpResponse::fromCode(HttpCodes::OK);
- });
- }
-
- public function updateUser(int $id): HttpResponse {
- return APIControl::runChecked([
- "email" => [DefaultValidators::email()],
- "username" => [DefaultValidators::name()],
- "isAdmin" => [DefaultValidators::bool()],
- ], function (HttpRequest $req) use ($id) {
- $mailAccount = $this->accounts->getAccountFromMail($req["email"]);
-
- if ($mailAccount != null && $mailAccount->getUser()->getId() != $id) {
- return new JsonHttpResponse([new ValidationFail("email exists", "The provided mail address already exists for another account.")], HttpCodes::FORBIDDEN);
- }
-
- $this->authModel->update($id, $req["email"], $req["username"], $req["isAdmin"]);
- return HttpResponse::fromCode(HttpCodes::OK);
- });
- }
-}
diff --git a/src/Api/Controller/APIAuthController.php b/src/Api/Controller/APIAuthController.php
deleted file mode 100644
index c715803..0000000
--- a/src/Api/Controller/APIAuthController.php
+++ /dev/null
@@ -1,44 +0,0 @@
-model = $model;
- }
-
-
- /**
- * From given email address and password, authenticate the user and respond with its authorization token.
- * @return HttpResponse
- */
- public function authorize(): HttpResponse {
- return APIControl::runChecked([
- "email" => [DefaultValidators::email(), DefaultValidators::lenBetween(5, 256)],
- "password" => [DefaultValidators::password()],
- ], function (HttpRequest $req) {
- $failures = [];
- $account = $this->model->login($req["email"], $req["password"], $failures);
-
- if (!empty($failures)) {
- return new JsonHttpResponse($failures, HttpCodes::UNAUTHORIZED);
- }
-
- return new JsonHttpResponse(["authorization" => $account->getToken()]);
- });
- }
-}
diff --git a/src/Api/Controller/APIServerController.php b/src/Api/Controller/APIServerController.php
deleted file mode 100644
index 1c82d3e..0000000
--- a/src/Api/Controller/APIServerController.php
+++ /dev/null
@@ -1,45 +0,0 @@
-basePath = $basePath;
- $this->pdo = $pdo;
- }
-
- private function countLines(string $table): int {
- $stmnt = $this->pdo->prepare("SELECT count(*) FROM $table");
- $stmnt->execute();
- $res = $stmnt->fetch(\PDO::FETCH_BOTH);
- return $res[0];
- }
-
-
- /**
- * @return HttpResponse some (useless) information about the server
- */
- public function getServerInfo(): HttpResponse {
-
- return new JsonHttpResponse([
- 'base_path' => $this->basePath,
- 'date' => (int) gettimeofday(true) * 1000,
- 'database' => [
- 'accounts' => $this->countLines("Account") . " line(s)",
- 'tactics' => $this->countLines("Tactic") . " line(s)",
- 'teams' => $this->countLines("Team") . " line(s)",
- ],
- ]);
- }
-
-}
diff --git a/src/Api/Controller/APITacticController.php b/src/Api/Controller/APITacticController.php
deleted file mode 100644
index eb00ff5..0000000
--- a/src/Api/Controller/APITacticController.php
+++ /dev/null
@@ -1,87 +0,0 @@
-model = $model;
- }
-
- /**
- * update name of tactic, specified by tactic identifier, given in url.
- * @param int $tactic_id
- * @param Account $account
- * @return HttpResponse
- */
- public function updateName(int $tactic_id, Account $account): HttpResponse {
- return APIControl::runChecked([
- "name" => [DefaultValidators::lenBetween(1, 50), DefaultValidators::nameWithSpaces()],
- ], function (HttpRequest $request) use ($tactic_id, $account) {
-
- $failures = $this->model->updateName($tactic_id, $request["name"], $account->getUser()->getId());
-
- if (!empty($failures)) {
- //TODO find a system to handle Unauthorized error codes more easily from failures.
- return new JsonHttpResponse($failures, HttpCodes::BAD_REQUEST);
- }
-
- return HttpResponse::fromCode(HttpCodes::OK);
- });
- }
-
- /**
- * @param int $id
- * @param Account $account
- * @return HttpResponse
- */
- public function saveContent(int $id, Account $account): HttpResponse {
- return APIControl::runChecked([
- "content" => [],
- ], function (HttpRequest $req) use ($id) {
- //TODO verify that the account has the rights to update the tactic content
- if ($fail = $this->model->updateContent($id, json_encode($req["content"]))) {
- return new JsonHttpResponse([$fail], HttpCodes::BAD_REQUEST);
- }
- return HttpResponse::fromCode(HttpCodes::OK);
- });
- }
-
-
- /**
- * @param int $userId
- * @return HttpResponse given user information.
- */
- public function getUserTactics(int $userId): HttpResponse {
- $tactics = $this->model->listAllOf($userId);
-
- $response = array_map(fn(TacticInfo $t) => [
- 'id' => $t->getId(),
- 'name' => $t->getName(),
- 'court' => $t->getCourtType(),
- 'creation_date' => $t->getCreationDate(),
-
- ], $tactics);
-
- return new JsonHttpResponse($response);
- }
-
-
-}
diff --git a/src/Api/Controller/APITeamController.php b/src/Api/Controller/APITeamController.php
deleted file mode 100644
index 270468d..0000000
--- a/src/Api/Controller/APITeamController.php
+++ /dev/null
@@ -1,79 +0,0 @@
-teamModel = $teamModel;
- }
-
- /**
- * @param array $req_params
- * @return HttpResponse
- */
- public function listTeams(array $req_params): HttpResponse {
- return APIControl::runCheckedFrom($req_params, [
- 'start' => [DefaultValidators::isUnsignedInteger()],
- 'n' => [DefaultValidators::isUnsignedInteger()],
- ], function (HttpRequest $req) {
- $teams = $this->teamModel->listAll(intval($req['start']), intval($req['n']));
- return new JsonHttpResponse([
- "totalCount" => $this->teamModel->countTeam(),
- "teams" => $teams,
- ]);
- });
- }
-
- public function addTeam(): HttpResponse {
- return APIControl::runChecked([
- 'name' => [DefaultValidators::name()],
- 'picture' => [DefaultValidators::isURL()],
- 'mainColor' => [DefaultValidators::hexColor()],
- 'secondaryColor' => [DefaultValidators::hexColor()],
-
- ], function (HttpRequest $req) {
- $this->teamModel->createTeam($req['name'], $req['picture'], $req['mainColor'], $req['secondaryColor']);
- return HttpResponse::fromCode(HttpCodes::OK);
- });
- }
-
- public function deleteTeamSelected(): HttpResponse {
- return APIControl::runChecked([
- 'teams' => [],
- ], function (HttpRequest $req) {
- $this->teamModel->deleteTeamSelected($req['teams']);
- return HttpResponse::fromCode(HttpCodes::OK);
- });
- }
-
- public function updateTeam(int $id): HttpResponse {
- return APIControl::runChecked([
- 'name' => [DefaultValidators::name()],
- 'picture' => [DefaultValidators::isURL()],
- 'mainColor' => [DefaultValidators::hexColor()],
- 'secondaryColor' => [DefaultValidators::hexColor()],
- ], function (HttpRequest $req) {
- $this->teamModel->editTeam($req['id'], $req['name'], $req['picture'], $req['mainColor'], $req['secondaryColor']);
- return HttpResponse::fromCode(HttpCodes::OK);
- });
- }
-
-
-}
diff --git a/src/App.tsx b/src/App.tsx
new file mode 100644
index 0000000..843568d
--- /dev/null
+++ b/src/App.tsx
@@ -0,0 +1,37 @@
+import {
+ BrowserRouter,
+ createBrowserRouter,
+ createRoutesFromElements,
+ Route,
+ RouterProvider,
+ Routes
+} from "react-router-dom";
+
+import loadable from "@loadable/component";
+
+
+const HomePage = loadable(() => import("./pages/Home.tsx"))
+const NotFoundPage = loadable(() => import("./pages/404.tsx"))
+const CreateTeamPage = loadable(() => import("./pages/CreateTeamPage.tsx"))
+const TeamPanelPage = loadable(() => import("./pages/TeamPanel.tsx"))
+const NewTacticPage = loadable(() => import("./pages/NewTacticPage.tsx"))
+const Editor = loadable(() => import("./pages/Editor.tsx"))
+
+
+export default function App() {
+ return (
+
+
+
+ }/>
+ }/>
+ }/>
+ }/>
+ }/>
+ }/>
+ }/>
+
+
+
+ )
+}
\ No newline at end of file
diff --git a/src/App/App.php b/src/App/App.php
deleted file mode 100644
index 557ad13..0000000
--- a/src/App/App.php
+++ /dev/null
@@ -1,98 +0,0 @@
-getCode());
-
- foreach ($response->getHeaders() as $header => $value) {
- header("$header: $value");
- }
-
- if ($response instanceof ViewHttpResponse) {
- self::renderView($response, $twigSupplier);
- } elseif ($response instanceof JsonHttpResponse) {
- header('Content-type: application/json');
- echo $response->getJson();
- }
- }
-
- /**
- * renders (prints out) given ViewHttpResponse to the client
- * @param ViewHttpResponse $response
- * @param callable(): Environment $twigSupplier
- * @return void
- * @throws LoaderError
- * @throws RuntimeError
- * @throws SyntaxError
- */
- private static function renderView(ViewHttpResponse $response, callable $twigSupplier): void {
- $file = $response->getFile();
- $args = $response->getArguments();
-
- switch ($response->getViewKind()) {
- case ViewHttpResponse::REACT_VIEW:
- send_react_front($file, $args);
- break;
- case ViewHttpResponse::TWIG_VIEW:
- try {
- $twig = call_user_func($twigSupplier);
- $twig->display($file, $args);
- } catch (RuntimeError|SyntaxError|LoaderError $e) {
- http_response_code(500);
- echo "There was an error rendering your view, please refer to an administrator.\nlogs date: " . date("YYYD, d M Y H:i:s");
- throw $e;
- }
- break;
- }
- }
-
- /**
- * run a user action, and return the generated response
- * @param string $authRoute the route towards an authentication page to response with a redirection
- * if the run action requires auth but session does not contain a logged-in account.
- * @param Action $action
- * @param mixed[] $params
- * @param MutableSessionHandle $session
- * @return HttpResponse
- */
- public static function runAction(string $authRoute, Action $action, array $params, MutableSessionHandle $session): HttpResponse {
- if ($action->getAuthType() != Action::NO_AUTH) {
- $account = $session->getAccount();
- if ($account == null) {
- // put in the session the initial url the user wanted to get
- $session->setInitialTarget($_SERVER['REQUEST_URI']);
- return HttpResponse::redirectAbsolute($authRoute);
- }
-
- if ($action->getAuthType() == Action::AUTH_ADMIN && !$account->getUser()->isAdmin()) {
- return new JsonHttpResponse([ValidationFail::unauthorized()], HttpCodes::UNAUTHORIZED);
- }
-
- }
-
- return $action->run($params, $session);
- }
-
-}
diff --git a/src/App/AppControl.php b/src/App/AppControl.php
deleted file mode 100644
index c313e69..0000000
--- a/src/App/AppControl.php
+++ /dev/null
@@ -1,44 +0,0 @@
- $failures], HttpCodes::BAD_REQUEST);
- }
- };
- }
-
- /**
- * Runs given callback, if the request's payload json validates the given schema.
- * @param array $schema an array of `fieldName => DefaultValidators` which represents the request object schema
- * @param callable(HttpRequest): HttpResponse $run the callback to run if the request is valid according to the given schema.
- * The callback must accept an HttpRequest, and return an HttpResponse object.
- * @return HttpResponse
- */
- public static function runChecked(array $schema, callable $run): HttpResponse {
- return Control::runChecked($schema, $run, self::errorFactory());
- }
-
- /**
- * Runs given callback, if the given request data array validates the given schema.
- * @param array $data the request's data array.
- * @param array $schema an array of `fieldName => DefaultValidators` which represents the request object schema
- * @param callable(HttpRequest): HttpResponse $run the callback to run if the request is valid according to the given schema.
- * The callback must accept an HttpRequest, and return an HttpResponse object.
- * @return HttpResponse
- */
- public static function runCheckedFrom(array $data, array $schema, callable $run): HttpResponse {
- return Control::runCheckedFrom($data, $schema, $run, self::errorFactory());
- }
-
-}
diff --git a/src/App/Controller/AuthController.php b/src/App/Controller/AuthController.php
deleted file mode 100644
index 27b268a..0000000
--- a/src/App/Controller/AuthController.php
+++ /dev/null
@@ -1,99 +0,0 @@
-model = $model;
- }
-
- public function displayRegister(): HttpResponse {
- return ViewHttpResponse::twig("display_register.html.twig", []);
- }
-
- /**
- * registers given account
- * @param mixed[] $requestData
- * @param MutableSessionHandle $session
- * @return HttpResponse
- */
- public function register(array $requestData, MutableSessionHandle $session): HttpResponse {
- $fails = [];
- $request = HttpRequest::from($requestData, $fails, [
- "username" => [DefaultValidators::name(), DefaultValidators::lenBetween(2, 32)],
- "password" => [DefaultValidators::password()],
- "confirmpassword" => [DefaultValidators::password()],
- "email" => [DefaultValidators::email(), DefaultValidators::lenBetween(5, 256)],
- ]);
-
- if (!empty($fails)) {
- return ViewHttpResponse::twig("display_register.html.twig", ['fails' => $fails, 'username' => $requestData['username'], 'email' => $requestData['email'], 'password' => $requestData['password'], 'confirmpassword' => $requestData['confirmpassword'], 'accept' => true]);
- }
-
- if ($request["password"] != $request['confirmpassword']) {
- $fails[] = new FieldValidationFail("confirmpassword", "Le mot de passe et la confirmation ne sont pas les mêmes.");
- }
-
- $account = $this->model->register($request['username'], $request["password"], $request['email']);
-
- if (!$account) {
- $fails[] = new FieldValidationFail("email", "L'email existe déjà");
- }
-
- if (!empty($fails)) {
- return ViewHttpResponse::twig("display_register.html.twig", ['fails' => $fails, 'password' => $requestData['password'], 'confirmpassword' => $requestData['confirmpassword'], 'accept' => true]);
- }
- $session->setAccount($account);
-
- $target_url = $session->getInitialTarget();
- if ($target_url != null) {
- return HttpResponse::redirectAbsolute($target_url);
- }
-
- return HttpResponse::redirect("/home");
- }
-
-
- public function displayLogin(): HttpResponse {
- return ViewHttpResponse::twig("display_login.html.twig", []);
- }
-
- /**
- * logins given account credentials
- * @param mixed[] $request
- * @param MutableSessionHandle $session
- * @return HttpResponse
- */
- public function login(array $request, MutableSessionHandle $session): HttpResponse {
- $fails = [];
- $account = $this->model->login($request['email'], $request['password'], $fails);
- if (!empty($fails)) {
- return ViewHttpResponse::twig("display_login.html.twig", ['fails' => $fails, 'password' => $request['password'], 'email' => $request['email']]);
- }
-
- $session->setAccount($account);
-
- $target_url = $session->getInitialTarget();
- $session->setInitialTarget(null);
- if ($target_url != null) {
- return HttpResponse::redirectAbsolute($target_url);
- }
-
- return HttpResponse::redirect("/home");
- }
-
-}
diff --git a/src/App/Controller/EditorController.php b/src/App/Controller/EditorController.php
deleted file mode 100644
index ec21324..0000000
--- a/src/App/Controller/EditorController.php
+++ /dev/null
@@ -1,87 +0,0 @@
-model = $model;
- }
-
- /**
- * @param TacticInfo $tactic
- * @return ViewHttpResponse the editor view for given tactic
- */
- private function openEditorFor(TacticInfo $tactic): ViewHttpResponse {
- return ViewHttpResponse::react("views/Editor.tsx", [
- "id" => $tactic->getId(),
- "name" => $tactic->getName(),
- "content" => $tactic->getContent(),
- "courtType" => $tactic->getCourtType()->name(),
- ]);
- }
-
- public function createNew(): ViewHttpResponse {
- return ViewHttpResponse::react("views/NewTacticPanel.tsx", []);
- }
-
- /**
- * @return ViewHttpResponse the editor view for a test tactic.
- */
- private function openTestEditor(CourtType $courtType): ViewHttpResponse {
- return ViewHttpResponse::react("views/Editor.tsx", [
- "id" => -1, //-1 id means that the editor will not support saves
- "name" => TacticModel::TACTIC_DEFAULT_NAME,
- "content" => '{"components": []}',
- "courtType" => $courtType->name(),
- ]);
- }
-
- /**
- * creates a new empty tactic, with default name
- * If the given session does not contain a connected account,
- * open a test editor.
- * @param SessionHandle $session
- * @param CourtType $type
- * @return ViewHttpResponse the editor view
- */
- public function createNewOfKind(CourtType $type, SessionHandle $session): ViewHttpResponse {
-
- $action = $session->getAccount();
-
- if ($action == null) {
- return $this->openTestEditor($type);
- }
-
- $tactic = $this->model->makeNewDefault($session->getAccount()->getUser()->getId(), $type);
- return $this->openEditorFor($tactic);
- }
-
- /**
- * returns an editor view for a given tactic
- * @param int $id the targeted tactic identifier
- * @param SessionHandle $session
- * @return ViewHttpResponse
- */
- public function openEditor(int $id, SessionHandle $session): ViewHttpResponse {
- $tactic = $this->model->get($id);
-
- $failure = TacticValidator::validateAccess($id, $tactic, $session->getAccount()->getUser()->getId());
-
- if ($failure != null) {
- return ViewHttpResponse::twig('error.html.twig', ['failures' => [$failure]], HttpCodes::NOT_FOUND);
- }
-
- return $this->openEditorFor($tactic);
- }
-}
diff --git a/src/App/Controller/TeamController.php b/src/App/Controller/TeamController.php
deleted file mode 100644
index 048d182..0000000
--- a/src/App/Controller/TeamController.php
+++ /dev/null
@@ -1,246 +0,0 @@
-model = $model;
- }
-
- /**
- * @param SessionHandle $session
- * @return ViewHttpResponse the team creation panel
- */
- public function displayCreateTeam(SessionHandle $session): ViewHttpResponse {
- return ViewHttpResponse::twig("insert_team.html.twig", []);
- }
-
- /**
- * @param SessionHandle $session
- * @return ViewHttpResponse the team panel to delete a member
- */
- public function displayDeleteMember(SessionHandle $session): ViewHttpResponse {
- return ViewHttpResponse::twig("delete_member.html.twig", []);
- }
-
- /**
- * create a new team from given request name, mainColor, secondColor and picture url
- * @param array $request
- * @param SessionHandle $session
- * @return HttpResponse
- */
- public function submitTeam(array $request, SessionHandle $session): HttpResponse {
- $failures = [];
- $request = HttpRequest::from($request, $failures, [
- "name" => [DefaultValidators::lenBetween(1, 32), DefaultValidators::nameWithSpaces()],
- "main_color" => [DefaultValidators::hexColor()],
- "second_color" => [DefaultValidators::hexColor()],
- "picture" => [DefaultValidators::isURL()],
- ]);
- if (!empty($failures)) {
- $badFields = [];
- foreach ($failures as $e) {
- if ($e instanceof FieldValidationFail) {
- $badFields[] = $e->getFieldName();
- }
- }
- return ViewHttpResponse::twig('insert_team.html.twig', ['bad_fields' => $badFields]);
- }
- $teamId = $this->model->createTeam($request['name'], $request['picture'], $request['main_color'], $request['second_color']);
- $this->model->addMember($session->getAccount()->getUser()->getEmail(), $teamId, 'COACH');
- return HttpResponse::redirect('/team/' . $teamId);
- }
-
- /**
- * @param SessionHandle $session
- * @return ViewHttpResponse the panel to search a team by its name
- */
- public function displayListTeamByName(SessionHandle $session): ViewHttpResponse {
- return ViewHttpResponse::twig("list_team_by_name.html.twig", []);
- }
-
- /**
- * returns a view that contains all the teams description whose name matches the given name needle.
- * @param array $request
- * @param SessionHandle $session
- * @return HttpResponse
- */
- public function listTeamByName(array $request, SessionHandle $session): HttpResponse {
- $errors = [];
- $request = HttpRequest::from($request, $errors, [
- "name" => [DefaultValidators::lenBetween(1, 32), DefaultValidators::nameWithSpaces()],
- ]);
-
- if (!empty($errors) && $errors[0] instanceof FieldValidationFail) {
- $badField = $errors[0]->getFieldName();
- return ViewHttpResponse::twig('list_team_by_name.html.twig', ['bad_field' => $badField]);
- }
-
- $teams = $this->model->listByName($request['name'], $session->getAccount()->getUser()->getId());
-
- if (empty($teams)) {
- return ViewHttpResponse::twig('display_teams.html.twig', []);
- }
- return ViewHttpResponse::twig('display_teams.html.twig', ['teams' => $teams]);
- }
-
- /**
- * Delete a team with its id
- * @param int $id
- * @param SessionHandle $session
- * @return HttpResponse
- */
- public function deleteTeamById(int $id, SessionHandle $session): HttpResponse {
- $a = $session->getAccount();
- $ret = $this->model->deleteTeam($a->getUser()->getEmail(), $id);
- if($ret != 0) {
- return ViewHttpResponse::twig('display_team.html.twig', ['notDeleted' => true]);
- }
- return HttpResponse::redirect('/');
- }
-
- /**
- * Display a team with its id
- * @param int $id
- * @param SessionHandle $session
- * @return ViewHttpResponse a view that displays given team information
- */
- public function displayTeam(int $id, SessionHandle $session): ViewHttpResponse {
- $result = $this->model->getTeam($id, $session->getAccount()->getUser()->getId());
- if($result == null) {
- return ViewHttpResponse::twig('error.html.twig', [
- 'failures' => [ValidationFail::unauthorized("Vous n'avez pas accès à cette équipe.")],
- ], HttpCodes::FORBIDDEN);
- }
- $role = $this->model->isCoach($id, $session->getAccount()->getUser()->getEmail());
-
- return ViewHttpResponse::react(
- 'views/TeamPanel.tsx',
- [
- 'team' => [
- "info" => $result->getInfo(),
- "members" => $result->listMembers(),
- ],
- 'isCoach' => $role,
- 'currentUserId' => $session->getAccount()->getUser()->getId()]
- );
- }
-
- /**
- * @param int $idTeam
- * @param SessionHandle $session
- * @return ViewHttpResponse the team panel to add a member
- */
- public function displayAddMember(int $idTeam, SessionHandle $session): ViewHttpResponse {
- return ViewHttpResponse::twig("add_member.html.twig", ['idTeam' => $idTeam]);
- }
-
- /**
- * add a member to a team
- * @param int $idTeam
- * @param array $request
- * @param SessionHandle $session
- * @return HttpResponse
- */
- public function addMember(int $idTeam, array $request, SessionHandle $session): HttpResponse {
- $errors = [];
- if(!$this->model->isCoach($idTeam, $session->getAccount()->getUser()->getEmail())) {
- return ViewHttpResponse::twig('error.html.twig', [
- 'failures' => [ValidationFail::unauthorized("Vous n'avez pas accès à cette action pour cette équipe.")],
- ], HttpCodes::FORBIDDEN);
- }
- $request = HttpRequest::from($request, $errors, [
- "email" => [DefaultValidators::email(), DefaultValidators::lenBetween(5, 256)],
- ]);
- if(!empty($errors)) {
- return ViewHttpResponse::twig('add_member.html.twig', ['badEmail' => true,'idTeam' => $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 HttpResponse::redirect('/team/' . $idTeam);
- }
- }
-
- /**
- * remove a member from a team with their ids
- * @param int $idTeam
- * @param int $idMember
- * @param SessionHandle $session
- * @return HttpResponse
- */
- public function deleteMember(int $idTeam, int $idMember, SessionHandle $session): HttpResponse {
- if(!$this->model->isCoach($idTeam, $session->getAccount()->getUser()->getEmail())) {
- return ViewHttpResponse::twig('error.html.twig', [
- 'failures' => [ValidationFail::unauthorized("Vous n'avez pas accès à cette action pour cette équipe.")],
- ], HttpCodes::FORBIDDEN);
- }
- $teamId = $this->model->deleteMember($idMember, $idTeam);
- if($teamId == -1 || $session->getAccount()->getUser()->getId() == $idMember) {
- return HttpResponse::redirect('/');
- }
- return $this->displayTeam($teamId, $session);
- }
-
- /**
- * @param int $idTeam
- * @param SessionHandle $session
- * @return ViewHttpResponse
- */
- public function displayEditTeam(int $idTeam, SessionHandle $session): ViewHttpResponse {
- return ViewHttpResponse::twig("edit_team.html.twig", ['team' => $this->model->getTeam($idTeam, $session->getAccount()->getUser()->getId())]);
- }
-
- /**
- * @param int $idTeam
- * @param array $request
- * @param SessionHandle $session
- * @return HttpResponse
- */
- public function editTeam(int $idTeam, array $request, SessionHandle $session): HttpResponse {
- if(!$this->model->isCoach($idTeam, $session->getAccount()->getUser()->getEmail())) {
- return ViewHttpResponse::twig('error.html.twig', [
- 'failures' => [ValidationFail::unauthorized("Vous n'avez pas accès à cette action pour cette équipe.")],
- ], HttpCodes::FORBIDDEN);
- }
- $failures = [];
- $request = HttpRequest::from($request, $failures, [
- "name" => [DefaultValidators::lenBetween(1, 32), DefaultValidators::nameWithSpaces()],
- "main_color" => [DefaultValidators::hexColor()],
- "second_color" => [DefaultValidators::hexColor()],
- "picture" => [DefaultValidators::isURL()],
- ]);
- if (!empty($failures)) {
- $badFields = [];
- foreach ($failures as $e) {
- if ($e instanceof FieldValidationFail) {
- $badFields[] = $e->getFieldName();
- }
- }
- return ViewHttpResponse::twig('edit_team.html.twig', ['bad_fields' => $badFields]);
- }
- $this->model->editTeam($idTeam, $request['name'], $request['picture'], $request['main_color'], $request['second_color']);
- return HttpResponse::redirect('/team/' . $idTeam);
- }
-}
diff --git a/src/App/Controller/UserController.php b/src/App/Controller/UserController.php
deleted file mode 100644
index 616bf54..0000000
--- a/src/App/Controller/UserController.php
+++ /dev/null
@@ -1,66 +0,0 @@
-tactics = $tactics;
- $this->teams = $teams;
- }
-
- /**
- * @param SessionHandle $session
- * @return ViewHttpResponse the home page view
- */
- public function home(SessionHandle $session): ViewHttpResponse {
- $limitNbTactics = 5;
-
- $user = $session->getAccount()->getUser();
-
- $lastTactics = $this->tactics->getLast($limitNbTactics, $user->getId());
- $allTactics = $this->tactics->getAll($user->getId());
- $name = $user->getName();
-
- if ($this->teams != null) {
- $teams = $this->teams->getAll($user->getId());
- } else {
- $teams = [];
- }
-
- return ViewHttpResponse::react("views/Home.tsx", [
- "lastTactics" => $lastTactics,
- "allTactics" => $allTactics,
- "teams" => $teams,
- "username" => $name,
- ]);
- }
-
- /**
- * @return ViewHttpResponse account settings page
- */
- public function settings(SessionHandle $session): ViewHttpResponse {
- return ViewHttpResponse::react("views/Settings.tsx", []);
- }
-
- public function disconnect(MutableSessionHandle $session): HttpResponse {
- $session->destroy();
- return HttpResponse::redirect("/");
- }
-
-}
diff --git a/src/App/Controller/VisualizerController.php b/src/App/Controller/VisualizerController.php
deleted file mode 100644
index 946f6d0..0000000
--- a/src/App/Controller/VisualizerController.php
+++ /dev/null
@@ -1,39 +0,0 @@
-tacticModel = $tacticModel;
- }
-
- /**
- * Opens a visualisation page for the tactic specified by its identifier in the url.
- * @param int $id
- * @param SessionHandle $session
- * @return HttpResponse
- */
- public function openVisualizer(int $id, SessionHandle $session): HttpResponse {
- $tactic = $this->tacticModel->get($id);
-
- $failure = TacticValidator::validateAccess($id, $tactic, $session->getAccount()->getUser()->getId());
-
- if ($failure != null) {
- return ViewHttpResponse::twig('error.html.twig', ['failures' => [$failure]], HttpCodes::NOT_FOUND);
- }
-
- return ViewHttpResponse::react("views/Visualizer.tsx", ["name" => $tactic->getName()]);
- }
-}
diff --git a/src/App/Session/MutableSessionHandle.php b/src/App/Session/MutableSessionHandle.php
deleted file mode 100644
index 14871b6..0000000
--- a/src/App/Session/MutableSessionHandle.php
+++ /dev/null
@@ -1,22 +0,0 @@
-getOwnerId() != $ownerId) {
- return ValidationFail::unauthorized("Vous ne pouvez pas accéder à cette tactique.");
- }
- return null;
- }
-
-}
diff --git a/src/App/ViewHttpResponse.php b/src/App/ViewHttpResponse.php
deleted file mode 100644
index dfbd1da..0000000
--- a/src/App/ViewHttpResponse.php
+++ /dev/null
@@ -1,75 +0,0 @@
- View arguments
- */
- private array $arguments;
- /**
- * @var int Kind of view, see {@link self::TWIG_VIEW} and {@link self::REACT_VIEW}
- */
- private int $kind;
-
- /**
- * @param int $code
- * @param int $kind
- * @param string $file
- * @param array $arguments
- */
- private function __construct(int $kind, string $file, array $arguments, int $code = HttpCodes::OK) {
- parent::__construct($code, []);
- $this->kind = $kind;
- $this->file = $file;
- $this->arguments = $arguments;
- }
-
- public function getViewKind(): int {
- return $this->kind;
- }
-
- public function getFile(): string {
- return $this->file;
- }
-
- /**
- * @return array
- */
- public function getArguments(): array {
- return $this->arguments;
- }
-
- /**
- * Create a twig view response
- * @param string $file
- * @param array $arguments
- * @param int $code
- * @return ViewHttpResponse
- */
- public static function twig(string $file, array $arguments, int $code = HttpCodes::OK): ViewHttpResponse {
- return new ViewHttpResponse(self::TWIG_VIEW, $file, $arguments, $code);
- }
-
- /**
- * Create a react view response
- * @param string $file
- * @param array $arguments
- * @param int $code
- * @return ViewHttpResponse
- */
- public static function react(string $file, array $arguments, int $code = HttpCodes::OK): ViewHttpResponse {
- return new ViewHttpResponse(self::REACT_VIEW, $file, $arguments, $code);
- }
-
-}
diff --git a/src/App/Views/account_settings.twig b/src/App/Views/account_settings.twig
deleted file mode 100644
index 04d7437..0000000
--- a/src/App/Views/account_settings.twig
+++ /dev/null
@@ -1,23 +0,0 @@
-
-
-
-
-
-
- Paramètres
-
-
-
-
-
-
-
-Paramètres
-
-
\ No newline at end of file
diff --git a/src/App/Views/add_member.html.twig b/src/App/Views/add_member.html.twig
deleted file mode 100644
index cfee16d..0000000
--- a/src/App/Views/add_member.html.twig
+++ /dev/null
@@ -1,118 +0,0 @@
-
-
-
-
- Ajouter un membre
-
-
-
-
-
-
-
Ajouter un membre à votre équipe
-
-
-
-
-
\ No newline at end of file
diff --git a/src/App/Views/delete_member.html.twig b/src/App/Views/delete_member.html.twig
deleted file mode 100644
index 3fa5ccd..0000000
--- a/src/App/Views/delete_member.html.twig
+++ /dev/null
@@ -1,73 +0,0 @@
-
-
-
-
- Ajouter un membre
-
-
-
-
-
-
Supprimez un membre de votre équipe
-
-
-
-
-
\ No newline at end of file
diff --git a/src/App/Views/display_auth_confirm.html.twig b/src/App/Views/display_auth_confirm.html.twig
deleted file mode 100644
index 60c63b2..0000000
--- a/src/App/Views/display_auth_confirm.html.twig
+++ /dev/null
@@ -1,46 +0,0 @@
-
-
-
-
- Profil Utilisateur
-
-
-
-
-
-
Votre profil
-
Pseudo : {{ username }}
-
Email : {{ email }}
-
-
-
-
\ No newline at end of file
diff --git a/src/App/Views/display_login.html.twig b/src/App/Views/display_login.html.twig
deleted file mode 100644
index 6e2d063..0000000
--- a/src/App/Views/display_login.html.twig
+++ /dev/null
@@ -1,108 +0,0 @@
-
-
-
- Connexion
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/App/Views/display_register.html.twig b/src/App/Views/display_register.html.twig
deleted file mode 100644
index 1f5a9c9..0000000
--- a/src/App/Views/display_register.html.twig
+++ /dev/null
@@ -1,123 +0,0 @@
-
-
-
- S'enregistrer
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/App/Views/display_results.html.twig b/src/App/Views/display_results.html.twig
deleted file mode 100644
index a33546b..0000000
--- a/src/App/Views/display_results.html.twig
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
-
- Twig view
-
-
-
-Hello world
-
-
-{% for v in results %}
- username: {{ v.name }}
- description: {{ v.description }}
-{% endfor %}
-
-
-
-
\ No newline at end of file
diff --git a/src/App/Views/display_team.html.twig b/src/App/Views/display_team.html.twig
deleted file mode 100644
index 8928e84..0000000
--- a/src/App/Views/display_team.html.twig
+++ /dev/null
@@ -1,109 +0,0 @@
-
-
-
-
- Twig view
-
-
-
-
-
-
- {% if notDeleted %}
-
- Cette équipe ne peut être supprimée.
-
- {% endif %}
-{% if team is defined %}
-
-
-
{{ team.getInfo().getName() }}
-
.getPicture() }})
-
-
- {% if isCoach %}
-
-
- {% endif %}
- {% for m in team.listMembers() %}
-
-
{{ m.getUserId() }}
- {% if m.getRole().isCoach() %}
-
: Coach
- {% else %}
-
: Joueur
- {% endif %}
-
- {% endfor %}
-
-{% else %}
-
-
Cette équipe ne peut être affichée
-
-{% endif %}
-
-
-
\ No newline at end of file
diff --git a/src/App/Views/display_teams.html.twig b/src/App/Views/display_teams.html.twig
deleted file mode 100644
index 3e3ab12..0000000
--- a/src/App/Views/display_teams.html.twig
+++ /dev/null
@@ -1,61 +0,0 @@
-
-
-
-
- Twig view
-
-
-
-
-
-{% if teams is empty %}
- Aucune équipe n'a été trouvée
-
-
Chercher une équipe
-
-
-{% else %}
- {% for t in teams %}
-
-
Nom de l'équipe : {{ t.getName() }}
-
 }})
-
- {% endfor %}
-{% endif %}
-
-
-
\ No newline at end of file
diff --git a/src/App/Views/edit_team.html.twig b/src/App/Views/edit_team.html.twig
deleted file mode 100644
index 409d71a..0000000
--- a/src/App/Views/edit_team.html.twig
+++ /dev/null
@@ -1,81 +0,0 @@
-
-
-
-
- Insertion view
-
-
-
-
-
-
Modifier votre équipe
-
-
-
-
-
\ No newline at end of file
diff --git a/src/App/Views/error.html.twig b/src/App/Views/error.html.twig
deleted file mode 100644
index bf90319..0000000
--- a/src/App/Views/error.html.twig
+++ /dev/null
@@ -1,57 +0,0 @@
-
-
-
-
- Error
-
-
-
-
-IQBall
-
-{% for fail in failures %}
- {{ fail.getKind() }} : {{ fail.getMessage() }}
-{% endfor %}
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/App/Views/home.twig b/src/App/Views/home.twig
deleted file mode 100644
index 2438ca1..0000000
--- a/src/App/Views/home.twig
+++ /dev/null
@@ -1,97 +0,0 @@
-
-
-
-
-
-
- Page d'accueil
-
-
-
-
-
-
-
-
IQ CourtObjects
-
-
 }})
-
Mon profil
-
-
-
-
-Mes équipes
-
-
-
-{% if recentTeam != null %}
- {% for team in recentTeam %}
-
- {% endfor %}
-{% else %}
- Aucune équipe créée !
-{% endif %}
-
- Mes strategies
-
-
-
-{% if recentTactic != null %}
- {% for tactic in recentTactic %}
-
-
{{ tactic.id }} - {{ tactic.name }} - {{ tactic.creation_date }}
-
-
- {% endfor %}
-{% else %}
- Aucune tactique créée !
-{% endif %}
-
-
-
\ No newline at end of file
diff --git a/src/App/Views/insert_team.html.twig b/src/App/Views/insert_team.html.twig
deleted file mode 100644
index 0c10114..0000000
--- a/src/App/Views/insert_team.html.twig
+++ /dev/null
@@ -1,81 +0,0 @@
-
-
-
-
- Insertion view
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/App/Views/list_team_by_name.html.twig b/src/App/Views/list_team_by_name.html.twig
deleted file mode 100644
index 092a149..0000000
--- a/src/App/Views/list_team_by_name.html.twig
+++ /dev/null
@@ -1,79 +0,0 @@
-
-
-
-
- Insertion view
-
-
-
-
-
-
Chercher une équipe
-
-
-
-
-
\ No newline at end of file
diff --git a/src/App/react-display-file.php b/src/App/react-display-file.php
deleted file mode 100755
index 2dfcd11..0000000
--- a/src/App/react-display-file.php
+++ /dev/null
@@ -1,58 +0,0 @@
-
-
-
-
-
- ">
-
-
-
-
- Document
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/App/react-display.php b/src/App/react-display.php
deleted file mode 100644
index 5baf41b..0000000
--- a/src/App/react-display.php
+++ /dev/null
@@ -1,13 +0,0 @@
- $arguments arguments to pass to the rendered react component
- * The arguments must be a json-encodable key/value dictionary.
- * @return void
- */
-function send_react_front(string $url, array $arguments) {
- // the $url and $argument values are used into the included file
- require_once "react-display-file.php";
-}
diff --git a/front/Constants.ts b/src/Constants.ts
similarity index 100%
rename from front/Constants.ts
rename to src/Constants.ts
diff --git a/src/Core/Action.php b/src/Core/Action.php
deleted file mode 100644
index df40ea9..0000000
--- a/src/Core/Action.php
+++ /dev/null
@@ -1,70 +0,0 @@
-action = $action;
- $this->authType = $authType;
- }
-
- public function getAuthType(): int {
- return $this->authType;
- }
-
- /**
- * Runs an action
- * @param mixed[] $params
- * @param S $session
- * @return HttpResponse
- */
- public function run(array $params, $session): HttpResponse {
- $params = array_values($params);
- $params[] = $session;
- return call_user_func_array($this->action, $params);
- }
-
- /**
- * @param callable(mixed[], S): HttpResponse $action
- * @return Action an action that does not require to have an authorization.
- */
- public static function noAuth(callable $action): Action {
- return new Action($action, self::NO_AUTH);
- }
-
- /**
- * @param callable(mixed[], S): HttpResponse $action
- * @return Action an action that does require to have an authorization.
- */
- public static function auth(callable $action): Action {
- return new Action($action, self::AUTH_USER);
- }
-
- /**
- * @param callable(mixed[], S): HttpResponse $action
- * @return Action an action that does require to have an authorization, and to be an administrator.
- */
- public static function admin(callable $action): Action {
- return new Action($action, self::AUTH_ADMIN);
- }
-}
diff --git a/src/Core/Connection.php b/src/Core/Connection.php
deleted file mode 100644
index 1dd559d..0000000
--- a/src/Core/Connection.php
+++ /dev/null
@@ -1,61 +0,0 @@
-pdo = $pdo;
- }
-
- public function lastInsertId(): string {
- return $this->pdo->lastInsertId();
- }
-
- /**
- * execute a request
- * @param string $query
- * @param array> $args
- * @return void
- */
- public function exec(string $query, array $args) {
- $stmnt = $this->prep($query, $args);
- $stmnt->execute();
- }
-
- /**
- * Execute a request, and return the returned rows
- * @param string $query the SQL request
- * @param array> $args an array containing the arguments label, value and type: ex: `[":label" => [$value, PDO::PARAM_TYPE]`
- * @return array[] the returned rows of the request
- */
- public function fetch(string $query, array $args): array {
- $stmnt = $this->prep($query, $args);
- $stmnt->execute();
- return $stmnt->fetchAll(PDO::FETCH_ASSOC);
- }
-
- /**
- * @param string $query
- * @param array> $args
- * @return \PDOStatement
- */
- private function prep(string $query, array $args): \PDOStatement {
- $stmnt = $this->pdo->prepare($query);
- foreach ($args as $name => $value) {
- $stmnt->bindValue($name, $value[0], $value[1]);
- }
- return $stmnt;
- }
-
- public function prepare(string $query): \PDOStatement {
- return $this->pdo->prepare($query);
- }
-
-}
diff --git a/src/Core/Control.php b/src/Core/Control.php
deleted file mode 100644
index 51d6622..0000000
--- a/src/Core/Control.php
+++ /dev/null
@@ -1,53 +0,0 @@
- $schema an array of `fieldName => DefaultValidators` which represents the request object schema
- * @param callable(HttpRequest): HttpResponse $run the callback to run if the request is valid according to the given schema.
- * The callback must accept an HttpRequest, and return an HttpResponse object.
- * @param ControlSchemaErrorResponseFactory $errorFactory an error factory to use if the request does not validate the required schema
- * @return HttpResponse
- */
- public static function runChecked(array $schema, callable $run, ControlSchemaErrorResponseFactory $errorFactory): HttpResponse {
- $request_body = file_get_contents('php://input');
- $payload_obj = json_decode($request_body);
- if (!$payload_obj instanceof \stdClass) {
- $fail = new ValidationFail("bad-payload", "request body is not a valid json object");
- return $errorFactory->apply([$fail]);
-
- }
- $payload = get_object_vars($payload_obj);
- return self::runCheckedFrom($payload, $schema, $run, $errorFactory);
- }
-
- /**
- * Runs given callback, if the given request data array validates the given schema.
- * @param array $data the request's data array.
- * @param array $schema an array of `fieldName => DefaultValidators` which represents the request object schema
- * @param callable(HttpRequest): HttpResponse $run the callback to run if the request is valid according to the given schema.
- * The callback must accept an HttpRequest, and return an HttpResponse object.
- * @param ControlSchemaErrorResponseFactory $errorFactory an error factory to use if the request does not validate the required schema
- * @return HttpResponse
- */
- public static function runCheckedFrom(array $data, array $schema, callable $run, ControlSchemaErrorResponseFactory $errorFactory): HttpResponse {
- $fails = [];
- $request = HttpRequest::from($data, $fails, $schema);
-
- if (!empty($fails)) {
- return $errorFactory->apply($fails);
-
- }
-
- return call_user_func_array($run, [$request]);
- }
-}
diff --git a/src/Core/ControlSchemaErrorResponseFactory.php b/src/Core/ControlSchemaErrorResponseFactory.php
deleted file mode 100644
index 9882a65..0000000
--- a/src/Core/ControlSchemaErrorResponseFactory.php
+++ /dev/null
@@ -1,14 +0,0 @@
-token = $token;
- $this->user = $user;
- }
-
- public function getToken(): string {
- return $this->token;
- }
-
- /**
- * @return User
- */
- public function getUser(): User {
- return $this->user;
- }
-
-}
diff --git a/src/Core/Data/CourtType.php b/src/Core/Data/CourtType.php
deleted file mode 100755
index caad45c..0000000
--- a/src/Core/Data/CourtType.php
+++ /dev/null
@@ -1,61 +0,0 @@
- self::COURT_HALF) {
- throw new InvalidArgumentException("Valeur du rôle invalide");
- }
- $this->value = $val;
- }
-
- public static function plain(): CourtType {
- return new CourtType(CourtType::COURT_PLAIN);
- }
-
- public static function half(): CourtType {
- return new CourtType(CourtType::COURT_HALF);
- }
-
- public function name(): string {
- switch ($this->value) {
- case self::COURT_HALF:
- return "HALF";
- case self::COURT_PLAIN:
- return "PLAIN";
- }
- die("unreachable");
- }
-
- public static function fromName(string $name): ?CourtType {
- switch ($name) {
- case "HALF":
- return CourtType::half();
- case "PLAIN":
- return CourtType::plain();
- default:
- return null;
- }
- }
-
- public function isPlain(): bool {
- return ($this->value == self::COURT_PLAIN);
- }
-
- public function isHalf(): bool {
- return ($this->value == self::COURT_HALF);
- }
-
-}
diff --git a/src/Core/Data/Member.php b/src/Core/Data/Member.php
deleted file mode 100755
index 30e4202..0000000
--- a/src/Core/Data/Member.php
+++ /dev/null
@@ -1,57 +0,0 @@
-user = $user;
- $this->teamId = $teamId;
- $this->role = $role;
- }
-
- /**
- * @return string
- */
- public function getRole(): string {
- return $this->role;
- }
-
- /**
- * @return int
- */
- public function getTeamId(): int {
- return $this->teamId;
- }
-
- /**
- * @return User
- */
- public function getUser(): User {
- return $this->user;
- }
-
-
- public function jsonSerialize() {
- return get_object_vars($this);
- }
-}
diff --git a/src/Core/Data/TacticInfo.php b/src/Core/Data/TacticInfo.php
deleted file mode 100644
index c3b8667..0000000
--- a/src/Core/Data/TacticInfo.php
+++ /dev/null
@@ -1,62 +0,0 @@
-id = $id;
- $this->name = $name;
- $this->ownerId = $ownerId;
- $this->creationDate = $creationDate;
- $this->courtType = $type;
- $this->content = $content;
- }
-
- /**
- * @return string
- */
- public function getContent(): string {
- return $this->content;
- }
-
- public function getId(): int {
- return $this->id;
- }
-
- public function getName(): string {
- return $this->name;
- }
-
- /**
- * @return int
- */
- public function getOwnerId(): int {
- return $this->ownerId;
- }
-
- public function getCourtType(): CourtType {
- return $this->courtType;
- }
-
- /**
- * @return int
- */
- public function getCreationDate(): int {
- return $this->creationDate;
- }
-}
diff --git a/src/Core/Data/Team.php b/src/Core/Data/Team.php
deleted file mode 100755
index 7adeb49..0000000
--- a/src/Core/Data/Team.php
+++ /dev/null
@@ -1,38 +0,0 @@
-info = $info;
- $this->members = $members;
- }
-
- public function getInfo(): TeamInfo {
- return $this->info;
- }
-
- /**
- * @return Member[]
- */
- public function listMembers(): array {
- return $this->members;
- }
-
- public function jsonSerialize() {
- return get_object_vars($this);
- }
-
-
-}
diff --git a/src/Core/Data/TeamInfo.php b/src/Core/Data/TeamInfo.php
deleted file mode 100644
index 964990c..0000000
--- a/src/Core/Data/TeamInfo.php
+++ /dev/null
@@ -1,50 +0,0 @@
-id = $id;
- $this->name = $name;
- $this->picture = $picture;
- $this->mainColor = $mainColor;
- $this->secondColor = $secondColor;
- }
-
- public function getId(): int {
- return $this->id;
- }
-
- public function getName(): string {
- return $this->name;
- }
-
- public function getPicture(): string {
- return $this->picture;
- }
-
- public function getMainColor(): string {
- return $this->mainColor;
- }
-
- public function getSecondColor(): string {
- return $this->secondColor;
- }
-
- public function jsonSerialize() {
- return get_object_vars($this);
- }
-}
diff --git a/src/Core/Data/User.php b/src/Core/Data/User.php
deleted file mode 100644
index 8471929..0000000
--- a/src/Core/Data/User.php
+++ /dev/null
@@ -1,84 +0,0 @@
-email = $email;
- $this->name = $name;
- $this->id = $id;
- $this->profilePicture = $profilePicture;
- $this->isAdmin = $isAdmin;
- }
-
- /**
- * @return bool
- */
- public function isAdmin(): bool {
- return $this->isAdmin;
- }
-
- /**
- * @return string
- */
- public function getEmail(): string {
- return $this->email;
- }
-
- /**
- * @return string
- */
- public function getName(): string {
- return $this->name;
- }
-
- /**
- * @return int
- */
- public function getId(): int {
- return $this->id;
- }
-
- /**
- * @return string
- */
- public function getProfilePicture(): string {
- return $this->profilePicture;
- }
-
- public function jsonSerialize() {
- return get_object_vars($this);
- }
-}
diff --git a/src/Core/Gateway/AccountGateway.php b/src/Core/Gateway/AccountGateway.php
deleted file mode 100644
index 1a0c689..0000000
--- a/src/Core/Gateway/AccountGateway.php
+++ /dev/null
@@ -1,180 +0,0 @@
-con = $con;
- }
-
- public function insertAccount(string $name, string $email, string $token, string $hash, string $profilePicture): int {
- $this->con->exec("INSERT INTO Account(username, hash, email, token,profile_picture) VALUES (:username,:hash,:email,:token,:profile_pic)", [
- ':username' => [$name, PDO::PARAM_STR],
- ':hash' => [$hash, PDO::PARAM_STR],
- ':email' => [$email, PDO::PARAM_STR],
- ':token' => [$token, PDO::PARAM_STR],
- ':profile_pic' => [$profilePicture, PDO::PARAM_STR],
- ]);
- return intval($this->con->lastInsertId());
- }
-
- public function updateAccount(int $id, string $name, string $email, string $token, bool $isAdmin): void {
- $this->con->exec("UPDATE Account SET username = :username, email = :email, token = :token WHERE id = :id", [
- ':username' => [$name, PDO::PARAM_STR],
- ':email' => [$email, PDO::PARAM_STR],
- ':token' => [$token, PDO::PARAM_STR],
- ':id' => [$id, PDO::PARAM_INT],
- ]);
- $this->setIsAdmin($id, $isAdmin);
- }
-
- public function isAdmin(int $id): bool {
- $stmnt = $this->con->prepare("SELECT * FROM Admins WHERE id = :id");
- $stmnt->bindValue(':id', $id, PDO::PARAM_INT);
- $stmnt->execute();
- $result = $stmnt->fetchAll(PDO::FETCH_ASSOC);
-
- return !empty($result);
- }
-
- /**
- * promote or demote a user to server administrator
- * @param int $id
- * @param bool $isAdmin true to promote, false to demote
- * @return bool true if the given user exists
- */
- public function setIsAdmin(int $id, bool $isAdmin): bool {
- if ($isAdmin) {
- $stmnt = $this->con->prepare("INSERT INTO Admins VALUES(:id)");
- } else {
- $stmnt = $this->con->prepare("DELETE FROM Admins WHERE id = :id");
- }
-
- $stmnt->bindValue(':id', $id);
- $stmnt->execute();
-
- return $stmnt->rowCount() > 0;
- }
-
- /**
- * @param string $email
- * @return array|null
- */
- private function getRowsFromMail(string $email): ?array {
- return $this->con->fetch("SELECT * FROM Account WHERE email = :email", [':email' => [$email, PDO::PARAM_STR]])[0] ?? null;
- }
-
- /**
- * @param string $email
- * @return string|null the hashed user's password, or null if the given mail does not exist
- */
- public function getHash(string $email): ?string {
- $results = $this->getRowsFromMail($email);
- if ($results == null) {
- return null;
- }
- return $results['hash'];
- }
-
- /**
- * @param string $email
- * @return bool true if the given email exists in the database
- */
- public function exists(string $email): bool {
- return $this->getRowsFromMail($email) != null;
- }
-
- /**
- * @param string $email
- * @return Account|null
- */
- public function getAccountFromMail(string $email): ?Account {
- $acc = $this->getRowsFromMail($email);
- if (empty($acc)) {
- return null;
- }
-
- return new Account($acc["token"], new User($email, $acc["username"], $acc["id"], $acc["profile_picture"], $this->isAdmin($acc["id"])));
- }
-
- /**
- * @param string $token get an account from given token
- * @return Account|null
- */
- public function getAccountFromToken(string $token): ?Account {
- $stmnt = $this->con->prepare("SELECT * FROM Account WHERE token = :token");
- $stmnt->bindValue(':token', $token);
- return $this->getAccountFrom($stmnt);
- }
-
- /**
- * @param int $id get an account from given identifier
- * @return Account|null
- */
- public function getAccount(int $id): ?Account {
- $stmnt = $this->con->prepare("SELECT * FROM Account WHERE id = :id");
- $stmnt->bindValue(':id', $id);
- return $this->getAccountFrom($stmnt);
- }
-
- private function getAccountFrom(\PDOStatement $stmnt): ?Account {
- $stmnt->execute();
- $acc = $stmnt->fetch(PDO::FETCH_ASSOC);
-
- if ($acc == null) {
- return null;
- }
-
- return new Account($acc["token"], new User($acc["email"], $acc["username"], $acc["id"], $acc["profile_picture"], $this->isAdmin($acc["id"])));
- }
-
- /**
- * Return a list containing n accounts from a given starting index
- *
- * @param integer $n the number of accounts to retrieve
- * @param int $start starting index of the list content
- * @return Account[]
- */
- public function searchAccounts(int $start, int $n, ?string $searchString): array {
- $res = $this->con->fetch(
- "SELECT * FROM Account WHERE username LIKE '%' || :search || '%' OR email LIKE '%' || :search || '%' ORDER BY username, email LIMIT :offset, :n",
- [
- ":offset" => [$start, PDO::PARAM_INT],
- ":n" => [$n, PDO::PARAM_INT],
- ":search" => [$searchString ?? "", PDO::PARAM_STR],
- ]
- );
- return array_map(fn(array $acc) => new Account($acc["token"], new User($acc["email"], $acc["username"], $acc["id"], $acc["profile_picture"], $this->isAdmin($acc["id"]))), $res);
-
- }
-
- /**
- * returns the total amount of accounts in the database
- * @return int
- */
- public function totalCount(): int {
- return $this->con->fetch("SELECT count(*) FROM Account", [])[0]['count(*)'];
- }
-
- /**
- * remove a bunch of account identifiers
- * @param int[] $accountIds
- */
- public function removeAccounts(array $accountIds): void {
- foreach ($accountIds as $accountId) {
- $this->con->fetch("DELETE FROM Account WHERE id = :accountId", [
- ":accountId" => [$accountId, PDO::PARAM_INT],
- ]);
- }
- }
-}
diff --git a/src/Core/Gateway/MemberGateway.php b/src/Core/Gateway/MemberGateway.php
deleted file mode 100644
index f79ff60..0000000
--- a/src/Core/Gateway/MemberGateway.php
+++ /dev/null
@@ -1,101 +0,0 @@
-con = $con;
- }
-
- /**
- * insert member to a team
- * @param int $idTeam
- * @param int $userId
- * @param string $role
- * @return void
- */
- public function insert(int $idTeam, int $userId, string $role): void {
- $this->con->exec(
- "INSERT INTO Member(id_team, id_user, role) VALUES (:id_team, :id_user, :role)",
- [
- ":id_team" => [$idTeam, PDO::PARAM_INT],
- ":id_user" => [$userId, PDO::PARAM_INT],
- ":role" => [$role, PDO::PARAM_STR],
- ]
- );
- }
-
- /**
- * @param int $teamId
- * @return Member[]
- */
- public function getMembersOfTeam(int $teamId): array {
- $rows = $this->con->fetch(
- "SELECT a.id,a.email,a.username,a.profile_picture,m.role FROM Account a,team t,Member m WHERE t.id = :id AND m.id_team = t.id AND m.id_user = a.id",
- [
- ":id" => [$teamId, PDO::PARAM_INT],
- ]
- );
- return array_map(fn($row) => new Member(new User($row['email'], $row['username'], $row['id'], $row['profile_picture'], $row['is_admin']), $teamId, $row['role']), $rows);
-
- }
-
- /**
- * remove member from given team
- * @param int $idTeam
- * @param int $idMember
- * @return void
- */
- public function remove(int $idTeam, int $idMember): void {
- $this->con->exec(
- "DELETE FROM Member WHERE id_team = :id_team AND id_user = :id_user",
- [
- ":id_team" => [$idTeam, PDO::PARAM_INT],
- ":id_user" => [$idMember, PDO::PARAM_INT],
- ]
- );
- }
-
- /**
- * @param string $email
- * @param int $idTeam
- * @return bool
- */
- public function isCoach(string $email, int $idTeam): bool {
- $result = $this->con->fetch(
- "SELECT role FROM Member WHERE id_team=:team AND id_user = (SELECT id FROM Account WHERE email=:email)",
- [
- "team" => [$idTeam, PDO::PARAM_INT],
- "email" => [$email, PDO::PARAM_STR],
- ]
- )[0]['role'];
-
- return $result == 'COACH';
- }
-
- /**
- * @param int $idTeam
- * @param int $idCurrentUser
- * @return bool
- */
- public function isMemberOfTeam(int $idTeam, int $idCurrentUser): bool {
- $result = $this->con->fetch(
- "SELECT id_user FROM Member WHERE id_team = :team AND id_user = :user",
- [
- "team" => [$idTeam, PDO::PARAM_INT],
- "user" => [$idCurrentUser, PDO::PARAM_INT],
- ]
- );
- return !empty($result);
- }
-}
diff --git a/src/Core/Gateway/TacticInfoGateway.php b/src/Core/Gateway/TacticInfoGateway.php
deleted file mode 100644
index d4b81e0..0000000
--- a/src/Core/Gateway/TacticInfoGateway.php
+++ /dev/null
@@ -1,151 +0,0 @@
-con = $con;
- }
-
- /**
- * get tactic information from given identifier
- * @param int $id
- * @return TacticInfo|null
- */
- public function get(int $id): ?TacticInfo {
- $res = $this->con->fetch(
- "SELECT * FROM Tactic WHERE id = :id",
- [":id" => [$id, PDO::PARAM_INT]]
- );
-
- if (!isset($res[0])) {
- return null;
- }
-
- $row = $res[0];
-
- $type = CourtType::fromName($row['court_type']);
- return new TacticInfo($id, $row["name"], strtotime($row["creation_date"]), $row["owner"], $type, $row['content']);
- }
-
-
- /**
- * Return the nb last tactics created
- *
- * @param integer $nb
- * @return array>
- */
- public function getLast(int $nb, int $ownerId): ?array {
- $res = $this->con->fetch(
- "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 [];
- }
- 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;
- }
-
-
- /**
- * Return a list containing the nth last tactics of a given user id
- *
- * @param integer $user_id
- * @return TacticInfo[]
- */
- public function listAllOf(int $user_id): array {
- $res = $this->con->fetch(
- "SELECT * FROM Tactic WHERE owner = :owner_id ORDER BY creation_date DESC",
- [
- ":owner_id" => [$user_id, PDO::PARAM_STR],
- ]
- );
- return array_map(fn(array $t) => new TacticInfo($t['id'], $t["name"], strtotime($t["creation_date"]), $t["owner"], CourtType::fromName($t['court_type']), $t['content']), $res);
- }
-
-
- /**
- * @param string $name
- * @param int $owner
- * @param CourtType $type
- * @return int inserted tactic id
- */
- public function insert(string $name, int $owner, CourtType $type): int {
- $this->con->exec(
- "INSERT INTO Tactic(name, owner, court_type) VALUES(:name, :owner, :court_type)",
- [
- ":name" => [$name, PDO::PARAM_STR],
- ":owner" => [$owner, PDO::PARAM_INT],
- ":court_type" => [$type->name(), PDO::PARAM_STR],
- ]
- );
- return intval($this->con->lastInsertId());
- }
-
- /**
- * update name of given tactic identifier
- * @param int $id
- * @param string $name
- * @return bool
- */
- public function updateName(int $id, string $name): bool {
- $stmnt = $this->con->prepare("UPDATE Tactic SET name = :name WHERE id = :id");
- $stmnt->execute([
- ":name" => $name,
- ":id" => $id,
- ]);
- return $stmnt->rowCount() == 1;
- }
-
- /***
- * Updates a given tactics content
- * @param int $id
- * @param string $json
- * @return bool
- */
- public function updateContent(int $id, string $json): bool {
- $stmnt = $this->con->prepare("UPDATE Tactic SET content = :content WHERE id = :id");
- $stmnt->execute([
- ":content" => $json,
- ":id" => $id,
- ]);
- return $stmnt->rowCount() == 1;
- }
-}
diff --git a/src/Core/Gateway/TeamGateway.php b/src/Core/Gateway/TeamGateway.php
deleted file mode 100644
index 4309a49..0000000
--- a/src/Core/Gateway/TeamGateway.php
+++ /dev/null
@@ -1,186 +0,0 @@
-con = $con;
- }
-
- /**
- * @param string $name
- * @param string $picture
- * @param string $mainColor
- * @param string $secondColor
- * @return int the inserted team identifier
- */
- public function insert(string $name, string $picture, string $mainColor, string $secondColor): int {
- $this->con->exec(
- "INSERT INTO team(name, picture, main_color, second_color) VALUES (:team_name , :picture, :main_color, :second_color)",
- [
- ":team_name" => [$name, PDO::PARAM_STR],
- ":picture" => [$picture, PDO::PARAM_STR],
- ":main_color" => [$mainColor, PDO::PARAM_STR],
- ":second_color" => [$secondColor, PDO::PARAM_STR],
- ]
- );
- return intval($this->con->lastInsertId());
- }
-
- /**
- * @param string $name
- * @param int $id
- * @return TeamInfo[]
- */
- public function listByName(string $name, int $id): array {
- $result = $this->con->fetch(
- "SELECT t.* FROM team t, Member m WHERE t.name LIKE '%' || :name || '%' AND t.id=m.id_team AND m.id_user=:id",
- [
- ":name" => [$name, PDO::PARAM_STR],
- "id" => [$id, PDO::PARAM_INT],
- ]
- );
-
- return array_map(fn($row) => new TeamInfo($row['id'], $row['name'], $row['picture'], $row['main_color'], $row['second_color']), $result);
- }
-
- /**
- * @param int $id
- * @return TeamInfo|null
- */
- public function getTeamById(int $id): ?TeamInfo {
- $row = $this->con->fetch(
- "SELECT * FROM team WHERE id = :id",
- [
- ":id" => [$id, PDO::PARAM_INT],
- ]
- )[0] ?? null;
- if ($row == null) {
- return null;
- }
- return new TeamInfo($row['id'], $row['name'], $row['picture'], $row['main_color'], $row['second_color']);
- }
-
- /**
- * @param string $name
- * @return int|null
- */
- public function getTeamIdByName(string $name): ?int {
- return $this->con->fetch(
- "SELECT id FROM team WHERE name = :name",
- [
- ":name" => [$name, PDO::PARAM_INT],
- ]
- )[0]['id'] ?? null;
- }
-
- /**
- * @param int $idTeam
- */
- public function deleteTeam(int $idTeam): void {
- $this->con->exec(
- "DELETE FROM Member WHERE id_team=:team",
- [
- "team" => [$idTeam, PDO::PARAM_INT],
- ]
- );
- $this->con->exec(
- "DELETE FROM TEAM WHERE id=:team",
- [
- "team" => [$idTeam, PDO::PARAM_INT],
- ]
- );
- }
-
- /**
- * @param int $idTeam
- * @param string $newName
- * @param string $newPicture
- * @param string $newMainColor
- * @param string $newSecondColor
- * @return void
- */
- public function editTeam(int $idTeam, string $newName, string $newPicture, string $newMainColor, string $newSecondColor) {
- $this->con->exec(
- "UPDATE team
- SET name = :newName,
- picture = :newPicture,
- main_color = :newMainColor,
- second_color = :newSecondColor
- WHERE id = :team",
- [
- "team" => [$idTeam, PDO::PARAM_INT],
- "newName" => [$newName, PDO::PARAM_STR],
- "newPicture" => [$newPicture, PDO::PARAM_STR],
- "newMainColor" => [$newMainColor, PDO::PARAM_STR],
- "newSecondColor" => [$newSecondColor, PDO::PARAM_STR],
- ]
- );
-
- }
-
- /**
- * @param int $user
- * @return array
- */
- public function getAll(int $user): array {
- return $this->con->fetch(
- "SELECT t.* FROM team t,Member m WHERE m.id_team = t.id AND m.id_user= :idUser ",
- [
- "idUser" => [$user, PDO::PARAM_INT],
- ]
- );
- }
-
- /**
- * @param int $start
- * @param int $n
- * @return TeamInfo[]
- */
- public function listAll(int $start, int $n): array {
- $rows = $this->con->fetch(
- "SELECT * FROM Team LIMIT :start, :n",
- [
- ":start" => [$start, PDO::PARAM_INT],
- ":n" => [$n, PDO::PARAM_INT],
- ]
- );
- return array_map(fn($row) => new TeamInfo($row['id'], $row['name'], $row['picture'], $row['main_color'], $row['second_color']), $rows);
- }
-
- public function countTeam(): int {
- $result = $this->con->fetch(
- "SELECT count(*) as count FROM Team",
- []
- );
- if (empty($result) || !isset($result[0]['count'])) {
- return 0;
- }
- return $result[0]['count'];
- }
-
- /**
- * @param array $selectedTeams
- * @return void
- */
- public function deleteTeamSelected(array $selectedTeams): void {
- foreach ($selectedTeams as $team) {
- $this->con->exec(
- "DELETE FROM TEAM WHERE id=:team",
- [
- "team" => [$team, PDO::PARAM_INT],
- ]
- );
- }
- }
-
-
-}
diff --git a/src/Core/Http/HttpCodes.php b/src/Core/Http/HttpCodes.php
deleted file mode 100644
index 1903f0c..0000000
--- a/src/Core/Http/HttpCodes.php
+++ /dev/null
@@ -1,18 +0,0 @@
-
- * */
-class HttpRequest implements ArrayAccess {
- /**
- * @var array
- */
- private array $data;
-
- /**
- * @param array $data
- */
- private function __construct(array $data) {
- $this->data = $data;
- }
-
- /**
- * Creates a new HttpRequest instance, and ensures that the given request data validates the given schema.
- * This is a simple function that only supports flat schemas (non-composed, the data must only be a k/v array pair.)
- * @param array $request the request's data
- * @param array $fails a reference to a failure array, that will contain the reported validation failures.
- * @param array $schema the schema to satisfy. a schema is a simple array with a string key (which is the top-level field name), and a set of validators
- * @return HttpRequest|null the built HttpRequest instance, or null if a field is missing, or if any of the schema validator failed
- */
- public static function from(array $request, array &$fails, array $schema): ?HttpRequest {
- $failure = false;
- foreach ($schema as $fieldName => $fieldValidators) {
- if (!isset($request[$fieldName])) {
- $fails[] = FieldValidationFail::missing($fieldName);
- $failure = true;
- continue;
- }
- $failure |= Validation::validate($request[$fieldName], $fieldName, $fails, ...$fieldValidators);
- }
-
- if ($failure) {
- return null;
- }
- return new HttpRequest($request);
- }
-
- public function offsetExists($offset): bool {
- return isset($this->data[$offset]);
- }
-
- /**
- * @param $offset
- * @return mixed
- */
- public function offsetGet($offset) {
- return $this->data[$offset];
- }
-
- /**
- * @param $offset
- * @param $value
- * @throws Exception
- */
- public function offsetSet($offset, $value) {
- throw new Exception("requests are immutable objects.");
- }
-
- /**
- * @param $offset
- * @throws Exception
- */
- public function offsetUnset($offset) {
- throw new Exception("requests are immutable objects.");
- }
-}
diff --git a/src/Core/Http/HttpResponse.php b/src/Core/Http/HttpResponse.php
deleted file mode 100644
index 6c6a743..0000000
--- a/src/Core/Http/HttpResponse.php
+++ /dev/null
@@ -1,65 +0,0 @@
-
- */
- private array $headers;
- private int $code;
-
- /**
- * @param int $code
- * @param array $headers
- */
- public function __construct(int $code, array $headers) {
- $this->code = $code;
- $this->headers = $headers;
- }
-
- public function getCode(): int {
- return $this->code;
- }
-
- /**
- * @return array
- */
- public function getHeaders(): array {
- return $this->headers;
- }
-
- /**
- * @param int $code
- * @return HttpResponse
- */
- public static function fromCode(int $code): HttpResponse {
- return new HttpResponse($code, []);
- }
-
- /**
- * @param string $url the url to redirect
- * @param int $code only HTTP 3XX codes are accepted.
- * @return HttpResponse a response that will redirect client to given url
- */
-
- public static function redirect(string $url, int $code = HttpCodes::FOUND): HttpResponse {
- global $basePath;
- return self::redirectAbsolute($basePath . $url, $code);
- }
-
- /**
- * @param string $url the url to redirect
- * @param int $code only HTTP 3XX codes are accepted.
- * @return HttpResponse a response that will redirect client to given url
- */
-
- public static function redirectAbsolute(string $url, int $code = HttpCodes::FOUND): HttpResponse {
- if ($code < 300 || $code >= 400) {
- throw new \InvalidArgumentException("given code is not a redirection http code");
- }
- return new HttpResponse($code, ["Location" => $url]);
- }
-
-
-}
diff --git a/src/Core/Http/JsonHttpResponse.php b/src/Core/Http/JsonHttpResponse.php
deleted file mode 100644
index bb897f7..0000000
--- a/src/Core/Http/JsonHttpResponse.php
+++ /dev/null
@@ -1,28 +0,0 @@
-payload = $payload;
- }
-
- public function getJson(): string {
- $result = json_encode($this->payload);
- if (!$result) {
- throw new \RuntimeException("Given payload is not json encodable");
- }
-
- return $result;
- }
-
-}
diff --git a/src/Core/Model/AuthModel.php b/src/Core/Model/AuthModel.php
deleted file mode 100644
index e1fc1bb..0000000
--- a/src/Core/Model/AuthModel.php
+++ /dev/null
@@ -1,78 +0,0 @@
-gateway = $gateway;
- }
-
- /**
- * @param string $username
- * @param string $password
- * @param string $email
- * @return Account|null the registered account or null if the account already exists for the given email address
- */
- public function register(
- string $username,
- string $password,
- string $email
- ): ?Account {
- if ($this->gateway->exists($email)) {
- return null;
- }
-
- $hash = password_hash($password, PASSWORD_DEFAULT);
- $token = $this->generateToken();
- $accountId = $this->gateway->insertAccount($username, $email, $token, $hash, self::DEFAULT_PROFILE_PICTURE);
- return new Account($token, new User($email, $username, $accountId, self::DEFAULT_PROFILE_PICTURE, false));
- }
-
- /**
- * Generate a random base 64 string
- * @return string
- */
- public static function generateToken(): string {
- try {
- return base64_encode(random_bytes(64));
- } catch (Exception $e) {
- throw new \RuntimeException($e);
- }
- }
-
- /**
- * @param string $email
- * @param string $password
- * @param ValidationFail[] $failures
- * @return Account|null the authenticated account or null if failures occurred
- */
- public function login(string $email, string $password, array &$failures): ?Account {
- $hash = $this->gateway->getHash($email);
- if ($hash == null or (!password_verify($password, $hash))) {
- $failures[] = new ValidationFail("email", "Adresse email ou mot de passe invalide");
- return null;
- }
- return $this->gateway->getAccountFromMail($email);
- }
-
- public function update(int $id, string $email, string $username, bool $isAdmin): void {
- $token = $this->generateToken();
- $this->gateway->updateAccount($id, $username, $email, $token, $isAdmin);
- }
-
-}
diff --git a/src/Core/Model/TacticModel.php b/src/Core/Model/TacticModel.php
deleted file mode 100644
index 920075b..0000000
--- a/src/Core/Model/TacticModel.php
+++ /dev/null
@@ -1,117 +0,0 @@
-tactics = $tactics;
- }
-
- /**
- * creates a new empty tactic, with given name
- * @param string $name
- * @param int $ownerId
- * @param CourtType $type
- * @return TacticInfo
- */
- public function makeNew(string $name, int $ownerId, CourtType $type): TacticInfo {
- $id = $this->tactics->insert($name, $ownerId, $type);
- return $this->tactics->get($id);
- }
-
- /**
- * creates a new empty tactic, with a default name
- * @param int $ownerId
- * @param CourtType $type
- * @return TacticInfo|null
- */
- public function makeNewDefault(int $ownerId, CourtType $type): ?TacticInfo {
- return $this->makeNew(self::TACTIC_DEFAULT_NAME, $ownerId, $type);
- }
-
- /**
- * Tries to retrieve information about a tactic
- * @param int $id tactic identifier
- * @return TacticInfo|null or null if the identifier did not match a tactic
- */
- public function get(int $id): ?TacticInfo {
- return $this->tactics->get($id);
- }
-
- /**
- * 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);
- }
-
-
- /**
- * Return a list containing all the tactics of a given user
- * NOTE: if given user id does not match any user, this function returns an empty array
- *
- * @param integer $user_id
- * @return TacticInfo[]
- */
- public function listAllOf(int $user_id): array {
- return$this->tactics->listAllOf($user_id);
- }
-
- /**
- * 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
- * @param string $name the new name to set
- * @return ValidationFail[] failures, if any
- */
- public function updateName(int $id, string $name, int $authId): array {
-
- $tactic = $this->tactics->get($id);
-
- if ($tactic == null) {
- return [ValidationFail::notFound("Could not find tactic")];
- }
-
- if ($tactic->getOwnerId() != $authId) {
- return [ValidationFail::unauthorized()];
- }
-
- if (!$this->tactics->updateName($id, $name)) {
- return [ValidationFail::error("Could not update name")];
- }
- return [];
- }
-
- public function updateContent(int $id, string $json): ?ValidationFail {
- if (!$this->tactics->updateContent($id, $json)) {
- return ValidationFail::error("Could not update content");
- }
- return null;
- }
-
-}
diff --git a/src/Core/Model/TeamModel.php b/src/Core/Model/TeamModel.php
deleted file mode 100644
index b6b7bdd..0000000
--- a/src/Core/Model/TeamModel.php
+++ /dev/null
@@ -1,164 +0,0 @@
-teams = $gateway;
- $this->members = $members;
- $this->users = $users;
- }
-
- /**
- * Create a team
- * @param string $name
- * @param string $picture
- * @param string $mainColor
- * @param string $secondColor
- * @return int
- */
- public function createTeam(string $name, string $picture, string $mainColor, string $secondColor): int {
- return $this->teams->insert($name, $picture, $mainColor, $secondColor);
- }
-
- /**
- * add a member to a team
- * @param string $mail
- * @param int $teamId
- * @param string $role
- * @return int
- */
- public function addMember(string $mail, int $teamId, string $role): int {
- $user = $this->users->getAccountFromMail($mail);
- 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;
- }
-
- /**
- * @param string $name
- * @param int $id
- * @return TeamInfo[]
- */
- public function listByName(string $name, int $id): array {
- return $this->teams->listByName($name, $id);
- }
-
- /**
- * @param int $idTeam
- * @param int $idCurrentUser
- * @return Team|null
- */
- public function getTeam(int $idTeam, int $idCurrentUser): ?Team {
- if (!$this->members->isMemberOfTeam($idTeam, $idCurrentUser)) {
- return null;
- }
- $teamInfo = $this->teams->getTeamById($idTeam);
- $members = $this->members->getMembersOfTeam($idTeam);
- return new Team($teamInfo, $members);
- }
-
- /**
- * delete a member from given team identifier
- * @param int $idMember
- * @param int $teamId
- * @return int
- */
- public function deleteMember(int $idMember, int $teamId): int {
- $this->members->remove($teamId, $idMember);
- if (empty($this->members->getMembersOfTeam($teamId))) {
- $this->teams->deleteTeam($teamId);
- return -1;
- }
- return $teamId;
- }
-
- /**
- * Delete a team
- * @param string $email
- * @param int $idTeam
- * @return int
- */
- public function deleteTeam(string $email, int $idTeam): int {
- if ($this->members->isCoach($email, $idTeam)) {
- $this->teams->deleteTeam($idTeam);
- return 0;
- }
- return -1;
- }
-
- /**
- * Verify if the account associated to an email is in a specific team indicated with its id
- * @param int $idTeam
- * @param string $email
- * @return bool
- */
- public function isCoach(int $idTeam, string $email): bool {
- return $this->members->isCoach($email, $idTeam);
- }
-
- /**
- * Edit a team with its id, and replace the current attributes with the new ones
- * @param int $idTeam
- * @param string $newName
- * @param string $newPicture
- * @param string $newMainColor
- * @param string $newSecondColor
- * @return void
- */
- public function editTeam(int $idTeam, string $newName, string $newPicture, string $newMainColor, string $newSecondColor) {
- $this->teams->editTeam($idTeam, $newName, $newPicture, $newMainColor, $newSecondColor);
- }
-
- /**
- * Get all user's teams
- *
- * @param integer $user
- * @return array>
- */
- public function getAll(int $user): array {
- return $this->teams->getAll($user);
- }
-
- /**
- * @param int $start
- * @param int $n
- * @return TeamInfo[]
- */
- public function listAll(int $start, int $n) {
- return $this->teams->listAll($start, $n);
- }
-
- public function countTeam(): int {
- return $this->teams->countTeam();
- }
-
- /**
- * @param array $selectedTeams
- * @return void
- */
- public function deleteTeamSelected(array $selectedTeams) {
- $this->teams->deleteTeamSelected($selectedTeams);
- }
-
-}
diff --git a/src/Core/Validation/ComposedValidator.php b/src/Core/Validation/ComposedValidator.php
deleted file mode 100644
index 58f4910..0000000
--- a/src/Core/Validation/ComposedValidator.php
+++ /dev/null
@@ -1,26 +0,0 @@
-first = $first;
- $this->then = $then;
- }
-
- public function validate(string $name, $val): array {
- $firstFailures = $this->first->validate($name, $val);
- $thenFailures = [];
- if (empty($firstFailures)) {
- $thenFailures = $this->then->validate($name, $val);
- }
- return array_merge($firstFailures, $thenFailures);
- }
-}
diff --git a/src/Core/Validation/DefaultValidators.php b/src/Core/Validation/DefaultValidators.php
deleted file mode 100644
index c898170..0000000
--- a/src/Core/Validation/DefaultValidators.php
+++ /dev/null
@@ -1,146 +0,0 @@
- preg_match($regex, $str),
- fn(string $name) => [new FieldValidationFail($name, $msg == null ? "le champ ne valide pas le pattern $regex" : $msg)]
- );
- }
-
- public static function hex(?string $msg = null): Validator {
- return self::regex('/#([0-9a-fA-F])/', $msg == null ? "le champ n'est pas un nombre hexadecimal valide" : $msg);
- }
-
- public static function hexColor(?string $msg = null): Validator {
- return self::regex('/#([0-9a-fA-F]{6})/', $msg == null ? "le champ n'est pas une couleur valide" : $msg);
- }
-
- /**
- * @return Validator a validator that validates strings that only contains numbers, letters, accents letters, `-` and `_`.
- */
- public static function name(?string $msg = null): Validator {
- return self::regex("/^[0-9a-zA-Zà-üÀ-Ü_-]*$/", $msg);
- }
-
- /**
- * @return Validator a validator that validates strings that only contains numbers, letters, accents letters, `-`, `_` and spaces.
- */
- public static function nameWithSpaces(): Validator {
- return self::regex("/^[0-9a-zA-Zà-üÀ-Ü _-]*$/");
- }
-
- public static function password(): Validator {
- return self::lenBetween(6, 256);
- }
-
- /**
- * Validate string if its length is between given range
- * @param int $min minimum accepted length, inclusive
- * @param int $max maximum accepted length, exclusive
- * @return Validator
- */
- public static function lenBetween(int $min, int $max): Validator {
- return new FunctionValidator(
- function (string $fieldName, string $str) use ($min, $max) {
- $len = strlen($str);
- if ($len >= $max) {
- return [new FieldValidationFail($fieldName, "trop long, maximum $max caractères.")];
- }
- if ($len < $min) {
- return [new FieldValidationFail($fieldName, "trop court, minimum $min caractères.")];
- }
- return [];
- }
- );
- }
-
- public static function email(?string $msg = null): Validator {
- return new SimpleFunctionValidator(
- fn(string $str) => filter_var($str, FILTER_VALIDATE_EMAIL),
- fn(string $name) => [new FieldValidationFail($name, $msg == null ? "addresse mail invalide" : $msg)]
- );
- }
-
-
- public static function isInteger(): Validator {
- return self::regex("/^[-+]?[0-9]+$/", "field is not an integer");
- }
-
- public static function isUnsignedInteger(): Validator {
- return self::regex("/^[0-9]+$/", "field is not an unsigned integer");
- }
-
- public static function isIntInRange(int $min, int $max): Validator {
- return new SimpleFunctionValidator(
- fn(string $val) => intval($val) >= $min && intval($val) <= $max,
- fn(string $name) => [new FieldValidationFail($name, "The value is not in the range $min to $max ")]
- );
- }
-
- /**
- * @param mixed[] $values
- * @return Validator
- */
- public static function oneOf(array $values): Validator {
- return new SimpleFunctionValidator(
- fn(string $val) => in_array($val, $values),
- fn(string $name) => [new FieldValidationFail($name, "The value must be one of '" . join(", ", $values) . "'")]
- );
- }
-
- public static function bool(): Validator {
- return self::oneOf([true, false]);
- }
-
- public static function isURL(): Validator {
- return new SimpleFunctionValidator(
- fn($val) => filter_var($val, FILTER_VALIDATE_URL),
- fn(string $name) => [new FieldValidationFail($name, "The value is not an URL")]
- );
- }
-
- /**
- * @return Validator
- */
- public static function array(): Validator {
- return new SimpleFunctionValidator(
- fn($val) => is_array($val),
- fn(string $name) => [new FieldValidationFail($name, "The value is not an array")]
- );
- }
-
- /**
- * @param Validator $validator
- * @return Validator
- */
- public static function forall(Validator $validator): Validator {
- return new class ($validator) extends Validator {
- private Validator $validator;
-
- /**
- * @param Validator $validator
- */
- public function __construct(Validator $validator) {
- $this->validator = $validator;
- }
-
- public function validate(string $name, $val): array {
- $failures = [];
- foreach ($val as $idx => $item) {
- $failures = array_merge($failures, $this->validator->validate($name . "[$idx]", $item));
- }
-
- return $failures;
- }
- };
- }
-}
diff --git a/src/Core/Validation/FieldValidationFail.php b/src/Core/Validation/FieldValidationFail.php
deleted file mode 100644
index e3a127d..0000000
--- a/src/Core/Validation/FieldValidationFail.php
+++ /dev/null
@@ -1,42 +0,0 @@
-fieldName = $fieldName;
- }
-
- public function getFieldName(): string {
- return $this->fieldName;
- }
-
- public static function invalidChars(string $fieldName): FieldValidationFail {
- return new FieldValidationFail($fieldName, "field contains illegal chars");
- }
-
- public static function empty(string $fieldName): FieldValidationFail {
- return new FieldValidationFail($fieldName, "field is empty");
- }
-
- public static function missing(string $fieldName): FieldValidationFail {
- return new FieldValidationFail($fieldName, "field is missing");
- }
-
- /**
- * @return array
- */
- public function jsonSerialize(): array {
- return ["field" => $this->fieldName, "message" => $this->getMessage()];
- }
-}
diff --git a/src/Core/Validation/FunctionValidator.php b/src/Core/Validation/FunctionValidator.php
deleted file mode 100644
index 1bd18d7..0000000
--- a/src/Core/Validation/FunctionValidator.php
+++ /dev/null
@@ -1,21 +0,0 @@
-validate_fn = $validate_fn;
- }
-
- public function validate(string $name, $val): array {
- return call_user_func_array($this->validate_fn, [$name, $val]);
- }
-}
diff --git a/src/Core/Validation/SimpleFunctionValidator.php b/src/Core/Validation/SimpleFunctionValidator.php
deleted file mode 100644
index f19462b..0000000
--- a/src/Core/Validation/SimpleFunctionValidator.php
+++ /dev/null
@@ -1,33 +0,0 @@
- bool`, to validate the given string
- * @param callable(string): ValidationFail[] $errorsFactory a factory function with signature `(string) => array` to emit failures when the predicate fails
- */
- public function __construct(callable $predicate, callable $errorsFactory) {
- $this->predicate = $predicate;
- $this->errorFactory = $errorsFactory;
- }
-
- public function validate(string $name, $val): array {
- if (!call_user_func_array($this->predicate, [$val])) {
- return call_user_func_array($this->errorFactory, [$name]);
- }
- return [];
- }
-}
diff --git a/src/Core/Validation/Validation.php b/src/Core/Validation/Validation.php
deleted file mode 100644
index 5b13354..0000000
--- a/src/Core/Validation/Validation.php
+++ /dev/null
@@ -1,29 +0,0 @@
-validate($valName, $val);
- if ($error != null) {
- $failures = array_merge($failures, $error);
- $had_errors = true;
- }
- }
- return $had_errors;
- }
-
-}
diff --git a/src/Core/Validation/ValidationFail.php b/src/Core/Validation/ValidationFail.php
deleted file mode 100644
index 9a74a03..0000000
--- a/src/Core/Validation/ValidationFail.php
+++ /dev/null
@@ -1,56 +0,0 @@
-message = $message;
- $this->kind = $kind;
- }
-
- public function getMessage(): string {
- return $this->message;
- }
-
- public function getKind(): string {
- return $this->kind;
- }
-
- /**
- * @return array
- */
- public function jsonSerialize(): array {
- return ["error" => $this->kind, "message" => $this->message];
- }
-
- /**
- * @param string $message
- * @return ValidationFail validation fail for unknown resource access
- */
- public static function notFound(string $message): ValidationFail {
- return new ValidationFail("Not found", $message);
- }
-
- /**
- * @param string $message
- * @return ValidationFail validation fail for unauthorized accesses
- */
- public static function unauthorized(string $message = "Unauthorized"): ValidationFail {
- return new ValidationFail("Unauthorized", $message);
- }
-
- public static function error(string $message): ValidationFail {
- return new ValidationFail("Error", $message);
- }
-
-}
diff --git a/src/Core/Validation/Validator.php b/src/Core/Validation/Validator.php
deleted file mode 100644
index d1761da..0000000
--- a/src/Core/Validation/Validator.php
+++ /dev/null
@@ -1,23 +0,0 @@
-
\ No newline at end of file
diff --git a/front/assets/icon/arrow.svg b/src/assets/icon/arrow.svg
similarity index 100%
rename from front/assets/icon/arrow.svg
rename to src/assets/icon/arrow.svg
diff --git a/front/assets/icon/ball.svg b/src/assets/icon/ball.svg
similarity index 100%
rename from front/assets/icon/ball.svg
rename to src/assets/icon/ball.svg
diff --git a/front/assets/icon/remove.svg b/src/assets/icon/remove.svg
similarity index 100%
rename from front/assets/icon/remove.svg
rename to src/assets/icon/remove.svg
diff --git a/front/assets/logo.svg b/src/assets/logo.svg
similarity index 100%
rename from front/assets/logo.svg
rename to src/assets/logo.svg
diff --git a/front/assets/logo192.png b/src/assets/logo192.png
similarity index 100%
rename from front/assets/logo192.png
rename to src/assets/logo192.png
diff --git a/front/assets/logo512.png b/src/assets/logo512.png
similarity index 100%
rename from front/assets/logo512.png
rename to src/assets/logo512.png
diff --git a/src/assets/react.svg b/src/assets/react.svg
new file mode 100644
index 0000000..6c87de9
--- /dev/null
+++ b/src/assets/react.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/assets/vite.svg b/src/assets/vite.svg
new file mode 100644
index 0000000..e7b8dfb
--- /dev/null
+++ b/src/assets/vite.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/front/components/Rack.tsx b/src/components/Rack.tsx
similarity index 100%
rename from front/components/Rack.tsx
rename to src/components/Rack.tsx
diff --git a/front/components/TitleInput.tsx b/src/components/TitleInput.tsx
similarity index 100%
rename from front/components/TitleInput.tsx
rename to src/components/TitleInput.tsx
diff --git a/front/components/actions/ArrowAction.tsx b/src/components/actions/ArrowAction.tsx
similarity index 100%
rename from front/components/actions/ArrowAction.tsx
rename to src/components/actions/ArrowAction.tsx
diff --git a/front/components/actions/BallAction.tsx b/src/components/actions/BallAction.tsx
similarity index 100%
rename from front/components/actions/BallAction.tsx
rename to src/components/actions/BallAction.tsx
diff --git a/front/components/arrows/BendableArrow.tsx b/src/components/arrows/BendableArrow.tsx
similarity index 100%
rename from front/components/arrows/BendableArrow.tsx
rename to src/components/arrows/BendableArrow.tsx
diff --git a/front/components/editor/BallPiece.tsx b/src/components/editor/BallPiece.tsx
similarity index 100%
rename from front/components/editor/BallPiece.tsx
rename to src/components/editor/BallPiece.tsx
diff --git a/front/components/editor/BasketCourt.tsx b/src/components/editor/BasketCourt.tsx
similarity index 88%
rename from front/components/editor/BasketCourt.tsx
rename to src/components/editor/BasketCourt.tsx
index 69bad37..2213525 100644
--- a/front/components/editor/BasketCourt.tsx
+++ b/src/components/editor/BasketCourt.tsx
@@ -1,14 +1,7 @@
-import {
- ReactElement,
- ReactNode,
- RefObject,
- useEffect,
- useLayoutEffect,
- useState,
-} from "react"
+import { ReactElement, ReactNode, RefObject } from "react"
import { Action } from "../../model/tactic/Action"
-import { CourtAction } from "../../views/editor/CourtAction"
+import { CourtAction } from "./CourtAction.tsx"
import { ComponentId, TacticComponent } from "../../model/tactic/Tactic"
export interface BasketCourtProps {
diff --git a/front/views/editor/CourtAction.tsx b/src/components/editor/CourtAction.tsx
similarity index 100%
rename from front/views/editor/CourtAction.tsx
rename to src/components/editor/CourtAction.tsx
diff --git a/front/components/editor/CourtBall.tsx b/src/components/editor/CourtBall.tsx
similarity index 100%
rename from front/components/editor/CourtBall.tsx
rename to src/components/editor/CourtBall.tsx
diff --git a/front/components/editor/CourtPlayer.tsx b/src/components/editor/CourtPlayer.tsx
similarity index 100%
rename from front/components/editor/CourtPlayer.tsx
rename to src/components/editor/CourtPlayer.tsx
diff --git a/front/components/editor/PlayerPiece.tsx b/src/components/editor/PlayerPiece.tsx
similarity index 100%
rename from front/components/editor/PlayerPiece.tsx
rename to src/components/editor/PlayerPiece.tsx
diff --git a/front/components/editor/SavingState.tsx b/src/components/editor/SavingState.tsx
similarity index 100%
rename from front/components/editor/SavingState.tsx
rename to src/components/editor/SavingState.tsx
diff --git a/front/editor/ActionsDomains.ts b/src/editor/ActionsDomains.ts
similarity index 100%
rename from front/editor/ActionsDomains.ts
rename to src/editor/ActionsDomains.ts
diff --git a/front/editor/PlayerDomains.ts b/src/editor/PlayerDomains.ts
similarity index 100%
rename from front/editor/PlayerDomains.ts
rename to src/editor/PlayerDomains.ts
diff --git a/front/editor/RackedItems.ts b/src/editor/RackedItems.ts
similarity index 100%
rename from front/editor/RackedItems.ts
rename to src/editor/RackedItems.ts
diff --git a/front/editor/TacticContentDomains.ts b/src/editor/TacticContentDomains.ts
similarity index 100%
rename from front/editor/TacticContentDomains.ts
rename to src/editor/TacticContentDomains.ts
diff --git a/front/geo/Box.ts b/src/geo/Box.ts
similarity index 100%
rename from front/geo/Box.ts
rename to src/geo/Box.ts
diff --git a/front/geo/Pos.ts b/src/geo/Pos.ts
similarity index 100%
rename from front/geo/Pos.ts
rename to src/geo/Pos.ts
diff --git a/src/index.css b/src/index.css
new file mode 100644
index 0000000..880d452
--- /dev/null
+++ b/src/index.css
@@ -0,0 +1,25 @@
+:root {
+ font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
+ line-height: 1.5;
+ font-weight: 400;
+
+ color-scheme: light dark;
+
+ font-synthesis: none;
+ text-rendering: optimizeLegibility;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+
+}
+
+body {
+ margin: 0;
+ display: flex;
+ place-items: center;
+}
+
+h1 {
+ font-size: 3.2em;
+ line-height: 1.1;
+}
+
diff --git a/src/main.tsx b/src/main.tsx
new file mode 100644
index 0000000..7229199
--- /dev/null
+++ b/src/main.tsx
@@ -0,0 +1,11 @@
+import React from 'react'
+import ReactDOM from 'react-dom/client'
+import './index.css'
+import App from "./App.tsx";
+
+
+ReactDOM.createRoot(document.getElementById('root')!).render(
+
+
+ ,
+)
diff --git a/front/model/Team.ts b/src/model/Team.ts
similarity index 100%
rename from front/model/Team.ts
rename to src/model/Team.ts
diff --git a/front/model/User.ts b/src/model/User.ts
similarity index 100%
rename from front/model/User.ts
rename to src/model/User.ts
diff --git a/front/model/tactic/Action.ts b/src/model/tactic/Action.ts
similarity index 100%
rename from front/model/tactic/Action.ts
rename to src/model/tactic/Action.ts
diff --git a/front/model/tactic/CourtObjects.ts b/src/model/tactic/CourtObjects.ts
similarity index 100%
rename from front/model/tactic/CourtObjects.ts
rename to src/model/tactic/CourtObjects.ts
diff --git a/front/model/tactic/Player.ts b/src/model/tactic/Player.ts
similarity index 100%
rename from front/model/tactic/Player.ts
rename to src/model/tactic/Player.ts
diff --git a/front/model/tactic/Tactic.ts b/src/model/tactic/Tactic.ts
similarity index 100%
rename from front/model/tactic/Tactic.ts
rename to src/model/tactic/Tactic.ts
diff --git a/src/pages/404.tsx b/src/pages/404.tsx
new file mode 100644
index 0000000..558b442
--- /dev/null
+++ b/src/pages/404.tsx
@@ -0,0 +1,11 @@
+import {useLocation} from "react-router-dom";
+import {BASE} from "../Constants.ts";
+export default function NotFoundPage() {
+
+ const target = useLocation()
+
+ return
+
{target.pathname} NOT FOUND !
+
+
+}
diff --git a/src/pages/CreateTeamPage.tsx b/src/pages/CreateTeamPage.tsx
new file mode 100644
index 0000000..daefb83
--- /dev/null
+++ b/src/pages/CreateTeamPage.tsx
@@ -0,0 +1,4 @@
+
+export default function CreateTeamPage() {
+ return Create Team Page
+}
\ No newline at end of file
diff --git a/front/views/Editor.tsx b/src/pages/Editor.tsx
similarity index 95%
rename from front/views/Editor.tsx
rename to src/pages/Editor.tsx
index 598f94a..15c9bfb 100644
--- a/front/views/Editor.tsx
+++ b/src/pages/Editor.tsx
@@ -28,7 +28,7 @@ import SavingState, {
} from "../components/editor/SavingState"
import { BALL_TYPE } from "../model/tactic/CourtObjects"
-import { CourtAction } from "./editor/CourtAction"
+import { CourtAction } from "../components/editor/CourtAction"
import { ActionPreview, BasketCourt } from "../components/editor/BasketCourt"
import { overlaps } from "../geo/Box"
import {
@@ -83,6 +83,20 @@ export interface EditorViewProps {
courtType: "PLAIN" | "HALF"
}
+
+export interface EditorPageProps {
+ courtType: "PLAIN" | "HALF"
+}
+
+export default function EditorPage({ courtType }: EditorPageProps) {
+ return
+}
+
export interface EditorProps {
id: number
name: string
@@ -90,7 +104,7 @@ export interface EditorProps {
courtType: "PLAIN" | "HALF"
}
-export default function Editor({ id, name, courtType, content }: EditorProps) {
+function Editor({ id, name, courtType, content }: EditorProps) {
const isInGuestMode = id == -1
const storage_content = localStorage.getItem(GUEST_MODE_CONTENT_STORAGE_KEY)
@@ -135,11 +149,11 @@ export default function Editor({ id, name, courtType, content }: EditorProps) {
}
function EditorView({
- tactic: { id, name, content: initialContent },
- onContentChange,
- onNameChange,
- courtType,
-}: EditorViewProps) {
+ tactic: { id, name, content: initialContent },
+ onContentChange,
+ onNameChange,
+ courtType,
+ }: EditorViewProps) {
const isInGuestMode = id == -1
const [titleStyle, setTitleStyle] = useState({})
@@ -520,12 +534,12 @@ interface PlayerRackProps {
}
function PlayerRack({
- id,
- objects,
- setObjects,
- courtRef,
- setComponents,
-}: PlayerRackProps) {
+ id,
+ objects,
+ setObjects,
+ courtRef,
+ setComponents,
+ }: PlayerRackProps) {
const courtBounds = useCallback(
() => courtRef.current!.getBoundingClientRect(),
[courtRef],
@@ -579,15 +593,15 @@ interface CourtPlayerArrowActionProps {
}
function CourtPlayerArrowAction({
- playerInfo,
- player,
- isInvalid,
-
- content,
- setContent,
- setPreviewAction,
- courtRef,
-}: CourtPlayerArrowActionProps) {
+ playerInfo,
+ player,
+ isInvalid,
+
+ content,
+ setContent,
+ setPreviewAction,
+ courtRef,
+ }: CourtPlayerArrowActionProps) {
const courtBounds = useCallback(
() => courtRef.current!.getBoundingClientRect(),
[courtRef],
@@ -754,4 +768,4 @@ function useContentState(
)
return [content, setContentSynced, savingState]
-}
+}
\ No newline at end of file
diff --git a/front/views/Home.tsx b/src/pages/Home.tsx
similarity index 95%
rename from front/views/Home.tsx
rename to src/pages/Home.tsx
index a9a4b0a..df27c11 100644
--- a/front/views/Home.tsx
+++ b/src/pages/Home.tsx
@@ -1,8 +1,8 @@
import "../style/home/home.css"
// import AccountSvg from "../assets/account.svg?react"
-import { Header } from "./template/Header"
-import { BASE } from "../Constants"
+import {Header} from "./template/Header"
+import {BASE} from "../Constants"
interface Tactic {
id: number
@@ -18,7 +18,14 @@ interface Team {
second_color: string
}
-export default function Home({
+
+export default function HomePage() {
+
+ console.log("HOME PAGE LOADED")
+ return
+}
+
+function Home({
lastTactics,
allTactics,
teams,
diff --git a/front/views/NewTacticPanel.tsx b/src/pages/NewTacticPage.tsx
similarity index 97%
rename from front/views/NewTacticPanel.tsx
rename to src/pages/NewTacticPage.tsx
index d02f314..2d056d8 100644
--- a/front/views/NewTacticPanel.tsx
+++ b/src/pages/NewTacticPage.tsx
@@ -5,7 +5,7 @@ import plainCourt from "../assets/court/full_court.svg"
import halfCourt from "../assets/court/half_court.svg"
import { BASE } from "../Constants"
-export default function NewTacticPanel() {
+export default function NewTacticPage() {
return (
diff --git a/front/views/TeamPanel.tsx b/src/pages/TeamPanel.tsx
similarity index 72%
rename from front/views/TeamPanel.tsx
rename to src/pages/TeamPanel.tsx
index 709d7f2..e0e2baa 100644
--- a/front/views/TeamPanel.tsx
+++ b/src/pages/TeamPanel.tsx
@@ -1,13 +1,25 @@
import "../style/team_panel.css"
-import { BASE } from "../Constants"
-import { Team, TeamInfo, Member } from "../model/Team"
-import { User } from "../model/User"
+import {BASE} from "../Constants"
+import {Member, Team, TeamInfo} from "../model/Team"
+import {useParams} from "react-router-dom";
-export default function TeamPanel({
- isCoach,
- team,
- currentUserId,
-}: {
+export default function TeamPanelPage() {
+ const {teamId} = useParams()
+ const teamInfo = {
+ id: parseInt(teamId!),
+ name: teamId!,
+ mainColor: "#FFFFFF",
+ secondColor: "#000000",
+ picture: "https://a.espncdn.com/combiner/i?img=/i/teamlogos/nba/500/lal.png"
+ }
+ return
+}
+
+function TeamPanel({
+ isCoach,
+ team,
+ currentUserId,
+ }: {
isCoach: boolean
team: Team
currentUserId: number
@@ -19,9 +31,9 @@ export default function TeamPanel({
IQBall
-
+
- {isCoach && }
+ {isCoach && }
{team.name}
-

+
@@ -46,19 +58,19 @@ function TeamDisplay({ team }: { team: TeamInfo }) {
Couleur secondaire
-
-
+
+
)
}
-function ColorDisplay({ color }: { color: string }) {
- return
+function ColorDisplay({color}: { color: string }) {
+ return
}
-function CoachOptions({ id }: { id: number }) {
+function CoachOptions({id}: { id: number }) {
return (