Browse Source

enregistrement des demandes

garthh 4 weeks ago
parent
commit
f12da5d3fc

+ 36 - 0
src/Controller/ManageController.php

@@ -48,4 +48,40 @@ final class ManageController extends AbstractController
             'events' => $events
         ]);
     }
+
+    #[Route('/manage/{id}/list', name: 'app_manage_party_list', requirements: ['id' => Requirement::UUID_V7], methods: ['GET', 'POST'])]
+    public function managePartyList(?Event $event, EventRepository $repository): Response
+    {
+        // Contrôler qu'un événement est bien ok
+        if (!$event) {
+            $this->addFlash('danger', 'Événement inconnu !');
+            $this->redirectToRoute('app_manage');
+        }
+
+        // Récupérer la liste des événements visibles
+        $events = $repository->findEventsToCome(false);
+
+        return $this->render('manage/list.html.twig', [
+            'event' => $event,
+            'events' => $events
+        ]);
+    }
+
+    #[Route('/manage/{id}/booking', name: 'app_manage_booking', requirements: ['id' => Requirement::UUID_V7], methods: ['GET', 'POST'])]
+    public function manageBooking(?Event $event, EventRepository $repository): Response
+    {
+        // Contrôler qu'un événement est bien ok
+        if (!$event) {
+            $this->addFlash('danger', 'Événement inconnu !');
+            $this->redirectToRoute('app_manage');
+        }
+
+        // Récupérer la liste des événements visibles
+        $events = $repository->findEventsToCome(false);
+
+        return $this->render('manage/booking.html.twig', [
+            'event' => $event,
+            'events' => $events
+        ]);
+    }
 }

+ 29 - 16
src/Controller/PartyRequestController.php

@@ -19,6 +19,7 @@ use App\Entity\Game;
 use App\Entity\Event;
 use App\Repository\GamemasterRepository;
 use App\Repository\GameRepository;
+use App\Repository\PartyRequestRepository;
 use App\Form\PartyRequestType;
 
 final class PartyRequestController extends AbstractController
@@ -51,34 +52,46 @@ final class PartyRequestController extends AbstractController
         $partyRequest->setRequester($user);
         $partyRequest->setDateRequest(new \Datetime('now'));
 
-        $form = $this->createForm(PartyRequestForm::class, $partyRequest);
+        $form = $this->createForm(PartyRequestType::class, $partyRequest);
 
         // Traitement du formulaire
         $form->handleRequest($request);
         if ($form->isSubmitted() && $form->isValid()) {
+            $gamemasterSelectedId = $request->request->get('party_gamemaster');
+            $gamemasterSelected = $gamemasterRepository->findByStrID($gamemasterSelectedId);
+            $gameSelectedId = $request->request->get('party_game');
+            $gameSelected = $gameRepository->findByStrID($gameSelectedId);
+            $partyRequest->setGameChoosen($gameSelected);
+            $partyRequest->setGamemasterChoosen($gamemasterSelected);
             $manager->persist($partyRequest);
             $manager->flush();
 
-            // Envoyer un mail
-            // Maintenant uniquement pour avoir l'ID
-            $email = (new TemplatedEmail())
-                ->from(new Address($_ENV['CONTACT_EMAIL'], $_ENV['CONTACT_NAME']))
-                ->to((string) $user->getEmail())
-                ->subject('Votre demande pour '.$event->getName())
-                ->htmlTemplate('party_request/request.email.html.twig')
-                ->textTemplate('party_request/request.email.txt.twig')
-                ->context([
-                    'partyRequest' => $partyRequest
-                ]);
-            $mailer->send($email);
+            // @todo: peut-être envoyer un mail de confirmation ??
 
-            $this->addFlash('danger', 'Demande enregistrée, les gestionnaires y répondront prochainement.');
-            $this->redirectToRoute('app_main_booking', ['id' => $event.getId()]);
+            $this->addFlash('success', 'Demande enregistrée, les gestionnaires y répondront prochainement.');
+            $referer = $request->headers->get('referer'); 
+            return $this->redirect($referer);
         }
 
         return $this->render('party_request/_modal.request.html.twig', [
             'form' => $form,
-            'partyRequest' => $partyRequest
+            'partyRequest' => $partyRequest,
+            'event' => $event,
+            'pathController' => 'app_party_request'
         ]);
     }
