From 8388c2ccc6caf81c40c4a2294245e61682d9d3b2 Mon Sep 17 00:00:00 2001
From: Michel <michel@iedsoftworks.com>
Date: Fri, 15 Nov 2024 13:41:52 +0100
Subject: [PATCH] Adds delete option

---
 src/js/pages/keys/index.ts                |  5 ++
 src/js/pages/keys/modals/delete.ts        | 42 ++++++++++++++
 src/js/pages/keys/modals/edit.ts          | 18 ++++++
 src/php/Routing/Api/Web/DeleteKeyList.php | 70 +++++++++++++++++++++++
 src/php/Routing/Api/Web/WebAPIRoutes.php  |  1 +
 src/templates/pages/key-manager.php       | 69 ++++++++++++++++++++--
 6 files changed, 199 insertions(+), 6 deletions(-)
 create mode 100644 src/js/pages/keys/modals/delete.ts
 create mode 100644 src/js/pages/keys/modals/edit.ts
 create mode 100644 src/php/Routing/Api/Web/DeleteKeyList.php

diff --git a/src/js/pages/keys/index.ts b/src/js/pages/keys/index.ts
index b22fecc..f1b3d0d 100644
--- a/src/js/pages/keys/index.ts
+++ b/src/js/pages/keys/index.ts
@@ -7,6 +7,8 @@ import {init as initImport} from "./import";
 import {init as initTable} from "./table";
 import {init as initUserLists} from "./userlists";
 import {initShare} from "./share";
