Эх сурвалжийг харах

gestion des participations de groupe

garthh 20 цаг өмнө
parent
commit
f249932dec

+ 43 - 3
src/Controller/ParticipationController.php

@@ -30,6 +30,16 @@ final class ParticipationController extends AbstractController
             $this->addFlash('danger', 'Participation inexistante !');
             return $this->redirectToRoute('app_main');
         }
+
+        $redirectPath = 'app_main';
+        $user = $this->getUser();
+        if ($user && $user->getEmail() == $participation->getParticipantEmail()) {
+            // L'utilisateur qui annule est connecté, la page de redirection est sa liste de parties
+            $redirectPath = 'app_profile_participations';
+        }
+
+        // @todo: prendre en charge l'annulation en une fois de réservations de groupe
+
         $form = $this->createFormBuilder(FormType::class)->getForm();
         $form->handleRequest($request);
         if ($form->isSubmitted() && $form->isValid()) {
@@ -40,12 +50,13 @@ final class ParticipationController extends AbstractController
             $manager->remove($participation);
             $manager->flush();
             $this->addFlash('info', 'Votre participation à '.$game.' du '.$gameDateStr.' a bien été annulée.');
-            return $this->redirectToRoute('app_main');
+            return $this->redirectToRoute($redirectPath);
         }
 
         return $this->render('participation/cancel.html.twig' , [
             'form' => $form,
             'participation' => $participation,
+            'redirectPath' => $redirectPath,
         ]);
 
     }
