// app/modules/loyalty/static/store/js/loyalty-card-detail.js // noqa: js-006 - async init pattern is safe, loadData has try/catch const loyaltyCardDetailLog = window.LogConfig.loggers.loyaltyCardDetail || window.LogConfig.createLogger('loyaltyCardDetail'); function storeLoyaltyCardDetail() { return { ...data(), currentPage: 'cards', cardId: null, card: null, transactions: [], pagination: { page: 1, per_page: 20, total: 0 }, loading: false, error: null, async init() { loyaltyCardDetailLog.info('=== LOYALTY CARD DETAIL PAGE INITIALIZING ==='); if (window._loyaltyCardDetailInitialized) return; window._loyaltyCardDetailInitialized = true; // IMPORTANT: Call parent init first to set storeCode from URL const parentInit = data().init; if (parentInit) { await parentInit.call(this); } // Extract card ID from URL const pathParts = window.location.pathname.split('/'); const cardsIndex = pathParts.indexOf('cards'); if (cardsIndex !== -1 && pathParts[cardsIndex + 1]) { this.cardId = parseInt(pathParts[cardsIndex + 1]); } if (!this.cardId) { this.error = 'Invalid card ID'; return; } // Use platform pagination setting if available if (window.PlatformSettings) { try { this.pagination.per_page = await window.PlatformSettings.getRowsPerPage(); } catch (e) { /* use default */ } } await this.loadData(); loyaltyCardDetailLog.info('=== LOYALTY CARD DETAIL PAGE INITIALIZATION COMPLETE ==='); }, async loadData() { this.loading = true; this.error = null; try { await Promise.all([ this.loadCard(), this.loadTransactions() ]); } catch (error) { loyaltyCardDetailLog.error('Failed to load data:', error); this.error = error.message; } finally { this.loading = false; } }, async loadCard() { const response = await apiClient.get(`/store/loyalty/cards/${this.cardId}`); if (response) { this.card = response; loyaltyCardDetailLog.info('Card loaded:', this.card.card_number); } }, async loadTransactions(page = 1) { try { const skip = (page - 1) * this.pagination.per_page; const response = await apiClient.get( `/store/loyalty/cards/${this.cardId}/transactions?skip=${skip}&limit=${this.pagination.per_page}` ); if (response && response.transactions) { this.transactions = response.transactions; this.pagination.total = response.total || 0; this.pagination.page = page; loyaltyCardDetailLog.info(`Loaded ${this.transactions.length} of ${this.pagination.total} transactions (page ${page})`); } } catch (error) { loyaltyCardDetailLog.warn('Failed to load transactions:', error.message); } }, // Standard pagination interface (matches shared pagination macro) get totalPages() { return Math.max(1, Math.ceil(this.pagination.total / this.pagination.per_page)); }, get startIndex() { if (this.pagination.total === 0) return 0; return (this.pagination.page - 1) * this.pagination.per_page + 1; }, get endIndex() { return Math.min(this.pagination.page * this.pagination.per_page, this.pagination.total); }, get pageNumbers() { const pages = []; for (let i = 1; i <= this.totalPages; i++) { if (i === 1 || i === this.totalPages || Math.abs(i - this.pagination.page) <= 1) { pages.push(i); } else if (pages[pages.length - 1] !== '...') { pages.push('...'); } } return pages; }, previousPage() { if (this.pagination.page > 1) this.loadTransactions(this.pagination.page - 1); }, nextPage() { if (this.pagination.page < this.totalPages) this.loadTransactions(this.pagination.page + 1); }, goToPage(p) { if (p >= 1 && p <= this.totalPages) this.loadTransactions(p); }, formatNumber(num) { return num == null ? '0' : new Intl.NumberFormat('en-US').format(num); }, formatDate(dateString) { if (!dateString) return '-'; try { return new Date(dateString).toLocaleDateString('en-US', { year: 'numeric', month: 'short', day: 'numeric' }); } catch (e) { return dateString; } }, formatDateTime(dateString) { if (!dateString) return '-'; try { return new Date(dateString).toLocaleString('en-US', { year: 'numeric', month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit' }); } catch (e) { return dateString; } } }; } if (!window.LogConfig.loggers.loyaltyCardDetail) { window.LogConfig.loggers.loyaltyCardDetail = window.LogConfig.createLogger('loyaltyCardDetail'); } loyaltyCardDetailLog.info('Loyalty card detail module loaded');