+
+    #[Route('/party/request/{id}/delete', name: 'app_party_request_delete', requirements: ['id' => Requirement::UUID_V7], methods: ['GET'])]
+    public function delete(?PartyRequest $partyRequest, Request $request, EntityManagerInterface $entityManager)
+    {
+        if (!$partyRequest) {
+            $this->addFlash('danger', 'Cette demande n\'existe pas.');
+        } else {
+            $entityManager->remove($partyRequest);
+            $entityManager->flush();
+        }
+
+        $referer = $request->headers->get('referer'); 
+        return $this->redirect($referer);
+    }
 }

+ 16 - 0
src/Controller/ProfileController.php

@@ -234,4 +234,20 @@ final class ProfileController extends AbstractController
             'user' => $user
         ]);
     }
+
+    #[Route('/profile/participations/requests', name: 'app_prodile_participations_requests')]
+    public function participationRequests(): Response
+    {
+        $user = $this->getUser();
+        if (!$user) {
+            $this->addFlash('danger', 'Aucun utilisateur connecté');
+            $this->redirectToRoute('app_main');
+        }
+        $partyRequests = $user->getPartyRequests();
+        
+        return $this->render('profile/partyrequests.html.twig', [
+            'user' => $user,
+            'partyRequests' => $partyRequests
+        ]);
+    }
 }

+ 14 - 2
src/Entity/PartyRequest.php

@@ -2,7 +2,7 @@
 
 namespace App\Entity;
 
-use App\Repository\PartyRepository;
+use App\Repository\PartyRequestRepository;
 use Doctrine\Common\Collections\ArrayCollection;
 use Doctrine\Common\Collections\Collection;
 use Doctrine\DBAL\Types\Types;
@@ -50,7 +50,19 @@ class PartyRequest
     #[ORM\Column(type: Types::TEXT, nullable: true)]
     private ?string $message = null;
 
-    public function getId(): ?int
+    public function getState(): ?array
+    {
+        $state = ['code' => 'REFUSED', 'name' => 'Refusée'];
+        if (is_null($this->modOnDate) && is_null($this->accepted)) {
+            $state = ['code' => 'WAIT', 'name' => 'En attente'];
+        }
+        if ($this->accepted) {
+            $state =  ['code' => 'ACCEPTED', 'name' => 'Acceptée'];;
+        }
+        return $state;
+    }
+
+    public function getId(): ?Uuid
     {
         return $this->id;
     }

File diff suppressed because it is too large
+ 1 - 1
templates/bulma.html.twig


+ 1 - 1
templates/main/booking.html.twig

@@ -83,7 +83,7 @@
     </div>
     {% if event.isEveryoneCanAskForGame and is_granted('ROLE_USER') %}
     <div class="column">
-      <a href="#" class="button is-primary open-modal">Demander une partie</a>
+      <a href="{{ path('app_party_request', {id: event.id}) }}" class="button is-primary open-modal">Demander une partie</a>
     </div>
     {% endif %}
   </div>

+ 1 - 1
templates/main/index.html.twig

@@ -38,7 +38,7 @@
               <div class="card-footer">
                 <a class="card-footer-item" href="{{ path('app_main_booking', {id: event.id}) }}">Réserver une place</a>
                 {% if is_granted('ROLE_MANAGER') or is_granted('ROLE_ADMIN') %}
-                <a class="card-footer-item" href="{{ path('app_manage', {id: event.id}) }}">Gérer</a>
+                <a class="card-footer-item" href="{{ path('app_manage_planning', {id: event.id}) }}">Gérer</a>
                 {% endif %} 
               </div>
             </div>

+ 113 - 0
templates/manage/booking.html.twig

