mirror of
https://github.com/Dvorinka/PPve.git
synced 2026-06-03 20:12:59 +00:00
te
This commit is contained in:
+49
-61
@@ -1217,27 +1217,7 @@
|
|||||||
<!-- Include icon picker component -->
|
<!-- Include icon picker component -->
|
||||||
<script src="components/icon-picker.js" defer></script>
|
<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>
|
<script>
|
||||||
// Get token and check authentication
|
// Get token and check authentication
|
||||||
@@ -2222,37 +2202,7 @@ function selectIcon(iconClass) {
|
|||||||
// Update the visible input with a friendly name
|
// Update the visible input with a friendly name
|
||||||
const iconName = iconClass.replace('fa-', '').replace(/-/g, ' ');
|
const iconName = iconClass.replace('fa-', '').replace(/-/g, ' ');
|
||||||
iconInput.value = iconName.split(' ')
|
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
|
// 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 (appIcon) appIcon.value = '';
|
||||||
if (customIconInput) customIconInput.value = '';
|
if (customIconInput) customIconInput.value = '';
|
||||||
if (customIconPreview) {
|
if (customIconPreview) {
|
||||||
@@ -2263,23 +2213,17 @@ function selectIcon(iconClass) {
|
|||||||
selectedIcon.className = 'fas fa-cube text-2xl text-gray-400';
|
selectedIcon.className = 'fas fa-cube text-2xl text-gray-400';
|
||||||
selectedIcon.classList.remove('hidden');
|
selectedIcon.classList.remove('hidden');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset color picker to default
|
// Reset color picker to default
|
||||||
const colorInput = document.getElementById('appColor');
|
const colorInput = document.getElementById('appColor');
|
||||||
const colorText = document.getElementById('appColorText');
|
const colorText = document.getElementById('appColorText');
|
||||||
if (colorInput) colorInput.value = '#4a6cf7';
|
if (colorInput) colorInput.value = '#4a6cf7';
|
||||||
if (colorText) colorText.value = '#4a6cf7';
|
if (colorText) colorText.value = '#4a6cf7';
|
||||||
|
|
||||||
// Reset icon picker selection
|
// Reset icon picker selection
|
||||||
const selectedIcons = document.querySelectorAll('.icon-option.selected');
|
const selectedIcons = document.querySelectorAll('.icon-option.selected');
|
||||||
selectedIcons.forEach(icon => icon.classList.remove('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
|
// Set focus to the first input field
|
||||||
const firstInput = form?.querySelector('input, textarea, select');
|
const firstInput = form?.querySelector('input, textarea, select');
|
||||||
if (firstInput) firstInput.focus();
|
if (firstInput) firstInput.focus();
|
||||||
@@ -2354,6 +2298,9 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||||||
// Initialize file input for custom icon upload
|
// Initialize file input for custom icon upload
|
||||||
setupFileInput();
|
setupFileInput();
|
||||||
|
|
||||||
|
// Initialize icon picker
|
||||||
|
window.iconPicker = IconPicker.getInstance();
|
||||||
|
|
||||||
// Add click handler for custom icon button
|
// Add click handler for custom icon button
|
||||||
const customIconBtn = document.getElementById('customIconBtn');
|
const customIconBtn = document.getElementById('customIconBtn');
|
||||||
const customIconInput = document.getElementById('customIconInput');
|
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 appColor = document.getElementById('appColor');
|
||||||
const appColorText = document.getElementById('appColorText');
|
const appColorText = document.getElementById('appColorText');
|
||||||
|
|
||||||
@@ -4151,10 +4110,39 @@ function applyTemplate(templateId) {
|
|||||||
if (bannerPreview) {
|
if (bannerPreview) {
|
||||||
bannerPreview.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
|
bannerPreview.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
|
||||||
}
|
}
|
||||||
}
|
}}}
|
||||||
|
|
||||||
// Load apps when the page loads
|
// Load apps when the page loads
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
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();
|
loadApps();
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -4,15 +4,30 @@ class IconPicker {
|
|||||||
this.container = null;
|
this.container = null;
|
||||||
this.searchInput = null;
|
this.searchInput = null;
|
||||||
this.iconList = null;
|
this.iconList = null;
|
||||||
|
this.closeButton = null;
|
||||||
this.isInitialized = false;
|
this.isInitialized = false;
|
||||||
this.isModalOpen = false;
|
this.isModalOpen = false;
|
||||||
this.icons = [];
|
this.icons = [];
|
||||||
this.currentSearch = '';
|
this.currentSearch = '';
|
||||||
|
this.eventListeners = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
static getInstance() {
|
||||||
|
if (!window._iconPickerInstance) {
|
||||||
|
window._iconPickerInstance = new IconPicker();
|
||||||
|
}
|
||||||
|
return window._iconPickerInstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
if (this.isInitialized) return;
|
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
|
// Create modal structure
|
||||||
this.modal = document.createElement('div');
|
this.modal = document.createElement('div');
|
||||||
this.modal.className = 'icon-picker-modal fixed inset-0 bg-black bg-opacity-50 z-50 hidden';
|
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.iconList = this.modal.querySelector('.icon-picker-list');
|
||||||
this.closeButton = this.modal.querySelector('.icon-picker-close');
|
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
|
// Add to body
|
||||||
document.body.appendChild(this.modal);
|
document.body.appendChild(this.modal);
|
||||||
|
|
||||||
@@ -136,35 +156,68 @@ class IconPicker {
|
|||||||
|
|
||||||
setupEventListeners() {
|
setupEventListeners() {
|
||||||
// Close button
|
// 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
|
// Search input
|
||||||
this.searchInput.addEventListener('input', (e) => {
|
const searchHandler = (e) => {
|
||||||
const searchTerm = e.target.value.toLowerCase();
|
const searchTerm = e.target.value.toLowerCase();
|
||||||
this.renderIcons(searchTerm);
|
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 click - close when clicking outside
|
||||||
document.addEventListener('click', (e) => {
|
const clickHandler = (e) => {
|
||||||
if (this.isModalOpen && !this.container.contains(e.target)) {
|
if (this.isModalOpen && !this.container.contains(e.target)) {
|
||||||
this.close();
|
this.close();
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
|
document.addEventListener('click', clickHandler);
|
||||||
|
this.eventListeners.push({ element: document, event: 'click', handler: clickHandler });
|
||||||
|
|
||||||
// Escape key
|
// Escape key
|
||||||
document.addEventListener('keydown', (e) => {
|
const keydownHandler = (e) => {
|
||||||
if (e.key === 'Escape' && this.isModalOpen) {
|
if (e.key === 'Escape' && this.isModalOpen) {
|
||||||
this.close();
|
this.close();
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
|
document.addEventListener('keydown', keydownHandler);
|
||||||
|
this.eventListeners.push({ element: document, event: 'keydown', handler: keydownHandler });
|
||||||
|
|
||||||
// Icon selection
|
// Icon selection
|
||||||
this.iconList.addEventListener('click', (e) => {
|
const iconClickHandler = (e) => {
|
||||||
const iconOption = e.target.closest('.icon-option');
|
const iconOption = e.target.closest('.icon-option');
|
||||||
if (iconOption && iconOption.dataset.icon) {
|
if (iconOption && iconOption.dataset.icon) {
|
||||||
this.selectIcon(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() {
|
open() {
|
||||||
|
|||||||
Reference in New Issue
Block a user