adjust admin page

This commit is contained in:
Christian Rute 2024-11-18 17:04:10 +01:00
parent 38774d518b
commit c18001738f
6 changed files with 163 additions and 65 deletions

View File

@ -21,6 +21,12 @@
<!-- Hauptbereich für Benutzerliste --> <!-- Hauptbereich für Benutzerliste -->
<main> <main>
<div id="custom-alert-confirm" style="display:none;" class="alert-box">
<p id="alert-message-confirm"></p>
<button id="close-alert-confirm">Close</button>
<button id="confirm-alert-confirm" style="display:none;">Confirm</button>
</div>
<div id="user-list" class="user-list"></div> <div id="user-list" class="user-list"></div>
</main> </main>
<script type="module" src="js/shared_functions.js"></script> <script type="module" src="js/shared_functions.js"></script>

View File

@ -372,8 +372,6 @@ main {
background-color: #27ae60; background-color: #27ae60;
} }
/* General alert styling */
/* General alert styling */ /* General alert styling */
.custom-alert { .custom-alert {
display: none; /* Hide by default */ display: none; /* Hide by default */
@ -428,6 +426,74 @@ main {
color: white; 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 */ /* Button common styles */
.close-btn { .close-btn {
border: none; border: none;

View File

@ -1,4 +1,4 @@
import { showAlert } from './shared_functions.js'; import {showAlert, showConfirm} from './shared_functions.js';
// IP-Adresse // IP-Adresse
const baseUrl = 'http://localhost:8015'; 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 = `
<p style="flex: 0 0 25%;">Benutzername: ${user.username}</p>
<p style="flex: 0 0 25%;">Email: ${user.email}</p>
<button id="button-delete" onclick="deleteUser('${user._id}')" style="flex: 0 0 50%;">Benutzer löschen</button>
`;
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 // 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'); const token = localStorage.getItem('token');
try { try {
const response = await fetch(`${baseUrl}/api/auth/user/${userId}`, { 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 = `
<p style="flex: 0 0 25%;">Benutzername: ${user.username}</p>
<p style="flex: 0 0 25%;">Email: ${user.email}</p>
<p style="flex: 0 0 20%;">Admin: ${user.isAdmin}</p>
<button class="button-delete" style="flex: 0 0 30%;">Benutzer löschen</button>
`;
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 // Abhängig von der Seite entweder Admin- oder Benutzerdaten laden
if (window.location.pathname.includes('admin.html')) { if (window.location.pathname.includes('admin.html')) {
// Funktion um auf die Willkommensseite zurückzukommen // Funktion um auf die Willkommensseite zurückzukommen

View File

@ -16,4 +16,36 @@ export function showAlert(message, type = 'error') {
closeButton.addEventListener('click', () => { closeButton.addEventListener('click', () => {
alertBox.style.display = 'none'; // Hide the alert box when the button is clicked 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)
});
});
} }

View File

@ -54,7 +54,7 @@ const login = async (req, res) => {
} }
// JWT-Token erstellen mit benutzerdefinierten Daten // 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' }); res.status(200).json({ token, message: 'Login erfolgreich' });

View File

@ -17,7 +17,6 @@ router.get('/me', authMiddleware, (req, res) => {
res.status(200).json({ res.status(200).json({
id: req.user.id, id: req.user.id,
user: req.user.username, user: req.user.username,
docAccess: req.user.docAccess,
isAdmin: req.user.isAdmin, isAdmin: req.user.isAdmin,
message: 'Benutzerinformationen abgerufen', message: 'Benutzerinformationen abgerufen',
}); });
@ -31,8 +30,8 @@ router.get('/admin', authMiddleware, adminMiddleware, (req, res) => {
// Admin-Route, die eine Liste aller Benutzer zurückgibt // Admin-Route, die eine Liste aller Benutzer zurückgibt
router.get('/users', authMiddleware, adminMiddleware, async (req, res) => { router.get('/users', authMiddleware, adminMiddleware, async (req, res) => {
try { try {
// Suche alle Benutzer und gib nur die Felder 'username', 'email' und 'docAccess' zurück // Suche alle Benutzer und gib nur die Felder 'username', 'email' und 'isAdmin' zurück
const users = await User.find({}, 'username email docAccess'); const users = await User.find({}, 'username email isAdmin');
res.status(200).json(users); res.status(200).json(users);
} catch (error) { } catch (error) {
console.error(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) => { router.delete('/user/:id', authMiddleware, adminMiddleware, async (req, res) => {
const { id } = req.params; const { id } = req.params;