@@ -0,0 +1,113 @@
+{% extends 'bulma.html.twig' %}
+
+{% block title %}Gestion pour {{ event.name }}{% endblock %}
+
+{% block content %}
+
+{{ component('Modal')}}
+
+
+<div class="card" {{ stimulus_controller('dropdown')}} >
+  <div class="card-footer">
+    <div class="dropdown card-footer-item is-flex is-justify-content-space-between is-align-items-center" data-action="click->dropdown#toggle">
+      <button>
+        <span><strong>{{ event.name }} - du {{ event.startOn|date('d/m/y à H:i', app_timezone) }} au {{ event.endOn|date('d/m/y à H:i', app_timezone)}}</strong></span>        
+      </button>
+      {% if events|length > 1 %}
+      <span class="icon is-small">
+        <twig:ux:icon name="bi:chevron-down" />&nbsp;
+      </span>
+      <div data-dropdown-target="menu" class="dropdown-menu">
+        <div class="dropdown-content">
+          {% for evt in events %}
+          {% if event.id != evt.id %}
+          <a href="{{ path('app_manage_planning', {id: evt.id})}}" class="dropdown-item"><strong>{{ evt.name }}</strong><small> du {{ evt.startOn|date('d/m/y H:i', app_timezone) }} au {{ evt.endOn|date('d/m/y H:i', app_timezone)}}</small></a>
+          {% endif %}
+          {% endfor %}
+        </div>
+      </div>
+      {% endif %}
+    </div>
+  </div>
+
+
+
+
+
+</div>
+
+<div class="box is-clearfix">
+  <div class="columns">
+    {% if not event.isHiddenPlanning %}
+    <div class="column">
+      <p>{{ event.getParties()|length }} parties proposées</p>
+    </div>
+    {% endif %}
+    <div class="column">
+      <p class="is-inline-block icon-text">{{ event.getGamemastersAssigned|length }} meneur(euse)s de jeu
+        {% for gamemaster in event.getGamemastersAssigned %}
+          <span class="icon">
+              <a href="{{ path('app_gamemaster_public_profile', {id: gamemaster.id}) }}" class="open-modal" title="{{ gamemaster.preferedName }}"><figure class="image is-24x24 is-inline-block">
+              {% if gamemaster.picture %}
+              <img class="is-rounded" src="/images/gamemasters/{{ gamemaster.picture }}" alt="{{ gamemaster.preferedName }}"/>
+              {% else %}
+              <twig:ux:icon name="bi:person-fill"/>
+              {% endif %}
+              </figure></a>
+          </span>   
+        {% endfor %}
+      </p>
+    </div>
+  </div>
+
+</div>
+
+    <div class="tabs is-boxed">
+        <ul>
+            <li><a href="{{ path('app_manage_planning', {id: event.id}) }}">Planning</a></li>
+            <li><a href="{{ path('app_manage_party_list', {id: event.id})}}">Liste des parties</a></li>
+            <li class="is-active"><a>Liste des participant(e)s</a></li>
+            <li><a>Liste des demandes</a></li>
+
+
+        </ul>
+    </div>
+
+
+<section>
+        <table id="datatable" {{ stimulus_controller('datatables') }} class="table is-striped is-hoverable is-fullwidth">
+            <thead>
+            <tr>
+                <th>Participant(e)</th>
+                <th>Horaire</th>
+                <th>Espace</th>
+                <th>Jeu</th>
+                <th>Meneur(euse)</th>
+                <th>Action</th>
+            </tr>
+            </thead>
+            <tbody>
+            {% for partie in event.getParties %}
+            {% for participation in partie.getParticipations %}
+                <tr>
+                    <td>{{ participation.participantName }}</td>
+                    <th>{{ participation.party.startOn|date('d/m/y @ H:i', app_timezone) }}</th>
+                    <td>{{ participation.party.slots.first.space.name }}</td>
+                    <td>{{ participation.party.game.name }}</td>
+                    <td>{{ participation.party.gamemaster.preferedName }}</td>
+
+                    
+                    
+
+                    <td>
+                      
+                    </td>
+                </tr>
+            {% endfor %}
+            {% endfor %}
+            </tbody>
+
+        </table>
+</section>
+
+{% endblock %}

+ 107 - 0
templates/manage/list.html.twig

