diff --git a/assets/img/logoPlaceholder.jpg b/assets/img/logoPlaceholder.jpg new file mode 100644 index 0000000..8524307 Binary files /dev/null and b/assets/img/logoPlaceholder.jpg differ diff --git a/config/services.yaml b/config/services.yaml index d7c311e..50292e8 100644 --- a/config/services.yaml +++ b/config/services.yaml @@ -6,6 +6,7 @@ parameters: aws_url: '%env(AWS_ENDPOINT)%' aws_public_url: '%env(AWS_ENDPOINT)%' + logos_directory: '%kernel.project_dir%/public/uploads/logos' services: # default configuration for services in *this* file diff --git a/public/uploads/logos/2025-08-06_fsadf_logofile.jpg b/public/uploads/logos/2025-08-06_fsadf_logofile.jpg new file mode 100644 index 0000000..8524307 Binary files /dev/null and b/public/uploads/logos/2025-08-06_fsadf_logofile.jpg differ diff --git a/public/uploads/logos/6893102127c028.11727111.jpg b/public/uploads/logos/6893102127c028.11727111.jpg new file mode 100644 index 0000000..8524307 Binary files /dev/null and b/public/uploads/logos/6893102127c028.11727111.jpg differ diff --git a/src/Controller/OrganizationController.php b/src/Controller/OrganizationController.php index dadde71..ccbb3b8 100644 --- a/src/Controller/OrganizationController.php +++ b/src/Controller/OrganizationController.php @@ -5,35 +5,36 @@ namespace App\Controller; use App\Entity\Apps; use App\Entity\Roles; use App\Entity\UsersOrganizations; +use App\Form\OrganizationForm; use App\Service\ActionService; use App\Service\OrganizationsService; use App\Service\UserOrganizationService; use Doctrine\ORM\EntityManagerInterface; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; +use Symfony\Component\HttpFoundation\Request; use Symfony\Component\Routing\Attribute\Route; use App\Entity\Organizations; use Symfony\Component\HttpFoundation\Response; +use Symfony\Contracts\Service\Attribute\Required; #[Route(path: '/organization', name: 'organization_')] - class OrganizationController extends AbstractController { private const NOT_FOUND = 'Entity not found'; private const ACCESS_DENIED = 'Access denied'; - public function __construct(private readonly EntityManagerInterface $entityManager, - private readonly OrganizationsService $organizationsService, - private readonly UserOrganizationService $usersOrganizationService) + public function __construct(private readonly EntityManagerInterface $entityManager, + private readonly OrganizationsService $organizationsService, + private readonly UserOrganizationService $usersOrganizationService) { } - #[Route(path: '/' , name: 'index', methods: ['GET'])] - public function index():Response + #[Route('/', name: 'index', methods: ['GET'])] + public function index(): Response { - if($this->isGranted('ROLE_SUPER_ADMIN')) - { + if ($this->isGranted('ROLE_SUPER_ADMIN')) { $organizations = $this->entityManager->getRepository(Organizations::class)->findBy(['isActive' => true]); - } else{ + } else { $user = $this->getUser(); if (!$user) { return $this->redirectToRoute('app_login'); @@ -41,7 +42,7 @@ class OrganizationController extends AbstractController $userIdentifier = $user->getUserIdentifier(); $organizations = $this->entityManager->getRepository(UsersOrganizations::class)->findOrganizationsByUserEmailAndRoleName($userIdentifier, 'ADMIN'); - if(!$organizations) { + if (!$organizations) { // if user is not admin in any organization, throw access denied throw $this->createNotFoundException(self::ACCESS_DENIED); } @@ -52,7 +53,44 @@ class OrganizationController extends AbstractController ]); } - #[Route(path: '/{id}', name: 'show', methods: ['GET'])] + #[Route('/new', name: 'new', methods: ['GET', 'POST'])] + public function new(Request $request): Response + { + if (!$this->isGranted('ROLE_SUPER_ADMIN')) { + throw $this->createNotFoundException(self::ACCESS_DENIED); + } + $form = $this->createForm(OrganizationForm::class); + $form->handleRequest($request); + if ($form->isSubmitted() && $form->isValid()) { + $organization = $form->getData(); +// dd($form); + $logoFile = $form->get('logoUrl')->getData(); + + if ($logoFile) { + $currentDate = (new \DateTime())->format('Y-m-d'); + $organizationName = preg_replace('/[^a-zA-Z0-9]/', '_', $organization->getName()); + $extension = $logoFile->guessExtension(); + $newFilename = $currentDate . '_' . $organizationName . $extension; + // Move the file to the directory where logos are stored + $logoFile->move( + $this->getParameter('logos_directory'), + $newFilename + ); + + // Update the 'logoUrl' property to store the file name + $organization->setLogoUrl($newFilename); + } + $this->entityManager->persist($organization); + $this->entityManager->flush(); + $this->addFlash('success', 'Organization created successfully'); + return $this->redirectToRoute('organization_index'); + } + return $this->render('organization/new.html.twig', [ + 'form' => $form->createView(), + ]); + } + + #[Route('/{id}', name: 'show',requirements: ['id' => '\d+'], methods: ['GET'])] public function show(int $id, ActionService $actionService): Response { if ($this->isGranted('ROLE_ADMIN')) { @@ -60,15 +98,7 @@ class OrganizationController extends AbstractController if (!$user) { return $this->redirectToRoute('app_login'); } - $roleAdmin = $this->entityManager->getRepository(Roles::class)->findOneBy(['name' => 'ADMIN']); - $uo = $this->entityManager->getRepository(UsersOrganizations::class)->findOneBy([ - 'users' => $user, - 'organization' => $id, - 'role' => $roleAdmin - ]); - if (!$uo) { - throw $this->createNotFoundException(self::ACCESS_DENIED); - } + //Don't care about the null pointer because if no UO found, it won't pass the previous check $organization = $this->entityManager->getRepository(Organizations::class)->find($id); $newUsers = $this->entityManager->getRepository(UsersOrganizations::class)->getLastNewActiveUsersByOrganization($organization); @@ -80,12 +110,12 @@ class OrganizationController extends AbstractController $applications = $this->organizationsService->getApplicationsWithAccessStatus($organization); $actions = $organization->getActions()->toArray(); - usort($actions, static function($a, $b) { + usort($actions, static function ($a, $b) { return $b->getDate() <=> $a->getDate(); }); //get the last 10 activities $actions = array_slice($actions, 0, 10); - $activities = array_map(static function($activity) use ($actionService) { + $activities = array_map(static function ($activity) use ($actionService) { return [ 'date' => $activity->getDate(), // or however you access the date 'actionType' => $activity->getActionType(), @@ -93,7 +123,7 @@ class OrganizationController extends AbstractController 'color' => $actionService->getActivityColor($activity->getDate()) ]; }, $actions); - }else{ + } else { throw $this->createNotFoundException(self::ACCESS_DENIED); } @@ -101,10 +131,12 @@ class OrganizationController extends AbstractController 'organization' => $organization, 'adminUsers' => $adminUsers, 'newUsers' => $newUsers, - 'org' => $org[0], + 'org' => !empty($org) ? $org[0] : null, 'applications' => $applications, 'activities' => $activities ]); } + + } diff --git a/src/Entity/Organizations.php b/src/Entity/Organizations.php index bdfd0b4..7786c19 100644 --- a/src/Entity/Organizations.php +++ b/src/Entity/Organizations.php @@ -31,10 +31,10 @@ class Organizations private ?\DateTimeImmutable $createdAt = null; #[ORM\Column(options: ['default' => false])] - private ?bool $isDeleted = null; + private ?bool $isDeleted = false; #[ORM\Column(options: ['default' => true])] - private ?bool $isActive = null; + private ?bool $isActive = true; /** * @var Collection @@ -55,6 +55,7 @@ class Organizations { $this->apps = new ArrayCollection(); $this->actions = new ArrayCollection(); + $this->createdAt = new \DateTimeImmutable(); } public function getId(): ?int diff --git a/src/Form/OrganizationForm.php b/src/Form/OrganizationForm.php new file mode 100644 index 0000000..e2d1b32 --- /dev/null +++ b/src/Form/OrganizationForm.php @@ -0,0 +1,36 @@ +add('email', EmailType::class, ['required' => true, 'label' => 'Email*']) + ->add('name', TextType::class, ['required' => true, 'label' => 'Nom de l\'organisation*']) + ->add('address', TextType::class, ['required' => false, 'label' => 'Adresse']) + ->add('number', TextType::class, ['required' => false, 'label' => 'Numéro de téléphone']) + ->add('logoUrl', FileType::class, [ + 'required' => false, + 'label' => 'Logo', + 'mapped' => true, // Important if the entity property is not directly mapped + 'attr' => ['accept' => 'image/*'], + ]); + } + + public function configureOptions(OptionsResolver $resolver): void + { + $resolver->setDefaults([ + 'data_class' => Organizations::class, + ]); + } +} diff --git a/src/Service/UserOrganizationService.php b/src/Service/UserOrganizationService.php index df97724..bf46b86 100644 --- a/src/Service/UserOrganizationService.php +++ b/src/Service/UserOrganizationService.php @@ -408,12 +408,12 @@ readonly class UserOrganizationService */ public function findActiveUsersByOrganizations(array $organizations): array { + if (empty($organizations)) { return []; } $userOrgs = $this->entityManager->getRepository(UsersOrganizations::class)->getAllActiveUserOrganizationLinks($organizations); - $usersByOrg = []; foreach ($userOrgs as $uo) { $org = $uo->getOrganization(); diff --git a/templates/organization/index.html.twig b/templates/organization/index.html.twig index b19df11..ad16986 100644 --- a/templates/organization/index.html.twig +++ b/templates/organization/index.html.twig @@ -6,11 +6,14 @@

