From ae8ec4823a9a744fb90dd38c0f44ef562b48c165 Mon Sep 17 00:00:00 2001 From: ghost Date: Tue, 3 Oct 2023 22:35:13 +0300 Subject: [PATCH] implement profile page #17 --- .env | 2 +- public/asset/default/css/common.css | 2 +- public/asset/default/css/framework.css | 22 ++- src/Controller/DashboardController.php | 33 ++++ src/Controller/HomeController.php | 20 -- src/Controller/PageController.php | 5 + src/Controller/ProfileController.php | 76 ------- src/Controller/UserController.php | 161 +++++++++++++++ src/Entity/User.php | 68 +++---- src/Repository/UserRepository.php | 41 ++-- src/Service/User.php | 12 -- src/Service/UserService.php | 63 ++++++ .../{home => dashboard}/index.html.twig | 0 templates/default/layout.html.twig | 6 +- templates/default/profile/index.html.twig | 2 - templates/default/profile/module.html.twig | 178 ----------------- templates/default/profile/setting.html.twig | 2 - templates/default/user/info.html.twig | 92 +++++++++ templates/default/user/module.html.twig | 186 ++++++++++++++++++ templates/default/user/profile.html.twig | 105 ++++++++++ templates/redirect/index.html.twig | 20 ++ 21 files changed, 736 insertions(+), 360 deletions(-) create mode 100644 src/Controller/DashboardController.php delete mode 100644 src/Controller/HomeController.php delete mode 100644 src/Controller/ProfileController.php create mode 100644 src/Controller/UserController.php delete mode 100644 src/Service/User.php create mode 100644 src/Service/UserService.php rename templates/default/{home => dashboard}/index.html.twig (100%) delete mode 100644 templates/default/profile/index.html.twig delete mode 100644 templates/default/profile/module.html.twig delete mode 100644 templates/default/profile/setting.html.twig create mode 100644 templates/default/user/info.html.twig create mode 100644 templates/default/user/module.html.twig create mode 100644 templates/default/user/profile.html.twig create mode 100644 templates/redirect/index.html.twig diff --git a/.env b/.env index 082bfb8..618d0fe 100644 --- a/.env +++ b/.env @@ -50,4 +50,4 @@ APP_VERSION='2.0.0' APP_NAME=YGGtracker APP_LOCALE=en -APP_LOCALES=en|uk +APP_LOCALES=en|uk \ No newline at end of file diff --git a/public/asset/default/css/common.css b/public/asset/default/css/common.css index 8f07131..cb5d2ff 100644 --- a/public/asset/default/css/common.css +++ b/public/asset/default/css/common.css @@ -54,7 +54,7 @@ textarea { color: #ccc; border: 0; border-radius: 3px; - padding: 6px 8px; + padding: 8px; font-size: 13px; } diff --git a/public/asset/default/css/framework.css b/public/asset/default/css/framework.css index 65e4289..21368cb 100644 --- a/public/asset/default/css/framework.css +++ b/public/asset/default/css/framework.css @@ -118,6 +118,10 @@ a.label-green:hover { position: fixed; } +.position-absolute { + position: absolute; +} + .vertical-align-middle { vertical-align: middle; } @@ -170,7 +174,7 @@ a.label-green:hover { border-top: 1px #5d627d solid; } -.border-width-2 { +.border-width-2-px { border-width: 2px; } @@ -299,6 +303,10 @@ a:visited.background-color-hover-night-light:hover { padding: 16px; } +.padding-24-px { + padding: 24px; +} + .margin-l-4-px { margin-left: 4px; } @@ -328,6 +336,10 @@ a:visited.background-color-hover-night-light:hover { margin-left: 12px; } +.margin-l-96-px { + margin-left: 96px; +} + .margin-l--196-px { margin-left: -196px; } @@ -366,6 +378,10 @@ a:visited.background-color-hover-night-light:hover { display: block; } +.display-flex { + display: flex; +} + .opacity-0 { opacity: 0; } @@ -410,6 +426,10 @@ a:visited.background-color-hover-night-light:hover { width: 80%; } +.width-80-px { + width: 80px; +} + .width-180-px { width: 180px; } diff --git a/src/Controller/DashboardController.php b/src/Controller/DashboardController.php new file mode 100644 index 0000000..13ba30a --- /dev/null +++ b/src/Controller/DashboardController.php @@ -0,0 +1,33 @@ +redirectToRoute( + 'dashboard_index', + [ + '_locale' => 'en' + ] + ); + } + + #[Route( + '/{_locale}', + name: 'dashboard_index' + )] + public function index(Request $request): Response + { + return $this->render( + 'default/dashboard/index.html.twig' + ); + } +} \ No newline at end of file diff --git a/src/Controller/HomeController.php b/src/Controller/HomeController.php deleted file mode 100644 index ee38aa2..0000000 --- a/src/Controller/HomeController.php +++ /dev/null @@ -1,20 +0,0 @@ -render('default/home/index.html.twig'); - } -} \ No newline at end of file diff --git a/src/Controller/PageController.php b/src/Controller/PageController.php index 7c45a43..8499718 100644 --- a/src/Controller/PageController.php +++ b/src/Controller/PageController.php @@ -15,6 +15,11 @@ class PageController extends AbstractController )] public function submit(): Response { + /* + return $this->redirectToRoute('page', [ + 'id' => $page->getId() + ]); + */ return $this->render('default/page/submit.html.twig', [ // @TODO ]); diff --git a/src/Controller/ProfileController.php b/src/Controller/ProfileController.php deleted file mode 100644 index c8a3b80..0000000 --- a/src/Controller/ProfileController.php +++ /dev/null @@ -1,76 +0,0 @@ -render( - 'default/profile/index.html.twig', - [ - 'user' => $user->init($request->getClientIp()) - ] - ); - } - - #[Route( - '/{_locale}/profile/setting', - name: 'profile_setting' - )] - public function setting(): Response - { - // @TODO - return $this->render( - 'default/profile/setting.html.twig' - ); - } - - public function module(string $route = ''): Response - { - return $this->render( - 'default/profile/module.html.twig', - [ - 'route' => $route, - 'stars' => 0, - 'views' => 0, - 'comments' => 0, - 'downloads' => 0, - 'editions' => 0, - 'identicon' => $this->_getIdenticon( - '@TODO', - 17, - [ - 'backgroundColor' => 'rgba(255, 255, 255, 0)', - ] - ) - ] - ); - } - - private function _getIdenticon( - mixed $id, - int $size, - array $style, - string $format = 'webp') : string - { - $identicon = new \Jdenticon\Identicon(); - - $identicon->setValue($id); - $identicon->setSize($size); - $identicon->setStyle($style); - - return $identicon->getImageDataUri($format); - } -} \ No newline at end of file diff --git a/src/Controller/UserController.php b/src/Controller/UserController.php new file mode 100644 index 0000000..c0b81ec --- /dev/null +++ b/src/Controller/UserController.php @@ -0,0 +1,161 @@ + '%app.locale%' + ], + requirements: [ + '_locale' => '%app.locales%', + ], + )] + public function profile( + Request $request, + UserService $userService, + TimeService $timeService): Response + { + // Init user + $user = $userService->init( + $request->getClientIp() + ); + + // Process post request + if ($request->isMethod('post')) + { + // Update locale + if (in_array($request->get('locale'), explode('|', $this->getParameter('app.locales')))) + { + $user->setLocale( + $request->get('locale') + ); + } + + // Update locales + if ($request->get('locales')) + { + $user->setLocales( + $request->get('locales') + ); + } + + // Save changes to DB + $userService->save($user); + } + + // Generate identicon + $identicon = new \Jdenticon\Identicon(); + + $identicon->setValue($user->getAddress()); + $identicon->setSize(48); + $identicon->setStyle( + [ + 'backgroundColor' => 'rgba(255, 255, 255, 0)', + 'padding' => 0 + ] + ); + + // Render template + return $this->render( + 'default/user/profile.html.twig', + [ + 'user' => [ + 'id' => $user->getId(), + 'address' => $request->getClientIp() == $user->getAddress() ? $user->getAddress() : false, + 'moderator' => $user->isModerator(), + 'approved' => $user->isApproved(), + 'status' => $user->isStatus(), + 'locale' => $user->getLocale(), + 'locales' => $user->getLocales(), + 'added' => $timeService->ago( + $user->getAdded() + ), + 'identicon' => $identicon->getImageDataUri('webp'), + ], + 'locales' => explode('|', $this->getParameter('app.locales')) + ] + ); + } + + #[Route( + '/{_locale}/user/{id}', + name: 'user_info', + defaults: [ + '_locale' => '%app.locale%' + ], + requirements: [ + '_locale' => '%app.locales%', + ], + )] + public function info( + int $id, + Request $request, + UserService $userService, + TimeService $timeService): Response + { + // Init user + if (!$user = $userService->get($id)) + { + throw $this->createNotFoundException(); + } + + // Generate identicon + $identicon = new \Jdenticon\Identicon(); + + $identicon->setValue($user->getAddress()); + $identicon->setSize(48); + $identicon->setStyle( + [ + 'backgroundColor' => 'rgba(255, 255, 255, 0)', + 'padding' => 0 + ] + ); + + // Render template + return $this->render( + 'default/user/info.html.twig', + [ + 'user' => [ + 'id' => $user->getId(), + 'address' => $request->getClientIp() == $user->getAddress() ? $user->getAddress() : false, + 'moderator' => $user->isModerator(), + 'approved' => $user->isApproved(), + 'status' => $user->isStatus(), + 'locale' => $user->getLocale(), + 'locales' => $user->getLocales(), + 'added' => $timeService->ago( + $user->getAdded() + ), + 'identicon' => $identicon->getImageDataUri('webp'), + ] + ] + ); + } + + public function module(string $route = ''): Response + { + return $this->render( + 'default/user/module.html.twig', + [ + 'route' => $route, + 'stars' => 0, + 'views' => 0, + 'comments' => 0, + 'downloads' => 0, + 'editions' => 0, + ] + ); + } +} \ No newline at end of file diff --git a/src/Entity/User.php b/src/Entity/User.php index cf631a7..fba0937 100644 --- a/src/Entity/User.php +++ b/src/Entity/User.php @@ -3,6 +3,7 @@ namespace App\Entity; use App\Repository\UserRepository; +use Doctrine\DBAL\Types\Types; use Doctrine\ORM\Mapping as ORM; #[ORM\Entity(repositoryClass: UserRepository::class)] @@ -19,15 +20,6 @@ class User #[ORM\Column] private ?int $added = null; - #[ORM\Column] - private ?int $updated = null; - - #[ORM\Column] - private ?int $visited = null; - - #[ORM\Column] - private ?bool $public = null; - #[ORM\Column] private ?bool $moderator = null; @@ -37,6 +29,12 @@ class User #[ORM\Column] private ?bool $status = null; + #[ORM\Column(length: 2)] + private ?string $locale = null; + + #[ORM\Column(type: Types::ARRAY)] + private array $locales = []; + public function getId(): ?int { return $this->id; @@ -73,74 +71,62 @@ class User return $this; } - public function getUpdated(): ?int - { - return $this->updated; - } - - public function setUpdated(int $updated): static - { - $this->updated = $updated; - - return $this; - } - - public function getVisited(): ?int + public function isModerator(): ?bool { - return $this->visited; + return $this->moderator; } - public function setVisited(int $visited): static + public function setModerator(bool $moderator): static { - $this->visited = $visited; + $this->moderator = $moderator; return $this; } - public function isPublic(): ?bool + public function isApproved(): ?bool { - return $this->public; + return $this->approved; } - public function setPublic(bool $public): static + public function setApproved(bool $approved): static { - $this->public = $public; + $this->approved = $approved; return $this; } - public function isModerator(): ?bool + public function isStatus(): ?bool { - return $this->moderator; + return $this->status; } - public function setModerator(bool $moderator): static + public function setStatus(bool $status): static { - $this->moderator = $moderator; + $this->status = $status; return $this; } - public function isApproved(): ?bool + public function getLocale(): ?string { - return $this->approved; + return $this->locale; } - public function setApproved(bool $approved): static + public function setLocale(string $locale): static { - $this->approved = $approved; + $this->locale = $locale; return $this; } - public function isStatus(): ?bool + public function getLocales(): array { - return $this->status; + return $this->locales; } - public function setStatus(bool $status): static + public function setLocales(array $locales): static { - $this->status = $status; + $this->locales = $locales; return $this; } diff --git a/src/Repository/UserRepository.php b/src/Repository/UserRepository.php index 3767526..49896f3 100644 --- a/src/Repository/UserRepository.php +++ b/src/Repository/UserRepository.php @@ -21,28 +21,23 @@ class UserRepository extends ServiceEntityRepository parent::__construct($registry, User::class); } -// /** -// * @return User[] Returns an array of User objects -// */ -// public function findByExampleField($value): array -// { -// return $this->createQueryBuilder('u') -// ->andWhere('u.exampleField = :val') -// ->setParameter('val', $value) -// ->orderBy('u.id', 'ASC') -// ->setMaxResults(10) -// ->getQuery() -// ->getResult() -// ; -// } + public function findOneByIdField(int $id): ?User + { + return $this->createQueryBuilder('u') + ->where('u.id = :id') + ->setParameter('id', $id) + ->getQuery() + ->getOneOrNullResult() + ; + } -// public function findOneBySomeField($value): ?User -// { -// return $this->createQueryBuilder('u') -// ->andWhere('u.exampleField = :val') -// ->setParameter('val', $value) -// ->getQuery() -// ->getOneOrNullResult() -// ; -// } + public function findOneByAddressField(string $address): ?User + { + return $this->createQueryBuilder('u') + ->where('u.address = :address') + ->setParameter('address', $address) + ->getQuery() + ->getOneOrNullResult() + ; + } } diff --git a/src/Service/User.php b/src/Service/User.php deleted file mode 100644 index 98890e0..0000000 --- a/src/Service/User.php +++ /dev/null @@ -1,12 +0,0 @@ -entityManager = $entityManager; + $this->userRepository = $entityManager->getRepository(User::class); + $this->parameterBagInterface = $parameterBagInterface; + } + + public function init(string $address): User + { + // Return existing user + if ($result = $this->userRepository->findOneByAddressField($address)) + { + return $result; + } + + // Create new user + $user = new User(); + + $user->setAddress($address); + $user->setAdded(time()); + $user->setApproved(false); + $user->setModerator(false); + $user->setStatus(true); + $user->setLocale( + $this->parameterBagInterface->get('app.locale') + ); + $user->setLocales( + explode('|', $this->parameterBagInterface->get('app.locales')) + ); + + $this->save($user); + + // Return user data + return $user; + } + + public function get(int $id): ?User + { + return $this->userRepository->findOneByIdField($id); + } + + public function save(User $user) : void + { + $this->entityManager->persist($user); + $this->entityManager->flush(); + } +} \ No newline at end of file diff --git a/templates/default/home/index.html.twig b/templates/default/dashboard/index.html.twig similarity index 100% rename from templates/default/home/index.html.twig rename to templates/default/dashboard/index.html.twig diff --git a/templates/default/layout.html.twig b/templates/default/layout.html.twig index 1227001..11a0a05 100644 --- a/templates/default/layout.html.twig +++ b/templates/default/layout.html.twig @@ -13,7 +13,7 @@
- {% block header_search %} @@ -32,11 +32,11 @@
{% block main_profile %} {{ render(controller( - 'App\\Controller\\ProfileController::module', + 'App\\Controller\\UserController::module', {route : app.request.get('_route')} )) }} {% endblock %} -
+
{% block main_content %}{% endblock %}
diff --git a/templates/default/profile/index.html.twig b/templates/default/profile/index.html.twig deleted file mode 100644 index 34c7353..0000000 --- a/templates/default/profile/index.html.twig +++ /dev/null @@ -1,2 +0,0 @@ -{% extends 'default/layout.html.twig' %} -{% block title %}{{ 'Profile - Settings'|trans }} - {{ name }}{% endblock %} \ No newline at end of file diff --git a/templates/default/profile/module.html.twig b/templates/default/profile/module.html.twig deleted file mode 100644 index 2277622..0000000 --- a/templates/default/profile/module.html.twig +++ /dev/null @@ -1,178 +0,0 @@ -
- -
- {% if route == 'home_index' %} - - - - - - {{ 'Home'|trans }} - - - {% else %} - - - - - - {{ 'Home'|trans }} - - - {% endif %} - {% if route == 'page_stars' %} - - - - - - {{ 'Stars'|trans }} - - - {{ stars }} - - - {% else %} - - - - - - {{ 'Stars'|trans }} - - - {{ stars }} - - - {% endif %} - {% if route == 'page_views' %} - - - - - - {{ 'Views'|trans }} - - - {{ views }} - - - {% else %} - - - - - - {{ 'Views'|trans }} - - - {{ views }} - - - {% endif %} - {% if route == 'page_comments' %} - - - - - - {{ 'Comments'|trans }} - - - {{ comments }} - - - {% else %} - - - - - - {{ 'Comments'|trans }} - - - {{ comments }} - - - {% endif %} - {% if route == 'page_downloads' %} - - - - - - {{ 'Downloads'|trans }} - - - {{ downloads }} - - - {% else %} - - - - - - {{ 'Downloads'|trans }} - - - {{ downloads }} - - - {% endif %} - {% if route == 'page_editions' %} - - - - - - {{ 'Editions'|trans }} - - - {{ editions }} - - - {% else %} - - - - - - {{ 'Editions'|trans }} - - - {{ editions }} - - - {% endif %} - {% if route == '/page/submit' %} - - - - - - {{ 'Submit'|trans }} - - - {% else %} - - - - - - {{ 'Submit'|trans }} - - - {% endif %} -
-
\ No newline at end of file diff --git a/templates/default/profile/setting.html.twig b/templates/default/profile/setting.html.twig deleted file mode 100644 index 34c7353..0000000 --- a/templates/default/profile/setting.html.twig +++ /dev/null @@ -1,2 +0,0 @@ -{% extends 'default/layout.html.twig' %} -{% block title %}{{ 'Profile - Settings'|trans }} - {{ name }}{% endblock %} \ No newline at end of file diff --git a/templates/default/user/info.html.twig b/templates/default/user/info.html.twig new file mode 100644 index 0000000..e4caf5c --- /dev/null +++ b/templates/default/user/info.html.twig @@ -0,0 +1,92 @@ +{% extends 'default/layout.html.twig' %} +{% block title %}{{ 'User'|trans }} #{{ user.id }} - {{ name }}{% endblock %} +{% block main_content %} +
+ identicon +
+

