saufen/public/assets/js/app.js
2025-06-09 19:56:08 +02:00

127 lines
4.7 KiB
JavaScript

// Sparkle effect on mouse move
document.addEventListener('mousemove', function (e) {
const emojis = ['✨', '💖', '🌟', '💅', '🦄', '🎉', '🌈'];
const sparkle = document.createElement('div');
sparkle.className = 'emoji-footprint';
sparkle.textContent = emojis[Math.floor(Math.random() * emojis.length)];
sparkle.style.left = e.pageX + 'px';
sparkle.style.top = e.pageY + 'px';
document.body.appendChild(sparkle);
setTimeout(() => {
sparkle.remove();
}, 1000);
});
// Function to initialize number input buttons
function initNumberInputs(container = document) {
container.querySelectorAll('.number-input-wrapper').forEach(function(wrapper) {
const input = wrapper.querySelector('input[type="number"]');
const decreaseBtn = wrapper.querySelector('[data-action="decrease"]');
const increaseBtn = wrapper.querySelector('[data-action="increase"]');
if (!input || !decreaseBtn || !increaseBtn) return;
// Skip if already initialized
if (decreaseBtn.hasAttribute('data-initialized')) return;
const step = parseFloat(input.getAttribute('step')) || 1;
const min = 0;
const max = input.getAttribute('max') ? parseFloat(input.getAttribute('max')) : null;
decreaseBtn.addEventListener('click', function() {
const currentValue = parseFloat(input.value) || 0;
const newValue = currentValue - step;
if (min === null || newValue >= min) {
input.value = newValue;
input.dispatchEvent(new Event('change', { bubbles: true }));
}
});
increaseBtn.addEventListener('click', function() {
const currentValue = parseFloat(input.value) || 0;
const newValue = currentValue + step;
if (max === null || newValue <= max) {
input.value = newValue;
input.dispatchEvent(new Event('change', { bubbles: true }));
}
});
// Validate input on change
input.addEventListener('input', function() {
const value = parseFloat(this.value);
if (min !== null && value < min) {
this.value = min;
}
if (max !== null && value > max) {
this.value = max;
}
});
// Mark as initialized
decreaseBtn.setAttribute('data-initialized', 'true');
increaseBtn.setAttribute('data-initialized', 'true');
});
}
document.addEventListener('DOMContentLoaded', function() {
// Bootstrap Modal handling
const htmxModal = document.getElementById('htmxModal');
if (htmxModal) {
htmxModal.addEventListener('show.bs.modal', function(event) {
// Get the button that triggered the modal
const button = event.relatedTarget;
// Extract the drink name from data-* attributes
const drinkName = button.getAttribute('data-drink-name');
// Update the modal title
if (drinkName) {
const modalTitle = htmxModal.querySelector('.modal-title');
if (modalTitle) {
modalTitle.textContent = 'Update Stock for ' + drinkName;
}
}
});
}
// HTMX Modal handling
document.body.addEventListener('htmx:afterSwap', function(event) {
// If the target is the modal body, initialize any form elements inside it
if (event.detail.target.id === 'htmxModalBody') {
// The modal content has been loaded
console.log('Modal content loaded');
// Initialize number inputs in the modal
initNumberInputs(event.detail.target);
}
});
// Handle form submissions in the modal
document.body.addEventListener('htmx:beforeSend', function(event) {
// If the event is from a form inside the modal
if (event.detail.elt.closest('#htmxModalBody')) {
// Add the HX-Request header to the request
event.detail.requestConfig.headers['HX-Request'] = 'true';
}
});
// Handle redirects from HTMX
document.body.addEventListener('htmx:responseError', function(event) {
if (event.detail.xhr.status === 303) {
const redirectUrl = event.detail.xhr.getResponseHeader('HX-Redirect');
if (redirectUrl) {
// Close the modal
const modal = bootstrap.Modal.getInstance(document.getElementById('htmxModal'));
if (modal) {
modal.hide();
}
// Redirect to the specified URL
window.location.href = redirectUrl;
}
}
});
// Initialize number inputs on page load
initNumberInputs();
});