Gestion des organisations

-{# Ajouter une organisation#} + Ajouter une organisation
{% if organizations|length == 0 %} Aucune organisation trouvée. + + Créer une organisation + {% else %} @@ -27,7 +30,7 @@ diff --git a/templates/organization/new.html.twig b/templates/organization/new.html.twig new file mode 100644 index 0000000..a20dac1 --- /dev/null +++ b/templates/organization/new.html.twig @@ -0,0 +1,21 @@ +{% extends 'base.html.twig' %} + +{% block title %}Ajouter une organisation{% endblock %} + +{% block body %} +
+
+
+

Ajouter une organisation

+
+
+
+ {{ form_start(form) }} + {{ form_widget(form) }} + + {{ form_end(form) }} + +
+
+
+{% endblock %} diff --git a/templates/organization/show.html.twig b/templates/organization/show.html.twig index 1134ac3..f9de6ab 100644 --- a/templates/organization/show.html.twig +++ b/templates/organization/show.html.twig @@ -31,7 +31,8 @@
{% include 'user/userList.html.twig' with { title: 'Mes utilisateurs', - organizationId: organization.id + organizationId: organization.id, + empty_message: 'Aucun utilisateurs trouvé.' } %}
{# APPLICATION ROW #} diff --git a/templates/user/userList.html.twig b/templates/user/userList.html.twig index fc625c8..242c5dc 100644 --- a/templates/user/userList.html.twig +++ b/templates/user/userList.html.twig @@ -22,45 +22,50 @@ - {% if org.users|length == 0 %} + {% if org|length == 0 %} + + + + {% elseif org.users|length == 0 %} + {% else %} + {% for user in org.users %} + + + + + + + + + {% endfor %} {% endif %} - {% for user in org.users %} - - - - - - - - - {% endfor %}
{% if organization.logoUrl %} - Organization logo + Organization logo {% endif %} {{ organization.name }}
Aucun utilisateur trouvé.
Aucun utilisateur trouvé.
+ {% if user.users.pictureUrl %} + User profile pic + {% endif %} + {{ user.users.surname }}{{ user.users.name }}{{ user.users.email }} + {% if user.is_connected %} + Actif + {% else %} + Inactif + {% endif %} + + {% if organizationId is defined %} + + {{ ux_icon('fa6-regular:eye', {height: '30px', width: '30px'}) }} + + {% else %} + + {{ ux_icon('fa6-regular:eye', {height: '30px', width: '30px'}) }} + + {% endif %} +
- {% if user.users.pictureUrl %} - User profile pic - {% endif %} - {{ user.users.surname }}{{ user.users.name }}{{ user.users.email }} - {% if user.is_connected %} - Actif - {% else %} - Inactif - {% endif %} - - {% if organizationId is defined %} - - {{ ux_icon('fa6-regular:eye', {height: '30px', width: '30px'}) }} - - {% else %} - - {{ ux_icon('fa6-regular:eye', {height: '30px', width: '30px'}) }} - - {% endif %} -