浏览代码

gestion des lock/unlock sur les slots

garthh 3 周之前
父节点
当前提交
3f6afa2b49

+ 77 - 0
assets/controllers/slot_toggle_controller.js

@@ -0,0 +1,77 @@
+
+import { Controller } from "@hotwired/stimulus"
+
+export default class extends Controller {
+    connect() {
+        // Écoute tous les clics sur .open-modal -> détournement vers #lastStep + MAJ des options du formulaire
+      document.querySelectorAll('.planning-cell-free, .planning-cell-locked').forEach(element => {
+          element.addEventListener('click', this.handleClick.bind(this))
+      })
+    }
+
+    handleClick(event) {
+        event.preventDefault()
+        const slotId = event.currentTarget.dataset.id
+        const cell = event.currentTarget;
+        const path = cell.querySelector('.icon path');
+
+        if (!slotId) return
+
+        // A partir du slotId ->
+        // 1. trouver l'état du slot cliqué et le basculer dans la BDD (LOCKED/UNLOCKED/GAME)
+        // 2. mettre à jour le style de la case cliquée
+
+        // Etape 1
+        fetch(`/api/slot/${slotId}/toggleStatus`, {
+          method: 'POST',
+          headers: {
+            'Accept': 'application/json'
+          }
+        })
+          .then(response => {
+            if (!response.ok) {
+              throw new Error(`Erreur API: ${response.status}`);
+            }
+            return response.json();
+          })
+          .then(data => {
+            
+            // Etape 2
+            console.log('ID du slot cliqué :', slotId);
+            console.log('ÉTAT DU SLOT :', data.status);
+
+            if (data.status === "UNLOCKED") {
+              cell.classList.add('planning-cell-free');
+              cell.classList.remove('planning-cell-locked');
+              path.setAttribute('d', 'M12 0a4 4 0 0 1 4 4v2.5h-1V4a3 3 0 1 0-6 0v2h.5A2.5 2.5 0 0 1 12 8.5v5A2.5 2.5 0 0 1 9.5 16h-7A2.5 2.5 0 0 1 0 13.5v-5A2.5 2.5 0 0 1 2.5 6H8V4a4 4 0 0 1 4-4');
+            } else if (data.status === "LOCKED") {
+              cell.classList.remove('planning-cell-free');
+              cell.classList.add('planning-cell-locked');
+              path.setAttribute('d', 'M8 0a4 4 0 0 1 4 4v2.05a2.5 2.5 0 0 1 2 2.45v5a2.5 2.5 0 0 1-2.5 2.5h-7A2.5 2.5 0 0 1 2 13.5v-5a2.5 2.5 0 0 1 2-2.45V4a4 4 0 0 1 4-4m0 1a3 3 0 0 0-3 3v2h6V4a3 3 0 0 0-3-3');
+            } else {
+              console.warn("Statut de réponse sans action :", data.status);
+            }
+
+          })
+          .catch(error => {
+            console.error('Erreur lors de la récupération des slots :', error);
+          });
+
+
+
+        
+
+
+
+
+
+    }
+
+    disconnect() {
+    this.element.querySelectorAll('.planning-cell-free').forEach(element => {
+        element.removeEventListener('click', this.handleClick)
+    })
+}
+
+
+}

+ 5 - 0
assets/styles/app.css

@@ -153,6 +153,11 @@
   border-bottom: 1px solid #ccc;
   z-index: 0;
   justify-content: center;
+  background-image: url('data:image/svg+xml;utf8,\
+<svg xmlns="http://www.w3.org/2000/svg" width="8" height="8" fill="none" stroke="%23ccc" stroke-width="1" stroke-opacity="0.66">\
+<path d="M0 8 L8 0"/>\
+</svg>');
+    );
 }
 
 /* Hidden slot */

+ 33 - 0
src/Controller/Admin/EventConfig/SlotController.php

@@ -18,6 +18,39 @@ use App\Service\DateTimeHelper;
 
 final class SlotController extends AbstractController
 {
+    #[Route('/api/slot/{id}/toggleStatus', name: 'api_slot_toggle_status', requirements: ['id' => '\d+'], methods: ['POST'])]
+    public function apiSlotToggleStatus(?Slot $slot, EntityManagerInterface $manager): JsonResponse
+    {
+        // Accès uniquement aux admin
+        if (!$this->isGranted('ROLE_ADMIN')) {
+            return $this->json(['error' => 'Unauthorized'], 403);
+        }
+        if (!$slot) {
+            return $this->json(['error' => 'Slot not found'], 404);
+        }
+
+        $returnCode = "ERROR";
+
+        // Partie, on arrête et modifie pas la BDD
+        if ($slot->getParty()) {
+            $returnCode = "PARTY|".$slot->getParty()->getId()->toString();
+        } else {
+            // Bascule Unavaible -> Available
+            if ($slot->isUnavailable()) {
+                $slot->setUnavailable(false);
+                $manager->persist($slot);
+                $manager->flush();
+                $returnCode = "UNLOCKED";
+            } else {
+                $slot->setUnavailable(true);
+                $manager->persist($slot);
+                $manager->flush();
+                $returnCode = "LOCKED";
+            }
+        }
+        return $this->json(["status" => $returnCode]);
+    }
+
     #[Route('/api/slot/{id}/nexts', name: 'api_slot_nexts', requirements: ['id' => '\d+'], methods: ['POST'])]
     public function apiSlotNexts(?Slot $slot, SlotRepository $repository): JsonResponse
     {

+ 2 - 2
templates/admin/event/config/slot.html.twig

@@ -83,11 +83,11 @@
         <div class="block">
           <div class="content">
           <h3 class="title is-3">Aperçu du planning</h3>
-          <p>Cliquez sur les <strong>slots</strong> pour les basculer <span class="icon-text"><span class="icon"><twig:ux:icon name="bi:lock-fill"/></span><span><em>indisponible</em></span></span> (aucune partie ne pourra être organisé sur ce slot) ou  <span class="icon-text"><span class="icon"><twig:ux:icon name="bi:unlock-fill"/></span><span><em>disponible</em></span></span>. <em class="has-text-danger">Fonctionnalité en cours de développement.</em></p>
+          <p>Cliquez sur les <strong>slots</strong> pour les basculer <span class="icon-text"><span class="icon"><twig:ux:icon name="bi:lock-fill"/></span><span><em>indisponible</em></span></span> (aucune partie ne pourra être organisé sur ce slot) ou  <span class="icon-text"><span class="icon"><twig:ux:icon name="bi:unlock-fill"/></span><span><em>disponible</em></span></span>.
           </div>
         </div>
         {% if event.getSlots()|length > 0 %}
-        <div id="planning">
+        <div id="planning" {{ stimulus_controller('slot_toggle') }}>
           {{ component('Planning', {event: event, displayLocked: true}) }}
         </div>
         {% else %}

+ 1 - 1
templates/components/Planning.html.twig

@@ -41,7 +41,7 @@
                                 <div class="icon"><twig:ux:icon name="bi:lock-fill" /></div>
                             </div>
                             {% else %}
-                            <div class="cell planning-cell planning-cell-hidden">
+                            <div class="cell planning-cell planning-cell-locked">
                             </div>
                             {% endif %}
                         {% endif %}