organization dashboard User management
This commit is contained in:
parent
e17e8e0eb2
commit
05d8ca0499
|
|
@ -3,6 +3,7 @@
|
|||
namespace App\Controller;
|
||||
|
||||
use App\Entity\UsersOrganizations;
|
||||
use App\Service\OrganizationsService;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\Routing\Attribute\Route;
|
||||
|
|
@ -16,7 +17,8 @@ class OrganizationController extends AbstractController
|
|||
private const NOT_FOUND = 'Entity not found';
|
||||
private const ACCESS_DENIED = 'Access denied';
|
||||
|
||||
public function __construct(private readonly EntityManagerInterface $entityManager)
|
||||
public function __construct(private readonly EntityManagerInterface $entityManager,
|
||||
private readonly OrganizationsService $organizationsService)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -48,14 +50,40 @@ class OrganizationController extends AbstractController
|
|||
#[Route(path: '/{id}', name: 'show', methods: ['GET'])]
|
||||
public function show(int $id): Response
|
||||
{
|
||||
$organization = $this->entityManager->getRepository(Organizations::class)->find($id);
|
||||
if (!$this->isGranted('ROLE_ADMIN')) {
|
||||
$user = $this->getUser();
|
||||
if (!$user) {
|
||||
return $this->redirectToRoute('app_login');
|
||||
}
|
||||
$userIdentifier = $user->getUserIdentifier();
|
||||
|
||||
$organization = $this->entityManager->getRepository(UsersOrganizations::class)->findOneBy([
|
||||
'userEmail' => $userIdentifier,
|
||||
'organization' => $id,
|
||||
'roleName' => 'ADMIN'
|
||||
]);
|
||||
|
||||
if (!$organization) {
|
||||
throw $this->createNotFoundException(self::ACCESS_DENIED);
|
||||
}
|
||||
}
|
||||
$organization = $this->entityManager->getRepository(Organizations::class)->find($id);
|
||||
if (!$organization) {
|
||||
throw $this->createNotFoundException(self::NOT_FOUND);
|
||||
}
|
||||
|
||||
$newUsers = $this->entityManager->getRepository(UsersOrganizations::class)->getLastNewActiveUsersByOrganization($organization);
|
||||
$adminUsers = $this->entityManager->getRepository(UsersOrganizations::class)->getAdminUsersByOrganization($organization);
|
||||
// reusing the method to avoid code duplication even though it returns an array of UsersOrganizations
|
||||
$org = $this->entityManager->getRepository(UsersOrganizations::class)->findActiveUsersByOrganizations([$organization]);
|
||||
|
||||
|
||||
|
||||
return $this->render('organization/show.html.twig', [
|
||||
'organization' => $organization,
|
||||
'adminUsers' => $adminUsers,
|
||||
'newUsers' => $newUsers,
|
||||
'org' => $org[0],
|
||||
]);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -193,4 +193,82 @@ class UsersOrganizationsRepository extends ServiceEntityRepository
|
|||
}
|
||||
return $userToOrgs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the last 10 new active users for a specific organization.
|
||||
* Users are ordered by creation date (most recent first).
|
||||
*
|
||||
* @param Organizations $organization
|
||||
* @return array
|
||||
*/
|
||||
public function getLastNewActiveUsersByOrganization(Organizations $organization): array
|
||||
{
|
||||
$results = $this->createQueryBuilder('uo')
|
||||
->select('u.id', 'u.surname', 'u.name', 'u.email', 'u.pictureUrl', 'u.isActive', 'uo.createdAt')
|
||||
->innerJoin('uo.users', 'u')
|
||||
->innerJoin('uo.organization', 'o')
|
||||
->where('uo.isActive = :isActive')
|
||||
->andWhere('u.isActive = :userIsActive')
|
||||
->andWhere('o.isActive = :orgIsActive')
|
||||
->andWhere('uo.organization = :organization')
|
||||
->setParameter('isActive', true)
|
||||
->setParameter('userIsActive', true)
|
||||
->setParameter('orgIsActive', true)
|
||||
->setParameter('organization', $organization)
|
||||
->orderBy('uo.createdAt', 'DESC')
|
||||
->setMaxResults(10)
|
||||
->getQuery()
|
||||
->getResult();
|
||||
|
||||
// Remove duplicates by user ID (in case user has multiple roles)
|
||||
$uniqueUsers = [];
|
||||
foreach ($results as $result) {
|
||||
$userId = $result['id'];
|
||||
if (!isset($uniqueUsers[$userId])) {
|
||||
$uniqueUsers[$userId] = $result;
|
||||
}
|
||||
}
|
||||
|
||||
return array_values($uniqueUsers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all active admin users for a specific organization.
|
||||
* Returns users who have the 'ADMIN' role in the given organization.
|
||||
*
|
||||
* @param Organizations $organization
|
||||
* @return array
|
||||
*/
|
||||
public function getAdminUsersByOrganization(Organizations $organization): array
|
||||
{
|
||||
$results = $this->createQueryBuilder('uo')
|
||||
->select('u.id', 'u.surname', 'u.name', 'u.email', 'u.pictureUrl', 'u.isActive')
|
||||
->innerJoin('uo.users', 'u')
|
||||
->innerJoin('uo.organization', 'o')
|
||||
->innerJoin('uo.role', 'r')
|
||||
->where('uo.isActive = :isActive')
|
||||
->andWhere('u.isActive = :userIsActive')
|
||||
->andWhere('o.isActive = :orgIsActive')
|
||||
->andWhere('uo.organization = :organization')
|
||||
->andWhere('r.name = :roleName')
|
||||
->setParameter('isActive', true)
|
||||
->setParameter('userIsActive', true)
|
||||
->setParameter('orgIsActive', true)
|
||||
->setParameter('organization', $organization)
|
||||
->setParameter('roleName', 'ADMIN')
|
||||
->orderBy('u.surname', 'ASC')
|
||||
->getQuery()
|
||||
->getResult();
|
||||
|
||||
// Remove duplicates by user ID (in case user has multiple admin-related roles)
|
||||
$uniqueUsers = [];
|
||||
foreach ($results as $result) {
|
||||
$userId = $result['id'];
|
||||
if (!isset($uniqueUsers[$userId])) {
|
||||
$uniqueUsers[$userId] = $result;
|
||||
}
|
||||
}
|
||||
|
||||
return array_values($uniqueUsers);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
namespace App\Service;
|
||||
|
||||
use App\Entity\Organizations;
|
||||
use App\Entity\Roles;
|
||||
use App\Entity\UsersOrganizations;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
|
||||
class OrganizationsService
|
||||
{
|
||||
public function __construct(private readonly EntityManagerInterface $entityManager)
|
||||
{
|
||||
}
|
||||
|
||||
public function getAdminUsers(Organizations $organization): array{
|
||||
$roleAdmin = $this->entityManager->getRepository(Roles::class)->findBy(['name' => 'ADMIN']);
|
||||
return $this->entityManager->getRepository(UsersOrganizations::class)->findBy(['organization'=>$organization,
|
||||
'role' => $roleAdmin,
|
||||
'isActive' => true]);
|
||||
}
|
||||
|
||||
public function getNewUsers(Organizations $organization): array{
|
||||
return $this->entityManager->getRepository(UsersOrganizations::class)->findBy(['organization'=>$organization,
|
||||
'isActive' => true]);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,10 +1,33 @@
|
|||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block body %}
|
||||
|
||||
<div class="col-md-12 m-auto p-5">
|
||||
<div class="col d-flex justify-content-between align-items-center ">
|
||||
<h1 class="mb-4">{{ organization.name|title }} - Dashboard</h1>
|
||||
{% if is_granted("ROLE_SUER_ADMIN") %}
|
||||
{# <a href="{{ path('user_deactivate', {'id': user.id}) }}" class="btn btn-danger">Désactiver</a> #}
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="row mb-4">
|
||||
<div class="col-sm-6 mb-3 mb-sm-0">
|
||||
{% include 'user/userListSmall.html.twig' with {
|
||||
title: 'Nouveaux utilisateurs',
|
||||
users: newUsers,
|
||||
empty_message: 'Aucun nouvel utilisateur trouvé.'
|
||||
} %}
|
||||
</div>
|
||||
<div class="col-sm-6 mb-3 mb-sm-0">
|
||||
{% include 'user/userListSmall.html.twig' with {
|
||||
title: 'Administrateurs',
|
||||
users: adminUsers,
|
||||
empty_message: 'Aucun administrateur trouvé.'
|
||||
} %}
|
||||
</div>
|
||||
</div>
|
||||
{% include 'user/userList.html.twig' with {
|
||||
title: 'Mes utilisateurs',
|
||||
} %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block title %}
|
||||
{{ organization.name|title }} - Dashboard
|
||||
{% endblock %}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,8 @@
|
|||
{% block body %}
|
||||
|
||||
{% if title is defined %}
|
||||
<h3>{{ title }}</h3>
|
||||
{% endif %}
|
||||
<table class="table align-middle shadow">
|
||||
<thead class="table-light shadow-sm">
|
||||
<tr>
|
||||
|
|
@ -7,10 +10,16 @@
|
|||
<th>Surname</th>
|
||||
<th>Name</th>
|
||||
<th>Email</th>
|
||||
{# <th>Statut</th>#}
|
||||
<th>Visualiser</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% if org.users|length == 0 %}
|
||||
<tr>
|
||||
<td colspan="5" class="text-center">Aucun utilisateur trouvé.</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% for user in org.users %}
|
||||
<tr>
|
||||
<td>
|
||||
|
|
@ -29,11 +38,7 @@
|
|||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% if org.users|length == 0 %}
|
||||
<tr>
|
||||
<td colspan="5" class="text-center">Aucun utilisateur trouvé.</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
{% endblock %}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
<div class="card card-bor">
|
||||
<div class="card-title p-3 d-flex justify-content-between align-items-center ">
|
||||
<h3>{{ title }}</h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<table class="table align-middle table-borderless">
|
||||
<thead class="table-light">
|
||||
<tr>
|
||||
<th>Picture</th>
|
||||
<th>Email</th>
|
||||
<th>Visualiser</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% if users|length == 0 %}
|
||||
<tr>
|
||||
<td colspan="3" class="text-center">{{ empty_message }}</td>
|
||||
</tr>
|
||||
{% else %}
|
||||
{% for user in users %}
|
||||
<tr>
|
||||
<td>
|
||||
{% if user.pictureUrl %}
|
||||
<img src="{{ asset(user.pictureUrl) }}" alt="User profile pic" class="rounded-circle" style="width:40px; height:40px;">
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>{{ user.email }}</td>
|
||||
<td>
|
||||
<a href="{{ path('user_show', {'id': user.id}) }}" class="p-3 align-middle color-primary">
|
||||
{{ ux_icon('fa6-regular:eye', {height: '30px', width: '30px'}) }}
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
Loading…
Reference in New Issue