From 36051ebd830d81c0a67c0d9f05f5ed67b468aa43 Mon Sep 17 00:00:00 2001 From: Override-6 Date: Fri, 24 Nov 2023 01:59:08 +0100 Subject: [PATCH] good routes, good controllers --- .../assets/icon}/account.png | Bin .../assets/icon}/account.svg | 0 public/api/index.php | 31 +++--- public/index.php | 87 ++++++++++++++++- src/Controller/{Sub => }/AuthController.php | 3 +- src/Controller/{Sub => }/EditorController.php | 7 +- src/Controller/Route/Action.php | 71 ++++++++++++++ .../{ => Route}/FrontController.php | 80 +++------------- src/Controller/{Sub => }/TeamController.php | 31 +++--- src/Controller/UserController.php | 90 ++++-------------- src/Controller/VisitorController.php | 28 ------ .../{Sub => }/VisualizerController.php | 5 +- src/Data/Color.php | 3 - src/Views/add_member.html.twig | 2 +- src/Views/delete_member.html.twig | 2 +- src/Views/display_teams.html.twig | 4 +- src/Views/home.twig | 12 +-- src/Views/insert_team.html.twig | 2 +- src/Views/list_team_by_name.html.twig | 2 +- 19 files changed, 238 insertions(+), 222 deletions(-) rename {public/img/welcomePage => front/assets/icon}/account.png (100%) rename {public/img/welcomePage => front/assets/icon}/account.svg (100%) rename src/Controller/{Sub => }/AuthController.php (97%) rename src/Controller/{Sub => }/EditorController.php (87%) create mode 100644 src/Controller/Route/Action.php rename src/Controller/{ => Route}/FrontController.php (61%) rename src/Controller/{Sub => }/TeamController.php (68%) delete mode 100644 src/Controller/VisitorController.php rename src/Controller/{Sub => }/VisualizerController.php (90%) diff --git a/public/img/welcomePage/account.png b/front/assets/icon/account.png similarity index 100% rename from public/img/welcomePage/account.png rename to front/assets/icon/account.png diff --git a/public/img/welcomePage/account.svg b/front/assets/icon/account.svg similarity index 100% rename from public/img/welcomePage/account.svg rename to front/assets/icon/account.svg diff --git a/public/api/index.php b/public/api/index.php index c5f8f2e..cb278df 100644 --- a/public/api/index.php +++ b/public/api/index.php @@ -30,7 +30,8 @@ function getAuthController(): APIAuthController { /** * A Front controller action */ -class Action { +//TODO workaround for generic Action +class ApiAction { /** * @var callable(mixed[]): HttpResponse $action action to call */ @@ -69,18 +70,18 @@ class Action { /** * @param callable(mixed[]): HttpResponse $action - * @return Action an action that does not require to have an authorization. + * @return ApiAction an action that does not require to have an authorization. */ - public static function noAuth(callable $action): Action { - return new Action($action, false); + public static function noAuth(callable $action): ApiAction { + return new ApiAction($action, false); } /** * @param callable(mixed[]): HttpResponse $action - * @return Action an action that does require to have an authorization. + * @return ApiAction an action that does require to have an authorization. */ - public static function auth(callable $action): Action { - return new Action($action, true); + public static function auth(callable $action): ApiAction { + return new ApiAction($action, true); } } @@ -95,23 +96,23 @@ function handleMatch(array $match): HttpResponse { } $action = $match['target']; - if (!$action instanceof Action) { + if (!$action instanceof ApiAction) { throw new Exception("routed action is not an Action object."); } $auth = null; if ($action->isAuthRequired()) { - $auth = tryGetAuthAccount(); + $auth = tryGetAuthorization(); if ($auth == null) { - return new JsonHttpResponse([ValidationFail::unauthorized("Missing or invalid 'Authorization' header")]); + return new JsonHttpResponse([ValidationFail::unauthorized("Missing or invalid 'Authorization' header.")]); } } return $action->run($match['params'], $auth); } -function tryGetAuthAccount(): ?Account { +function tryGetAuthorization(): ?Account { $headers = getallheaders(); // If no authorization header is set, try fallback to php session. @@ -128,10 +129,10 @@ function tryGetAuthAccount(): ?Account { $router = new AltoRouter(); $router->setBasePath(get_public_path() . "/api"); -$router->map("POST", "/tactic/[i:id]/edit/name", Action::auth(fn(int $id, Account $acc) => getTacticController()->updateName($id, $acc))); -$router->map("GET", "/tactic/[i:id]", Action::auth(fn(int $id, Account $acc) => getTacticController()->getTacticInfo($id, $acc))); -$router->map("POST", "/tactic/new", Action::auth(fn(Account $acc) => getTacticController()->newTactic($acc))); -$router->map("POST", "/auth", Action::noAuth(fn() => getAuthController()->authorize())); +$router->map("POST", "/tactic/[i:id]/edit/name", ApiAction::auth(fn(int $id, Account $acc) => getTacticController()->updateName($id, $acc))); +$router->map("GET", "/tactic/[i:id]", ApiAction::auth(fn(int $id, Account $acc) => getTacticController()->getTacticInfo($id, $acc))); +$router->map("POST", "/tactic/new", ApiAction::auth(fn(Account $acc) => getTacticController()->newTactic($acc))); +$router->map("POST", "/auth", ApiAction::noAuth(fn() => getAuthController()->authorize())); $match = $router->match(); diff --git a/public/index.php b/public/index.php index d8dd098..8d1f148 100644 --- a/public/index.php +++ b/public/index.php @@ -7,12 +7,93 @@ require "../sql/database.php"; require "utils.php"; require "../src/react-display.php"; -use App\Controller\FrontController; +use App\Controller\AuthController; +use App\Controller\EditorController; +use App\Controller\Route\Action; +use App\Controller\Route\FrontController; +use App\Controller\TeamController; +use App\Controller\UserController; +use App\Controller\VisualizerController; +use App\Gateway\AccountGateway; +use App\Gateway\TacticInfoGateway; +use App\Gateway\TeamGateway; +use App\Model\AuthModel; +use App\Model\TacticModel; +use App\Model\TeamModel; +use App\Session\MutableSessionHandle; use App\Session\PhpSessionHandle; +use App\Connexion; +use App\Session\SessionHandle; +$connexion = new Connexion(get_database()); + +function getUserController(): UserController { + global $connexion; + return new UserController(new TacticModel(new TacticInfoGateway($connexion))); +} + +function getVisualizerController(): VisualizerController { + global $connexion; + return new VisualizerController(new TacticModel(new TacticInfoGateway($connexion))); +} + +function getEditorController(): EditorController { + global $connexion; + return new EditorController(new TacticModel(new TacticInfoGateway($connexion))); +} + +function getTeamController(): TeamController { + global $connexion; + return new TeamController(new TeamModel(new TeamGateway($connexion))); +} + +function getAuthController(): AuthController { + global $connexion; + return new AuthController(new AuthModel(new AccountGateway($connexion))); +} + +function initFrontController(FrontController $fc) { + //authentication + $fc->addRoute("GET", "/login", Action::noAuth(fn() => getAuthController()->displayLogin())); + $fc->addRoute("GET", "/register", Action::noAuth(fn() => getAuthController()->displayRegister())); + $fc->addRoute("POST", "/login", Action::noAuth(fn(SessionHandle $s) => getAuthController()->confirmLogin($_POST, $s))); + $fc->addRoute("POST", "/register", Action::noAuth(fn(SessionHandle $s) => getAuthController()->confirmRegister($_POST, $s))); + + //user-related + $fc->addRoute("GET", "/home", Action::auth(fn(SessionHandle $s) => getUserController()->home($s))); + $fc->addRoute("GET", "/settings", Action::auth(fn(SessionHandle $s) => getUserController()->settings($s))); + + //tactic-related + $fc->addRoute("GET", "/tactic/[i:id]/view", Action::auth(fn(int $id, SessionHandle $s) => getVisualizerController()->visualize($id, $s))); + $fc->addRoute("GET", "/tactic/[i:id]/edit", Action::auth(fn(int $id, SessionHandle $s) => getEditorController()->edit($id, $s))); + $fc->addRoute("GET", "/tactic/new", Action::auth(fn(SessionHandle $s) => getEditorController()->createNew($s))); + + //team-related + $fc->addRoute("GET", "/team/new", Action::auth(fn(SessionHandle $s) => getTeamController()->displayCreateTeam($s))); + $fc->addRoute("POST", "/team/new", Action::auth(fn(SessionHandle $s) => getTeamController()->submitTeam($_POST, $s))); + $fc->addRoute("GET", "/team/search", Action::auth(fn(SessionHandle $s) => getTeamController()->displayListTeamByName($s))); + $fc->addRoute("POST", "/team/search", Action::auth(fn(SessionHandle $s) => getTeamController()->listTeamByName($_POST, $s))); + $fc->addRoute("GET", "/team/[i:id]", Action::auth(fn(int $id, SessionHandle $s) => getTeamController()->displayTeam($id, $s))); + $fc->addRoute("GET", "/team/members/add", Action::auth(fn(SessionHandle $s) => getTeamController()->displayAddMember($s))); + $fc->addRoute("POST", "/team/members/add", Action::auth(fn(SessionHandle $s) => getTeamController()->addMember($_POST, $s))); + $fc->addRoute("GET", "/team/members/remove", Action::auth(fn(SessionHandle $s) => getTeamController()->displayDeleteMember($s))); + $fc->addRoute("POST", "/team/members/remove", Action::auth(fn(SessionHandle $s) => getTeamController()->deleteMember($_POST, $s))); +} + +//this is a global variable $basePath = get_public_path(); -$frontController = new FrontController($basePath); -$frontController->run(PhpSessionHandle::init()); +function run() { + global $basePath; + + $fc = new FrontController($basePath); + + initFrontController($fc); + $fc->run(PhpSessionHandle::init()); +} + + +run(); + diff --git a/src/Controller/Sub/AuthController.php b/src/Controller/AuthController.php similarity index 97% rename from src/Controller/Sub/AuthController.php rename to src/Controller/AuthController.php index 709be3e..0ee9a46 100644 --- a/src/Controller/Sub/AuthController.php +++ b/src/Controller/AuthController.php @@ -1,13 +1,12 @@ action = $action; + $this->isAuthRequired = $isAuthRequired; + } + + public function isAuthRequired(): bool { + return $this->isAuthRequired; + } + + /** + * @param mixed[] $params + * @param SessionHandle $session + * @return HttpResponse + * @throws Exception

+ * thrown if this action is required to be authenticated, but the given session does not contain a logged-in account. + *

+ *

+ * Caller is supposed to ensure that the user is logged-in before, if `$this->isAuthRequired()` is true before + * running this action. + *

+ */ + public function run(array $params, SessionHandle $session): HttpResponse { + $params = array_values($params); + if ($this->isAuthRequired) { + if ($session->getAccount() == null) { + throw new Exception("action requires authorization."); + } + } + + $params[] = $session; + return call_user_func_array($this->action, $params); + } + + /** + * @param callable(mixed[]): 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, false); + } + + /** + * @param callable(mixed[]): HttpResponse $action + * @return Action an action that does require to have an authorization. + */ + public static function auth(callable $action): Action { + return new Action($action, true); + } +} \ No newline at end of file diff --git a/src/Controller/FrontController.php b/src/Controller/Route/FrontController.php similarity index 61% rename from src/Controller/FrontController.php rename to src/Controller/Route/FrontController.php index d02bcbc..05b440e 100644 --- a/src/Controller/FrontController.php +++ b/src/Controller/Route/FrontController.php @@ -1,6 +1,6 @@ router = $this->createRouter($basePath); - $this->initializeRouterMap(); $this->basePath = $basePath; } + public function addRoute(string $method, string $path, Action $action): void { + $this->router->map($method, $path, $action); + } + /** * @param MutableSessionHandle $session * @return void @@ -61,85 +60,36 @@ class FrontController { return $router; } - /** - * Initialize project's routes - * - * @return void - */ - private function initializeRouterMap(): void { - $this->router->map("GET", "/home", self::USER_CONTROLLER); - $this->router->map("GET|POST", "/user/[a:action]/[i:idTactic]?", self::USER_CONTROLLER); - $this->router->map("GET|POST", "/visitor/[a:action]", self::VISITOR_CONTROLLER); - } - /** * @param array $match * @param MutableSessionHandle $session * @return void */ private function handleMatch(array $match, MutableSessionHandle $session): void { - $tag = $match['target']; - - $action = $this->getAction($match); - $params = $match["params"]; - unset($params['action']); - $this->handleResponseByType($this->tryToCall($tag, $action, array_values($params), $session)); + $action = $match['target']; + $params = array_values($match["params"]); + $this->handleResponseByType($this->tryToCall($action, $params, $session)); } /** - * @param string $controllerName - * @param string $action + * @param Action $action * @param array $params * @param MutableSessionHandle $session * @return HttpResponse */ - private function tryToCall(string $controllerName, string $action, array $params, MutableSessionHandle $session): HttpResponse { - if ($controllerName != self::VISITOR_CONTROLLER) { + private function tryToCall(Action $action, array $params, MutableSessionHandle $session): HttpResponse { + $account = null; + if ($action->isAuthRequired()) { $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::redirect($this->basePath . "/visitor/login"); + return HttpResponse::redirect($this->basePath . "/login"); } } - $controller = $this->getController($controllerName); - - if (is_callable([$controller, $action])) { - // append the session as the last parameter of a controller function - $params[] = $session; - return call_user_func_array([$controller, $action], $params); - } else { - return ViewHttpResponse::twig("error.html.twig", [ - 'failures' => [ValidationFail::notFound("Could not find page ${_SERVER['REQUEST_URI']}.")], - ], HttpCodes::NOT_FOUND); - } - } - - /** - * Get the right method to call to do an action - * - * @param array $match - * @return string - */ - private function getAction(array $match): string { - if (isset($match["params"]["action"])) { - return $match["params"]["action"]; - } - return "home"; - } - - /** - * Initialize the right controller by the user's role - * - * @param string $controller - * @return mixed - */ - private function getController(string $controller) { - $namespace = "\\App\\Controller\\"; - $controller = $namespace . $controller; - return new $controller(); + return $action->run($params, $session); } /** @@ -182,7 +132,7 @@ class FrontController { $loader = new FilesystemLoader('../src/Views/'); $twig = new Environment($loader); $twig->display($file, $args); - } catch (RuntimeError | SyntaxError | LoaderError $e) { + } 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; diff --git a/src/Controller/Sub/TeamController.php b/src/Controller/TeamController.php similarity index 68% rename from src/Controller/Sub/TeamController.php rename to src/Controller/TeamController.php index adefa41..6edb847 100644 --- a/src/Controller/Sub/TeamController.php +++ b/src/Controller/TeamController.php @@ -1,11 +1,12 @@ model = $model; } - public function displaySubmitTeam(): HttpResponse { + public function displayCreateTeam(SessionHandle $session): HttpResponse { return ViewHttpResponse::twig("insert_team.html.twig", []); } - public function displayAddMember() : HttpResponse { + public function displayAddMember(SessionHandle $session): HttpResponse { return ViewHttpResponse::twig("add_member.html.twig", []); } - public function displayDeleteMember() : HttpResponse { + public function displayDeleteMember(SessionHandle $session): HttpResponse { return ViewHttpResponse::twig("delete_member.html.twig", []); } - public function submitTeam(array $request): HttpResponse { + public function submitTeam(array $request, SessionHandle $session): HttpResponse { $errors = []; @@ -51,10 +52,10 @@ class TeamController { } return ViewHttpResponse::twig('insert_team.html.twig', ['bad_fields' => $badFields]); } - return $this->getTeam($this->model->createTeam($request['name'], $request['picture'], $request['mainColor'], $request['secondColor'])); + return $this->displayTeam($this->model->createTeam($request['name'], $request['picture'], $request['mainColor'], $request['secondColor']), $session); } - public function displayListTeamByName(): HttpResponse { + public function displayListTeamByName(SessionHandle $session): HttpResponse { return ViewHttpResponse::twig("list_team_by_name.html.twig", []); } @@ -62,7 +63,7 @@ class TeamController { * @param array $request * @return HttpResponse */ - public function listTeamByName(array $request): HttpResponse { + public function listTeamByName(array $request, SessionHandle $session): HttpResponse { $errors = []; $request = HttpRequest::from($request, $errors, [ "name" => [Validators::lenBetween(1, 32), Validators::nameWithSpaces()], @@ -82,30 +83,30 @@ class TeamController { return ViewHttpResponse::twig('display_teams.html.twig', ['teams' => $results]); } - public function getTeam(int $id): HttpResponse { + public function displayTeam(int $id, SessionHandle $session): HttpResponse { $result = $this->model->displayTeam($id); return ViewHttpResponse::twig('display_team.html.twig', ['team' => $result]); } - public function addMember(array $request) : HttpResponse { + public function addMember(array $request, SessionHandle $session): HttpResponse { $errors = []; $request = HttpRequest::from($request, $errors, [ "team" => [Validators::isInteger()], - "mail" => [Validators::regex("/^\\S+@\\S+\\.\\S+$/"),Validators::lenBetween(5, 256)] + "mail" => [Validators::regex("/^\\S+@\\S+\\.\\S+$/"), Validators::lenBetween(5, 256)] ]); - return $this->getTeam($this->model->addMember($request['mail'], intval($request['team']), $request['role'])); + return $this->displayTeam($this->model->addMember($request['mail'], intval($request['team']), $request['role']), $session); } - public function deleteMember(array $request) : HttpResponse { + public function deleteMember(array $request, SessionHandle $session): HttpResponse { $errors = []; $request = HttpRequest::from($request, $errors, [ "team" => [Validators::isInteger()], - "mail" => [Validators::regex("/^\\S+@\\S+\\.\\S+$/"),Validators::lenBetween(5, 256)] + "mail" => [Validators::regex("/^\\S+@\\S+\\.\\S+$/"), Validators::lenBetween(5, 256)] ]); - return $this->getTeam($this->model->deleteMember($request['mail'], intval($request['team']))); + return $this->displayTeam($this->model->deleteMember($request['mail'], intval($request['team'])), $session); } } diff --git a/src/Controller/UserController.php b/src/Controller/UserController.php index 51b6d97..3868aa4 100644 --- a/src/Controller/UserController.php +++ b/src/Controller/UserController.php @@ -3,86 +3,38 @@ namespace App\Controller; use App\Connexion; -use App\Controller\Sub\EditorController; use App\Gateway\TacticInfoGateway; -use App\Gateway\TeamGateway; use App\Http\HttpResponse; use App\Http\ViewHttpResponse; use App\Model\TacticModel; -use App\Model\TeamModel; use App\Session\SessionHandle; -class UserController extends VisitorController { - public function home(): HttpResponse { - $model = new TacticModel(new TacticInfoGateway(new Connexion(get_database()))); - $listTactic = $model->getLast(5); - return ViewHttpResponse::twig("home.twig", ["recentTactic" => $listTactic]); - } - - public function settings(): HttpResponse { - return ViewHttpResponse::twig("account_settings.twig", []); - } - - public function view(int $id, SessionHandle $session): HttpResponse { - $model = new TacticModel(new TacticInfoGateway(new Connexion(get_database()))); - return (new Sub\VisualizerController($model))->visualize($id, $session); - } - - public function edit(int $id, SessionHandle $session): HttpResponse { - $model = new TacticModel(new TacticInfoGateway(new Connexion(get_database()))); - return (new EditorController($model))->edit($id, $session); - } +class UserController { - public function create(SessionHandle $session): HttpResponse { - $model = new TacticModel(new TacticInfoGateway(new Connexion(get_database()))); - return (new EditorController($model))->createNew($session); - } - - public function open(int $id, SessionHandle $session): HttpResponse { - $model = new TacticModel(new TacticInfoGateway(new Connexion(get_database()))); - return (new Sub\VisualizerController($model))->visualize($id, $session); - } - - public function createTeam(): HttpResponse { - $model = new TeamModel(new TeamGateway(new Connexion(get_database()))); - $ctrl = new Sub\TeamController($model); - if ($_SERVER['REQUEST_METHOD'] === 'GET') { - return $ctrl->displaySubmitTeam(); - } - return $ctrl->submitTeam($_POST); - } + private TacticModel $tactics; - public function listTeams(): HttpResponse { - $model = new TeamModel(new TeamGateway(new Connexion(get_database()))); - $ctrl = new Sub\TeamController($model); - if ($_SERVER['REQUEST_METHOD'] === 'GET') { - return $ctrl->displayListTeamByName(); - } - return $ctrl->listTeamByName($_POST); + /** + * @param TacticModel $tactics + */ + public function __construct(TacticModel $tactics) { + $this->tactics = $tactics; } - public function getTeam(int $id): HttpResponse { - $model = new TeamModel(new TeamGateway(new Connexion(get_database()))); - $ctrl = new Sub\TeamController($model); - return $ctrl->getTeam($id); - } - - public function addMember(): HttpResponse { - $model = new TeamModel(new TeamGateway(new Connexion(get_database()))); - $ctrl = new Sub\TeamController($model); - if ($_SERVER['REQUEST_METHOD'] === 'GET') { - return $ctrl->displayAddMember($_POST); - } - return $ctrl->addMember($_POST); + /** + * @param SessionHandle $session + * @return HttpResponse the home page + */ + public function home(SessionHandle $session): HttpResponse { + //TODO use session's account to get the last 5 tactics if the logged-in account + $listTactic = $this->tactics->getLast(5); + return ViewHttpResponse::twig("home.twig", ["recentTactic" => $listTactic]); } - public function deleteMember(): HttpResponse { - $model = new TeamModel(new TeamGateway(new Connexion(get_database()))); - $ctrl = new Sub\TeamController($model); - if ($_SERVER['REQUEST_METHOD'] === 'GET') { - return $ctrl->displayDeleteMember($_POST); - } - return $ctrl->deleteMember($_POST); + /** + * @return HttpResponse account settings page + */ + public function settings(SessionHandle $session): HttpResponse { + return ViewHttpResponse::twig("account_settings.twig", []); } -} +} \ No newline at end of file diff --git a/src/Controller/VisitorController.php b/src/Controller/VisitorController.php deleted file mode 100644 index e74934a..0000000 --- a/src/Controller/VisitorController.php +++ /dev/null @@ -1,28 +0,0 @@ -displayRegister(); - } - return (new Sub\AuthController($model))->confirmRegister($_POST, $session); - } - - final public function login(MutableSessionHandle $session): HttpResponse { - $model = new AuthModel(new AccountGateway(new Connexion(get_database()))); - if ($_SERVER['REQUEST_METHOD'] === 'GET') { - return (new Sub\AuthController($model))->displayLogin(); - } - return (new Sub\AuthController($model))->confirmLogin($_POST, $session); - } - -} diff --git a/src/Controller/Sub/VisualizerController.php b/src/Controller/VisualizerController.php similarity index 90% rename from src/Controller/Sub/VisualizerController.php rename to src/Controller/VisualizerController.php index c7e5098..9b971c6 100644 --- a/src/Controller/Sub/VisualizerController.php +++ b/src/Controller/VisualizerController.php @@ -1,14 +1,12 @@ tacticModel = $tacticModel; } diff --git a/src/Data/Color.php b/src/Data/Color.php index b12e27a..b2da83b 100755 --- a/src/Data/Color.php +++ b/src/Data/Color.php @@ -16,9 +16,6 @@ class Color { */ private function __construct(string $value) { - if ($value < 0 || $value > 0xFFFFFF) { - throw new InvalidArgumentException("int color value is invalid, must be positive and lower than 0xFFFFFF"); - } $this->hex = $value; } diff --git a/src/Views/add_member.html.twig b/src/Views/add_member.html.twig index ef74da2..6c5a3e3 100644 --- a/src/Views/add_member.html.twig +++ b/src/Views/add_member.html.twig @@ -73,7 +73,7 @@

Ajouter un membre à votre équipe

-
+
diff --git a/src/Views/delete_member.html.twig b/src/Views/delete_member.html.twig index a478284..b7d0d3b 100644 --- a/src/Views/delete_member.html.twig +++ b/src/Views/delete_member.html.twig @@ -56,7 +56,7 @@

Supprimez un membre de votre équipe

- +
diff --git a/src/Views/display_teams.html.twig b/src/Views/display_teams.html.twig index bf89909..e4da64e 100644 --- a/src/Views/display_teams.html.twig +++ b/src/Views/display_teams.html.twig @@ -10,7 +10,7 @@

Aucune équipe n'a été trouvée

Chercher une équipe

- +
@@ -22,7 +22,7 @@
{% else %} {% for t in teams %} -
+

Nom de l'équipe : {{ t.name }}

logo de l'équipe
diff --git a/src/Views/home.twig b/src/Views/home.twig index 35379ce..29d228a 100644 --- a/src/Views/home.twig +++ b/src/Views/home.twig @@ -52,9 +52,9 @@

IQ Ball

-
+
Account logo

Mon profil

@@ -63,7 +63,7 @@

Mes équipes

- + {% if recentTeam != null %} {% for team in recentTeam %} @@ -77,13 +77,13 @@

Mes strategies

- + {% if recentTactic != null %} {% for tactic in recentTactic %} -
+

{{tactic.id}} - {{tactic.name}} - {{tactic.creation_date}}

- +
{% endfor %} {% else %} diff --git a/src/Views/insert_team.html.twig b/src/Views/insert_team.html.twig index 0fc59ca..0cc85dd 100644 --- a/src/Views/insert_team.html.twig +++ b/src/Views/insert_team.html.twig @@ -64,7 +64,7 @@

Créer une équipe

- +
diff --git a/src/Views/list_team_by_name.html.twig b/src/Views/list_team_by_name.html.twig index 0ea1905..09768e6 100644 --- a/src/Views/list_team_by_name.html.twig +++ b/src/Views/list_team_by_name.html.twig @@ -62,7 +62,7 @@

Chercher une équipe

- +