.
This commit is contained in:
parent
071a4d8a97
commit
4d3ca1c554
39 changed files with 3386 additions and 0 deletions
274
static/js/main.js
Normal file
274
static/js/main.js
Normal file
|
@ -0,0 +1,274 @@
|
|||
document.addEventListener('DOMContentLoaded', function() {
|
||||
// Mobile menu toggle
|
||||
const mobileMenuButton = document.querySelector('.mobile-menu-button');
|
||||
const mobileMenu = document.querySelector('.mobile-menu');
|
||||
|
||||
mobileMenuButton.addEventListener('click', () => {
|
||||
mobileMenu.classList.toggle('hidden');
|
||||
|
||||
// Update button state
|
||||
mobileMenuButton.setAttribute('aria-expanded', !isExpanded);
|
||||
|
||||
// Toggle icons
|
||||
menuIconOpen.classList.toggle('hidden');
|
||||
menuIconClosed.classList.toggle('hidden');
|
||||
});
|
||||
|
||||
// Close mobile menu when clicking outside
|
||||
document.addEventListener('click', (e) => {
|
||||
if (!mobileMenuButton.contains(e.target) && !mobileMenu.contains(e.target)) {
|
||||
mobileMenu.classList.add('hidden');
|
||||
mobileMenuButton.setAttribute('aria-expanded', 'false');
|
||||
menuIconOpen.classList.remove('hidden');
|
||||
menuIconClosed.classList.add('hidden');
|
||||
}
|
||||
});
|
||||
|
||||
// Theme toggle functionality
|
||||
function updateTheme(isDark) {
|
||||
const html = document.documentElement;
|
||||
if (isDark) {
|
||||
html.classList.add('dark');
|
||||
} else {
|
||||
html.classList.remove('dark');
|
||||
}
|
||||
localStorage.setItem('theme', isDark ? 'dark' : 'light');
|
||||
}
|
||||
|
||||
// Desktop theme toggle
|
||||
const darkModeToggle = document.getElementById('darkModeToggle');
|
||||
darkModeToggle.addEventListener('click', () => {
|
||||
const isDark = document.documentElement.classList.contains('dark');
|
||||
updateTheme(!isDark);
|
||||
});
|
||||
|
||||
// Mobile theme toggle
|
||||
const darkModeToggleMobile = document.getElementById('darkModeToggleMobile');
|
||||
darkModeToggleMobile.addEventListener('click', () => {
|
||||
const isDark = document.documentElement.classList.contains('dark');
|
||||
updateTheme(!isDark);
|
||||
});
|
||||
|
||||
// Initialize theme
|
||||
const savedTheme = localStorage.getItem('theme');
|
||||
if (savedTheme) {
|
||||
updateTheme(savedTheme === 'dark');
|
||||
} else {
|
||||
// Default to dark theme
|
||||
updateTheme(true);
|
||||
}
|
||||
|
||||
// Header scroll behavior
|
||||
const header = document.querySelector('header');
|
||||
let lastScroll = 0;
|
||||
|
||||
window.addEventListener('scroll', () => {
|
||||
const currentScroll = window.pageYOffset;
|
||||
|
||||
if (currentScroll <= 0) {
|
||||
header.classList.remove('shadow-lg', 'bg-white/95', 'dark:bg-gray-900/95');
|
||||
header.style.transform = 'translateY(0)';
|
||||
return;
|
||||
}
|
||||
|
||||
if (currentScroll > lastScroll && !header.contains(document.activeElement)) {
|
||||
// Scrolling down
|
||||
header.style.transform = 'translateY(-100%)';
|
||||
} else {
|
||||
// Scrolling up
|
||||
header.style.transform = 'translateY(0)';
|
||||
header.classList.add('shadow-lg', 'bg-white/95', 'dark:bg-gray-900/95');
|
||||
}
|
||||
|
||||
lastScroll = currentScroll;
|
||||
});
|
||||
|
||||
// Menu tab functionality
|
||||
const tabButtons = document.querySelectorAll('.tab-button');
|
||||
const menuContents = document.querySelectorAll('.menu-content');
|
||||
|
||||
tabButtons.forEach(button => {
|
||||
button.addEventListener('click', () => {
|
||||
// Remove active state from all buttons
|
||||
tabButtons.forEach(btn => {
|
||||
btn.classList.remove('bg-pizza-red', 'text-white');
|
||||
btn.classList.add('bg-gray-200', 'dark:bg-pizza-darker', 'text-gray-700', 'dark:text-white');
|
||||
});
|
||||
|
||||
// Add active state to clicked button
|
||||
button.classList.remove('bg-gray-200', 'dark:bg-pizza-darker', 'text-gray-700', 'dark:text-white');
|
||||
button.classList.add('bg-pizza-red', 'text-white');
|
||||
|
||||
// Hide all content sections
|
||||
menuContents.forEach(content => {
|
||||
content.classList.add('hidden');
|
||||
});
|
||||
|
||||
// Show selected content
|
||||
const targetContent = document.getElementById(`${button.dataset.tab}-content`);
|
||||
targetContent.classList.remove('hidden');
|
||||
});
|
||||
});
|
||||
|
||||
// Price group toggles
|
||||
const priceGroups = document.querySelectorAll('.price-group-header');
|
||||
|
||||
priceGroups.forEach(group => {
|
||||
group.addEventListener('click', () => {
|
||||
const content = group.nextElementSibling;
|
||||
const arrow = group.querySelector('svg');
|
||||
|
||||
// Toggle content visibility
|
||||
content.classList.toggle('hidden');
|
||||
|
||||
// Rotate arrow
|
||||
if (content.classList.contains('hidden')) {
|
||||
arrow.style.transform = 'rotate(0deg)';
|
||||
} else {
|
||||
arrow.style.transform = 'rotate(180deg)';
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Auto-expand first price group
|
||||
const firstPriceGroup = document.querySelector('.price-group-header');
|
||||
if (firstPriceGroup) {
|
||||
firstPriceGroup.click();
|
||||
}
|
||||
|
||||
// Legend hover effect
|
||||
const legendContainer = document.querySelector('.legend-container');
|
||||
const legend = legendContainer.querySelector('.price-legend');
|
||||
|
||||
legendContainer.addEventListener('mouseenter', () => {
|
||||
legend.style.opacity = '0';
|
||||
});
|
||||
|
||||
legendContainer.addEventListener('mouseleave', () => {
|
||||
legend.style.opacity = '1';
|
||||
});
|
||||
|
||||
// Smooth scroll for menu links
|
||||
const menuLinks = document.querySelectorAll('a[href*="#menu-section"]');
|
||||
|
||||
menuLinks.forEach(link => {
|
||||
link.addEventListener('click', function(e) {
|
||||
e.preventDefault();
|
||||
console.log('Menu link clicked'); // Debug log
|
||||
|
||||
const menuSection = document.getElementById('menu-section');
|
||||
if (menuSection) {
|
||||
const headerHeight = document.querySelector('header').offsetHeight;
|
||||
const menuPosition = menuSection.offsetTop - headerHeight;
|
||||
|
||||
window.scrollTo({
|
||||
top: menuPosition,
|
||||
behavior: 'smooth'
|
||||
});
|
||||
} else {
|
||||
console.error('Menu section not found'); // Debug log
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Language dropdown functionality
|
||||
const languageButton = document.getElementById('languageButton');
|
||||
const languageDropdown = document.getElementById('languageDropdown');
|
||||
|
||||
if (languageButton && languageDropdown) {
|
||||
// Toggle dropdown
|
||||
languageButton.addEventListener('click', (e) => {
|
||||
e.stopPropagation();
|
||||
languageDropdown.classList.toggle('hidden');
|
||||
});
|
||||
|
||||
// Close dropdown when clicking outside
|
||||
document.addEventListener('click', (e) => {
|
||||
if (!languageButton.contains(e.target) && !languageDropdown.contains(e.target)) {
|
||||
languageDropdown.classList.add('hidden');
|
||||
}
|
||||
});
|
||||
|
||||
// Close dropdown when clicking a language option
|
||||
languageDropdown.querySelectorAll('a').forEach(link => {
|
||||
link.addEventListener('click', () => {
|
||||
languageDropdown.classList.add('hidden');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Auto-detect browser language
|
||||
function detectLanguage() {
|
||||
const browserLang = navigator.language.split('-')[0];
|
||||
const supportedLangs = ['de', 'en']; // Add your supported languages here
|
||||
|
||||
if (!localStorage.getItem('userLanguage')) {
|
||||
const detectedLang = supportedLangs.includes(browserLang) ? browserLang : 'de';
|
||||
localStorage.setItem('userLanguage', detectedLang);
|
||||
|
||||
// Redirect if needed
|
||||
const currentLang = document.documentElement.lang;
|
||||
if (currentLang !== detectedLang) {
|
||||
const newPath = window.location.pathname.replace(`/${currentLang}/`, `/${detectedLang}/`);
|
||||
window.location.href = newPath;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
detectLanguage();
|
||||
|
||||
function checkOpenStatus() {
|
||||
const now = new Date();
|
||||
const currentTime = now.toLocaleTimeString('de-DE', {
|
||||
hour: '2-digit',
|
||||
minute: '2-digit',
|
||||
hour12: false
|
||||
});
|
||||
const currentDay = now.toLocaleDateString('de-DE', { weekday: 'long' });
|
||||
|
||||
// Get opening hours from data attributes
|
||||
const hoursRows = document.querySelectorAll('.hours-row');
|
||||
let isOpen = false;
|
||||
|
||||
hoursRows.forEach(row => {
|
||||
const rowDay = row.dataset.day;
|
||||
const openTime = row.dataset.open;
|
||||
const closeTime = row.dataset.close;
|
||||
|
||||
// Convert times to comparable numbers (e.g., "14:30" -> 1430)
|
||||
const currentNum = parseInt(currentTime.replace(':', ''));
|
||||
const openNum = parseInt(openTime.replace(':', ''));
|
||||
const closeNum = parseInt(closeTime.replace(':', ''));
|
||||
|
||||
if (rowDay === currentDay && currentNum >= openNum && currentNum <= closeNum) {
|
||||
isOpen = true;
|
||||
row.classList.add('border-2', 'border-status-green');
|
||||
} else {
|
||||
row.classList.remove('border-2', 'border-status-green');
|
||||
}
|
||||
});
|
||||
|
||||
// Update status bar
|
||||
const statusBar = document.getElementById('status-bar');
|
||||
const statusText = document.getElementById('status-text');
|
||||
|
||||
if (statusBar && statusText) {
|
||||
if (isOpen) {
|
||||
statusBar.classList.remove('bg-status-red');
|
||||
statusBar.classList.add('bg-status-green');
|
||||
statusText.textContent = statusText.dataset.textOpen;
|
||||
} else {
|
||||
statusBar.classList.remove('bg-status-green');
|
||||
statusBar.classList.add('bg-status-red');
|
||||
statusText.textContent = statusText.dataset.textClosed;
|
||||
}
|
||||
}
|
||||
|
||||
return { isOpen, currentDay, currentTime };
|
||||
}
|
||||
|
||||
// Update status every minute
|
||||
setInterval(checkOpenStatus, 60000);
|
||||
// Initial check
|
||||
checkOpenStatus();
|
||||
});
|
Loading…
Add table
Add a link
Reference in a new issue