@@ -88,6 +99,14 @@ final class ParticipationController extends AbstractController
         // Traitement des entrées du formulaire
         $form->handleRequest($request);
         if ($form->isSubmitted() && $form->isValid()) {
+
+            // Récupérer le tableau des accompagnant.e envoyé
+            $partyMore = $request->request->all('party_more');
+            // Garder uniquement les noms non vides
+            $partyMore = array_filter($partyMore, fn($name) => trim($name) !== '');
+            // Réindexer pour avoir un tableau propre (0, 1, 2, ...)
+            $partyMore = array_values($partyMore);
+
             // On contrôle qu'il y a encore de la place, sinon -> erreur
             if ($party->getSeatsLeft() < 1) {
                 if ($party->getSeatsLeft() > 0) {
@@ -98,8 +117,6 @@ final class ParticipationController extends AbstractController
             } else {
                 $reservationsCounter = 1;
 
-                // @todo: réservation multiples
-
                 // On enregistre dans la base
                 $manager->persist($participation);
                 $manager->flush();
@@ -116,6 +133,29 @@ final class ParticipationController extends AbstractController
                         'participation' => $participation,
                     ]);
                 $mailer->send($email);
+
+                // On traite les accompagnant.e.s
+                foreach ($partyMore as $companion) {
+                    $newParticipation = new Participation;
+                    $newParticipation->setParty($participation->getParty());
+                    $newParticipation->setParticipantName($companion);
+                    $newParticipation->setParticipantEmail($participation->getParticipantEmail());
+                    $newParticipation->setParticipantPhone($participation->getParticipantPhone());
+                    $manager->persist($newParticipation);
+                    $manager->flush();                   
+                    $email = (new TemplatedEmail())
+                        ->from(new Address($_ENV['CONTACT_EMAIL'], $_ENV['CONTACT_NAME']))
+                        ->to((string) $participation->getParticipantEmail())
+                        ->subject('Votre réservation pour '.$party->getGame()->getName())
+                        ->htmlTemplate('participation/booking.email.html.twig')
+                        ->textTemplate('participation/booking.email.txt.twig')
+                        ->context([
+                            'participation' => $newParticipation,
+                        ]);
+                    $mailer->send($email);
+                    $reservationsCounter++;
+                }
+
                 // On informe
                 if ($reservationsCounter > 1) {
                     $this->addFlash('success', $reservationsCounter.' réservations enregistrées.');

+ 38 - 3
src/Controller/ProfileController.php

@@ -19,6 +19,8 @@ use App\Entity\User;
 use App\Entity\Gamemaster;
 use App\Entity\Game;
 use App\Service\PictureService;
+use App\Entity\Participation;
+use App\Repository\ParticipationRepository;
 
 
 final class ProfileController extends AbstractController
@@ -193,10 +195,43 @@ final class ProfileController extends AbstractController
 
 
 
-    #[Route('/profile/games', name: 'app_profile_games')]
-    public function games(): Response
+    #[Route('/profile/participations', name: 'app_profile_participations')]
+    public function participations(ParticipationRepository $repository): Response
     {
-        return $this->render('profile/games.html.twig', [
+        $user = $this->getUser();
+        if (!$user) {
+            $this->addFlash('danger', 'Aucun utilisateur connecté');
+        }
+        // Retrouver le mail de l'utilisateur
+        $email = $user->getEmail();
+        $participations = $repository->findAllByEmail($email);
+        
+        return $this->render('profile/participations.html.twig', [
+            'participations' => $participations,
+            'user' => $user
+        ]);
+    }
+
+
+    #[Route('/profile/participations/gamemastering', name: 'app_profile_participations_gming')]
+    public function participationsGM(): Response
+    {
+        $user = $this->getUser();
+        if (!$user) {
+            $this->addFlash('danger', 'Aucun utilisateur connecté');
+            $this->redirectToRoute('app_main');
+        }
+        $gamemaster = $user->getLinkToGamemaster();
+        if (!$gamemaster) {
+            $this->addFlash('danger', 'Profil non MJ !');
+            $this->redirectToRoute('app_profile_participations');
+        }
+
+        $participations = $gamemaster->getParties();
+        
+        return $this->render('profile/gamemastering.html.twig', [
+            'participations' => $participations,
+            'user' => $user
         ]);
     }
 }

+ 9 - 0
src/Repository/ParticipationRepository.php

@@ -16,6 +16,15 @@ class ParticipationRepository extends ServiceEntityRepository
         parent::__construct($registry, Participation::class);
     }
 
+    public function findAllByEmail(string $email): array 
+    {
+        return $this->createQueryBuilder('p')
+            ->where('p.participantEmail = :email')
+            ->setParameter('email', $email)
+            ->getQuery()
+            ->getResult();
+    }
+
     //    /**
     //     * @return Participation[] Returns an array of Participation objects
     //     */

+ 1 - 1
templates/bulma.html.twig

@@ -67,7 +67,7 @@
                 <a class="navbar-link">{{ app.user.firstName }}</a>
                 <div class="navbar-dropdown is-right">
                   <a class="navbar-item" href="{{ path('app_profile') }}" class="">Mon compte</a>
-                  <a class="navbar-item" href="{{ path('app_profile_games') }}">Mes parties</a>
+                  <a class="navbar-item" href="{{ path('app_profile_participations') }}">Mes parties</a>
                   {% if is_granted('ROLE_ADMIN') %}
                   <hr class="navbar-divider" />
                   <a class="navbar-item" href="{{ path('app_admin') }}">Administration</a>

+ 16 - 0
templates/participation/_modal.add.html.twig

@@ -99,6 +99,22 @@
       {{ form_help(form.consentImage) }}
     </div>
 
+    <div class="box">
+      <div class="block">
+        <h3 class="title is-6">Participation de groupe</h3>
+        <p>Si des joueur(euse)s vous accompagnent sur cette partie, inscrivez simplement leurs noms ci-dessous.</p>
+      </div>
+      <div class="block">
+      {% for i in 2..party.getSeatsLeft %}
+        <div class="field">
+          <label class="label">Accompagnant(e) {{ i-1 }}</label>
+          <input id="party_more_{{ i-1 }}" name="party_more[{{ i-1 }}]" class="input" type="text" />
+        </div>
+      {% endfor %}
+      </div>
+
+    </div>
+
     {{ form_widget(form)}}
 
     <div class="control">

+ 8 - 5
templates/participation/cancel.html.twig

@@ -6,21 +6,24 @@
 
 <div class="container">
   <div class="columns is-centered">
-    <div class="column is-5">
+    <div class="column is-6">
       <div class="box">
-        <h1 class="title is-4 has-text-centered">Annuler</h1>
+        <div class="block">
+        <h1 class="title is-4 has-text-centered">Annuler une participation</h1>
         
-        <p>Merci de cliquer sur <span class="has-text-danger">Confirmer</span> pour annuler votre participation à la partie de {{ participation.party.game.name }} du {{ participation.party.startOn|date('d/m/y H:i', app_timezone) }}.</p>
-
+        <p>Merci de cliquer sur <strong class="has-text-danger">Confirmer</strong> pour annuler votre participation à la partie de <strong>{{ participation.party.game.name }}</strong> du {{ participation.party.startOn|date('d/m/y H:i', app_timezone) }}.</p>
+</div>
+        <div class="block">
         <div class="field is-grouped is-grouped-centered">
           <div class="control">
             {{ form_start(form) }}
             {{ form_widget(form) }}
             <button class="button is-danger" type="submit">Confirmer</button>
-            <a href="{{ path('app_main') }}" class="button">Retour</a>
+            <a href="{{ path(redirectPath) }}" class="button">Retour</a>
             {{ form_end(form) }}
           </div>
         </div>
+        </div>
       </div>
     </div>
   </div>

+ 52 - 0
templates/profile/gamemastering.html.twig

@@ -0,0 +1,52 @@
+{% extends 'bulma.html.twig' %}
+
+{% block title %}Mes parties{% endblock %}
+
+{% block content %}
+
+    <nav class="breadcrumb has-arrow-separator" aria-label="breadcrumbs">
+      <ul>
+        <li><a href="{{ path('app_main') }}">Accueil</a></li>
+        <li class="is-active"><a href="{{ path('app_profile_participations') }}">Mes parties</a></li>
+      </ul>
+    </nav>
+
+    <div class="tabs is-boxed">
+        <ul>
+            <li><a href="{{ path('app_profile_participations') }}">En tant que joueur(euse)</a></li>
+            {% if app.user.linkToGamemaster %}
+            <li class="is-active"><a>En tant que meneur(euse) de jeu</a></li>
+            {% endif %}
+            <li><a>Mes demandes</a></li>
+        </ul>
+    </div>
+
+    <div class="block">
+        <table id="datatable" {{ stimulus_controller('datatables') }} class="table is-striped is-hoverable is-fullwidth">
+            <thead>
+            <tr>
+                <th>Événement</th>
+                <th>Jeu</th>
+                <th>Date et heure</th>
+                <th>Participants</th>
+                <th>Action</th>
+            </tr>
+            </thead>
+            <tbody>
+            {% for participation in participations %}
+                <tr>
+                    <th>{{ participation.event.name }}</th>
+                    <td>{{ participation.game.name }}</td>
+                    <td>{{ participation.startOn|date('d/m/y H:i', app_timezone) }}</td>
+                    <td>{{ participation.getSeatsOccuped }} / {{ participation.getMaxParticipants }}</td>
+                    <td>
+                      
+                    </td>
+                </tr>
+            {% endfor %}
+            </tbody>
+
+        </table>
+    </div>
+
+{% endblock %}

+ 0 - 30
templates/profile/games.html.twig

@@ -1,30 +0,0 @@
-{% extends 'bulma.html.twig' %}
-
-{% block title %}Mes parties{% endblock %}
-
-{% block content %}
-
-    <nav class="breadcrumb has-arrow-separator" aria-label="breadcrumbs">
-      <ul>
-        <li><a href="{{ path('app_main') }}">Accueil</a></li>
-        <li class="is-active"><a href="{{ path('app_profile_games') }}">Mes parties</a></li>
-      </ul>
-    </nav>
-
-    <div class="tabs is-boxed">
-        <ul>
-            <li class="is-active"><a>En tant que joueur(euse)</a></li>
-            {% if app.user.linkToGamemaster %}
-            <li><a>En tant que meneur(euse) de jeu</a></li>
-            {% endif %}
-            <li><a>Mes demandes</a></li>
-        </ul>
-
-
-    </div>
-
-
-
-
-
-{% endblock %}

+ 52 - 0
templates/profile/participations.html.twig

@@ -0,0 +1,52 @@
+{% extends 'bulma.html.twig' %}
+
+{% block title %}Mes parties{% endblock %}
+
+{% block content %}
+
+    <nav class="breadcrumb has-arrow-separator" aria-label="breadcrumbs">
+      <ul>
+        <li><a href="{{ path('app_main') }}">Accueil</a></li>
+        <li class="is-active"><a href="{{ path('app_profile_participations') }}">Mes parties</a></li>
+      </ul>
+    </nav>
+
+    <div class="tabs is-boxed">
+        <ul>
+            <li class="is-active"><a>En tant que joueur(euse)</a></li>
+            {% if app.user.linkToGamemaster %}
+            <li><a href="{{ path('app_profile_participations_gming') }}">En tant que meneur(euse) de jeu</a></li>
+            {% endif %}
+            <li><a>Mes demandes</a></li>
+        </ul>
+    </div>
+
+    <div class="block">
+        <table id="datatable" {{ stimulus_controller('datatables') }} class="table is-striped is-hoverable is-fullwidth">
+            <thead>
+            <tr>
+                <th>Événement</th>
+                <th>Participant</th>
+                <th>Partie</th>
+                <th>Date et heure</th>
+                <th>Action</th>
+            </tr>
+            </thead>
+            <tbody>
+            {% for participation in participations %}
+                <tr>
+                    <th>{{ participation.party.event.name }}</th>
+                    <td>{{ participation.participantName }}</td>
+                    <td>{{ participation.party.game.name }}</td>
+                    <td>{{ participation.party.startOn|date('d/m/y H:i', app_timezone) }}</td>
+                    <td>
+                      <a href="{{ path('app_participation_cancel', {id: participation.id}) }}" data-turbo="false" class="button is-danger">Annuler</a>
+                    </td>
+                </tr>
+            {% endfor %}
+            </tbody>
+
+        </table>
+    </div>
+
+{% endblock %}