Read User information
This commit is contained in:
parent
10a8eb2255
commit
4a2f9d9547
|
|
@ -141,7 +141,6 @@
|
|||
<path value="$PROJECT_DIR$/vendor/defuse/php-encryption" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/ux-turbo" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/stimulus-bundle" />
|
||||
<path value="$PROJECT_DIR$/vendor/doctrine/cache" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/type-info" />
|
||||
<path value="$PROJECT_DIR$/vendor/doctrine/event-manager" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/console" />
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="https://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="currentColor" d="M256 464a208 208 0 1 1 0-416a208 208 0 1 1 0 416m0-464a256 256 0 1 0 0 512a256 256 0 1 0 0-512m120.9 294.6c4.5-4.2 7.1-10.1 7.1-16.3c0-12.3-10-22.3-22.3-22.3H304v-96c0-17.7-14.3-32-32-32h-32c-17.7 0-32 14.3-32 32v96h-57.7c-12.3 0-22.3 10-22.3 22.3c0 6.2 2.6 12.1 7.1 16.3l107.1 99.9c3.8 3.5 8.7 5.5 13.8 5.5s10.1-2 13.8-5.5z"/></svg>
|
||||
|
After Width: | Height: | Size: 425 B |
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="https://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="currentColor" d="M256 48a208 208 0 1 1 0 416a208 208 0 1 1 0-416m0 464a256 256 0 1 0 0-512a256 256 0 1 0 0 512M151.2 217.4c-4.6 4.2-7.2 10.1-7.2 16.4c0 12.3 10 22.3 22.3 22.3H208v96c0 17.7 14.3 32 32 32h32c17.7 0 32-14.3 32-32v-96h41.7c12.3 0 22.3-10 22.3-22.3c0-6.2-2.6-12.1-7.2-16.4l-91-84c-3.8-3.5-8.7-5.4-13.9-5.4s-10.1 1.9-13.9 5.4l-91 84z"/></svg>
|
||||
|
After Width: | Height: | Size: 428 B |
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="https://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="currentColor" d="M406.5 399.6c-19.1-46.7-65-79.6-118.5-79.6h-64c-53.5 0-99.4 32.9-118.5 79.6C69.9 362.2 48 311.7 48 256c0-114.9 93.1-208 208-208s208 93.1 208 208c0 55.7-21.9 106.2-57.5 143.6m-40.1 32.7c-32 20.1-69.8 31.7-110.4 31.7s-78.4-11.6-110.5-31.7c7.3-36.7 39.7-64.3 78.5-64.3h64c38.8 0 71.2 27.6 78.5 64.3zM256 512a256 256 0 1 0 0-512a256 256 0 1 0 0 512m0-272a40 40 0 1 1 0-80a40 40 0 1 1 0 80m-88-40a88 88 0 1 0 176 0a88 88 0 1 0-176 0"/></svg>
|
||||
|
After Width: | Height: | Size: 528 B |
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="https://www.w3.org/2000/svg" viewBox="0 0 576 512"><path fill="currentColor" d="M288 80c-65.2 0-118.8 29.6-159.9 67.7C89.6 183.5 63 226 49.4 256C63 286 89.6 328.5 128 364.3c41.2 38.1 94.8 67.7 160 67.7s118.8-29.6 159.9-67.7C486.4 328.5 513 286 526.6 256c-13.6-30-40.2-72.5-78.6-108.3C406.8 109.6 353.2 80 288 80M95.4 112.6C142.5 68.8 207.2 32 288 32s145.5 36.8 192.6 80.6c46.8 43.5 78.1 95.4 93 131.1c3.3 7.9 3.3 16.7 0 24.6c-14.9 35.7-46.2 87.7-93 131.1C433.5 443.2 368.8 480 288 480s-145.5-36.8-192.6-80.6C48.6 356 17.3 304 2.5 268.3c-3.3-7.9-3.3-16.7 0-24.6C17.3 208 48.6 156 95.4 112.6M288 336c44.2 0 80-35.8 80-80s-35.8-80-80-80h-2c1.3 5.1 2 10.5 2 16c0 35.3-28.7 64-64 64c-5.5 0-10.9-.7-16-2v2c0 44.2 35.8 80 80 80m0-208a128 128 0 1 1 0 256a128 128 0 1 1 0-256"/></svg>
|
||||
|
After Width: | Height: | Size: 787 B |
|
|
@ -1,3 +1,13 @@
|
|||
/*variable*/
|
||||
:root{
|
||||
--primary-blue-light : #086572;
|
||||
--primary-blue-dark : #094754;
|
||||
--black-font: #1D1E1C;
|
||||
--delete : #E42E31;
|
||||
--disable : #A3A3A3;
|
||||
--check : #80F20E;
|
||||
}
|
||||
|
||||
html {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
|
|
@ -77,4 +87,30 @@ body {
|
|||
font-family: "Nunito", sans-serif;
|
||||
font-weight: 400;
|
||||
border-top: 1px solid rgba(0, 0, 0, 0.06);
|
||||
}
|
||||
|
||||
.btn-primary{
|
||||
background: var(--primary-blue-light);
|
||||
color : #FFFFFF;
|
||||
border: var(--primary-blue-dark);
|
||||
border-radius: 1rem;
|
||||
}
|
||||
.btn-primary:hover{
|
||||
background: var(--primary-blue-dark);
|
||||
color : #FFFFFF;
|
||||
border: var(--primary-blue-light);
|
||||
}
|
||||
|
||||
.btn-danger{
|
||||
background: var(--delete);
|
||||
color : #FFFFFF;
|
||||
border: var(--delete);
|
||||
border-radius: 1rem;
|
||||
}
|
||||
|
||||
.color-primary{
|
||||
color: var(--primary-blue-light);
|
||||
}
|
||||
.color-primary-dark{
|
||||
color: var(--primary-blue-dark);
|
||||
}
|
||||
|
|
@ -154,99 +154,6 @@
|
|||
},
|
||||
"time": "2023-06-19T06:10:36+00:00"
|
||||
},
|
||||
{
|
||||
"name": "doctrine/cache",
|
||||
"version": "2.2.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/doctrine/cache.git",
|
||||
"reference": "1ca8f21980e770095a31456042471a57bc4c68fb"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/doctrine/cache/zipball/1ca8f21980e770095a31456042471a57bc4c68fb",
|
||||
"reference": "1ca8f21980e770095a31456042471a57bc4c68fb",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "~7.1 || ^8.0"
|
||||
},
|
||||
"conflict": {
|
||||
"doctrine/common": ">2.2,<2.4"
|
||||
},
|
||||
"require-dev": {
|
||||
"cache/integration-tests": "dev-master",
|
||||
"doctrine/coding-standard": "^9",
|
||||
"phpunit/phpunit": "^7.5 || ^8.5 || ^9.5",
|
||||
"psr/cache": "^1.0 || ^2.0 || ^3.0",
|
||||
"symfony/cache": "^4.4 || ^5.4 || ^6",
|
||||
"symfony/var-exporter": "^4.4 || ^5.4 || ^6"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Doctrine\\Common\\Cache\\": "lib/Doctrine/Common/Cache"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Guilherme Blanco",
|
||||
"email": "guilhermeblanco@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Roman Borschel",
|
||||
"email": "roman@code-factory.org"
|
||||
},
|
||||
{
|
||||
"name": "Benjamin Eberlei",
|
||||
"email": "kontakt@beberlei.de"
|
||||
},
|
||||
{
|
||||
"name": "Jonathan Wage",
|
||||
"email": "jonwage@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Johannes Schmitt",
|
||||
"email": "schmittjoh@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "PHP Doctrine Cache library is a popular cache implementation that supports many different drivers such as redis, memcache, apc, mongodb and others.",
|
||||
"homepage": "https://www.doctrine-project.org/projects/cache.html",
|
||||
"keywords": [
|
||||
"abstraction",
|
||||
"apcu",
|
||||
"cache",
|
||||
"caching",
|
||||
"couchdb",
|
||||
"memcached",
|
||||
"php",
|
||||
"redis",
|
||||
"xcache"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/doctrine/cache/issues",
|
||||
"source": "https://github.com/doctrine/cache/tree/2.2.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://www.doctrine-project.org/sponsorship.html",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://www.patreon.com/phpdoctrine",
|
||||
"type": "patreon"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/doctrine%2Fcache",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2022-05-20T20:07:39+00:00"
|
||||
},
|
||||
{
|
||||
"name": "doctrine/collections",
|
||||
"version": "2.3.0",
|
||||
|
|
@ -335,28 +242,31 @@
|
|||
},
|
||||
{
|
||||
"name": "doctrine/dbal",
|
||||
"version": "3.9.5",
|
||||
"version": "3.10.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/doctrine/dbal.git",
|
||||
"reference": "4a4e2eed3134036ee36a147ee0dac037dfa17868"
|
||||
"reference": "1cf840d696373ea0d58ad0a8875c0fadcfc67214"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/doctrine/dbal/zipball/4a4e2eed3134036ee36a147ee0dac037dfa17868",
|
||||
"reference": "4a4e2eed3134036ee36a147ee0dac037dfa17868",
|
||||
"url": "https://api.github.com/repos/doctrine/dbal/zipball/1cf840d696373ea0d58ad0a8875c0fadcfc67214",
|
||||
"reference": "1cf840d696373ea0d58ad0a8875c0fadcfc67214",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"composer-runtime-api": "^2",
|
||||
"doctrine/cache": "^1.11|^2.0",
|
||||
"doctrine/deprecations": "^0.5.3|^1",
|
||||
"doctrine/event-manager": "^1|^2",
|
||||
"php": "^7.4 || ^8.0",
|
||||
"psr/cache": "^1|^2|^3",
|
||||
"psr/log": "^1|^2|^3"
|
||||
},
|
||||
"conflict": {
|
||||
"doctrine/cache": "< 1.11"
|
||||
},
|
||||
"require-dev": {
|
||||
"doctrine/cache": "^1.11|^2.0",
|
||||
"doctrine/coding-standard": "13.0.0",
|
||||
"fig/log-test": "^1",
|
||||
"jetbrains/phpstorm-stubs": "2023.1",
|
||||
|
|
@ -426,7 +336,7 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/doctrine/dbal/issues",
|
||||
"source": "https://github.com/doctrine/dbal/tree/3.9.5"
|
||||
"source": "https://github.com/doctrine/dbal/tree/3.10.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
|
@ -442,7 +352,7 @@
|
|||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-06-15T22:40:05+00:00"
|
||||
"time": "2025-07-10T21:11:04+00:00"
|
||||
},
|
||||
{
|
||||
"name": "doctrine/deprecations",
|
||||
|
|
|
|||
|
|
@ -11,8 +11,10 @@ security:
|
|||
property: email
|
||||
|
||||
role_hierarchy:
|
||||
ROLE_ADMIN: ROLE_USER
|
||||
ROLE_SUPER_ADMIN: [ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]
|
||||
ROLE_SUDALYS: ROLE_USER
|
||||
ROLE_ADMIN: ROLE_USER
|
||||
ROLE_SUDALYS_ADMIN: [ROLE_SUDALYS, ROLE_ALLOWED_TO_SWITCH, ROLE_ADMIN]
|
||||
|
||||
|
||||
firewalls:
|
||||
dev:
|
||||
|
|
|
|||
|
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace DoctrineMigrations;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\Migrations\AbstractMigration;
|
||||
|
||||
/**
|
||||
* Auto-generated Migration: Please modify to your needs!
|
||||
*/
|
||||
final class Version20250716130850 extends AbstractMigration
|
||||
{
|
||||
public function getDescription(): string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function up(Schema $schema): void
|
||||
{
|
||||
// this up() migration is auto-generated, please modify it to your needs
|
||||
|
||||
}
|
||||
|
||||
public function down(Schema $schema): void
|
||||
{
|
||||
// this down() migration is auto-generated, please modify it to your needs
|
||||
$this->addSql('CREATE SCHEMA public');
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
<?php
|
||||
|
||||
namespace App\Controller;
|
||||
|
||||
use App\Entity\User;
|
||||
use App\Entity\UsersOrganizations;
|
||||
use App\Service\UserOrganizationService;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Routing\Attribute\Route;
|
||||
|
||||
#[Route(path: '/user', name: 'user_')]
|
||||
class UserController extends AbstractController
|
||||
{
|
||||
public function __construct(private readonly UserOrganizationService $userOrganizationService)
|
||||
{
|
||||
}
|
||||
|
||||
#[Route('/dashboard', name: 'dashboard')]
|
||||
public function index(EntityManagerInterface $entityManager): Response
|
||||
{
|
||||
if ($this->isGranted('ROLE_SUDALYS_ADMIN')) {
|
||||
$users = $entityManager->getRepository(User::class)->getAllActiveUsers();
|
||||
} else {
|
||||
$users = 'Not Super Admin';
|
||||
}
|
||||
return $this->render('user/index.html.twig', [
|
||||
'users' => $users,
|
||||
'controller_name' => 'IndexController',
|
||||
]);
|
||||
}
|
||||
|
||||
#[Route('/{id}', name: 'view')]
|
||||
public function userProfile(Request $request, EntityManagerInterface $entityManager): Response
|
||||
{
|
||||
if ($this->isGranted('ROLE_SUDALYS_ADMIN')) {
|
||||
$userId = $request->attributes->get('id');
|
||||
$user = $entityManager->getRepository(User::class)->find($userId);
|
||||
$userOrganizations = $this->userOrganizationService->getUserOrganizations($user);
|
||||
}
|
||||
return $this->render('user/profile.html.twig', [
|
||||
'user' => $user,
|
||||
'userOrganizations' => $userOrganizations,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
@ -33,28 +33,13 @@ class UserRepository extends ServiceEntityRepository implements PasswordUpgrader
|
|||
$this->getEntityManager()->flush();
|
||||
}
|
||||
|
||||
// /**
|
||||
// * @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 findOneBySomeField($value): ?User
|
||||
// {
|
||||
// return $this->createQueryBuilder('u')
|
||||
// ->andWhere('u.exampleField = :val')
|
||||
// ->setParameter('val', $value)
|
||||
// ->getQuery()
|
||||
// ->getOneOrNullResult()
|
||||
// ;
|
||||
// }
|
||||
public function getAllActiveUsers(): array{
|
||||
$queryBuilder = $this->createQueryBuilder('u')
|
||||
->select('u.surname', 'u.email', 'u.id', 'u.isActive', 'u.name', 'u.pictureUrl')
|
||||
// Remove this line: ->from(User::class, 'u')
|
||||
->where('u.isActive = :isActive') // Also fixed the concatenation
|
||||
->orderBy('u.surname', 'ASC');
|
||||
$queryBuilder->setParameter('isActive', true);
|
||||
return $queryBuilder->getQuery()->getResult();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,9 +6,7 @@ use App\Entity\UsersOrganizations;
|
|||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||
use Doctrine\Persistence\ManagerRegistry;
|
||||
|
||||
/**
|
||||
* @extends ServiceEntityRepository<UsersOrganizations>
|
||||
*/
|
||||
|
||||
class UsersOrganizationsRepository extends ServiceEntityRepository
|
||||
{
|
||||
public function __construct(ManagerRegistry $registry)
|
||||
|
|
@ -16,28 +14,18 @@ class UsersOrganizationsRepository extends ServiceEntityRepository
|
|||
parent::__construct($registry, UsersOrganizations::class);
|
||||
}
|
||||
|
||||
// /**
|
||||
// * @return UsersOrganizations[] Returns an array of UsersOrganizations 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 findAllDistinctOrganizationsByUserId(int $userId): array
|
||||
{
|
||||
return $this->createQueryBuilder('uo')
|
||||
->select('DISTINCT uo')
|
||||
->leftJoin('uo.organization', 'o')
|
||||
->leftJoin('uo.role', 'r')
|
||||
->addSelect('o', 'r')
|
||||
->where('uo.users = :userId', 'uo.isActive = :isActive')
|
||||
->setParameter('userId', $userId)
|
||||
->setParameter('isActive', true)
|
||||
->getQuery()
|
||||
->getResult();
|
||||
}
|
||||
|
||||
// public function findOneBySomeField($value): ?UsersOrganizations
|
||||
// {
|
||||
// return $this->createQueryBuilder('u')
|
||||
// ->andWhere('u.exampleField = :val')
|
||||
// ->setParameter('val', $value)
|
||||
// ->getQuery()
|
||||
// ->getOneOrNullResult()
|
||||
// ;
|
||||
// }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,103 @@
|
|||
<?php
|
||||
|
||||
namespace App\Service;
|
||||
|
||||
use App\Entity\Roles;
|
||||
use App\Entity\User;
|
||||
use App\Entity\UsersOrganizations;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
|
||||
readonly class UserOrganizationService
|
||||
{
|
||||
public function __construct(private readonly EntityManagerInterface $entityManager) {}
|
||||
|
||||
/**
|
||||
* Returns all organizations the given user belongs to,
|
||||
* including the unique roles and apps the user has in each organization.
|
||||
*
|
||||
* @param User $user The user whose organizations are being fetched
|
||||
* @return array<array{organization:object, roles:Roles[], apps:object[]}>
|
||||
*/
|
||||
public function getUserOrganizations(User $user): array
|
||||
{
|
||||
$userOrganizations = $this->entityManager
|
||||
->getRepository(UsersOrganizations::class)
|
||||
->findAllDistinctOrganizationsByUserId($user->getId());
|
||||
$organizations = [];
|
||||
|
||||
foreach ($userOrganizations as $uo) {
|
||||
$orgId = $uo->getOrganization()->getId();
|
||||
|
||||
// Initialize the organization entry if it doesn't exist
|
||||
$organizations[$orgId] = $organizations[$orgId] ?? $this->createEmptyOrganizationBucket($uo);
|
||||
|
||||
// Aggregate roles & apps
|
||||
$this->addRole($organizations[$orgId]['roles'], $uo->getRole());
|
||||
$this->addApps($organizations[$orgId]['apps'], $uo->getApps());
|
||||
}
|
||||
|
||||
$this->normalizeAppsIndexes($organizations);
|
||||
|
||||
return array_values($organizations);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the initial array structure for a fresh organization entry.
|
||||
*
|
||||
* @param UsersOrganizations $link
|
||||
* @return array{organization:object, roles:Roles[], apps:array<int,object>}
|
||||
*/
|
||||
private function createEmptyOrganizationBucket(UsersOrganizations $link): array
|
||||
{
|
||||
return [
|
||||
'organization' => $link->getOrganization(),
|
||||
'roles' => [],
|
||||
'apps' => [],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a Role entity to the roles array only if it is not already present (by ID).
|
||||
*
|
||||
* @param Roles[] &$roles
|
||||
* @param Roles|null $role
|
||||
*/
|
||||
private function addRole(array &$roles, ?Roles $role): void
|
||||
{
|
||||
if ($role === null) {
|
||||
return;
|
||||
}
|
||||
foreach ($roles as $existingRole) {
|
||||
if ($existingRole->getId() === $role->getId()) {
|
||||
return; // Already present
|
||||
}
|
||||
}
|
||||
$roles[] = $role;
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge one or many apps into the apps map, keeping only one entry per id.
|
||||
*
|
||||
* @param array<int,object> &$apps
|
||||
* @param iterable $appsToAdd Collection returned by $userOrganizations->getApps()
|
||||
*/
|
||||
private function addApps(array &$apps, iterable $appsToAdd): void
|
||||
{
|
||||
foreach ($appsToAdd as $app) {
|
||||
$apps[$app->getId()] = $apps[$app->getId()] ?? $app;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert apps from associative maps (keyed by id) to plain indexed arrays,
|
||||
* so the final output is clean JSON-able.
|
||||
*
|
||||
* @param array &$organizations
|
||||
*/
|
||||
private function normalizeAppsIndexes(array &$organizations): void
|
||||
{
|
||||
foreach ($organizations as &$org) {
|
||||
$org['apps'] = array_values($org['apps']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -22,11 +22,14 @@
|
|||
</ul>
|
||||
</div>
|
||||
</li>
|
||||
{# if user is Super Admin#}
|
||||
{% if is_granted('ROLE_SUDALYS_ADMIN') %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="#">
|
||||
<a class="nav-link" href="{{ path('user_dashboard') }}">
|
||||
<i class="icon-grid menu-icon">{{ ux_icon('bi:menu-up', {height: '15px', width: '15px'}) }}</i>
|
||||
<span class="menu-title">Menu 2</span>
|
||||
<span class="menu-title">Users</span>
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</nav>
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
{% block body %}
|
||||
|
||||
<div class="card">
|
||||
<div class="card-title shadow-sm p-3">
|
||||
<h2>{{ user.surname|capitalize }} {{ user.name|capitalize }}</h2>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<p> <b>Email: </b>{{ user.email }}</p>
|
||||
<p><b>Dernière connection: </b>{{ user.lastConnection|date('d/m/Y') }} à {{ user.lastConnection|date('H:m:s') }} </p>
|
||||
<p><b>Compte crée le: </b>{{ user.createdAt|date('d/m/Y') }}</p>
|
||||
<p><b>Numéro de téléphone: </b>{{ user.phoneNumber ? user.phoneNumber : 'Non renseigné' }}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
|
|
@ -0,0 +1,85 @@
|
|||
{% block body %}
|
||||
|
||||
|
||||
<div class="card col-4 mt-3 me-3 user-org-card" style="cursor:pointer;" data-bs-toggle="collapse"
|
||||
data-bs-target="#org-details-{{ organization.id }}" aria-expanded="false"
|
||||
aria-controls="org-details-{{ organization.id }}">
|
||||
|
||||
<div class="card-title shadow-sm p-3 d-flex ">
|
||||
<h2 class=" pe-2">{{ organization.name|capitalize }}</h2>
|
||||
<i class="pt-2" id="arrow-icon-{{ organization.id }}">
|
||||
{{ ux_icon('fa6-regular:circle-down', {height: '25px', width: '25px'}) }}
|
||||
</i>
|
||||
</div>
|
||||
|
||||
{# Information principale sur l'utilisateur dans l'organisation#}
|
||||
<div class="card-body">
|
||||
{# Affichage du plus haut role #}
|
||||
<p><b>Role:</b>
|
||||
{% if roles|length > 0 %}
|
||||
{% set firstRole = roles[0] %}
|
||||
{% if firstRole.name == "ROLE ADMIN SUDALYS" or firstRole.name == "ROLE ADMIN" %}
|
||||
<span class="badge bg-danger">{{ firstRole.name|capitalize }}</span>
|
||||
{% elseif firstRole.name == "ROLE USER" %}
|
||||
<span class="badge bg-primary">{{ firstRole.name|capitalize }}</span>
|
||||
{% else %}
|
||||
<span class="badge bg-success">{{ firstRole.name|capitalize }}</span>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
Aucun rôle
|
||||
{% endif %}
|
||||
</p>
|
||||
|
||||
{# Affichage des applications dont l'utilisateur à accès #}
|
||||
<div class="d-flex">
|
||||
{% if apps is not empty %}
|
||||
{% for app in apps %}
|
||||
<div class="col">
|
||||
{{ app.name }}
|
||||
<img src="{{ asset(app.logoUrl) }}" alt="Logo {{ app.name }}" class="img-fluid ms-2" style="height: 20px; width: 20px;">
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
Aucune application associée.
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{# Détails supplémentaires sur l'organisation #}
|
||||
<div class="collapse card-body border-top" id="org-details-{{ organization.id }}">
|
||||
{% if roles|length > 1 %}
|
||||
<p><b>Autres rôles:</b>
|
||||
{% for role in roles|slice(1) %}
|
||||
{% if role.name == "ROLE ADMIN SUDALYS" or role.name == "ROLE ADMIN" %}
|
||||
<span class="badge bg-danger">{{ role.name|capitalize }}</span>
|
||||
{% elseif role.name == "ROLE USER" %}
|
||||
<span class="badge bg-primary">{{ role.name|capitalize }}</span>
|
||||
{% else %}
|
||||
<span class="badge bg-success">{{ role.name|capitalize }}</span>
|
||||
{% endif %}
|
||||
{% if not loop.last %} - {% endif %}
|
||||
{% endfor %}
|
||||
</p>
|
||||
{% endif %}
|
||||
<p><b>Membre depuis:</b> {{ organization.createdAt|date('d/m/Y') }}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block javascript %}
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
var collapseEl = document.getElementById('org-details-{{ organization.id }}');
|
||||
var arrowEl = document.getElementById('arrow-icon-{{ organization.id }}');
|
||||
if (collapseEl && arrowEl) {
|
||||
collapseEl.addEventListener('show.bs.collapse', function () {
|
||||
arrowEl.innerHTML = `{{ ux_icon('fa6-regular:circle-up', {height: '25px', width: '25px'})|e('js') }}`;
|
||||
});
|
||||
collapseEl.addEventListener('hide.bs.collapse', function () {
|
||||
arrowEl.innerHTML = `{{ ux_icon('fa6-regular:circle-down', {height: '25px', width: '25px'})|e('js') }}`;
|
||||
});
|
||||
}
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block title %}User Profile{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<div class="w-100 h-100 p-5 m-auto ">
|
||||
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||
<h1>Gestion Utilisateurs</h1>
|
||||
<a href="#" class="btn btn-primary">Ajouter un utilisateur</a>
|
||||
</div>
|
||||
|
||||
|
||||
<table class="table align-middle shadow">
|
||||
<thead class="table-light shadow-sm">
|
||||
<tr>
|
||||
<th>Picture</th>
|
||||
<th>Surname</th>
|
||||
<th>Name</th>
|
||||
<th>Email</th>
|
||||
<th>Visualiser</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for user in users %}
|
||||
<tr>
|
||||
<td></td>
|
||||
<td>{{ user.surname }}</td>
|
||||
<td>{{ user.name }}</td>
|
||||
<td>{{ user.email }}</td>
|
||||
<td>
|
||||
<a href="{{ path('user_view', {'id': user.id}) }}" class="p-3 align-middle">
|
||||
<i class="icon-grid menu-icon color-primary">
|
||||
{{ ux_icon('fa6-regular:eye', {height: '30px', width: '30px'}) }}
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% if users|length == 0 %}
|
||||
<tr>
|
||||
<td colspan="5" class="text-center">Aucun utilisateur trouvé.</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
|
||||
{% endblock %}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block body %}
|
||||
|
||||
<div class="col-md-10 m-auto p-5">
|
||||
<div class="col d-flex justify-content-between align-items-center ">
|
||||
<h1 class="mb-4">Gestion Utilisateur</h1>
|
||||
<a href="#" class="btn btn-danger">Désactiver</a>
|
||||
</div>
|
||||
{% include 'elements/userInformation.html.twig' %}
|
||||
|
||||
<h1 class="mt-5 mb-4">Organisations</h1>
|
||||
<div class="row">
|
||||
{% if userOrganizations is empty %}
|
||||
<div class="col-md-10 m-auto p-auto">
|
||||
<h3>Aucune organisation associée à cet utilisateur.</h3>
|
||||
</div>
|
||||
{% else %}
|
||||
{% for organization in userOrganizations %}
|
||||
{% include 'elements/userOrganizationInformation.html.twig'
|
||||
with {'organization': organization.organization, 'roles': organization.roles, 'apps': organization.apps} %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block title %}
|
||||
|
||||
{% endblock %}
|
||||
|
||||
Loading…
Reference in New Issue