/** * LoadUsers - System do ładowania użytkowników z API z paginacją, filtrowaniem i sortowaniem * Obsługuje duże bazy danych (setki tysięcy użytkowników) */ class LoadUsers { constructor(apiUrl = '/api/loadUsers.php') { this.apiUrl = apiUrl; this.currentPage = 1; this.limit = 50; this.sortBy = 'id'; this.sortOrder = 'ASC'; this.filters = {}; this.cache = {}; } /** * Główna metoda pobierająca użytkowników * @param {Object} options - Opcje zapytania (page, limit, sortBy, sortOrder, filters) * @returns {Promise} - Obiekt z użytkownikami i informacjami o paginacji */ async getUsers(options = {}) { // Aktualizacja parametrów if (options.page !== undefined) this.currentPage = options.page; if (options.limit !== undefined) this.limit = options.limit; if (options.sortBy !== undefined) this.sortBy = options.sortBy; if (options.sortOrder !== undefined) this.sortOrder = options.sortOrder; if (options.filters !== undefined) this.filters = options.filters; // Budowanie URL z parametrami const url = this.buildUrl(); // Sprawdzenie cache const cacheKey = url; if (this.cache[cacheKey]) { console.log('Zwracam z cache:', cacheKey); return this.cache[cacheKey]; } try { const response = await fetch(url); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } const data = await response.json(); if (!data.success) { throw new Error(data.error || 'Błąd pobierania użytkowników'); } // Zapisanie do cache this.cache[cacheKey] = data; return data; } catch (error) { console.error('Błąd podczas pobierania użytkowników:', error); throw error; } } /** * Buduje URL z parametrami * @returns {string} - Pełny URL z parametrami */ buildUrl() { const params = new URLSearchParams(); params.append('page', this.currentPage); params.append('limit', this.limit); params.append('sortBy', this.sortBy); params.append('sortOrder', this.sortOrder); // Dodanie filtrów Object.keys(this.filters).forEach(key => { if (this.filters[key] !== null && this.filters[key] !== undefined && this.filters[key] !== '') { params.append(key, this.filters[key]); } }); return `${this.apiUrl}?${params.toString()}`; } /** * Przechodzi do następnej strony * @returns {Promise} */ async nextPage() { return await this.getUsers({ page: this.currentPage + 1 }); } /** * Przechodzi do poprzedniej strony * @returns {Promise} */ async previousPage() { if (this.currentPage > 1) { return await this.getUsers({ page: this.currentPage - 1 }); } return null; } /** * Przechodzi do konkretnej strony * @param {number} page - Numer strony * @returns {Promise} */ async goToPage(page) { return await this.getUsers({ page: page }); } /** * Ustawia sortowanie * @param {string} column - Kolumna do sortowania * @param {string} order - Kierunek sortowania (ASC/DESC) * @returns {Promise} */ async sort(column, order = 'ASC') { return await this.getUsers({ sortBy: column, sortOrder: order, page: 1 // Reset do pierwszej strony przy sortowaniu }); } /** * Ustawia filtry * @param {Object} filters - Obiekt z filtrami * @returns {Promise} */ async filter(filters) { return await this.getUsers({ filters: filters, page: 1 // Reset do pierwszej strony przy filtrowaniu }); } /** * Dodaje pojedynczy filtr * @param {string} key - Nazwa filtru * @param {*} value - Wartość filtru * @returns {Promise} */ async addFilter(key, value) { this.filters[key] = value; return await this.getUsers({ page: 1 }); } /** * Usuwa pojedynczy filtr * @param {string} key - Nazwa filtru * @returns {Promise} */ async removeFilter(key) { delete this.filters[key]; return await this.getUsers({ page: 1 }); } /** * Czyści wszystkie filtry * @returns {Promise} */ async clearFilters() { this.filters = {}; return await this.getUsers({ page: 1 }); } /** * Czyści cache */ clearCache() { this.cache = {}; } /** * Resetuje wszystkie parametry do domyślnych * @returns {Promise} */ async reset() { this.currentPage = 1; this.limit = 50; this.sortBy = 'id'; this.sortOrder = 'ASC'; this.filters = {}; this.clearCache(); return await this.getUsers(); } /** * Eksportuje aktualny stan jako URL (do bookmarków) * @returns {string} */ getShareableUrl() { return this.buildUrl(); } /** * Wczytuje stan z URL * @param {string} url - URL ze stanem * @returns {Promise} */ async loadFromUrl(url) { const urlObj = new URL(url); const params = new URLSearchParams(urlObj.search); const options = {}; if (params.has('page')) options.page = parseInt(params.get('page')); if (params.has('limit')) options.limit = parseInt(params.get('limit')); if (params.has('sortBy')) options.sortBy = params.get('sortBy'); if (params.has('sortOrder')) options.sortOrder = params.get('sortOrder'); // Wczytanie filtrów const filters = {}; params.forEach((value, key) => { if (!['page', 'limit', 'sortBy', 'sortOrder'].includes(key)) { filters[key] = value; } }); if (Object.keys(filters).length > 0) { options.filters = filters; } return await this.getUsers(options); } } // Export dla Node.js / ES Modules if (typeof module !== 'undefined' && module.exports) { module.exports = LoadUsers; }