Files
orion/static/admin/js/icons-page.js

209 lines
7.2 KiB
JavaScript

// 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',
// 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() {
iconsLog.info('=== ICONS PAGE INITIALIZING ===');
// Prevent multiple initializations
if (window._iconsPageInitialized) {
iconsLog.warn('Icons page already initialized, skipping...');
return;
}
window._iconsPageInitialized = true;
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 ===');
},
/**
* 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('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('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');