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

210 lines
7.3 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// static/admin/js/icons-page.js
// Setup logging
const ICONS_PAGE_LOG_LEVEL = 3;
const iconsLog = {
error: (...args) => ICONS_PAGE_LOG_LEVEL >= 1 && console.error('❌ [ICONS PAGE ERROR]', ...args),
warn: (...args) => ICONS_PAGE_LOG_LEVEL >= 2 && console.warn('⚠️ [ICONS PAGE WARN]', ...args),
info: (...args) => ICONS_PAGE_LOG_LEVEL >= 3 && console.info(' [ICONS PAGE INFO]', ...args),
debug: (...args) => ICONS_PAGE_LOG_LEVEL >= 4 && console.log('🔍 [ICONS PAGE DEBUG]', ...args)
};
/**
* 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;
// Load icons from global Icons object
this.loadIcons();
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) {
iconsLog.error('Failed to copy code:', error);
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) {
iconsLog.error('Failed to copy name:', error);
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');