This commit is contained in:
pika 2025-03-30 23:42:24 +02:00
parent 3b2f1db4ce
commit 5c16964b76
47 changed files with 2080 additions and 1053 deletions

View file

@ -1,3 +1,7 @@
/**
* DITTO Application JavaScript
* Modern ES6+ syntax with proper error handling
*/
document.addEventListener('DOMContentLoaded', () => {
console.log('App script loaded.');
@ -76,8 +80,121 @@ document.addEventListener('DOMContentLoaded', () => {
// Initialize notifications
initNotifications();
});
// Initialize Bootstrap components
initBootstrapComponents();
// Setup sidebar toggle functionality
setupSidebar();
// Add form validation
setupFormValidation();
});
/**
* Initialize Bootstrap components
*/
function initBootstrapComponents() {
// Initialize all tooltips
const tooltipTriggerList = document.querySelectorAll('[data-bs-toggle="tooltip"]');
tooltipTriggerList.forEach(el => {
try {
new bootstrap.Tooltip(el);
} catch (e) {
console.warn('Error initializing tooltip:', e);
}
});
// Initialize all popovers
const popoverTriggerList = document.querySelectorAll('[data-bs-toggle="popover"]');
popoverTriggerList.forEach(el => {
try {
new bootstrap.Popover(el);
} catch (e) {
console.warn('Error initializing popover:', e);
}
});
}
/**
* Setup sidebar toggle functionality
*/
function setupSidebar() {
const sidebarToggler = document.querySelector('.sidebar-toggler');
const sidebar = document.querySelector('.sidebar');
if (sidebarToggler && sidebar) {
sidebarToggler.addEventListener('click', () => {
sidebar.classList.toggle('show');
});
// Close sidebar when clicking outside on mobile
document.addEventListener('click', (event) => {
const isClickInside = sidebar.contains(event.target) ||
sidebarToggler.contains(event.target);
if (!isClickInside && sidebar.classList.contains('show') && window.innerWidth < 992) {
sidebar.classList.remove('show');
}
});
}
}
/**
* Setup form validation
*/
function setupFormValidation() {
// Add custom validation for forms
const forms = document.querySelectorAll('.needs-validation');
forms.forEach(form => {
form.addEventListener('submit', event => {
if (!form.checkValidity()) {
event.preventDefault();
event.stopPropagation();
}
form.classList.add('was-validated');
}, false);
});
}
/**
* Safe query selector with error handling
* @param {string} selector - CSS selector
* @param {Element} parent - Parent element (optional)
* @returns {Element|null} - The selected element or null
*/
function $(selector, parent = document) {
try {
return parent.querySelector(selector);
} catch (e) {
console.warn(`Error selecting "${selector}":`, e);
return null;
}
}
/**
* Format date for display
* @param {string|Date} date - Date to format
* @returns {string} - Formatted date string
*/
function formatDate(date) {
try {
const d = new Date(date);
return d.toLocaleDateString(undefined, {
year: 'numeric',
month: 'short',
day: 'numeric',
hour: '2-digit',
minute: '2-digit'
});
} catch (e) {
console.warn('Error formatting date:', e);
return String(date);
}
}
function initTiptapEditor(element) {
// Load required Tiptap scripts
const editorContainer = document.getElementById('editor-container');