@@ -0,0 +1,107 @@
+{% extends 'bulma.html.twig' %}
+
+{% block title %}Gestion pour {{ event.name }}{% endblock %}
+
+{% block content %}
+
+{{ component('Modal')}}
+
+
+<div class="card" {{ stimulus_controller('dropdown')}} >
+  <div class="card-footer">
+    <div class="dropdown card-footer-item is-flex is-justify-content-space-between is-align-items-center" data-action="click->dropdown#toggle">
+      <button>
+        <span><strong>{{ event.name }} - du {{ event.startOn|date('d/m/y à H:i', app_timezone) }} au {{ event.endOn|date('d/m/y à H:i', app_timezone)}}</strong></span>        
+      </button>
+      {% if events|length > 1 %}
+      <span class="icon is-small">
+        <twig:ux:icon name="bi:chevron-down" />&nbsp;
+      </span>
+      <div data-dropdown-target="menu" class="dropdown-menu">
+        <div class="dropdown-content">
+          {% for evt in events %}
+          {% if event.id != evt.id %}
+          <a href="{{ path('app_manage_planning', {id: evt.id})}}" class="dropdown-item"><strong>{{ evt.name }}</strong><small> du {{ evt.startOn|date('d/m/y H:i', app_timezone) }} au {{ evt.endOn|date('d/m/y H:i', app_timezone)}}</small></a>
+          {% endif %}
+          {% endfor %}
+        </div>
+      </div>
+      {% endif %}
+    </div>
+  </div>
+
+
+
+
+
+</div>
+
+<div class="box is-clearfix">
+  <div class="columns">
+    {% if not event.isHiddenPlanning %}
+    <div class="column">
+      <p>{{ event.getParties()|length }} parties proposées</p>
+    </div>
+    {% endif %}
+    <div class="column">
+      <p class="is-inline-block icon-text">{{ event.getGamemastersAssigned|length }} meneur(euse)s de jeu
+        {% for gamemaster in event.getGamemastersAssigned %}
+          <span class="icon">
+              <a href="{{ path('app_gamemaster_public_profile', {id: gamemaster.id}) }}" class="open-modal" title="{{ gamemaster.preferedName }}"><figure class="image is-24x24 is-inline-block">
+              {% if gamemaster.picture %}
+              <img class="is-rounded" src="/images/gamemasters/{{ gamemaster.picture }}" alt="{{ gamemaster.preferedName }}"/>
+              {% else %}
+              <twig:ux:icon name="bi:person-fill"/>
+              {% endif %}
+              </figure></a>
+          </span>   
+        {% endfor %}
+      </p>
+    </div>
+  </div>
+
+</div>
+
+    <div class="tabs is-boxed">
+        <ul>
+            <li><a href="{{ path('app_manage_planning', {id: event.id}) }}">Planning</a></li>
+            <li class="is-active"><a>Liste des parties</a></li>
+            <li><a href="{{ path('app_manage_booking', {id: event.id}) }}">Liste des participant(e)s</a></li>
+            <li><a>Liste des demandes</a></li>
+
+
+        </ul>
+    </div>
+
+
+<section>
+        <table id="datatable" {{ stimulus_controller('datatables') }} class="table is-striped is-hoverable is-fullwidth">
+            <thead>
+            <tr>
+                <th>Horaire</th>
+                <th>Espace</th>
+                <th>Jeu</th>
+                <th>Meneur(euse)</th>
+                <th>Participant(e)s</th>
+                <th>Action</th>
+            </tr>
+            </thead>
+            <tbody>
+            {% for party in event.getParties %}
+                <tr>
+                    <th>{{ party.startOn|date('d/m/y @ H:i', app_timezone) }} à {{ party.endOn|date('H:i', app_timezone) }}</th>
+                    <td>{{ party.slots.first.space.name }}</td>
+                    <td>{{ party.game.name }}</td>
+                    <td>{{ party.gamemaster.preferedName }}</td>
+                    <td>{{ party.getSeatsOccuped }} / {{ party.getMaxParticipants }}</td>
+                    <td>
+                      
+                    </td>
+                </tr>
+            {% endfor %}
+            </tbody>
+
+        </table>
+</section>
+
+{% endblock %}

+ 2 - 2
templates/manage/manage.html.twig

@@ -65,8 +65,8 @@
     <div class="tabs is-boxed">
         <ul>
             <li class="is-active"><a>Planning</a></li>
-            <li><a>Liste des parties</a></li>
-            <li><a>Liste des participants</a></li>
+            <li><a href="{{ path('app_manage_party_list', {id: event.id})}}">Liste des parties</a></li>
+            <li><a href="{{ path('app_manage_booking', {id: event.id}) }}">Liste des participant(e)s</a></li>
             <li><a>Liste des demandes</a></li>
 
 

+ 51 - 0
templates/party_request/_modal.request.html.twig

