Loading app/Http/Controllers/ManualPalanqueeController.php 0 → 100644 +53 −0 Original line number Diff line number Diff line <?php namespace App\Http\Controllers; use App\Models\DivingGroup; use App\Models\DivingSignUpModel; use App\Models\User; use Illuminate\Http\Request; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Log; class ManualPalanqueeController extends Controller { public function show(){ $token = csrf_token(); return view('palanque_manuel', compact('token')); } public function index(){ } public function store(Request $request){ try { $divingGroups = $request->json()->all(); $ds_code = end($divingGroups); $maxDG = DivingGroup::select()->where('DS_CODE', $ds_code)->max('DG_NUMBER'); if($maxDG == null) $maxDG = 1; else $maxDG += 1; for($i = 0; $i < count($divingGroups) - 1; $i++) { $divingNumber = $i + 1; if($divingNumber >= $maxDG){ Log::info('Creating diving group ' . $maxDG . ' for diving session ' . $ds_code); DivingGroup::insert(['DS_CODE' => $ds_code, 'DG_NUMBER' => $maxDG]); $maxDG += 1; } foreach($divingGroups[$i] as $diver){ Log::info('Adding diver ' . $diver . ' to diving group ' . $divingNumber . ' for diving session ' . $ds_code); $update = DivingSignUpModel::where('US_ID', $diver) ->where('DS_CODE', $ds_code)->update(['DG_NUMBER' => $divingNumber]); } } $responseData = ['message' => 'Data received successfully', 'additionalData' => $divingGroups]; return response()->json($responseData); } catch (\Illuminate\Database\QueryException $e) { return response()->json(['error' => 'Internal Server Error', 'errData' => $e], 500); } } } app/Models/DivingGroup.php +1 −0 Original line number Diff line number Diff line Loading @@ -9,6 +9,7 @@ class DivingGroup extends Model { protected $table = 'CAR_DIVING_GROUP'; protected $fillable = ['DS_CODE', 'DG_NUMBER']; use HasFactory; Loading app/Models/DivingSession.php +0 −24 Original line number Diff line number Diff line Loading @@ -41,28 +41,4 @@ public function disable() $this->DS_ACTIVE = 0; $this->save(); } public function getRoleForUser(User $user){ if($user->US_ID === $this->US_ID_CAR_DIRECT){ return "Directeur de plongée"; } if($user->US_ID === $this->US_ID){ return "Pilote"; } if($user->US_ID === $this->US_ID_CAR_SECURE){ return "Sécurité de surface"; } if($user->US_TEACHING_LEVEL > 0){ return "Encadrant"; } if(strpos($user->PRE_CODE, 'GP')){ return "Guide de palanquée"; } return "Plongeur"; } } public/js/Palanque/manualPalanque.js 0 → 100644 +294 −0 Original line number Diff line number Diff line class DropZoneClass{ counter; zoneNumber; constructor(zoneNumber){ this.counter = 0; this.zoneNumber = zoneNumber; } getCounter(){ return this.counter; } getZoneNumber(){ return this.zoneNumber; } updateCounterPos(number){ this.counter += number; } updateCounterNeg(number){ this.counter -= number; } } const zoneStart = document.getElementById("zoneStart"); const DropZone = document.getElementById("DropZone"); const removePalanque = document.getElementById("removePal"); const addPalanque = document.getElementById("addPal"); const validatePalanque = document.getElementById("validatePal"); let countZone = 0; let countDiver = 0; let zoneList = []; let counterCheck = 0; let disableVal = true; getDiver("DS1").then(data => fillZoneWithAlreadyExistingPalanque(data)); window.onload = () => { setZoneSize(DropZone.childNodes); } function allowDrop(event) { event.preventDefault(); } function drag(event) { event.dataTransfer.setData("draggable", event.target.id); } function drop(event) { event.preventDefault(); let index = event.target.id.split('zone')[1]; if(isElementInList('item', event.target.id.split(','))) return; let data = event.dataTransfer.getData("draggable"); let draggedItem = document.getElementById(data); if(event.target === zoneStart){ zoneList[draggedItem.parentElement.id.split('zone')[1]].updateCounterNeg(setDropZoneSize(draggedItem)); console.log("Count" + zoneList[draggedItem.parentElement.id.split('zone')[1]].getCounter()); zoneStart.appendChild(draggedItem); }else if(zoneList[index].getCounter() <= 3 && zoneList[index].getCounter() + setDropZoneSize(draggedItem) <= 3){ if(draggedItem.parentElement !== zoneStart && draggedItem.parentElement !== undefined && draggedItem.parentElement !== zoneList[index]) zoneList[draggedItem.parentElement.id.split('zone')[1]].updateCounterNeg(setDropZoneSize(draggedItem)); zoneList[index].updateCounterPos(setDropZoneSize(draggedItem)); console.log("Count" + zoneList[index].getCounter()); event.target.appendChild(draggedItem); }else{ zoneStart.appendChild(draggedItem); zoneList[index].updateCounterNeg(setDropZoneSize(draggedItem)); console.log("Count" + zoneList[index].getCounter()); } } function setZoneSize(zone){ zone.forEach(element => { element.childNodes.forEach(elements => { if(elements.id.split(',')[1] === 'PB') zoneList[element.id.split('zone')[1] ].updateCounterPos(2); else zoneList[element.id.split('zone')[1] ].updateCounterPos(1); }); }); } function setDropZoneSize(element){ let targetItemsSplit = element.id.split(','); for(let i = 0; i < targetItemsSplit.length; i++){ if(targetItemsSplit[i] === 'PB') return 2; } return 1; } function isElementInList(element, list){ for(let i = 0; i < list.length; i++){ if(element == list[i]) return true; } return false; } addPalanque.addEventListener("click", function(){ let palanque = document.createElement("div"); palanque.setAttribute("class", "border-2 p-4 zone"); palanque.setAttribute("id", "zone" + countZone); palanque.setAttribute("ondrop", "drop(event)"); palanque.setAttribute("ondragover", "allowDrop(event)"); zoneList.push(new DropZoneClass(countZone)); DropZone.appendChild(palanque); countZone++; }); removePalanque.addEventListener("click", function(){ countZone--; let palanque = document.getElementById("zone" + countZone); if(palanque.childElementCount > 0){ console.log(palanque.childNodes[1]); for(let i = 0; i < palanque.childElementCount; i++){ console.log(palanque.childNodes[i]); zoneStart.appendChild(palanque.childNodes[i]); } } zoneList.splice(zoneList.length - 1, 1); DropZone.removeChild(palanque); }); async function getDiver(ds_code){ let response = await fetch(`/api/dives/${ds_code}/divers`); let data = await response.json().then(data => proccessDiverData(data)); return data; } function proccessDiverData(data){ for(let i = 0; i < data.length; i++){ countDiver++; let diver = document.createElement("div"); diver.setAttribute("class", "w-fit h-8 border-2"); diver.setAttribute("id", 'item' + data[i].US_ID +',' + data[i].PRE_CODE + ',E' + data[i].US_TEACHING_LEVEL + ',' + data[i].US_ID); diver.setAttribute("draggable", "true"); diver.setAttribute("ondragstart", "drag(event)"); diver.innerHTML = data[i].US_FIRST_NAME + " " + data[i].US_NAME + " " + data[i].PRE_CODE + " " + data[i].US_TEACHING_LEVEL; zoneStart.appendChild(diver); } return data; } let validatePalanqueCombinate = { 'PB': ['E1', 'E2', 'E3', 'E4', 'PA-60-GP'], 'PA': ['E1', 'E2', 'E3', 'E4', 'PA-60-GP'], 'PO': ['E1', 'E2', 'E3', 'E4', 'PA-60-GP'], 'PE-12': ['E2', 'E3', 'E4', 'PA-60-GP'], 'PE-20': ['E2', 'E3', 'E4', 'PA-60-GP'], 'PE-40': ['E2', 'E3', 'E4', 'PA-60-GP'] }; function validateAllCombination(){ let counterCheck = 0; zoneList.forEach(element => { element = document.getElementById("zone" + element.getZoneNumber()); if(element.hasChildNodes()){ if(element.childElementCount < 2){ element.style.backgroundColor = 'red'; return false; } let children = element.childNodes; for(let i = 0; i < children.length; i++){ for(let j = 0; j < children.length; j++){ if(children[j].id.split(',')[1] === 'PA-60-GP'){ counterCheck++; if(element.style.backgroundColor === 'red') element.style.backgroundColor = 'white'; return true; } } } for(let i = 0; i < children.length; i++){ { let targetItemsSplit = children[i].id.split(',')[2]; for(targetItemsSplit in validatePalanqueCombinate){ for(let j = 0; j < children.length; j++){ let targetItemsSplit2 = children[j].id.split(',')[2]; if(validatePalanqueCombinate[targetItemsSplit].includes(targetItemsSplit2)){ counterCheck++; if(element.style.backgroundColor === 'red') element.style.backgroundColor = 'white'; return true; } } element.style.backgroundColor = 'red'; return false; } } } }else { element.style.backgroundColor = 'white'; return false; } }); if(DropZone.childElementCount === counterCheck){ disableVal = false; return true; }else { disableVal = true; return false; } } let interval = setInterval(function(){ validateAllCombination(); }, 250); validatePalanque.addEventListener("click", function(){ if(!disableVal){ sendPalanque(); clearInterval(interval); } }); function returnValueToPhp(ds_code) { let palanque = document.querySelectorAll("div.zone"); let palanqueList = []; for (let i = 0; i < palanque.length; i++) { let zoneList = []; for (let j = 0; j < palanque[i].childElementCount; j++) { let item = palanque[i].childNodes[j]; zoneList.push(item.id.split(',')[3]); } palanqueList.push(zoneList); } palanqueList.push(ds_code); return palanqueList; } function sendPalanque() { let palanqueList = returnValueToPhp("DS1"); let palanqueListJson = JSON.stringify(palanqueList); let csrfToken = document.querySelector('meta[name="csrf-token"]').getAttribute('content'); let xhr = new XMLHttpRequest(); xhr.open('POST', '/api/palanques', true); xhr.setRequestHeader("Content-Type", "application/json"); xhr.setRequestHeader('X-CSRF-TOKEN', csrfToken); xhr.onreadystatechange = function () { if (xhr.readyState === XMLHttpRequest.DONE) { if (xhr.status === 200) { console.log("Request successful"); const responseData = JSON.parse(xhr.responseText); console.log("Additional Data:", responseData.additionalData); } else { const responseData = JSON.parse(xhr.responseText); console.error("Request failed", responseData.errData); } } }; xhr.send(palanqueListJson); console.log("send"); } function fillZoneWithAlreadyExistingPalanque(diverList) { diverList.forEach(element => { let diver = document.getElementById('item' + element.US_ID + ',' + element.PRE_CODE + ',E' + element.US_TEACHING_LEVEL + ',' + element.US_ID); if (element.DG_NUMBER !== 0 && element.DG_NUMBER !== null) { let dgNumber = element.DG_NUMBER - 1; let zone = document.getElementById("zone" + dgNumber); if (zone) { zone.appendChild(diver); if(zoneStart.contains(diver)) zoneStart.removeChild(diver); }else{ let palanque = document.createElement("div"); palanque.setAttribute("class", "border-2 p-4 zone"); palanque.setAttribute("id", "zone" + dgNumber); palanque.setAttribute("ondrop", "drop(event)"); palanque.setAttribute("ondragover", "allowDrop(event)"); zoneList.push(new DropZoneClass(dgNumber)); DropZone.appendChild(palanque); palanque.appendChild(diver); if(zoneStart.contains(diver)) zoneStart.removeChild(diver); countZone++; } } }); } resources/views/palanque_manuel.blade.php 0 → 100644 +17 −0 Original line number Diff line number Diff line <meta name="csrf-token" content="{{ $token }}"> <x-layout> <div class="flex justify-around m-5"> <div class="grid grid-cols-1"> <h3>Zone 1</h3> <div class="border-2" id="zoneStart" ondrop="drop(event)" ondragover="allowDrop(event)"> </div> </div> <div class="p-2 grid grid-cols-2 md:grid-cols-3 gap-4" id="DropZone"></div> </div> </div> <button type='button' id="addPal">Add P</button> <button type='button' id="removePal">Remove P</button> <button type='button' id="validatePal">Val</button> <script src=" {{ asset('js/Palanque/manualPalanque.js') }} "></script> </x-layout> Loading
app/Http/Controllers/ManualPalanqueeController.php 0 → 100644 +53 −0 Original line number Diff line number Diff line <?php namespace App\Http\Controllers; use App\Models\DivingGroup; use App\Models\DivingSignUpModel; use App\Models\User; use Illuminate\Http\Request; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Log; class ManualPalanqueeController extends Controller { public function show(){ $token = csrf_token(); return view('palanque_manuel', compact('token')); } public function index(){ } public function store(Request $request){ try { $divingGroups = $request->json()->all(); $ds_code = end($divingGroups); $maxDG = DivingGroup::select()->where('DS_CODE', $ds_code)->max('DG_NUMBER'); if($maxDG == null) $maxDG = 1; else $maxDG += 1; for($i = 0; $i < count($divingGroups) - 1; $i++) { $divingNumber = $i + 1; if($divingNumber >= $maxDG){ Log::info('Creating diving group ' . $maxDG . ' for diving session ' . $ds_code); DivingGroup::insert(['DS_CODE' => $ds_code, 'DG_NUMBER' => $maxDG]); $maxDG += 1; } foreach($divingGroups[$i] as $diver){ Log::info('Adding diver ' . $diver . ' to diving group ' . $divingNumber . ' for diving session ' . $ds_code); $update = DivingSignUpModel::where('US_ID', $diver) ->where('DS_CODE', $ds_code)->update(['DG_NUMBER' => $divingNumber]); } } $responseData = ['message' => 'Data received successfully', 'additionalData' => $divingGroups]; return response()->json($responseData); } catch (\Illuminate\Database\QueryException $e) { return response()->json(['error' => 'Internal Server Error', 'errData' => $e], 500); } } }
app/Models/DivingGroup.php +1 −0 Original line number Diff line number Diff line Loading @@ -9,6 +9,7 @@ class DivingGroup extends Model { protected $table = 'CAR_DIVING_GROUP'; protected $fillable = ['DS_CODE', 'DG_NUMBER']; use HasFactory; Loading
app/Models/DivingSession.php +0 −24 Original line number Diff line number Diff line Loading @@ -41,28 +41,4 @@ public function disable() $this->DS_ACTIVE = 0; $this->save(); } public function getRoleForUser(User $user){ if($user->US_ID === $this->US_ID_CAR_DIRECT){ return "Directeur de plongée"; } if($user->US_ID === $this->US_ID){ return "Pilote"; } if($user->US_ID === $this->US_ID_CAR_SECURE){ return "Sécurité de surface"; } if($user->US_TEACHING_LEVEL > 0){ return "Encadrant"; } if(strpos($user->PRE_CODE, 'GP')){ return "Guide de palanquée"; } return "Plongeur"; } }
public/js/Palanque/manualPalanque.js 0 → 100644 +294 −0 Original line number Diff line number Diff line class DropZoneClass{ counter; zoneNumber; constructor(zoneNumber){ this.counter = 0; this.zoneNumber = zoneNumber; } getCounter(){ return this.counter; } getZoneNumber(){ return this.zoneNumber; } updateCounterPos(number){ this.counter += number; } updateCounterNeg(number){ this.counter -= number; } } const zoneStart = document.getElementById("zoneStart"); const DropZone = document.getElementById("DropZone"); const removePalanque = document.getElementById("removePal"); const addPalanque = document.getElementById("addPal"); const validatePalanque = document.getElementById("validatePal"); let countZone = 0; let countDiver = 0; let zoneList = []; let counterCheck = 0; let disableVal = true; getDiver("DS1").then(data => fillZoneWithAlreadyExistingPalanque(data)); window.onload = () => { setZoneSize(DropZone.childNodes); } function allowDrop(event) { event.preventDefault(); } function drag(event) { event.dataTransfer.setData("draggable", event.target.id); } function drop(event) { event.preventDefault(); let index = event.target.id.split('zone')[1]; if(isElementInList('item', event.target.id.split(','))) return; let data = event.dataTransfer.getData("draggable"); let draggedItem = document.getElementById(data); if(event.target === zoneStart){ zoneList[draggedItem.parentElement.id.split('zone')[1]].updateCounterNeg(setDropZoneSize(draggedItem)); console.log("Count" + zoneList[draggedItem.parentElement.id.split('zone')[1]].getCounter()); zoneStart.appendChild(draggedItem); }else if(zoneList[index].getCounter() <= 3 && zoneList[index].getCounter() + setDropZoneSize(draggedItem) <= 3){ if(draggedItem.parentElement !== zoneStart && draggedItem.parentElement !== undefined && draggedItem.parentElement !== zoneList[index]) zoneList[draggedItem.parentElement.id.split('zone')[1]].updateCounterNeg(setDropZoneSize(draggedItem)); zoneList[index].updateCounterPos(setDropZoneSize(draggedItem)); console.log("Count" + zoneList[index].getCounter()); event.target.appendChild(draggedItem); }else{ zoneStart.appendChild(draggedItem); zoneList[index].updateCounterNeg(setDropZoneSize(draggedItem)); console.log("Count" + zoneList[index].getCounter()); } } function setZoneSize(zone){ zone.forEach(element => { element.childNodes.forEach(elements => { if(elements.id.split(',')[1] === 'PB') zoneList[element.id.split('zone')[1] ].updateCounterPos(2); else zoneList[element.id.split('zone')[1] ].updateCounterPos(1); }); }); } function setDropZoneSize(element){ let targetItemsSplit = element.id.split(','); for(let i = 0; i < targetItemsSplit.length; i++){ if(targetItemsSplit[i] === 'PB') return 2; } return 1; } function isElementInList(element, list){ for(let i = 0; i < list.length; i++){ if(element == list[i]) return true; } return false; } addPalanque.addEventListener("click", function(){ let palanque = document.createElement("div"); palanque.setAttribute("class", "border-2 p-4 zone"); palanque.setAttribute("id", "zone" + countZone); palanque.setAttribute("ondrop", "drop(event)"); palanque.setAttribute("ondragover", "allowDrop(event)"); zoneList.push(new DropZoneClass(countZone)); DropZone.appendChild(palanque); countZone++; }); removePalanque.addEventListener("click", function(){ countZone--; let palanque = document.getElementById("zone" + countZone); if(palanque.childElementCount > 0){ console.log(palanque.childNodes[1]); for(let i = 0; i < palanque.childElementCount; i++){ console.log(palanque.childNodes[i]); zoneStart.appendChild(palanque.childNodes[i]); } } zoneList.splice(zoneList.length - 1, 1); DropZone.removeChild(palanque); }); async function getDiver(ds_code){ let response = await fetch(`/api/dives/${ds_code}/divers`); let data = await response.json().then(data => proccessDiverData(data)); return data; } function proccessDiverData(data){ for(let i = 0; i < data.length; i++){ countDiver++; let diver = document.createElement("div"); diver.setAttribute("class", "w-fit h-8 border-2"); diver.setAttribute("id", 'item' + data[i].US_ID +',' + data[i].PRE_CODE + ',E' + data[i].US_TEACHING_LEVEL + ',' + data[i].US_ID); diver.setAttribute("draggable", "true"); diver.setAttribute("ondragstart", "drag(event)"); diver.innerHTML = data[i].US_FIRST_NAME + " " + data[i].US_NAME + " " + data[i].PRE_CODE + " " + data[i].US_TEACHING_LEVEL; zoneStart.appendChild(diver); } return data; } let validatePalanqueCombinate = { 'PB': ['E1', 'E2', 'E3', 'E4', 'PA-60-GP'], 'PA': ['E1', 'E2', 'E3', 'E4', 'PA-60-GP'], 'PO': ['E1', 'E2', 'E3', 'E4', 'PA-60-GP'], 'PE-12': ['E2', 'E3', 'E4', 'PA-60-GP'], 'PE-20': ['E2', 'E3', 'E4', 'PA-60-GP'], 'PE-40': ['E2', 'E3', 'E4', 'PA-60-GP'] }; function validateAllCombination(){ let counterCheck = 0; zoneList.forEach(element => { element = document.getElementById("zone" + element.getZoneNumber()); if(element.hasChildNodes()){ if(element.childElementCount < 2){ element.style.backgroundColor = 'red'; return false; } let children = element.childNodes; for(let i = 0; i < children.length; i++){ for(let j = 0; j < children.length; j++){ if(children[j].id.split(',')[1] === 'PA-60-GP'){ counterCheck++; if(element.style.backgroundColor === 'red') element.style.backgroundColor = 'white'; return true; } } } for(let i = 0; i < children.length; i++){ { let targetItemsSplit = children[i].id.split(',')[2]; for(targetItemsSplit in validatePalanqueCombinate){ for(let j = 0; j < children.length; j++){ let targetItemsSplit2 = children[j].id.split(',')[2]; if(validatePalanqueCombinate[targetItemsSplit].includes(targetItemsSplit2)){ counterCheck++; if(element.style.backgroundColor === 'red') element.style.backgroundColor = 'white'; return true; } } element.style.backgroundColor = 'red'; return false; } } } }else { element.style.backgroundColor = 'white'; return false; } }); if(DropZone.childElementCount === counterCheck){ disableVal = false; return true; }else { disableVal = true; return false; } } let interval = setInterval(function(){ validateAllCombination(); }, 250); validatePalanque.addEventListener("click", function(){ if(!disableVal){ sendPalanque(); clearInterval(interval); } }); function returnValueToPhp(ds_code) { let palanque = document.querySelectorAll("div.zone"); let palanqueList = []; for (let i = 0; i < palanque.length; i++) { let zoneList = []; for (let j = 0; j < palanque[i].childElementCount; j++) { let item = palanque[i].childNodes[j]; zoneList.push(item.id.split(',')[3]); } palanqueList.push(zoneList); } palanqueList.push(ds_code); return palanqueList; } function sendPalanque() { let palanqueList = returnValueToPhp("DS1"); let palanqueListJson = JSON.stringify(palanqueList); let csrfToken = document.querySelector('meta[name="csrf-token"]').getAttribute('content'); let xhr = new XMLHttpRequest(); xhr.open('POST', '/api/palanques', true); xhr.setRequestHeader("Content-Type", "application/json"); xhr.setRequestHeader('X-CSRF-TOKEN', csrfToken); xhr.onreadystatechange = function () { if (xhr.readyState === XMLHttpRequest.DONE) { if (xhr.status === 200) { console.log("Request successful"); const responseData = JSON.parse(xhr.responseText); console.log("Additional Data:", responseData.additionalData); } else { const responseData = JSON.parse(xhr.responseText); console.error("Request failed", responseData.errData); } } }; xhr.send(palanqueListJson); console.log("send"); } function fillZoneWithAlreadyExistingPalanque(diverList) { diverList.forEach(element => { let diver = document.getElementById('item' + element.US_ID + ',' + element.PRE_CODE + ',E' + element.US_TEACHING_LEVEL + ',' + element.US_ID); if (element.DG_NUMBER !== 0 && element.DG_NUMBER !== null) { let dgNumber = element.DG_NUMBER - 1; let zone = document.getElementById("zone" + dgNumber); if (zone) { zone.appendChild(diver); if(zoneStart.contains(diver)) zoneStart.removeChild(diver); }else{ let palanque = document.createElement("div"); palanque.setAttribute("class", "border-2 p-4 zone"); palanque.setAttribute("id", "zone" + dgNumber); palanque.setAttribute("ondrop", "drop(event)"); palanque.setAttribute("ondragover", "allowDrop(event)"); zoneList.push(new DropZoneClass(dgNumber)); DropZone.appendChild(palanque); palanque.appendChild(diver); if(zoneStart.contains(diver)) zoneStart.removeChild(diver); countZone++; } } }); }
resources/views/palanque_manuel.blade.php 0 → 100644 +17 −0 Original line number Diff line number Diff line <meta name="csrf-token" content="{{ $token }}"> <x-layout> <div class="flex justify-around m-5"> <div class="grid grid-cols-1"> <h3>Zone 1</h3> <div class="border-2" id="zoneStart" ondrop="drop(event)" ondragover="allowDrop(event)"> </div> </div> <div class="p-2 grid grid-cols-2 md:grid-cols-3 gap-4" id="DropZone"></div> </div> </div> <button type='button' id="addPal">Add P</button> <button type='button' id="removePal">Remove P</button> <button type='button' id="validatePal">Val</button> <script src=" {{ asset('js/Palanque/manualPalanque.js') }} "></script> </x-layout>