All checks were successful
continuous-integration/drone/push Build is passing
Several modifications made to the API and several bug fixes
236 lines
10 KiB
Plaintext
236 lines
10 KiB
Plaintext
<!DOCTYPE html>
|
|
<html lang="en">
|
|
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">
|
|
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@10"></script>
|
|
<link rel="stylesheet" href="/public/css/login.css">
|
|
<title>Parameter Admin</title>
|
|
<link rel="icon" href="/public/assets/homelab_logo.png" />
|
|
</head>
|
|
|
|
<style>
|
|
.pagination .active .page-link {
|
|
background-color: #007bff !important;
|
|
color: white !important;
|
|
}
|
|
|
|
.table-container {
|
|
max-width: 90%;
|
|
}
|
|
|
|
#searchInput {
|
|
flex-grow: 1;
|
|
}
|
|
#searchButton {
|
|
margin-left: 10px;
|
|
}
|
|
|
|
.custom-btn {
|
|
transition: transform 0.3s ease, background-color 0.3s ease, border-color 0.3s ease;
|
|
color: #007BFF;
|
|
background-color: transparent;
|
|
padding: 5px 10px;
|
|
text-decoration: none;
|
|
display: inline-block;
|
|
font-size: 14px;
|
|
margin: 4px 2px;
|
|
border-radius: 50px;
|
|
cursor: pointer;
|
|
box-shadow: 0 2px 5px rgba(0,0,0,0.25);
|
|
border: 2px solid #007BFF;
|
|
}
|
|
|
|
.custom-btn:hover {
|
|
transform: scale(1.15);
|
|
background-color: #007BFF;
|
|
color: #fff;
|
|
}
|
|
|
|
</style>
|
|
|
|
<body class="light-mode animate">
|
|
<div class="container mt-4 table-container animate">
|
|
<h2 class="text-center">Gestion des utilisateurs</h2><br>
|
|
<div class="d-flex justify-content-between align-items-center">
|
|
<input type="text" id="searchInput" class="form-control rounded mr-2" placeholder="Rechercher par nom ou ID">
|
|
<span id="shortcutHint" class="mr-2 align-self-center"></span>
|
|
<button id="searchButton" class="btn btn-primary custom-btn">Rechercher</button>
|
|
<select id="usersPerPage" class="form-control rounded ml-2" style="width: auto;">
|
|
<option value="10">10</option>
|
|
<option value="50">50</option>
|
|
<option value="100">100</option>
|
|
<option value="500">500</option>
|
|
</select>
|
|
</div>
|
|
<div class="table-responsive mt-2">
|
|
<table class="table w-100 table table-hover">
|
|
<thead>
|
|
<tr>
|
|
<th>ID</th>
|
|
<th>Nom</th>
|
|
<th>Rôle</th>
|
|
<th class="text-right">Action</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<% users.forEach(user => { %>
|
|
<tr>
|
|
<td><%= user.id %></td>
|
|
<td><%= user.name %></td>
|
|
<td><%= user.role %></td>
|
|
<td>
|
|
<form id="update-role-form" action="/api/dpanel/dashboard/admin/update-role" method="POST" class="d-flex align-items-center">
|
|
<input type="hidden" name="id" value="<%= user.id %>">
|
|
<input type="hidden" name="name" value="<%= user.name %>">
|
|
<select class="form-control rounded mr-2" name="role">
|
|
<option value="user" <%= user.role === 'user' ? 'selected' : '' %>>User</option>
|
|
<option value="admin" <%= user.role === 'admin' ? 'selected' : '' %>>Admin</option>
|
|
</select>
|
|
<button type="submit" class="btn btn-primary btn-round custom-btn">Mettre à jour</button>
|
|
</form>
|
|
<form id="generate-token-form" action="/api/dpanel/generate-token" method="POST" class="d-flex align-items-center mt-2">
|
|
<input type="hidden" name="id" value="<%= user.id %>">
|
|
<input type="hidden" name="name" value="<%= user.name %>">
|
|
<button type="submit" class="btn btn-secondary btn-round custom-btn">Générer Token</button>
|
|
</form>
|
|
</td>
|
|
</tr>
|
|
<% }) %>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<nav aria-label="Page navigation example">
|
|
<ul class="pagination justify-content-center">
|
|
<% for(let i = 1; i <= pages; i++) { %>
|
|
<li class="page-item <%= i === currentPage ? 'active' : '' %>">
|
|
<a class="page-link" href="/dpanel/dashboard/admin/users?page=<%= i %>&limit=<%= limit %>"><%= i %></a>
|
|
</li>
|
|
<% } %>
|
|
</ul>
|
|
</nav>
|
|
<div class="d-flex justify-content-center align-items-center">
|
|
<a class="dropdown-item text-center text-white no-hover custom-btn" href="/dpanel/dashboard/admin/" style="max-width: 250px; padding: 10px;">
|
|
<i class="fas fa-sign-out-alt text-white "></i> Retourner au dashboard admin
|
|
</a>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="d-flex justify-content-center animate">
|
|
<button id="themeSwitcher" class="btn btn-warning mt-3 animate ">Changer de Thème</button>
|
|
</div>
|
|
|
|
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js"></script>
|
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"></script>
|
|
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>
|
|
|
|
<script>
|
|
const body = document.body;
|
|
|
|
document.getElementById('themeSwitcher').addEventListener('click', function () {
|
|
body.classList.toggle('dark-mode');
|
|
});
|
|
|
|
document.getElementById('usersPerPage').addEventListener('change', function () {
|
|
window.location.href = "/dpanel/dashboard/admin/users?page=1&limit=" + this.value;
|
|
});
|
|
|
|
window.onload = function() {
|
|
var urlParams = new URLSearchParams(window.location.search);
|
|
var limit = urlParams.get('limit');
|
|
document.getElementById('usersPerPage').value = limit;
|
|
}
|
|
|
|
document.addEventListener('DOMContentLoaded', function () {
|
|
const darkModeSwitch = document.getElementById('darkModeSwitch');
|
|
|
|
const darkModeMediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
|
|
|
|
body.classList.toggle('dark-mode', darkModeMediaQuery.matches);
|
|
|
|
darkModeMediaQuery.addListener(function (e) {
|
|
body.classList.toggle('dark-mode', e.matches);
|
|
});
|
|
});
|
|
|
|
function searchUsers() {
|
|
var input = document.getElementById('searchInput');
|
|
var filter = input.value.toUpperCase();
|
|
var table = document.querySelector('.table');
|
|
var tr = table.getElementsByTagName('tr');
|
|
|
|
for (var i = 0; i < tr.length; i++) {
|
|
var tdName = tr[i].getElementsByTagName('td')[1];
|
|
var tdId = tr[i].getElementsByTagName('td')[0];
|
|
if (tdName || tdId) {
|
|
var txtValueName = tdName.textContent || tdName.innerText;
|
|
var txtValueId = tdId.textContent || tdId.innerText;
|
|
if (txtValueName.toUpperCase().indexOf(filter) > -1 || txtValueId.toUpperCase().indexOf(filter) > -1) {
|
|
tr[i].style.display = "";
|
|
} else {
|
|
tr[i].style.display = "none";
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
document.getElementById('searchButton').addEventListener('click', function (e) {
|
|
e.preventDefault();
|
|
searchUsers();
|
|
});
|
|
|
|
document.addEventListener('keydown', function (e) {
|
|
if (e.ctrlKey && e.key === 'k') {
|
|
e.preventDefault();
|
|
document.getElementById('searchInput').focus();
|
|
}
|
|
});
|
|
|
|
var isMac = navigator.platform.toUpperCase().indexOf('MAC') >= 0;
|
|
var searchInput = document.getElementById('searchInput');
|
|
searchInput.placeholder = isMac ? 'Rechercher par nom ou ID (Cmd + K)' : 'Rechercher par nom ou ID (Ctrl + K)';
|
|
|
|
|
|
document.getElementById('generate-token-form').addEventListener('submit', function(e) {
|
|
e.preventDefault();
|
|
var url = this.getAttribute('action');
|
|
var method = this.getAttribute('method');
|
|
|
|
var name = this.querySelector('input[name="name"]').value;
|
|
var id = this.querySelector('input[name="id"]').value;
|
|
var data = { name: name, id: id };
|
|
|
|
fetch(url, {
|
|
method: method,
|
|
headers: {
|
|
'Content-Type': 'application/json'
|
|
},
|
|
body: JSON.stringify(data)
|
|
})
|
|
.then(response => response.json())
|
|
.then(response => {
|
|
Swal.fire({
|
|
title: 'Votre Token',
|
|
html: `<input type="text" id="swal-input1" class="swal2-input" value="${response.token}">`,
|
|
confirmButtonText: 'Copier le Token',
|
|
footer: '<div style="text-align: center;">Gardez ce token en sécurité. Il ne sera pas possible de le récupérer sans le régénérer.</div>',
|
|
focusConfirm: false,
|
|
preConfirm: () => {
|
|
const copyText = document.querySelector('#swal-input1');
|
|
copyText.select();
|
|
document.execCommand("copy");
|
|
}
|
|
}).then(() => {
|
|
Swal.fire('Copié!', 'Votre token a été copié.', 'success');
|
|
});
|
|
})
|
|
.catch(error => {
|
|
Swal.fire('Error', error.message, 'error');
|
|
});
|
|
});
|
|
</script>
|
|
</body>
|
|
|
|
</html> |