{{ 'Profile'|trans }}

+ + + + + + {% if user.address %} + + + + + + + + + {% else %} + + + + + {% endif %} + + + + + + + + + + + + + + + + + + + + + + + + + + + +
{{ 'Common'|trans }}
{{ 'Address'|trans }} + {{ user.address }} + + + + + + + + +
{{ 'Joined'|trans }}{{ user.added }}
{{ 'Joined'|trans }}{{ user.added }}
{{ 'Access'|trans }}
{{ 'Status'|trans }} + {% if user.status %} + {{ 'active'|trans }} + {% else %} + {{ 'disabled'|trans }} + {% endif %} +
{{ 'Approved'|trans }} + {% if user.approved %} + {{ 'yes'|trans }} + {% else %} + {{ 'no'|trans }} + {% endif %} +
{{ 'Moderator'|trans }} + {% if user.moderator %} + {{ 'yes'|trans }} + {% else %} + {{ 'no'|trans }} + {% endif %} +
{{ 'Settings'|trans }}
{{ 'Interface'|trans }} + {{ user.locale|trans }} +
{{ 'Content filter'|trans }} + {% for locale in user.locales %} +
+ {{ locale|trans }} +
+ {% endfor %} +
+{% endblock %} \ No newline at end of file diff --git a/templates/default/user/module.html.twig b/templates/default/user/module.html.twig new file mode 100644 index 0000000..366eb66 --- /dev/null +++ b/templates/default/user/module.html.twig @@ -0,0 +1,186 @@ +
+
+ {% if route == 'dashboard_index' %} + + + + + + {{ 'Home'|trans }} + + + {% else %} + + + + + + {{ 'Home'|trans }} + + + {% endif %} + {% if route == 'user_profile' %} + + + + + + {{ 'Profile'|trans }} + + + {% else %} + + + + + + {{ 'Profile'|trans }} + + + {% endif %} + {% if route == 'page_stars' %} + + + + + + {{ 'Stars'|trans }} + + + {{ stars }} + + + {% else %} + + + + + + {{ 'Stars'|trans }} + + + {{ stars }} + + + {% endif %} + {% if route == 'page_views' %} + + + + + + {{ 'Views'|trans }} + + + {{ views }} + + + {% else %} + + + + + + {{ 'Views'|trans }} + + + {{ views }} + + + {% endif %} + {% if route == 'page_comments' %} + + + + + + {{ 'Comments'|trans }} + + + {{ comments }} + + + {% else %} + + + + + + {{ 'Comments'|trans }} + + + {{ comments }} + + + {% endif %} + {% if route == 'page_downloads' %} + + + + + + {{ 'Downloads'|trans }} + + + {{ downloads }} + + + {% else %} + + + + + + {{ 'Downloads'|trans }} + + + {{ downloads }} + + + {% endif %} + {% if route == 'page_editions' %} + + + + + + {{ 'Editions'|trans }} + + + {{ editions }} + + + {% else %} + + + + + + {{ 'Editions'|trans }} + + + {{ editions }} + + + {% endif %} + {% if route == 'page_submit' %} + + + + + + {{ 'Submit'|trans }} + + + {% else %} + + + + + + {{ 'Submit'|trans }} + + + {% endif %} +
+
\ No newline at end of file diff --git a/templates/default/user/profile.html.twig b/templates/default/user/profile.html.twig new file mode 100644 index 0000000..e287961 --- /dev/null +++ b/templates/default/user/profile.html.twig @@ -0,0 +1,105 @@ +{% extends 'default/layout.html.twig' %} +{% block title %}{{ 'Profile'|trans }} - {{ name }}{% endblock %} +{% block main_content %} +
+
+ identicon +
+

