This commit is contained in:
Tomas Dvorak
2025-05-30 12:50:29 +02:00
parent c110df7a53
commit e8ac93bdfb
2 changed files with 110 additions and 69 deletions
+49 -61
View File
@@ -1217,27 +1217,7 @@
<!-- Include icon picker component -->
<script src="components/icon-picker.js" defer></script>
<!-- Initialize icon picker -->
<script>
// Initialize icon picker when the page loads
document.addEventListener('DOMContentLoaded', function() {
// Initialize banner visibility
bannerVisible = document.getElementById('bannerVisibility');
// Initialize icon picker
window.iconPicker = IconPicker.getInstance();
// Toggle icon picker when clicking the icon input
const iconInput = document.getElementById('appIcon');
if (iconInput) {
iconInput.addEventListener('click', function(e) {
e.preventDefault();
e.stopPropagation();
window.iconPicker.open();
});
}
});
</script>
<script>
// Get token and check authentication
@@ -2222,37 +2202,7 @@ function selectIcon(iconClass) {
// Update the visible input with a friendly name
const iconName = iconClass.replace('fa-', '').replace(/-/g, ' ');
iconInput.value = iconName.split(' ')
.map(word => word.charAt(0).toUpperCase() + word.slice(1))
.join(' ');
// Highlight the selected icon
const selectedOption = document.querySelector(`.icon-option[data-icon="${iconClass}"]`);
if (selectedOption) {
// Remove active class from all icons
document.querySelectorAll('.icon-option').forEach(option => {
option.classList.remove('active');
});
// Add active class to selected icon
selectedOption.classList.add('active');
}
// Close the modal
isModalOpen = false;
document.body.style.overflow = '';
iconPickerModal.style.display = 'none';
// Update the preview
if (iconPreview) {
iconPreview.className = 'w-12 h-12 rounded-full bg-blue-100 text-blue-600 flex items-center justify-center mr-3';
}
}
}
// Reset icon selection
const appIcon = document.getElementById('appIcon');
const customIconInput = document.getElementById('customIconInput');
const customIconPreview = document.getElementById('customIconPreview');
const selectedIcon = document.getElementById('selectedIcon');
if (appIcon) appIcon.value = '';
if (customIconInput) customIconInput.value = '';
if (customIconPreview) {
@@ -2263,23 +2213,17 @@ function selectIcon(iconClass) {
selectedIcon.className = 'fas fa-cube text-2xl text-gray-400';
selectedIcon.classList.remove('hidden');
}
// Reset color picker to default
const colorInput = document.getElementById('appColor');
const colorText = document.getElementById('appColorText');
if (colorInput) colorInput.value = '#4a6cf7';
if (colorText) colorText.value = '#4a6cf7';
// Reset icon picker selection
const selectedIcons = document.querySelectorAll('.icon-option.selected');
selectedIcons.forEach(icon => icon.classList.remove('selected'));
// Show the modal
const modal = document.getElementById('appModal');
if (modal) {
modal.classList.remove('hidden');
}
// Set focus to the first input field
const firstInput = form?.querySelector('input, textarea, select');
if (firstInput) firstInput.focus();
@@ -2354,6 +2298,9 @@ document.addEventListener('DOMContentLoaded', function() {
// Initialize file input for custom icon upload
setupFileInput();
// Initialize icon picker
window.iconPicker = IconPicker.getInstance();
// Add click handler for custom icon button
const customIconBtn = document.getElementById('customIconBtn');
const customIconInput = document.getElementById('customIconInput');
@@ -2364,6 +2311,18 @@ document.addEventListener('DOMContentLoaded', function() {
});
}
// Add click handler for icon picker
const appIcon = document.getElementById('appIcon');
if (appIcon) {
appIcon.addEventListener('click', function(e) {
e.preventDefault();
e.stopPropagation();
if (window.iconPicker) {
window.iconPicker.open();
}
});
}
const appColor = document.getElementById('appColor');
const appColorText = document.getElementById('appColorText');
@@ -4151,10 +4110,39 @@ function applyTemplate(templateId) {
if (bannerPreview) {
bannerPreview.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
}
}
}}}
// Load apps when the page loads
document.addEventListener('DOMContentLoaded', function() {
// Initialize icon picker
window.iconPicker = IconPicker.getInstance();
// Initialize file input for custom icon upload
setupFileInput();
// Add click handler for custom icon button
const customIconBtn = document.getElementById('customIconBtn');
const customIconInput = document.getElementById('customIconInput');
if (customIconBtn && customIconInput) {
customIconBtn.addEventListener('click', function(e) {
e.preventDefault();
customIconInput.click();
});
}
// Add click handler for icon picker
const appIcon = document.getElementById('appIcon');
if (appIcon) {
appIcon.addEventListener('click', function(e) {
e.preventDefault();
e.stopPropagation();
if (window.iconPicker) {
window.iconPicker.open();
}
});
}
// Load apps
loadApps();
});
</script>
+61 -8
View File
@@ -4,15 +4,30 @@ class IconPicker {
this.container = null;
this.searchInput = null;
this.iconList = null;
this.closeButton = null;
this.isInitialized = false;
this.isModalOpen = false;
this.icons = [];
this.currentSearch = '';
this.eventListeners = [];
}
static getInstance() {
if (!window._iconPickerInstance) {
window._iconPickerInstance = new IconPicker();
}
return window._iconPickerInstance;
}
init() {
if (this.isInitialized) return;
// Check if DOM is ready
if (!document.body) {
console.error('DOM not ready - cannot initialize icon picker');
return;
}
// Create modal structure
this.modal = document.createElement('div');
this.modal.className = 'icon-picker-modal fixed inset-0 bg-black bg-opacity-50 z-50 hidden';
@@ -54,6 +69,11 @@ class IconPicker {
this.iconList = this.modal.querySelector('.icon-picker-list');
this.closeButton = this.modal.querySelector('.icon-picker-close');
if (!this.container || !this.searchInput || !this.iconList || !this.closeButton) {
console.error('Failed to initialize icon picker - missing elements');
return;
}
// Add to body
document.body.appendChild(this.modal);
@@ -136,35 +156,68 @@ class IconPicker {
setupEventListeners() {
// Close button
this.closeButton.addEventListener('click', () => this.close());
const closeHandler = () => this.close();
this.closeButton.addEventListener('click', closeHandler);
this.eventListeners.push({ element: this.closeButton, event: 'click', handler: closeHandler });
// Search input
this.searchInput.addEventListener('input', (e) => {
const searchHandler = (e) => {
const searchTerm = e.target.value.toLowerCase();
this.renderIcons(searchTerm);
});
};
this.searchInput.addEventListener('input', searchHandler);
this.eventListeners.push({ element: this.searchInput, event: 'input', handler: searchHandler });
// Document click - close when clicking outside
document.addEventListener('click', (e) => {
const clickHandler = (e) => {
if (this.isModalOpen && !this.container.contains(e.target)) {
this.close();
}
});
};
document.addEventListener('click', clickHandler);
this.eventListeners.push({ element: document, event: 'click', handler: clickHandler });
// Escape key
document.addEventListener('keydown', (e) => {
const keydownHandler = (e) => {
if (e.key === 'Escape' && this.isModalOpen) {
this.close();
}
});
};
document.addEventListener('keydown', keydownHandler);
this.eventListeners.push({ element: document, event: 'keydown', handler: keydownHandler });
// Icon selection
this.iconList.addEventListener('click', (e) => {
const iconClickHandler = (e) => {
const iconOption = e.target.closest('.icon-option');
if (iconOption && iconOption.dataset.icon) {
this.selectIcon(iconOption.dataset.icon);
}
};
this.iconList.addEventListener('click', iconClickHandler);
this.eventListeners.push({ element: this.iconList, event: 'click', handler: iconClickHandler });
}
cleanupEventListeners() {
this.eventListeners.forEach(listener => {
const { element, event, handler } = listener;
element.removeEventListener(event, handler);
});
this.eventListeners = [];
}
close() {
if (!this.isModalOpen) return;
this.isModalOpen = false;
this.modal.style.display = 'none';
document.body.style.overflow = '';
// Clear search
this.searchInput.value = '';
this.renderIcons('');
// Cleanup event listeners
this.cleanupEventListeners();
}
open() {