+import {init as initEditModal} from "./modals/edit";
+import {init as initDeleteModal} from "./modals/delete";
 
 document.addEventListener('DOMContentLoaded', () => {
     const triggerTabList = document.querySelectorAll('#key-tab button')
@@ -23,4 +25,7 @@ document.addEventListener('DOMContentLoaded', () => {
     initTable();
     initUserLists();
     initShare();
+    
+    initEditModal();
+    initDeleteModal();
 })
\ No newline at end of file
diff --git a/src/js/pages/keys/modals/delete.ts b/src/js/pages/keys/modals/delete.ts
new file mode 100644
index 0000000..24286c8
--- /dev/null
+++ b/src/js/pages/keys/modals/delete.ts
@@ -0,0 +1,42 @@
+import {getCurrentlySelectedList} from "../userlists";
+
+export function init() {
+    const modalElem = document.querySelector<HTMLDivElement>('#delete-list-modal');
+
+    if (!modalElem) {
+        return;
+    }
+
+    modalElem.addEventListener('show.bs.modal', () => {
+        const listSelect = document.querySelector<HTMLSelectElement>('#list-select');
+        const text = listSelect?.selectedOptions[0].text ?? '';
+
+        const listnameElem = modalElem.querySelector<HTMLSpanElement>('.list-name');
+        if (!listnameElem) {
+            return;
+        }
+        listnameElem.textContent = text;
+    })
+    
+    modalElem.querySelector<HTMLButtonElement>('.js--yes')
+        ?.addEventListener('click', async () => {
+            const id = getCurrentlySelectedList();
+
+            const formData = new FormData();
+            formData.append('id', id?.toString() ?? '-1');
+
+            const response = await fetch(
+                `/api/web/keys/list/delete`,
+                {
+                    method: 'POST',
+                    body: formData
+                }
+            );
+
+            if (!response.ok) {
+                throw new Error(response.statusText);
+            }
+
+            window.location.reload();
+        })
+}
diff --git a/src/js/pages/keys/modals/edit.ts b/src/js/pages/keys/modals/edit.ts
new file mode 100644
index 0000000..6c79cee
--- /dev/null
+++ b/src/js/pages/keys/modals/edit.ts
@@ -0,0 +1,18 @@
+export function init() {
+    const modalElem = document.querySelector<HTMLDivElement>('#edit-list-modal');
+    
+    if (!modalElem) {
+        return;
+    }
+    
+    modalElem.addEventListener('show.bs.modal', () => {
+        const listSelect = document.querySelector<HTMLSelectElement>('#list-select');
+        const text = listSelect?.selectedOptions[0].text ?? '';
+        
+        const listnameElem = modalElem.querySelector<HTMLSpanElement>('.list-name');
+        if (!listnameElem) {
+            return;
+        }
+        listnameElem.textContent = text;
+    })
+}
\ No newline at end of file
diff --git a/src/php/Routing/Api/Web/DeleteKeyList.php b/src/php/Routing/Api/Web/DeleteKeyList.php
new file mode 100644
index 0000000..db550cb
--- /dev/null
+++ b/src/php/Routing/Api/Web/DeleteKeyList.php
@@ -0,0 +1,70 @@
+<?php declare(strict_types=1);
+
+namespace GamesShop\Routing\Api\Web;
+
+use Doctrine\ORM\EntityManager;
+use GamesShop\Entities\Games\Key;
+use GamesShop\Entities\GamesList;
+use GamesShop\Login\LoginHandler;
+use GamesShop\Login\UserPermission;
+use Laminas\Diactoros\Response;
+use League\Route\Http\Exception\BadRequestException;
+use League\Route\Http\Exception\ForbiddenException;
+use League\Route\Http\Exception\UnauthorizedException;
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\ServerRequestInterface;
+
+final class DeleteKeyList
+{
+
+    public function __construct(
+        private readonly LoginHandler $loginHandler,
+        private readonly EntityManager $entityManager
+    )
+    {
+    }
+
+    public function __invoke(ServerRequestInterface $request): ResponseInterface
+    {
+        if (!$this->loginHandler->isLoggedIn()) {
+            throw new UnauthorizedException();
+        }
+
+        $user = $this->loginHandler->getCurrentUser();
+        if (!$user->getPermission()->hasLevel(UserPermission::PROVIDER)) {
+            throw new ForbiddenException();
+        }
+
+        $body = $request->getParsedBody();
+        if (!array_key_exists('id', $body)) {
+            throw new BadRequestException();
+        }
+
+        $id = $body['id'];
+        $list = $this->entityManager->getRepository(GamesList::class)->findOneBy(
+            [
+                'id' => $id,
+                'owner' => $user,
+            ]
+        );
+        
+        if ($list === null) {
+            throw new BadRequestException();
+        }
+        
+        $this->entityManager->remove($list);
+
+        $keys = $this->entityManager->getRepository(Key::class)->findBy(
+            [
+                'list' => $list
+            ]
+        );
+        foreach ($keys as $key) {
+            $this->entityManager->remove($key);
+        }
+        
+        $this->entityManager->flush();
+        
+        return new Response();
+    }
+}
\ No newline at end of file
diff --git a/src/php/Routing/Api/Web/WebAPIRoutes.php b/src/php/Routing/Api/Web/WebAPIRoutes.php
index 02f2033..66347f4 100644
--- a/src/php/Routing/Api/Web/WebAPIRoutes.php
+++ b/src/php/Routing/Api/Web/WebAPIRoutes.php
@@ -14,6 +14,7 @@ final class WebAPIRoutes
         $group->post('/keys/import/perform', ImportKeysRoute::class);
 
         $group->post('/keys/list/create', CreateKeyListRoute::class);
+        $group->post('/keys/list/delete',DeleteKeyList::class);
         
         $group->get('/share/search', SearchForUsers::class);
         $group->post('/share/add', AddUserToList::class);
diff --git a/src/templates/pages/key-manager.php b/src/templates/pages/key-manager.php
index 4182414..0248605 100644
--- a/src/templates/pages/key-manager.php
+++ b/src/templates/pages/key-manager.php
@@ -19,12 +19,17 @@ $this->layout('layout/main', [ 'resourceEntry' => 'keys' ]);
     </div>
     <div class="col-sm-6 align-self-center">
         <?php if (!empty($usersLists)): ?>
-        <select name="lists" id="list-select" class="form-select w-100">
-            <?php foreach ($usersLists as $list): ?>
-            <option value="<?= $list->getId() ?>"><?= $list->getName() ?></option>
-            <?php endforeach; ?>
-            <option value="_create">+ Create New</option>
-        </select>
+        <div class="input-group w-100">
+            <select name="lists" id="list-select" class="form-select">
+                <?php foreach ($usersLists as $list): ?>
+                    <option value="<?= $list->getId() ?>"><?= $list->getName() ?></option>
+                <?php endforeach; ?>
+                <option value="_create">+ Create New</option>
+            </select>
+            <button class="btn btn-outline-secondary" data-bs-target="#edit-list-modal" data-bs-toggle="modal">
+                <i class="fa-solid fa-gear"></i>
+            </button>
+        </div>
         <?php endif; ?>
     </div>
 </div>
@@ -151,4 +156,56 @@ $this->layout('layout/main', [ 'resourceEntry' => 'keys' ]);
     </div>
 </div>
 
+<div class="modal" id="edit-list-modal">
+    <div class="modal-dialog">
+        <div class="modal-content">
+            <div class="modal-header">
+                <h1 class="modal-title h3">
+                    Edit <span class="list-name"></span>
+                </h1>
+            </div>
+            <div class="modal-body">
+                <h2 class="h4 mt-2">
+                    Actions
+                </h2>
+                <button data-bs-toggle="modal" data-bs-target="#delete-list-modal" class="w-100 btn btn-danger">Delete List</button>
+            </div>
+            <div class="modal-footer">
+                <button data-bs-dismiss="modal" class="flex-grow-1 btn btn-primary">
+                    Save
+                </button>
+            </div>
+        </div>
+    </div>
+</div>
+
+
+<div class="modal" id="delete-list-modal">
+    <div class="modal-dialog">
+        <div class="modal-content">
+            <div class="modal-header">
+                <h1 class="modal-title h3">
+                    Delete <span class="list-name"></span>?
+                </h1>
+            </div>
+            <div class="modal-body">
+                <p>
+                    Are you <b>sure</b> you want to <b class="text-danger">delete</b> this list?
+                </p>
+                <p>
+                    Deleting this will remove all the keys you added from the database.
+                </p>
+            </div>
+            <div class="modal-footer">
+                <button data-bs-dismiss="modal" class="flex-grow-1 btn btn-outline-primary">
+                    Cancel
+                </button>
+                <button data-bs-dismiss="modal" class="js--yes flex-grow-1 btn btn-danger">
+                    Yes
+                </button>
+            </div>
+        </div>
+    </div>
+</div>
+
 <?php $this->end() ?>