From a155313cbd608fce6c1712165ea66eb4cf49885b Mon Sep 17 00:00:00 2001 From: ChrisChrome Date: Sun, 22 Dec 2024 18:11:46 -0700 Subject: [PATCH] Basic pagination --- public/assets/js/admin/dashboard.js | 140 +++++++++++++++++++++------- routes/admin.js | 4 +- views/admin/dashboard.ejs | 7 ++ 3 files changed, 115 insertions(+), 36 deletions(-) diff --git a/public/assets/js/admin/dashboard.js b/public/assets/js/admin/dashboard.js index c5b076b..bdda2fe 100644 --- a/public/assets/js/admin/dashboard.js +++ b/public/assets/js/admin/dashboard.js @@ -1,42 +1,114 @@ var reasonFlags = {}; +let currentPage = 1; +let itemsPerPage = 5; +let data; + +function renderTable(data, reasonFlags) { + const tableBody = document.querySelector('#bansTableBody'); + tableBody.innerHTML = ''; + const start = (currentPage - 1) * itemsPerPage; + const end = start + itemsPerPage; + const pageData = data.slice(start, end); + + pageData.forEach(ban => { + const row = document.createElement('tr'); + const banTimestamp = new Date(ban.banTimestamp).toLocaleString(); + const expiresTimestamp = ban.expiresTimestamp ? new Date(ban.expiresTimestamp).toLocaleString() : 'Never'; + const reasonsFlagNames = getSetFlags(ban.reasonsFlag, reasonFlags).join(', '); + row.innerHTML = ` + ${ban.id} + ${ban.robloxId || 'N/A'} + ${ban.discordId || 'N/A'} + ${ban.robloxUsername || 'N/A'} + ${ban.discordUsername || 'N/A'} + ${ban.reasonShort || 'N/A'} + ${ban.reasonLong || 'N/A'} + ${reasonsFlagNames} + ${ban.moderator || 'N/A'} + ${banTimestamp} + + ${expiresTimestamp} + + + Edit + + `; + tableBody.appendChild(row); + }); +} +const itemsToShowDropdown = document.querySelector('#itemsToShowDropdown'); +const itemsOptions = [5, 10, 20, 30, 40, 50, 100, 200, 500, 1000]; + +itemsOptions.forEach(option => { + const optionElement = document.createElement('option'); + optionElement.value = option; + optionElement.textContent = option; + itemsToShowDropdown.appendChild(optionElement); +}); + +itemsToShowDropdown.addEventListener('change', (e) => { + const selectedValue = e.target.value; + itemsPerPage = parseInt(selectedValue, 10) || 5; + currentPage = 1; + renderTable(data, reasonFlags); + setupPagination(data); + console.log('Items per page:', itemsPerPage); +}); + +function setupPagination(data) { + const pagination = document.querySelector('#pagination'); + pagination.innerHTML = ''; + const totalPages = Math.ceil(data.length / itemsPerPage); + + const ul = document.createElement('ul'); + ul.classList.add('pagination'); + + const createPageItem = (page, text = page) => { + const li = document.createElement('li'); + li.classList.add('page-item'); + if (page === currentPage) { + li.classList.add('active'); + } + + const a = document.createElement('a'); + a.classList.add('page-link'); + a.textContent = text; + a.href = '#'; + a.addEventListener('click', (e) => { + e.preventDefault(); + currentPage = page; + renderTable(data, reasonFlags); + setupPagination(data); + }); + + li.appendChild(a); + return li; + }; + + ul.appendChild(createPageItem(1, 'First')); + ul.appendChild(createPageItem(Math.max(1, currentPage - 1), 'Prev')); + + for (let i = Math.max(1, currentPage - 2); i <= Math.min(totalPages, currentPage + 2); i++) { + ul.appendChild(createPageItem(i)); + } + + ul.appendChild(createPageItem(Math.min(totalPages, currentPage + 1), 'Next')); + ul.appendChild(createPageItem(totalPages, 'Last')); + + pagination.appendChild(ul); +} + fetch('/api/v1/info') .then(response => response.json()) .then(data => { reasonFlags = data.reasonFlags; console.log('Reason Flags:', reasonFlags); - fetch('/admin/api/bans') - .then(response => response.json()) - .then(data => { - const tableBody = document.querySelector('#bansTableBody'); - data.forEach(ban => { - const row = document.createElement('tr'); - const banTimestamp = new Date(ban.banTimestamp).toLocaleString(); - const expiresTimestamp = ban.expiresTimestamp ? new Date(ban.expiresTimestamp).toLocaleString() : 'Never'; - const reasonsFlagNames = getSetFlags(ban.reasonsFlag, reasonFlags).join(', '); - console.log(ban.reasonsFlag) - console.log(reasonFlags) - console.log(getSetFlags(ban.reasonsFlag, reasonFlags)) - row.innerHTML = ` - ${ban.id} - ${ban.robloxId || 'N/A'} - ${ban.discordId || 'N/A'} - ${ban.robloxUsername || 'N/A'} - ${ban.discordUsername || 'N/A'} - ${ban.reasonShort || 'N/A'} - ${ban.reasonLong || 'N/A'} - ${reasonsFlagNames} - ${ban.moderator || 'N/A'} - ${banTimestamp} - - ${expiresTimestamp} - - - Edit - - `; - tableBody.appendChild(row); - }); - }) - .catch(error => console.error('Error fetching ban data:', error)); + fetch('/admin/api/bans') + .then(response => response.json()) + .then(data => { + renderTable(data, reasonFlags); + setupPagination(data); + }) + .catch(error => console.error('Error fetching ban data:', error)); }) .catch(error => console.error('Error fetching reason flags:', error)); \ No newline at end of file diff --git a/routes/admin.js b/routes/admin.js index 7bec6fa..a218ba0 100644 --- a/routes/admin.js +++ b/routes/admin.js @@ -177,8 +177,8 @@ router.post('/import', authenticate, upload.single('fileInput'), async (req, res for (const line of lines) { // This is a text file, split by "x/"", get [0], then split by / and get the last element, that will be an ID. All other values are static. const robloxId = line.split('x/')[0].split('/').pop(); - let reasonLong = line.split('/profile ')[1]; - if (reasonLong.length > 255) { + let reasonLong = line.split('/profile ')[1] || "Undefined"; + if (reasonLong?.length > 255) { reasonLong = reasonLong.substring(0, 2048); } const reasonShort = "Listed by MFD"; diff --git a/views/admin/dashboard.ejs b/views/admin/dashboard.ejs index 5a5a9c8..9505ac4 100644 --- a/views/admin/dashboard.ejs +++ b/views/admin/dashboard.ejs @@ -39,6 +39,13 @@

Bans

+ +
+ + +