Files
dev-manufaktur/Dashboard/templates/dashboard.html
2025-02-16 21:47:35 +01:00

611 lines
30 KiB
HTML

<!DOCTYPE html>
<html lang="de" class="dark">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Dashboard</title>
<!-- Tailwind & FontAwesome -->
<script src="https://cdn.tailwindcss.com"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css" rel="stylesheet">
<!-- GSAP (Animations) -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.9.1/gsap.min.js"></script>
<script>
tailwind.config = {
darkMode: 'class',
theme: {
extend: {
colors: {
primary: '#3b82f6',
secondary: '#10b981',
}
}
}
}
</script>
<style>
/* Hintergrundbild per CSS (aus settings) */
body {
background-image: url('{{ url_for("static", filename=wallpaper) }}');
background-size: cover;
background-position: center;
background-attachment: fixed;
}
.glassmorphism {
background: rgba(255, 255, 255, 0.1);
backdrop-filter: blur(10px);
border: 1px solid rgba(255, 255, 255, 0.2);
border-radius: 10px;
}
.dark .glassmorphism {
background: rgba(0, 0, 0, 0.2);
}
/* Eingabe-Felder in Dark Mode */
.dark input[type="text"],
.dark input[type="email"],
.dark input[type="password"],
.dark textarea,
.dark select {
background-color: #374151;
color: #fff;
}
.dock-icon {
transition: all 0.3s ease;
}
.dock-icon:hover {
transform: scale(1.1);
}
</style>
</head>
<body class="min-h-screen bg-gray-100 dark:bg-gray-900 text-gray-800 dark:text-white transition-colors duration-300">
<div class="container mx-auto p-4 sm:p-6 lg:p-8 pb-20 flex flex-col items-center">
<!-- Bookmark Modal (Pop-up für Lesezeichen) -->
<div id="bookmarkModal" class="fixed inset-0 bg-black bg-opacity-50 hidden items-center justify-center z-50">
<div class="bg-white dark:bg-gray-800 glassmorphism p-6 rounded-lg max-w-md w-full mx-4">
<h2 class="text-2xl font-bold mb-4 text-gray-900 dark:text-white">Lesezeichen</h2>
<div class="mb-4">
<input type="text" id="bookmarkInput" placeholder="URL eingeben..." class="w-full p-2 border rounded bg-white dark:bg-gray-700 text-gray-900 dark:text-white">
</div>
<div class="flex justify-between">
<button id="addBookmark" class="bg-blue-500 hover:bg-blue-600 text-white px-4 py-2 rounded transition-colors duration-200">Hinzufügen</button>
<button class="bg-gray-300 dark:bg-gray-600 hover:bg-gray-400 dark:hover:bg-gray-500 text-gray-800 dark:text-white px-4 py-2 rounded transition-colors duration-200 close-modal">Schließen</button>
</div>
<div class="mt-6">
<h3 class="text-lg font-semibold mb-2 text-gray-900 dark:text-white">Meine Lesezeichen</h3>
<ul id="bookmarksList" class="space-y-2 max-h-60 overflow-y-auto">
<!-- Dynamisch per JS -->
</ul>
</div>
</div>
</div>
<!-- Bookmark-Button (öffnet das Modal) -->
<button id="bookmarkButton" class="fixed top-4 left-4 z-10 w-12 h-12 bg-blue-500 hover:bg-blue-600 text-white rounded-xl transition-colors duration-200 flex items-center justify-center">
<i class="fas fa-bookmark text-xl"></i>
</button>
<!-- Dark Mode Toggle (Sonne/Mond) -->
<button id="darkModeToggle" class="fixed top-4 right-4 w-12 h-12 rounded-xl bg-gray-200 dark:bg-gray-800 z-10 transition-colors duration-300">
<i class="fas fa-sun text-yellow-400 dark:hidden text-xl"></i>
<i class="fas fa-moon text-blue-200 hidden dark:inline text-xl"></i>
</button>
<!-- Logo, Begrüßung, Uhr -->
<div class="flex flex-col items-center justify-center space-y-4 text-center mb-6">
<a id="logo-link" href="https://{{ domain }}" target="_blank">
<img id="logo-img" src="{{ logo_path }}" alt="Firmenlogo" class="w-20 h-auto mb-2">
</a>
<h1 class="text-2xl sm:text-3xl font-bold text-gray-800 dark:text-white transition-colors duration-300">
Willkommen zurück, {{ user }}
</h1>
<div id="clock" class="text-xl sm:text-2xl font-semibold"></div>
</div>
<!-- Flash Messages -->
{% with messages = get_flashed_messages(with_categories=true) %}
{% if messages %}
<div class="mb-4">
{% for category, message in messages %}
<div class="alert flex items-center bg-{{ category }}-500 text-white text-sm font-bold px-4 py-3" role="alert">
<p>{{ message }}</p>
<svg class="fill-current h-6 w-6 text-white ml-auto close-flash" role="button" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20">
<title>Schließen</title>
<path d="M14.348 14.849a1.2 1.2 0 0 1-1.697 0L10 11.819l-2.651 3.029a1.2 1.2 0 1 1-1.697-1.697L8.302 10 5.651 7.349a1.2 1.2 0 1 1 1.697-1.697L10 8.181l2.651-2.529a1.2 1.2 0 1 1 1.697 1.697L11.698 10l2.651 2.651a1.2 1.2 0 0 1 0 1.698z"/>
</svg>
</div>
{% endfor %}
</div>
{% endif %}
{% endwith %}
<!-- Widgets (Wetter, Speicher, usw.) -->
<div class="grid grid-cols-1 sm:grid-cols-3 gap-4 mb-6 w-full max-w-3xl">
<!-- Wetter-Box -->
<div class="glassmorphism p-2 sm:p-3 shadow-lg rounded-md">
<h2 class="text-xs sm:text-sm font-semibold mb-1 text-center sm:text-left">Wetter in {{ city }}</h2>
<div class="flex items-center justify-center sm:justify-start mb-2">
<i class="fas {{ weather_icon }} text-base sm:text-lg md:text-xl mr-1"></i>
<p class="text-sm sm:text-base md:text-lg font-bold">{{ current_temp }}°C</p>
</div>
<!-- Forecast -->
<div class="space-y-1">
{% for day in forecast %}
<div class="flex items-center justify-between rounded-sm p-1">
<div class="flex items-center">
<i class="fas {{ day.weather_icon }} text-2xs sm:text-xs mr-1"></i>
<p class="text-2xs sm:text-xs">{{ day.date }}</p>
</div>
<p class="text-2xs sm:text-xs font-semibold">{{ day.day.avgtemp_c }}°C</p>
</div>
{% endfor %}
</div>
</div>
<!-- Beispiel: Speicher / RAM (nur Demo, falls du Systemdaten abrufst) -->
<div class="glassmorphism p-4 shadow-lg">
<h2 class="text-lg font-semibold mb-2">Speicher</h2>
<p class="text-xl font-bold mb-1">— Demo —</p>
</div>
<div class="glassmorphism p-4 shadow-lg">
<h2 class="text-lg font-semibold mb-2">RAM-Nutzung</h2>
<p class="text-xl font-bold mb-1">— Demo —</p>
</div>
</div>
<!-- App Launcher (Carousel) -->
<div class="glassmorphism p-4 mb-12 relative w-full max-w-3xl">
<div id="appCarousel" class="overflow-hidden">
<div class="flex transition-transform duration-300 ease-in-out">
{% for app_chunk in user_app_chunks %}
<div class="w-full flex-shrink-0">
<div class="grid grid-cols-3 sm:grid-cols-5 gap-4">
{% for app in app_chunk %}
<a href="https://{{ app.subdomain }}.{{ domain }}" class="flex flex-col items-center" title="{{ app.appkey }}">
<div class="w-12 h-12 flex items-center justify-center {{ app.bg_color }} rounded-xl mb-1 hover:scale-110 transition-transform">
<i class="{{ app.icon_class }} text-white text-xl"></i>
</div>
<p class="text-center text-xs font-medium">{{ app.name }}</p>
</a>
{% endfor %}
</div>
</div>
{% endfor %}
</div>
</div>
<button id="prevSlide" class="absolute top-1/2 left-2 transform -translate-y-1/2 bg-white/50 dark:bg-black/50 text-gray-800 dark:text-white rounded-full p-1 hover:bg-white/70 dark:hover:bg-black/70 transition-colors duration-200">
<i class="fas fa-chevron-left text-sm"></i>
</button>
<button id="nextSlide" class="absolute top-1/2 right-2 transform -translate-y-1/2 bg-white/50 dark:bg-black/50 text-gray-800 dark:text-white rounded-full p-1 hover:bg-white/70 dark:hover:bg-black/70 transition-colors duration-200">
<i class="fas fa-chevron-right text-sm"></i>
</button>
</div>
</div>
<!-- Dock mit Buttons: Home, Suche, Settings, Support -->
<div class="fixed bottom-4 left-1/2 transform -translate-x-1/2 glassmorphism p-2 flex space-x-4">
<button class="dock-icon w-12 h-12 flex items-center justify-center bg-blue-500 hover:bg-blue-600 rounded-xl" data-modal="homeModal">
<i class="fas fa-home text-white text-xl"></i>
</button>
<button class="dock-icon w-12 h-12 flex items-center justify-center bg-green-500 hover:bg-green-600 rounded-xl" data-modal="searchModal">
<i class="fas fa-search text-white text-xl"></i>
</button>
<button class="dock-icon w-12 h-12 flex items-center justify-center bg-yellow-500 hover:bg-yellow-600 rounded-xl" data-modal="settingsModal">
<i class="fas fa-cog text-white text-xl"></i>
</button>
<button class="dock-icon w-12 h-12 flex items-center justify-center bg-purple-500 hover:bg-purple-600 rounded-xl" data-modal="supportModal">
<i class="fas fa-question-circle text-white text-xl"></i>
</button>
</div>
<!-- Home Modal (Konto löschen, Daten-Export, Logout) -->
<div id="homeModal" class="fixed inset-0 bg-black bg-opacity-50 hidden items-center justify-center z-50">
<div class="bg-white dark:bg-gray-800 glassmorphism p-6 rounded-lg max-w-md w-full mx-auto shadow-lg">
<h2 class="text-2xl font-bold mb-4 text-gray-900 dark:text-white">
Willkommen Zuhause, {{ user }}!
</h2>
<p class="mb-4">Schneller Zugriff auf wichtige Funktionen</p>
<!-- Datenexport -->
<form action="{{ url_for('request_data_export') }}" method="GET" class="mb-3">
<button type="submit" class="w-full bg-green-500 hover:bg-green-600 text-white font-bold py-2 px-4 rounded transition ease-in-out duration-150">
Daten exportieren
</button>
</form>
<!-- Konto löschen -->
<form action="{{ url_for('delete_account') }}" method="POST">
<button type="submit" class="w-full bg-red-500 hover:bg-red-600 text-white font-bold py-2 px-4 rounded transition ease-in-out duration-150" onclick="return confirm('Sind Sie sicher, dass Sie Ihr Konto löschen möchten? Diese Aktion kann nicht rückgängig gemacht werden.');">
Konto löschen
</button>
</form>
<!-- Logout -->
<form action="{{ url_for('logout') }}" method="POST" class="mb-3 mt-2">
<button type="submit" class="w-full bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded transition ease-in-out duration-150">
Abmelden
</button>
</form>
<button class="mt-4 bg-gray-300 dark:bg-gray-700 hover:bg-gray-400 dark:hover:bg-gray-800 text-gray-800 dark:text-white font-bold py-2 px-4 rounded transition ease-in-out duration-150 close-modal">
Schließen
</button>
</div>
</div>
<!-- Search Modal -->
<div id="searchModal" class="fixed inset-0 bg-black bg-opacity-50 hidden items-center justify-center">
<div class="bg-white dark:bg-gray-800 glassmorphism p-6 rounded-lg max-w-md w-full mx-4">
<h2 class="text-2xl font-bold mb-4">Suche</h2>
<input type="text" id="searchInput" placeholder="Suchen..." class="w-full p-2 border rounded mb-4">
<select id="searchEngine" class="w-full p-2 border rounded mb-4">
<option value="qwant">Qwant</option>
<option value="google">Google</option>
</select>
<button id="startSearch" class="bg-green-500 text-white px-4 py-2 rounded">Suche starten</button>
<button class="mt-4 bg-blue-500 text-white px-4 py-2 rounded close-modal">Schließen</button>
</div>
</div>
<!-- Einstellungen-Modal -->
<div id="settingsModal" class="fixed inset-0 bg-black bg-opacity-50 hidden items-center justify-center overflow-auto">
<div class="bg-white dark:bg-gray-800 glassmorphism p-6 rounded-lg w-full max-w-md max-h-screen overflow-y-auto mx-4">
<h2 class="text-2xl font-bold mb-4">Einstellungen</h2>
<p>Hier können Sie Ihre Einstellungen anpassen und das System nach Ihren Wünschen konfigurieren.</p>
<!-- Wallpaper-Auswahl -->
<h3 class="text-lg font-semibold mb-2">Hintergrundbild auswählen</h3>
<div id="wallpaperSelection" class="grid grid-cols-2 sm:grid-cols-3 gap-2 mb-4">
{% for i in range(1, 27) %}
<img src="{{ url_for('static', filename=i ~ '.png') }}"
alt="Wallpaper {{ i }}"
class="w-full h-auto wallpaper-thumb cursor-pointer border-2
{{ 'border-blue-500' if wallpaper == i ~ '.png' else 'border-transparent' }}
rounded"
data-wallpaper="{{ i }}.png">
{% endfor %}
</div>
<!-- Stadt -->
<h3 class="text-lg font-semibold mb-2">Stadt ändern</h3>
<input type="text" id="cityInput" class="w-full p-2 border rounded mb-4" placeholder="Geben Sie Ihre Stadt ein" value="{{ city }}">
<!-- Wettervorhersage Toggle (versteckt, aber im Code notwendig) -->
<div style="display: none;">
<h3 class="text-lg font-semibold mb-2">Wochenvorhersage anzeigen</h3>
<label class="inline-flex items-center mt-2">
<input type="checkbox"
id="weatherForecastToggle"
class="form-checkbox h-5 w-5 text-blue-600"
{% if show_forecast %} checked {% endif %}>
<span class="ml-2 text-gray-700 dark:text-gray-300">Wochenvorhersage anzeigen</span>
</label>
</div>
<!-- Nur für Admins: Benutzerverwaltung -->
{% if role == 'admin' %}
<div class="mt-6 p-4 bg-gray-100 dark:bg-gray-700 rounded">
<h3 class="text-lg font-semibold mb-2 text-gray-900 dark:text-white">Benutzerverwaltung</h3>
<p class="text-sm mb-3">
Als Admin kannst du hier neue Benutzer anlegen, bearbeiten oder löschen
</p>
<a href="{{ url_for('admin') }}"
class="bg-blue-500 hover:bg-blue-600 text-white px-4 py-2 rounded">
Zum Admin-Panel
</a>
</div>
{% endif %}
<button id="saveSettings" class="mt-4 bg-yellow-500 text-white px-4 py-2 rounded hover:bg-yellow-600 transition-colors duration-200">Speichern</button>
<button class="mt-4 ml-2 bg-gray-500 text-white px-4 py-2 rounded hover:bg-gray-600 transition-colors duration-200 close-modal">Schließen</button>
</div>
</div>
<!-- Support Modal -->
<div id="supportModal" class="fixed inset-0 bg-black bg-opacity-50 hidden items-center justify-center">
<div class="bg-white dark:bg-gray-800 p-8 rounded-lg max-w-md w-full">
<h2 class="text-2xl font-bold mb-4">Support kontaktieren</h2>
<label for="problemType" class="block mb-2 text-lg font-semibold">Art des Problems</label>
<select id="problemType" class="w-full p-2 border rounded mb-4">
<option value="Technisches Problem">Technisches Problem</option>
<option value="Account Problem">Account Problem</option>
<option value="Sonstiges">Sonstiges</option>
</select>
<label for="emailInput" class="block mb-2 text-lg font-semibold">Ihre E-Mail</label>
<input type="email" id="emailInput" class="w-full p-2 border rounded mb-4" placeholder="Ihre E-Mail-Adresse">
<label for="messageInput" class="block mb-2 text-lg font-semibold">Nachricht</label>
<textarea id="messageInput" class="w-full p-2 border rounded mb-4" rows="4" placeholder="Beschreiben Sie Ihr Problem"></textarea>
<button id="sendSupportMessage" class="bg-purple-500 text-white px-4 py-2 rounded hover:bg-purple-600 transition-colors duration-200">
Nachricht senden
</button>
<button class="mt-4 bg-blue-500 text-white px-4 py-2 rounded hover:bg-blue-600 transition-colors duration-200 close-modal">
Schließen
</button>
</div>
</div>
<!-- JavaScript für Modal, Dark Mode, Clock, App Carousel, Bookmarks, usw. -->
<script>
// Dark Mode
const darkModeToggle = document.getElementById('darkModeToggle');
function toggleDarkMode() {
document.documentElement.classList.toggle('dark');
localStorage.setItem('darkMode', document.documentElement.classList.contains('dark'));
}
darkModeToggle.addEventListener('click', toggleDarkMode);
if (localStorage.getItem('darkMode') === 'true' ||
(!('darkMode' in localStorage) && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
document.documentElement.classList.add('dark');
}
// Uhr
function updateClock() {
const now = new Date();
const timeString = now.toLocaleTimeString('de-DE');
const dateString = now.toLocaleDateString('de-DE', { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' });
document.getElementById('clock').innerHTML = `${timeString}<br><span class="text-sm font-normal">${dateString}</span>`;
}
setInterval(updateClock, 1000);
updateClock();
// Carousel
const carousel = document.getElementById('appCarousel');
const carouselContent = carousel.querySelector('.flex');
const prevButton = document.getElementById('prevSlide');
const nextButton = document.getElementById('nextSlide');
let currentSlide = 0;
const totalSlides = carouselContent.children.length;
function showSlide(index) {
currentSlide = index;
const offset = -currentSlide * 100;
gsap.to(carouselContent, {duration: 0.5, x: `${offset}%`, ease: "power2.inOut"});
}
prevButton.addEventListener('click', () => {
currentSlide = (currentSlide - 1 + totalSlides) % totalSlides;
showSlide(currentSlide);
});
nextButton.addEventListener('click', () => {
currentSlide = (currentSlide + 1) % totalSlides;
showSlide(currentSlide);
});
// Animations
gsap.from(".glassmorphism", {duration: 1, opacity: 0, y: 50, stagger: 0.2, ease: "power3.out"});
gsap.from(".dock-icon", {duration: 0.5, opacity: 0, y: 20, stagger: 0.1, ease: "back.out(1.7)", delay: 1});
// Modal-Fenster öffnen/schließen
const modals = document.querySelectorAll('[id$="Modal"]');
const modalTriggers = document.querySelectorAll('[data-modal]');
const closeButtons = document.querySelectorAll('.close-modal');
modalTriggers.forEach(trigger => {
trigger.addEventListener('click', () => {
const modalId = trigger.getAttribute('data-modal');
const modal = document.getElementById(modalId);
modal.classList.remove('hidden');
modal.classList.add('flex');
});
});
closeButtons.forEach(button => {
button.addEventListener('click', () => {
const modal = button.closest('[id$="Modal"]');
modal.classList.remove('flex');
modal.classList.add('hidden');
});
});
modals.forEach(modal => {
modal.addEventListener('click', (e) => {
if (e.target === modal) {
modal.classList.remove('flex');
modal.classList.add('hidden');
}
});
});
// Wallpaper-Auswahl
let selectedWallpaper = '{{ wallpaper }}';
const wallpaperThumbnails = document.querySelectorAll('.wallpaper-thumb');
wallpaperThumbnails.forEach(thumb => {
thumb.addEventListener('click', function() {
wallpaperThumbnails.forEach(t => {
t.classList.remove('border-blue-500');
t.classList.add('border-transparent');
});
this.classList.remove('border-transparent');
this.classList.add('border-blue-500');
selectedWallpaper = this.getAttribute('data-wallpaper');
});
});
// Save Settings
document.getElementById('saveSettings').addEventListener('click', function() {
const city = document.getElementById('cityInput').value.trim();
const showForecast = document.getElementById('weatherForecastToggle').checked;
// Aktuelle Settings laden, um Bookmarks nicht zu überschreiben
fetch('/get_settings')
.then(res => res.json())
.then(settings => {
const bookmarks = settings.bookmarks || [];
fetch('/save_settings', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
'wallpaper': selectedWallpaper,
'city': city,
'show_forecast': showForecast,
'bookmarks': bookmarks
})
})
.then(response => response.json())
.then(data => {
if (data.success) {
location.reload();
} else {
alert('Fehler beim Speichern der Einstellungen: ' + (data.message || 'unbekannt'));
}
});
});
});
// Websuche
document.getElementById('startSearch').addEventListener('click', () => {
const query = document.getElementById('searchInput').value.trim();
const engine = document.getElementById('searchEngine').value;
if (query) {
let searchURL = '';
if (engine === 'qwant') {
searchURL = `https://www.qwant.com/?q=${encodeURIComponent(query)}`;
} else {
searchURL = `https://www.google.com/search?q=${encodeURIComponent(query)}`;
}
window.open(searchURL, '_blank');
}
});
// Bookmarks
const bookmarkModal = document.getElementById('bookmarkModal');
const bookmarkButton = document.getElementById('bookmarkButton');
const bookmarkInput = document.getElementById('bookmarkInput');
const addBookmark = document.getElementById('addBookmark');
const bookmarksList = document.getElementById('bookmarksList');
function openBookmarkModal() {
bookmarkModal.classList.remove('hidden');
bookmarkModal.classList.add('flex');
loadBookmarks();
}
function closeBookmarkModal() {
bookmarkModal.classList.remove('flex');
bookmarkModal.classList.add('hidden');
}
bookmarkButton.addEventListener('click', openBookmarkModal);
bookmarkModal.addEventListener('click', (e) => {
if (e.target === bookmarkModal) {
closeBookmarkModal();
}
});
closeButtons.forEach(button => {
button.addEventListener('click', closeBookmarkModal);
});
addBookmark.addEventListener('click', () => {
let url = bookmarkInput.value.trim();
if (url) {
const urlPattern = /^https?:\/\//i;
if (!urlPattern.test(url)) {
alert('Bitte gib eine vollständige URL mit http:// oder https:// ein.');
return;
}
addBookmarkToList(url);
bookmarkInput.value = '';
saveBookmarks();
}
});
function addBookmarkToList(url) {
const li = document.createElement('li');
li.innerHTML = `
<div class="flex items-center justify-between p-2 bg-gray-100 dark:bg-gray-700 rounded">
<a href="${url}" target="_blank" class="text-blue-600 dark:text-blue-400 hover:underline truncate">${url}</a>
<button class="delete-bookmark text-red-500 hover:text-red-700">
<i class="fas fa-trash-alt"></i>
</button>
</div>
`;
bookmarksList.appendChild(li);
const deleteButton = li.querySelector('.delete-bookmark');
deleteButton.addEventListener('click', () => {
li.remove();
saveBookmarks();
});
}
function loadBookmarks() {
fetch('/get_settings')
.then(res => res.json())
.then(settings => {
const b = settings.bookmarks || [];
bookmarksList.innerHTML = '';
b.forEach(bookmark => addBookmarkToList(bookmark));
});
}
function saveBookmarks() {
const b = Array.from(bookmarksList.children).map(li => li.querySelector('a').href);
fetch('/get_settings')
.then(res => res.json())
.then(settings => {
const city = settings.city;
const wallpaper = settings.wallpaper_url.split('/').pop();
const show_forecast = settings.show_forecast;
fetch('/save_settings', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
bookmarks: b,
city: city,
wallpaper: wallpaper,
show_forecast: show_forecast
})
}).then(response => {
if (!response.ok) {
alert('Fehler beim Speichern der Lesezeichen.');
}
});
});
}
// Beim Laden sofort Lesezeichen laden
window.addEventListener('DOMContentLoaded', loadBookmarks);
// Support Modal
const supportModal = document.getElementById('supportModal');
const supportModalToggle = document.querySelector('[data-modal="supportModal"]');
supportModalToggle.addEventListener('click', () => {
supportModal.classList.remove('hidden');
supportModal.classList.add('flex');
});
const sendSupportMessage = document.getElementById('sendSupportMessage');
sendSupportMessage.addEventListener('click', () => {
const email = document.getElementById('emailInput').value.trim();
const problemType = document.getElementById('problemType').value;
const message = document.getElementById('messageInput').value.trim();
if (email && message) {
fetch('/send_support_message', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ email, problemType, message })
}).then(response => {
if (response.ok) {
alert('Ihre Nachricht wurde erfolgreich gesendet.');
supportModal.classList.remove('flex');
supportModal.classList.add('hidden');
} else {
alert('Fehler beim Senden der Nachricht.');
}
});
} else {
alert('Bitte füllen Sie alle Felder aus.');
}
});
// Flash-Nachrichten per Klick schließen
document.addEventListener('DOMContentLoaded', function () {
const flashCloseBtns = document.querySelectorAll('.close-flash');
flashCloseBtns.forEach(btn => {
btn.addEventListener('click', function () {
const alertBox = this.closest('.alert');
alertBox.style.transition = 'opacity 0.5s ease';
alertBox.style.opacity = '0';
setTimeout(() => alertBox.remove(), 500);
});
});
});
</script>
</body>
</html>