@@ -0,0 +1,51 @@
+{% extends 'modal.html.twig' %}
+
+{% block title %}Votre demande{% endblock %}
+
+{% block content %}
+
+    <div class="block">
+        <div class="content">
+        <p>Ce formulaire vous permet de demander une partie particulière. Votre demande sera traitée par les gestionnaires qui vous proposeront des horaires sur l'événements selon les disponibilités du(e la) meneur(euse) de jeu. Vous recevrez un mail avec la proposition de partie. Si vous êtes accompagné, merci de l'indiquer dès maintenant dans le message (nombre d'accompagnant(e)s, précisions particulières sur vos disponibilités..).</p>
+        <ol>
+            <li>Choisissez votre jeu</li>
+            <li>Choisissez votre MJ</li>
+            <li>Ajoutez un message</li>
+        </ol>
+        </div>
+    </div>
+
+    {{ form_errors(form) }}
+    {{ form_start(form, {action: path(pathController, {id: event.getId}), attr: {'data-turbo-frame': 'modal-content'}}) }}
+
+    <div id="game-controller" class="field" {{ stimulus_controller('partyrequest_selector') }}>
+        <label class="label">Jeu de rôle</label>
+        <select id="party_game" name="party_game" class="input">
+            <option value=""></option>
+            {% for game in event.gameAssigned %}
+            <option value="{{ game.id }}" data-gamemasters="{{ game.gamemasters|map(gm => gm.getId)|join('|')}}">{{ game.getName() }}</option> 
+            {% endfor %}
+        </select>
+    </div>
+
+    <div id="gamemaster-controller" class="field">
+        <label class="label">Meneur(euse) de jeu</label>
+        <select id="party_gamemaster" name="party_gamemaster" class="input">
+            <option value=""></option>
+            {% for gamemaster in event.gamemastersAssigned %}
+            <option value="{{ gamemaster.id }}" disabled>{{ gamemaster.getPreferedName() }} </option> 
+            {% endfor %}
+        </select>
+    </div>
+
+    {{ form_row(form.message) }}
+
+    {{ form_widget(form) }}
+    
+    <div class="control">
+        <button class="button is-primary" type="submit">Envoyer</button>
+    </div>
+
+    {{ form_end(form) }}
+
+{% endblock %}

+ 0 - 20
templates/party_request/index.html.twig

@@ -1,20 +0,0 @@
-{% extends 'base.html.twig' %}
-
-{% block title %}Hello PartyRequestController!{% endblock %}
-
-{% block body %}
-<style>
-    .example-wrapper { margin: 1em auto; max-width: 800px; width: 95%; font: 18px/1.5 sans-serif; }
-    .example-wrapper code { background: #F5F5F5; padding: 2px 6px; }
-</style>
-
-<div class="example-wrapper">
-    <h1>Hello {{ controller_name }}! ✅</h1>
-
-    This friendly message is coming from:
-    <ul>
-        <li>Your controller at <code>/Users/garthh/Developpement/orgasso/src/Controller/PartyRequestController.php</code></li>
-        <li>Your template at <code>/Users/garthh/Developpement/orgasso/templates/party_request/index.html.twig</code></li>
-    </ul>
-</div>
-{% endblock %}

+ 2 - 2
templates/profile/gamemastering.html.twig

@@ -17,7 +17,7 @@
             {% 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>
+            <li><a href="{{ path('app_prodile_participations_requests') }}">Mes demandes</a></li>
         </ul>
     </div>
 
@@ -28,7 +28,7 @@
                 <th>Événement</th>
                 <th>Jeu</th>
                 <th>Date et heure</th>
-                <th>Participants</th>
+                <th>Participant(e)s</th>
                 <th>Action</th>
             </tr>
             </thead>

+ 2 - 2
templates/profile/participations.html.twig

@@ -17,7 +17,7 @@
             {% 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>
+            <li><a href="{{ path('app_prodile_participations_requests') }}">Mes demandes</a></li>
         </ul>
     </div>
 
@@ -40,7 +40,7 @@
                     <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>
+                      <a href="#" data-id="{{ path('app_participation_cancel', {id: participation.id}) }}" class="button is-danger" {{ stimulus_controller('admin_confirm') }}>Annuler</a>
                     </td>
                 </tr>
             {% endfor %}

+ 54 - 0
templates/profile/partyrequests.html.twig

@@ -0,0 +1,54 @@
+{% 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><a href="{{ path('app_profile_participations_gming') }}">En tant que meneur(euse) de jeu</a></li>
+            {% endif %}
+            <li class="is-active"><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>Meneur</th>
+                <th>État</th>
+                <th>Action</th>
+            </tr>
+            </thead>
+            <tbody>
+            {% for partyRq in partyRequests %}
+                <tr>
+                    <th>{{ partyRq.event.name }}</th>
+                    <td>{{ partyRq.gameChoosen.name }}</td>
+                    <td>{{ partyRq.gamemasterChoosen.preferedName }}</td>
+                    <td>{{ partyRq.state['name'] }}</td>
+                    <td>
+                        {% if partyRq.state['code'] == 'WAIT' %}
+                        <a href="#" data-id="{{ path('app_party_request_delete', {id: partyRq.id}) }}" class="button is-danger" {{ stimulus_controller('admin_confirm') }}>Supprimer</a>
+                        {% endif %}
+                    </td>
+                </tr>
+            {% endfor %}
+            </tbody>
+
+        </table>
+    </div>
+
+{% endblock %}

Some files were not shown because too many files changed in this diff