342 lines
10 KiB
JavaScript
342 lines
10 KiB
JavaScript
// ===========================
|
||
// Dark Mode Toggle
|
||
// ===========================
|
||
|
||
// Sofort beim Laden: Dark Mode Preference wiederherstellen
|
||
// Ab 16:00 Uhr automatisch Dark Mode, sofern kein manueller Override gespeichert ist
|
||
(function() {
|
||
const saved = localStorage.getItem('darkMode');
|
||
const hour = new Date().getHours();
|
||
const autoDark = hour >= 16;
|
||
const useDark = saved !== null ? saved === 'true' : autoDark;
|
||
|
||
if (useDark) {
|
||
document.documentElement.classList.add('dark');
|
||
document.body.classList.add('dark');
|
||
}
|
||
})();
|
||
|
||
// Nach DOM Load: Event Listener attachen
|
||
document.addEventListener('DOMContentLoaded', function() {
|
||
const darkModeToggle = document.getElementById('dark-mode-toggle');
|
||
|
||
if (darkModeToggle) {
|
||
const icon = darkModeToggle.querySelector('.dark-mode-icon');
|
||
|
||
// Icon auf aktuellen Status setzen
|
||
const isDarkMode = localStorage.getItem('darkMode') === 'true';
|
||
icon.textContent = isDarkMode ? '☀️' : '🌙';
|
||
|
||
// Click-Handler
|
||
darkModeToggle.addEventListener('click', function(e) {
|
||
e.preventDefault();
|
||
e.stopPropagation();
|
||
|
||
// Toggle Dark Mode
|
||
document.body.classList.toggle('dark');
|
||
document.documentElement.classList.toggle('dark');
|
||
|
||
// Manuellen Override in localStorage speichern
|
||
const darkModeState = document.body.classList.contains('dark');
|
||
localStorage.setItem('darkMode', darkModeState ? 'true' : 'false');
|
||
|
||
// Icon aktualisieren
|
||
icon.textContent = darkModeState ? '☀️' : '🌙';
|
||
});
|
||
}
|
||
|
||
// ===========================
|
||
// Hamburger Navigation
|
||
// ===========================
|
||
const navToggle = document.getElementById('nav-toggle');
|
||
const mainNav = document.getElementById('main-nav');
|
||
|
||
if (navToggle && mainNav) {
|
||
navToggle.addEventListener('click', function(e) {
|
||
e.stopPropagation();
|
||
const isOpen = mainNav.classList.toggle('open');
|
||
navToggle.classList.toggle('open', isOpen);
|
||
navToggle.setAttribute('aria-expanded', String(isOpen));
|
||
});
|
||
|
||
// Menü schließen wenn ein Link geklickt wird
|
||
mainNav.querySelectorAll('a').forEach(function(link) {
|
||
link.addEventListener('click', function() {
|
||
mainNav.classList.remove('open');
|
||
navToggle.classList.remove('open');
|
||
navToggle.setAttribute('aria-expanded', 'false');
|
||
});
|
||
});
|
||
|
||
// Menü schließen bei Klick außerhalb
|
||
document.addEventListener('click', function(e) {
|
||
if (!navToggle.contains(e.target) && !mainNav.contains(e.target)) {
|
||
mainNav.classList.remove('open');
|
||
navToggle.classList.remove('open');
|
||
navToggle.setAttribute('aria-expanded', 'false');
|
||
}
|
||
});
|
||
}
|
||
|
||
// ===========================
|
||
// Dropdown "Start" – Touch/Click Toggle
|
||
// ===========================
|
||
const dropdowns = document.querySelectorAll('.nav-dropdown');
|
||
dropdowns.forEach(function(dd) {
|
||
const trigger = dd.querySelector('.nav-dropdown-trigger');
|
||
if (!trigger) return;
|
||
// Auf Touch-Geräten: Klick toggelt das Dropdown
|
||
trigger.addEventListener('click', function(e) {
|
||
// Nur wenn hover nicht greift (touch) oder Desktop-Klick direkt auf Trigger
|
||
const isMobile = window.matchMedia('(max-width: 768px)').matches;
|
||
if (!isMobile) {
|
||
// Desktop: navigate to index.html if it's a link click
|
||
return; // hover handles it
|
||
}
|
||
e.preventDefault();
|
||
// Im Hamburger-Menü: nichts tun (always open via CSS)
|
||
});
|
||
|
||
// Desktop: Dropdown per Klick schließen wenn man außerhalb klickt
|
||
document.addEventListener('click', function(e) {
|
||
if (!dd.contains(e.target)) {
|
||
dd.classList.remove('open');
|
||
}
|
||
});
|
||
});
|
||
|
||
// ===========================
|
||
// Active Navigation Highlighting
|
||
// ===========================
|
||
// Highlight active navigation link
|
||
const currentLocation = location.pathname.split('/').pop() || 'index.html';
|
||
const navLinks = document.querySelectorAll('nav a');
|
||
|
||
navLinks.forEach(link => {
|
||
const href = link.getAttribute('href');
|
||
if (href === currentLocation) {
|
||
link.classList.add('active');
|
||
} else {
|
||
link.classList.remove('active');
|
||
}
|
||
});
|
||
|
||
// Initialize lightbox gallery
|
||
initializeLightbox();
|
||
|
||
// Initialize contact form
|
||
initializeContactForm();
|
||
|
||
// ===========================
|
||
// Begrüssung nach Tageszeit (U13)
|
||
// ===========================
|
||
function aktualisiereUhrzeit() {
|
||
const el = document.getElementById('begruessung');
|
||
if (!el) return;
|
||
|
||
const jetzt = new Date();
|
||
const stunde = jetzt.getHours();
|
||
const minute = String(jetzt.getMinutes()).padStart(2, '0');
|
||
|
||
let gruss;
|
||
if (stunde < 12) {
|
||
gruss = 'Guten Morgen';
|
||
} else if (stunde < 17) {
|
||
gruss = 'Guten Mittag';
|
||
} else {
|
||
gruss = 'Guten Abend';
|
||
}
|
||
|
||
el.textContent = gruss + ', es ist ' + stunde + ':' + minute + ' Uhr';
|
||
}
|
||
|
||
aktualisiereUhrzeit();
|
||
setInterval(aktualisiereUhrzeit, 60000); // jede Minute aktualisieren
|
||
});
|
||
|
||
// ===========================
|
||
// Lightbox Gallery
|
||
// ===========================
|
||
|
||
function initializeLightbox() {
|
||
const galleryImages = document.querySelectorAll('.galerie img');
|
||
|
||
galleryImages.forEach(img => {
|
||
img.addEventListener('click', function() {
|
||
openLightbox(this.src);
|
||
});
|
||
});
|
||
}
|
||
|
||
function openLightbox(imageSrc) {
|
||
// Create overlay
|
||
const overlay = document.createElement('div');
|
||
overlay.className = 'lightbox-overlay';
|
||
|
||
// Create image container
|
||
const imgContainer = document.createElement('div');
|
||
imgContainer.style.position = 'relative';
|
||
|
||
// Create close button
|
||
const closeBtn = document.createElement('span');
|
||
closeBtn.className = 'lightbox-close';
|
||
closeBtn.innerHTML = '×';
|
||
closeBtn.addEventListener('click', function(e) {
|
||
e.stopPropagation();
|
||
overlay.remove();
|
||
});
|
||
|
||
// Create large image
|
||
const img = document.createElement('img');
|
||
img.src = imageSrc;
|
||
|
||
imgContainer.appendChild(closeBtn);
|
||
imgContainer.appendChild(img);
|
||
overlay.appendChild(imgContainer);
|
||
|
||
// Close on overlay click
|
||
overlay.addEventListener('click', function() {
|
||
overlay.remove();
|
||
});
|
||
|
||
// Close on Escape key
|
||
document.addEventListener('keydown', function(e) {
|
||
if (e.key === 'Escape') {
|
||
overlay.remove();
|
||
}
|
||
});
|
||
|
||
document.body.appendChild(overlay);
|
||
}
|
||
|
||
// ===========================
|
||
// Contact Form Handling
|
||
// ===========================
|
||
|
||
function initializeContactForm() {
|
||
const form = document.getElementById('contactForm');
|
||
if (!form) return;
|
||
|
||
// Live-Validierung: Fehler beim Verlassen des Feldes clearen
|
||
['name', 'email', 'subject', 'message'].forEach(function(id) {
|
||
const field = document.getElementById(id);
|
||
if (field) {
|
||
field.addEventListener('input', function() {
|
||
clearFieldError(id);
|
||
});
|
||
}
|
||
});
|
||
|
||
form.addEventListener('submit', function(e) {
|
||
e.preventDefault();
|
||
|
||
const name = document.getElementById('name').value.trim();
|
||
const email = document.getElementById('email').value.trim();
|
||
const subject = document.getElementById('subject').value.trim();
|
||
const message = document.getElementById('message').value.trim();
|
||
|
||
let valid = true;
|
||
|
||
// Name prüfen
|
||
if (!name) {
|
||
showFieldError('name', 'Bitte gib deinen Namen ein.');
|
||
valid = false;
|
||
} else {
|
||
clearFieldError('name');
|
||
}
|
||
|
||
// E-Mail prüfen
|
||
if (!email) {
|
||
showFieldError('email', 'Bitte gib deine E-Mail-Adresse ein.');
|
||
valid = false;
|
||
} else if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
|
||
showFieldError('email', 'Die E-Mail-Adresse muss ein @ enthalten und gültig sein.');
|
||
valid = false;
|
||
} else {
|
||
clearFieldError('email');
|
||
}
|
||
|
||
// Betreff prüfen
|
||
if (!subject) {
|
||
showFieldError('subject', 'Bitte gib einen Betreff ein.');
|
||
valid = false;
|
||
} else {
|
||
clearFieldError('subject');
|
||
}
|
||
|
||
// Nachricht prüfen
|
||
if (!message) {
|
||
showFieldError('message', 'Bitte schreib uns eine Nachricht.');
|
||
valid = false;
|
||
} else if (message.length < 10) {
|
||
showFieldError('message', 'Die Nachricht sollte mindestens 10 Zeichen lang sein.');
|
||
valid = false;
|
||
} else {
|
||
clearFieldError('message');
|
||
}
|
||
|
||
if (!valid) return;
|
||
|
||
// Erfolg
|
||
form.reset();
|
||
['name', 'email', 'subject', 'message'].forEach(clearFieldError);
|
||
|
||
const formMessage = document.getElementById('formMessage');
|
||
if (formMessage) {
|
||
formMessage.innerHTML =
|
||
'<div class="form-success">' +
|
||
'<span class="form-success-icon">✅</span>' +
|
||
'<div>' +
|
||
'<strong>Danke für deine Nachricht!</strong><br>' +
|
||
'Wir melden uns bald bei dir. 💕' +
|
||
'</div>' +
|
||
'</div>';
|
||
formMessage.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
|
||
}
|
||
});
|
||
}
|
||
|
||
function showFieldError(fieldId, message) {
|
||
const field = document.getElementById(fieldId);
|
||
const errorEl = document.getElementById('error-' + fieldId);
|
||
if (field) field.classList.add('input-error');
|
||
if (errorEl) errorEl.textContent = message;
|
||
}
|
||
|
||
function clearFieldError(fieldId) {
|
||
const field = document.getElementById(fieldId);
|
||
const errorEl = document.getElementById('error-' + fieldId);
|
||
if (field) field.classList.remove('input-error');
|
||
if (errorEl) errorEl.textContent = '';
|
||
}
|
||
|
||
function showFormMessage(message, type) {
|
||
const formMessage = document.getElementById('formMessage');
|
||
if (!formMessage) return;
|
||
formMessage.textContent = message;
|
||
}
|
||
|
||
// ===========================
|
||
// Smooth Scroll (Progressive Enhancement)
|
||
// ===========================
|
||
|
||
document.addEventListener('click', function(e) {
|
||
if (e.target.tagName === 'A' && e.target.getAttribute('href').startsWith('#')) {
|
||
e.preventDefault();
|
||
const targetId = e.target.getAttribute('href').substring(1);
|
||
const targetElement = document.getElementById(targetId);
|
||
|
||
if (targetElement) {
|
||
targetElement.scrollIntoView({ behavior: 'smooth' });
|
||
}
|
||
}
|
||
});
|
||
|
||
// ===========================
|
||
// Utility: Log
|
||
// ===========================
|
||
|
||
console.log('✅ EIS Website erfolgreich geladen!');
|
||
console.log('📚 Veranstaltung: Entwicklung interaktiver Softwareanwendungen');
|
||
console.log('🏫 Institution: PH Weingarten');
|
||
console.log('👨🏫 Dozenten: Stefan Franke und Prof. Dr. Wolfgang Müller');
|