diff --git a/actix_mvc_app/src/views/governance/proposal_detail.html b/actix_mvc_app/src/views/governance/proposal_detail.html
index e6f8323..d899a1c 100644
--- a/actix_mvc_app/src/views/governance/proposal_detail.html
+++ b/actix_mvc_app/src/views/governance/proposal_detail.html
@@ -275,7 +275,7 @@
+
+
+
+
+
+
+
+
+
+ {% endif %}
@@ -362,41 +399,237 @@
// Filter votes by type
filterButtons.forEach(button => {
- button.addEventListener('click', function () {
+ button.addEventListener('click', function() {
// Update active button
filterButtons.forEach(btn => btn.classList.remove('active'));
this.classList.add('active');
-
- const filterType = this.getAttribute('data-filter');
-
- voteRows.forEach(row => {
- if (filterType === 'all') {
- row.style.display = '';
- } else {
- const voteType = row.getAttribute('data-vote-type');
- row.style.display = (voteType === filterType) ? '' : 'none';
- }
- });
+
+ // Reset to first page and update pagination
+ currentPage = 1;
+ updatePagination();
});
});
// Search functionality
if (searchInput) {
- searchInput.addEventListener('input', function () {
+ searchInput.addEventListener('input', function() {
const searchTerm = this.value.toLowerCase();
-
+
voteRows.forEach(row => {
const voterName = row.querySelector('td:first-child').textContent.toLowerCase();
const comment = row.querySelector('td:nth-child(3)').textContent.toLowerCase();
-
+
if (voterName.includes(searchTerm) || comment.includes(searchTerm)) {
row.style.display = '';
} else {
row.style.display = 'none';
}
});
+
+ // Reset pagination after search
+ currentPage = 1;
+ updatePagination();
});
}
+
+ // Pagination functionality
+ const rowsPerPageSelect = document.getElementById('rowsPerPage');
+ const paginationControls = document.getElementById('paginationControls');
+ const votesTableBody = document.getElementById('votesTableBody');
+ const startRowElement = document.getElementById('startRow');
+ const endRowElement = document.getElementById('endRow');
+ const totalRowsElement = document.getElementById('totalRows');
+ const prevPageBtn = document.getElementById('prevPage');
+ const nextPageBtn = document.getElementById('nextPage');
+
+ let currentPage = 1;
+ let rowsPerPage = rowsPerPageSelect ? parseInt(rowsPerPageSelect.value) : 10;
+
+ // Function to update pagination display
+ function updatePagination() {
+ if (!paginationControls) return;
+
+ // Get all rows that match the current filter
+ const currentFilter = document.querySelector('[data-filter].active');
+ const filterType = currentFilter ? currentFilter.getAttribute('data-filter') : 'all';
+
+ // Get rows that match the current filter and search term
+ let filteredRows = Array.from(voteRows);
+ if (filterType !== 'all') {
+ filteredRows = filteredRows.filter(row => row.getAttribute('data-vote-type') === filterType);
+ }
+
+ // Apply search filter if there's a search term
+ const searchTerm = searchInput ? searchInput.value.toLowerCase() : '';
+ if (searchTerm) {
+ filteredRows = filteredRows.filter(row => {
+ const voterName = row.querySelector('td:first-child').textContent.toLowerCase();
+ const comment = row.querySelector('td:nth-child(3)').textContent.toLowerCase();
+ return voterName.includes(searchTerm) || comment.includes(searchTerm);
+ });
+ }
+
+ const totalRows = filteredRows.length;
+
+ // Calculate total pages
+ const totalPages = Math.max(1, Math.ceil(totalRows / rowsPerPage));
+
+ // Ensure current page is valid
+ if (currentPage > totalPages) {
+ currentPage = totalPages;
+ }
+
+ // Update pagination controls
+ if (paginationControls) {
+ // Clear existing page links (except prev/next)
+ const pageLinks = paginationControls.querySelectorAll('li:not(#prevPage):not(#nextPage)');
+ pageLinks.forEach(link => link.remove());
+
+ // Add new page links
+ const maxVisiblePages = 5;
+ let startPage = Math.max(1, currentPage - Math.floor(maxVisiblePages / 2));
+ let endPage = Math.min(totalPages, startPage + maxVisiblePages - 1);
+
+ // Adjust if we're near the end
+ if (endPage - startPage + 1 < maxVisiblePages && startPage > 1) {
+ startPage = Math.max(1, endPage - maxVisiblePages + 1);
+ }
+
+ // Insert page links before the next button
+ const nextPageElement = document.getElementById('nextPage');
+ for (let i = startPage; i <= endPage; i++) {
+ const li = document.createElement('li');
+ li.className = `page-item ${i === currentPage ? 'active' : ''}`;
+
+ const a = document.createElement('a');
+ a.className = 'page-link';
+ a.href = '#';
+ a.textContent = i;
+ a.addEventListener('click', function(e) {
+ e.preventDefault();
+ currentPage = i;
+ updatePagination();
+ });
+
+ li.appendChild(a);
+ paginationControls.insertBefore(li, nextPageElement);
+ }
+
+ // Update prev/next buttons
+ prevPageBtn.className = `page-item ${currentPage === 1 ? 'disabled' : ''}`;
+ nextPageBtn.className = `page-item ${currentPage === totalPages ? 'disabled' : ''}`;
+ }
+
+ // Show current page
+ showCurrentPage();
+ }
+
+ // Function to show current page
+ function showCurrentPage() {
+ if (!votesTableBody) return;
+
+ // Get all rows that match the current filter
+ const currentFilter = document.querySelector('[data-filter].active');
+ const filterType = currentFilter ? currentFilter.getAttribute('data-filter') : 'all';
+
+ // Get rows that match the current filter and search term
+ let filteredRows = Array.from(voteRows);
+ if (filterType !== 'all') {
+ filteredRows = filteredRows.filter(row => row.getAttribute('data-vote-type') === filterType);
+ }
+
+ // Apply search filter if there's a search term
+ const searchTerm = searchInput ? searchInput.value.toLowerCase() : '';
+ if (searchTerm) {
+ filteredRows = filteredRows.filter(row => {
+ const voterName = row.querySelector('td:first-child').textContent.toLowerCase();
+ const comment = row.querySelector('td:nth-child(3)').textContent.toLowerCase();
+ return voterName.includes(searchTerm) || comment.includes(searchTerm);
+ });
+ }
+
+ // Hide all rows first
+ voteRows.forEach(row => row.style.display = 'none');
+
+ // Calculate pagination
+ const totalRows = filteredRows.length;
+ const totalPages = Math.max(1, Math.ceil(totalRows / rowsPerPage));
+
+ // Ensure current page is valid
+ if (currentPage > totalPages) {
+ currentPage = totalPages;
+ }
+
+ // Show only rows for current page
+ const start = (currentPage - 1) * rowsPerPage;
+ const end = start + rowsPerPage;
+
+ filteredRows.slice(start, end).forEach(row => row.style.display = '');
+
+ // Update pagination info
+ if (startRowElement && endRowElement && totalRowsElement) {
+ startRowElement.textContent = totalRows > 0 ? start + 1 : 0;
+ endRowElement.textContent = Math.min(end, totalRows);
+ totalRowsElement.textContent = totalRows;
+ }
+ }
+
+ // Event listeners for pagination
+ if (prevPageBtn) {
+ prevPageBtn.addEventListener('click', function(e) {
+ e.preventDefault();
+ if (currentPage > 1) {
+ currentPage--;
+ updatePagination();
+ }
+ });
+ }
+
+ if (nextPageBtn) {
+ nextPageBtn.addEventListener('click', function(e) {
+ e.preventDefault();
+ // Get all rows that match the current filter
+ const currentFilter = document.querySelector('[data-filter].active');
+ const filterType = currentFilter ? currentFilter.getAttribute('data-filter') : 'all';
+
+ // Get rows that match the current filter and search term
+ let filteredRows = Array.from(voteRows);
+ if (filterType !== 'all') {
+ filteredRows = filteredRows.filter(row => row.getAttribute('data-vote-type') === filterType);
+ }
+
+ // Apply search filter if there's a search term
+ const searchTerm = searchInput ? searchInput.value.toLowerCase() : '';
+ if (searchTerm) {
+ filteredRows = filteredRows.filter(row => {
+ const voterName = row.querySelector('td:first-child').textContent.toLowerCase();
+ const comment = row.querySelector('td:nth-child(3)').textContent.toLowerCase();
+ return voterName.includes(searchTerm) || comment.includes(searchTerm);
+ });
+ }
+
+ const totalRows = filteredRows.length;
+ const totalPages = Math.max(1, Math.ceil(totalRows / rowsPerPage));
+
+ if (currentPage < totalPages) {
+ currentPage++;
+ updatePagination();
+ }
+ });
+ }
+
+ if (rowsPerPageSelect) {
+ rowsPerPageSelect.addEventListener('change', function() {
+ rowsPerPage = parseInt(this.value);
+ currentPage = 1; // Reset to first page
+ updatePagination();
+ });
+ }
+
+ // Initialize pagination
+ if (paginationControls) {
+ updatePagination();
+ }
// Initialize tooltips for all elements with title attributes
const tooltipElements = document.querySelectorAll('[title]');