From c18001738f4c049fab2e2b5e98c29362a9862a6f Mon Sep 17 00:00:00 2001 From: Christian Rute Date: Mon, 18 Nov 2024 17:04:10 +0100 Subject: [PATCH] adjust admin page --- client/admin.html | 6 ++ client/css/styles.css | 70 +++++++++++++++++++++- client/js/main.js | 90 +++++++++++++++++----------- client/js/shared_functions.js | 32 ++++++++++ server/controllers/authController.js | 2 +- server/routes/authRoutes.js | 28 +-------- 6 files changed, 163 insertions(+), 65 deletions(-) diff --git a/client/admin.html b/client/admin.html index 30b61dc..085dbf9 100644 --- a/client/admin.html +++ b/client/admin.html @@ -21,6 +21,12 @@
+ +
diff --git a/client/css/styles.css b/client/css/styles.css index c017430..0a8ce6b 100644 --- a/client/css/styles.css +++ b/client/css/styles.css @@ -372,8 +372,6 @@ main { background-color: #27ae60; } - -/* General alert styling */ /* General alert styling */ .custom-alert { display: none; /* Hide by default */ @@ -428,6 +426,74 @@ main { color: white; } + + + +/* General alert box styling */ +#custom-alert-confirm { + display: none; + position: fixed; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + background-color: #fff; + border-radius: 10px; + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); + padding: 20px; + width: 300px; + z-index: 1000; + text-align: center; +} + +/* Styling the alert message */ +#alert-message-confirm { + margin-bottom: 15px; + font-size: 16px; + color: #333; +} + +/* Styling for the buttons container */ +#custom-alert-confirm button { + font-size: 14px; + padding: 10px 20px; + border: none; + border-radius: 5px; + margin: 10px 5px; + cursor: pointer; + transition: background-color 0.3s ease; +} + +/* Confirm button */ +#confirm-alert-confirm { + background-color: #4CAF50; /* Green button for confirm */ + color: white; +} + +/* Close button */ +#close-alert-confirm { + background-color: #f44336; /* Red button for cancel */ + color: white; +} + +/* On hover, change background color for buttons */ +#confirm-alert-confirm:hover { + background-color: #45a049; +} + +#close-alert-confirm:hover { + background-color: #e53935; +} + +/* Additional success and error styling based on alert type */ +#custom-alert-confirm.success { + border-left: 5px solid #4CAF50; /* Green left border for success */ +} + +#custom-alert-confirm.error { + border-left: 5px solid #f44336; /* Red left border for error */ +} + + /* Button common styles */ .close-btn { border: none; diff --git a/client/js/main.js b/client/js/main.js index c5adc1c..815ce46 100644 --- a/client/js/main.js +++ b/client/js/main.js @@ -1,4 +1,4 @@ -import { showAlert } from './shared_functions.js'; +import {showAlert, showConfirm} from './shared_functions.js'; // IP-Adresse const baseUrl = 'http://localhost:8015'; @@ -92,42 +92,17 @@ async function loadAdminData() { } } -async function loadUserList() { - const token = localStorage.getItem('token'); - const response = await fetch(`${baseUrl}/api/auth/users`, { - headers: { 'Authorization': `Bearer ${token}` } - }); - - if (response.ok) { - const users = await response.json(); - const userList = document.getElementById('user-list'); - userList.innerHTML = ''; // Liste leeren - - users.forEach(user => { - const userDiv = document.createElement('div'); - userDiv.style.display = 'flex'; - userDiv.style.alignItems = 'center'; - userDiv.setAttribute('id', `user-list-element`); - userDiv.innerHTML = ` -

Benutzername: ${user.username}

-

Email: ${user.email}

- -`; - userList.appendChild(userDiv); - }); - } else { - showAlert('Fehler beim Laden der Benutzerliste'); - } -} - -// Überprüfen, ob wir uns auf der Admin-Seite befinden, und dann den Event-Listener hinzufügen -const loadUserListBtn = document.getElementById('loadUserListBtn'); -if (loadUserListBtn) { - loadUserListBtn.addEventListener('click', loadUserList); // Benutzerliste laden, wenn der Button geklickt wird -} - // Funktion zum Löschen eines Benutzers -async function deleteUser(userId) { +async function deleteUser(userId, isAdmin) { + + // If the user is an admin, show a warning confirmation + if (isAdmin) { + const userConfirmed = await showConfirm('Warnung: Möchten Sie wirklich einen Administrator löschen? Dies kann nicht rückgängig gemacht werden.', 'error'); + if (!userConfirmed) { + return; // If the user cancels, do nothing + } + } + const token = localStorage.getItem('token'); try { const response = await fetch(`${baseUrl}/api/auth/user/${userId}`, { @@ -145,6 +120,49 @@ async function deleteUser(userId) { } } +async function loadUserList() { + const token = localStorage.getItem('token'); + const response = await fetch(`${baseUrl}/api/auth/users`, { + headers: { 'Authorization': `Bearer ${token}` } + }); + + if (response.ok) { + const users = await response.json(); + const userList = document.getElementById('user-list'); + userList.innerHTML = ''; // Liste leeren + + users.forEach(user => { + const userDiv = document.createElement('div'); + userDiv.style.display = 'flex'; + userDiv.style.alignItems = 'center'; + userDiv.setAttribute('id', `user-list-element-${user._id}`); // Give each div a unique ID + userDiv.innerHTML = ` +

Benutzername: ${user.username}

+

Email: ${user.email}

+

Admin: ${user.isAdmin}

+ + `; + userList.appendChild(userDiv); + + // Add event listener to the specific delete button + const deleteButton = userDiv.querySelector(".button-delete"); + deleteButton.addEventListener("click", function() { + deleteUser(user._id, user.isAdmin); + }); + }); + } else { + showAlert('Fehler beim Laden der Benutzerliste'); + } +} + +// Überprüfen, ob wir uns auf der Admin-Seite befinden, und dann den Event-Listener hinzufügen +const loadUserListBtn = document.getElementById('loadUserListBtn'); +if (loadUserListBtn) { + loadUserListBtn.addEventListener('click', loadUserList); // Benutzerliste laden, wenn der Button geklickt wird +} + + + // Abhängig von der Seite entweder Admin- oder Benutzerdaten laden if (window.location.pathname.includes('admin.html')) { // Funktion um auf die Willkommensseite zurückzukommen diff --git a/client/js/shared_functions.js b/client/js/shared_functions.js index 7056630..3864219 100644 --- a/client/js/shared_functions.js +++ b/client/js/shared_functions.js @@ -16,4 +16,36 @@ export function showAlert(message, type = 'error') { closeButton.addEventListener('click', () => { alertBox.style.display = 'none'; // Hide the alert box when the button is clicked }); +} + +export function showConfirm(message, type = 'error') { + return new Promise((resolve) => { + const alertBox = document.getElementById('custom-alert-confirm'); + const alertMessage = document.getElementById('alert-message-confirm'); + const closeButton = document.getElementById('close-alert-confirm'); + const confirmButton = document.getElementById('confirm-alert-confirm'); + + alertMessage.textContent = message; // Set the message to display + alertBox.style.display = 'block'; // Show the alert box + + // Reset previous styles + alertBox.classList.remove('success', 'error'); + alertBox.classList.add(type); // Add the appropriate class (success/error) + + // Display the confirm button + confirmButton.style.display = 'inline-block'; + closeButton.style.display = 'inline-block'; + + // When "Confirm" button is clicked + confirmButton.addEventListener('click', () => { + alertBox.style.display = 'none'; // Hide the alert box + resolve(true); // Resolve the promise as true (user confirmed) + }); + + // When "Close" button is clicked + closeButton.addEventListener('click', () => { + alertBox.style.display = 'none'; // Hide the alert box + resolve(false); // Resolve the promise as false (user canceled) + }); + }); } \ No newline at end of file diff --git a/server/controllers/authController.js b/server/controllers/authController.js index 02f7937..7431df8 100644 --- a/server/controllers/authController.js +++ b/server/controllers/authController.js @@ -54,7 +54,7 @@ const login = async (req, res) => { } // JWT-Token erstellen mit benutzerdefinierten Daten - const token = jwt.sign({ id: user._id, username: user.username, docAccess: user.docAccess, isAdmin: user.isAdmin }, process.env.JWT_SECRET, { expiresIn: '1h' }); + const token = jwt.sign({ id: user._id, username: user.username, isAdmin: user.isAdmin }, process.env.JWT_SECRET, { expiresIn: '1h' }); res.status(200).json({ token, message: 'Login erfolgreich' }); diff --git a/server/routes/authRoutes.js b/server/routes/authRoutes.js index e8dd282..000e90d 100644 --- a/server/routes/authRoutes.js +++ b/server/routes/authRoutes.js @@ -17,7 +17,6 @@ router.get('/me', authMiddleware, (req, res) => { res.status(200).json({ id: req.user.id, user: req.user.username, - docAccess: req.user.docAccess, isAdmin: req.user.isAdmin, message: 'Benutzerinformationen abgerufen', }); @@ -31,8 +30,8 @@ router.get('/admin', authMiddleware, adminMiddleware, (req, res) => { // Admin-Route, die eine Liste aller Benutzer zurückgibt router.get('/users', authMiddleware, adminMiddleware, async (req, res) => { try { - // Suche alle Benutzer und gib nur die Felder 'username', 'email' und 'docAccess' zurück - const users = await User.find({}, 'username email docAccess'); + // Suche alle Benutzer und gib nur die Felder 'username', 'email' und 'isAdmin' zurück + const users = await User.find({}, 'username email isAdmin'); res.status(200).json(users); } catch (error) { console.error(error); @@ -40,29 +39,6 @@ router.get('/users', authMiddleware, adminMiddleware, async (req, res) => { } }); -router.put('/user/:id/docAccess', authMiddleware, adminMiddleware, async (req, res) => { - const { id } = req.params; - const { docAccess } = req.body; - - // Sicherheitsvalidierung: docAccess-Wert muss zwischen 0 und 4 liegen - if (![0, 1, 2, 3, 4].includes(docAccess)) { - return res.status(400).json({ message: 'Ungültiger docAccess-Wert' }); - } - - try { - const user = await User.findByIdAndUpdate( - id, - { docAccess }, - { new: true, fields: 'username email docAccess' } // nur ausgewählte Felder zurückgeben - ); - if (!user) return res.status(404).json({ message: 'Benutzer nicht gefunden' }); - res.status(200).json(user); - } catch (error) { - console.error(error); - res.status(500).json({ message: 'Fehler beim Aktualisieren von docAccess' }); - } -}); - router.delete('/user/:id', authMiddleware, adminMiddleware, async (req, res) => { const { id } = req.params;