// app/modules/dev_tools/static/admin/js/icons-page.js // ✅ Use centralized logger - ONE LINE! // Create custom logger since icons page is not pre-configured const iconsLog = window.LogConfig.createLogger('ICONS'); /** * Icons Browser Alpine.js Component * Browse and search all available icons */ function adminIcons() { return { // ✅ CRITICAL: Inherit base layout functionality ...data(), // ✅ CRITICAL: Set page identifier currentPage: 'icons', // Loading state loading: false, // Search and filter searchQuery: '', activeCategory: 'all', // Icon categories categories: [ { id: 'all', name: 'All Icons', icon: 'collection' }, { id: 'navigation', name: 'Navigation', icon: 'menu' }, { id: 'user', name: 'User & Profile', icon: 'user' }, { id: 'actions', name: 'Actions', icon: 'lightning-bolt' }, { id: 'ecommerce', name: 'E-commerce', icon: 'shopping-bag' }, { id: 'inventory', name: 'Inventory', icon: 'cube' }, { id: 'communication', name: 'Communication', icon: 'mail' }, { id: 'files', name: 'Files', icon: 'document' }, { id: 'settings', name: 'Settings', icon: 'cog' }, { id: 'status', name: 'Status', icon: 'check-circle' }, { id: 'testing', name: 'Testing', icon: 'beaker' } ], // All icons organized by category iconsByCategory: {}, allIcons: [], filteredIcons: [], // Selected icon for detail view selectedIcon: null, // ✅ CRITICAL: Proper initialization with guard async init() { // Prevent multiple initializations if (window._iconsPageInitialized) { iconsLog.warn('Icons page already initialized, skipping...'); return; } window._iconsPageInitialized = true; this.loading = true; try { // Load i18n translations await I18n.loadModule('dev_tools'); iconsLog.info('=== ICONS PAGE INITIALIZING ==='); const startTime = performance.now(); // Load icons from global Icons object this.loadIcons(); const duration = performance.now() - startTime; window.LogConfig.logPerformance('Icons Page Init', duration); iconsLog.info('=== ICONS PAGE INITIALIZATION COMPLETE ==='); } catch (error) { iconsLog.error('Init failed:', error); } finally { this.loading = false; } }, /** * Load icons from global Icons object */ loadIcons() { if (!window.Icons) { iconsLog.error('Icons object not found! Make sure icons.js is loaded.'); return; } // Get all icon names this.allIcons = Object.keys(window.Icons).map(name => ({ name: name, category: this.categorizeIcon(name) })); // Organize by category this.iconsByCategory = this.allIcons.reduce((acc, icon) => { if (!acc[icon.category]) { acc[icon.category] = []; } acc[icon.category].push(icon); return acc; }, {}); // Initial filter this.filterIcons(); iconsLog.info(`Loaded ${this.allIcons.length} icons across ${Object.keys(this.iconsByCategory).length} categories`); }, /** * Categorize icon based on name */ categorizeIcon(iconName) { const categoryMap = { navigation: ['home', 'menu', 'search', 'arrow', 'chevron'], user: ['user', 'identification', 'badge'], actions: ['edit', 'delete', 'plus', 'check', 'close', 'refresh', 'duplicate', 'eye', 'filter', 'dots'], ecommerce: ['shopping', 'credit-card', 'currency', 'gift', 'tag', 'truck', 'receipt'], inventory: ['cube', 'collection', 'photograph', 'chart'], communication: ['mail', 'phone', 'chat', 'bell', 'inbox'], files: ['document', 'folder', 'download', 'upload'], settings: ['cog', 'adjustments', 'calendar', 'moon', 'sun'], status: ['exclamation', 'information', 'spinner', 'star', 'heart', 'flag'], testing: ['view-grid', 'beaker', 'clipboard-list', 'check-circle', 'lightning-bolt', 'clock', 'lock-closed', 'database', 'light-bulb', 'book-open', 'play'] }; for (const [category, keywords] of Object.entries(categoryMap)) { if (keywords.some(keyword => iconName.includes(keyword))) { return category; } } return 'navigation'; // default }, /** * Filter icons based on search and category */ filterIcons() { let icons = this.allIcons; // Filter by category if (this.activeCategory !== 'all') { icons = icons.filter(icon => icon.category === this.activeCategory); } // Filter by search query if (this.searchQuery.trim()) { const query = this.searchQuery.toLowerCase(); icons = icons.filter(icon => icon.name.toLowerCase().includes(query)); } this.filteredIcons = icons; iconsLog.debug(`Filtered to ${icons.length} icons`); }, /** * Set active category */ setCategory(categoryId) { iconsLog.info('Setting category:', categoryId); this.activeCategory = categoryId; this.filterIcons(); }, /** * Select icon for detail view */ selectIcon(iconName) { iconsLog.info('Selected icon:', iconName); this.selectedIcon = iconName; }, /** * Copy icon usage code to clipboard */ async copyIconUsage(iconName) { const code = `x-html="$icon('${iconName}', 'w-5 h-5')"`; try { await navigator.clipboard.writeText(code); Utils.showToast(`'${iconName}' code copied!`, 'success'); iconsLog.debug('Icon usage code copied:', iconName); } catch (error) { window.LogConfig.logError(error, 'Copy Icon Usage'); Utils.showToast(I18n.t('dev_tools.messages.failed_to_copy_code'), 'error'); } }, /** * Copy icon name to clipboard */ async copyIconName(iconName) { try { await navigator.clipboard.writeText(iconName); Utils.showToast(`'${iconName}' copied!`, 'success'); iconsLog.debug('Icon name copied:', iconName); } catch (error) { window.LogConfig.logError(error, 'Copy Icon Name'); Utils.showToast(I18n.t('dev_tools.messages.failed_to_copy_name'), 'error'); } }, /** * Get category info */ getCategoryInfo(categoryId) { return this.categories.find(c => c.id === categoryId) || this.categories[0]; }, /** * Get icon count for category */ getCategoryCount(categoryId) { if (categoryId === 'all') { return this.allIcons.length; } return this.iconsByCategory[categoryId]?.length || 0; } }; } iconsLog.info('Icons page module loaded');