Skip to main content

max / goingson

4.3 KB · 155 lines History Blame Raw
1 /**
2 * GoingsOn - Pagination Manager
3 * Generic pagination handling for lists.
4 * Replaces duplicate pagination code in tasks.js and emails.js.
5 */
6
7 class PaginationManager {
8 /**
9 * Create a pagination manager.
10 * @param {string} type - Item type identifier (used for DOM element IDs)
11 * @param {number} itemsPerPage - Number of items per page
12 */
13 constructor(type, itemsPerPage = 25) {
14 this.type = type;
15 this.itemsPerPage = itemsPerPage;
16 this.currentPage = 1;
17 this.totalItems = 0;
18 }
19
20 /**
21 * Navigate to a page.
22 * @param {'prev'|'next'|number} direction - Direction or page number
23 * @returns {number} The new current page
24 */
25 goToPage(direction) {
26 const maxPage = this.getMaxPage();
27
28 if (direction === 'prev') {
29 this.currentPage = Math.max(1, this.currentPage - 1);
30 } else if (direction === 'next') {
31 this.currentPage = Math.min(maxPage, this.currentPage + 1);
32 } else if (typeof direction === 'number') {
33 this.currentPage = Math.max(1, Math.min(maxPage, direction));
34 }
35
36 return this.currentPage;
37 }
38
39 /**
40 * Get the current page number.
41 * @returns {number}
42 */
43 getCurrentPage() {
44 return this.currentPage;
45 }
46
47 /**
48 * Get the maximum page number.
49 * @returns {number}
50 */
51 getMaxPage() {
52 return Math.max(1, Math.ceil(this.totalItems / this.itemsPerPage));
53 }
54
55 /**
56 * Set the total number of items and validate current page.
57 * @param {number} total - Total number of items
58 */
59 setTotalItems(total) {
60 this.totalItems = total;
61 // Validate current page
62 const maxPage = this.getMaxPage();
63 if (this.currentPage > maxPage) {
64 this.currentPage = maxPage;
65 }
66 if (this.currentPage < 1) {
67 this.currentPage = 1;
68 }
69 }
70
71 /**
72 * Reset pagination to first page.
73 */
74 reset() {
75 this.currentPage = 1;
76 }
77
78 /**
79 * Get the offset for the current page (for backend pagination).
80 * @returns {number} The number of items to skip
81 */
82 getOffset() {
83 return (this.currentPage - 1) * this.itemsPerPage;
84 }
85
86 /**
87 * Get a paginated slice of items (for client-side pagination).
88 * @param {Array} items - All items
89 * @returns {Array} Paginated items
90 */
91 paginate(items) {
92 const start = this.getOffset();
93 return items.slice(start, start + this.itemsPerPage);
94 }
95
96 /**
97 * Update the pagination UI elements.
98 */
99 updateUI() {
100 const container = document.getElementById(`${this.type}-pagination`);
101 const prevBtn = document.getElementById(`${this.type}-prev-page`);
102 const nextBtn = document.getElementById(`${this.type}-next-page`);
103 const pageInfo = document.getElementById(`${this.type}-page-info`);
104
105 if (!container) return;
106
107 // Show/hide pagination
108 if (this.totalItems <= this.itemsPerPage) {
109 container.style.display = 'none';
110 return;
111 }
112
113 container.style.display = 'flex';
114
115 const maxPage = this.getMaxPage();
116
117 // Update buttons
118 if (prevBtn) prevBtn.disabled = this.currentPage <= 1;
119 if (nextBtn) nextBtn.disabled = this.currentPage >= maxPage;
120
121 // Update page info
122 if (pageInfo) {
123 const start = (this.currentPage - 1) * this.itemsPerPage + 1;
124 const end = Math.min(this.currentPage * this.itemsPerPage, this.totalItems);
125 pageInfo.textContent = `${start}-${end} of ${this.totalItems} (Page ${this.currentPage}/${maxPage})`;
126 }
127 }
128
129 /**
130 * Get pagination info for display.
131 * @returns {Object} Pagination info
132 */
133 getInfo() {
134 const maxPage = this.getMaxPage();
135 const start = (this.currentPage - 1) * this.itemsPerPage + 1;
136 const end = Math.min(this.currentPage * this.itemsPerPage, this.totalItems);
137
138 return {
139 currentPage: this.currentPage,
140 maxPage,
141 start,
142 end,
143 total: this.totalItems,
144 hasPrev: this.currentPage > 1,
145 hasNext: this.currentPage < maxPage
146 };
147 }
148 }
149
150 // ============ Populate GoingsOn Namespace ============
151
152 if (window.GoingsOn) {
153 GoingsOn.PaginationManager = PaginationManager;
154 }
155