{{ 'Profile'|trans }}

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
{{ 'Common'|trans }}
{{ 'Address'|trans }} + {{ user.address }} + + + + + + + + +
{{ 'Joined'|trans }}{{ user.added }}
{{ 'Access'|trans }}
{{ 'Status'|trans }} + {% if user.status %} + {{ 'active'|trans }} + {% else %} + {{ 'disabled'|trans }} + {% endif %} +
{{ 'Approved'|trans }} + {% if user.approved %} + {{ 'yes'|trans }} + {% else %} + {{ 'no'|trans }} + {% endif %} +
{{ 'Moderator'|trans }} + {% if user.moderator %} + {{ 'yes'|trans }} + {% else %} + {{ 'no'|trans }} + {% endif %} +
{{ 'Settings'|trans }}
{{ 'Interface'|trans }} + +
{{ 'Content filter'|trans }} + {% for locale in locales %} +
+ {% if locale in user.locales %} + + {% else %} + + {% endif %} + +
+ {% endfor %} +
+
+ +
+
+{% endblock %} \ No newline at end of file diff --git a/templates/redirect/index.html.twig b/templates/redirect/index.html.twig new file mode 100644 index 0000000..18beeb9 --- /dev/null +++ b/templates/redirect/index.html.twig @@ -0,0 +1,20 @@ +{% extends 'base.html.twig' %} + +{% block title %}Hello RedirectController!{% endblock %} + +{% block body %} + + +
+

Hello {{ controller_name }}! ✅

+ + This friendly message is coming from: + +
+{% endblock %}