From b610d85313a1a53b09dfd139381ba048faf30a43 Mon Sep 17 00:00:00 2001 From: Carsten Graf Date: Mon, 8 Sep 2025 21:44:18 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=94=A7=20Fix=20location=20name=20logic:?= =?UTF-8?q?=20User=20determines=20name,=20API=20only=20provides=20coordina?= =?UTF-8?q?tes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Removed automatic API location name usage - User input from locationSearch field is used as location name - API search only provides coordinates (latitude/longitude) - User has full control over location naming - Search functionality purely for coordinate lookup --- public/js/generator.js | 912 ++++++++++++++++++++--------------------- 1 file changed, 451 insertions(+), 461 deletions(-) diff --git a/public/js/generator.js b/public/js/generator.js index a90212d..575d3f8 100644 --- a/public/js/generator.js +++ b/public/js/generator.js @@ -3,7 +3,7 @@ function toggleTokenFields() { const tierInput = document.getElementById("tier"); const dbConfig = document.getElementById("dbConfig"); const tier = parseInt(tierInput.value); - + if (tier >= 3 && !isNaN(tier)) { dbConfig.innerHTML = `

🗄️ Token-Informationen (für Stufe 3+)

@@ -59,332 +59,322 @@ function toggleTokenFields() { 📝 Standorte werden in der lokalen PostgreSQL-Datenbank gespeichert `; - dbConfig.classList.add("show"); - } else { - dbConfig.classList.remove("show"); - setTimeout(() => { - if (!dbConfig.classList.contains("show")) { - dbConfig.innerHTML = ""; - } - }, 400); + dbConfig.classList.add("show"); + } else { + dbConfig.classList.remove("show"); + setTimeout(() => { + if (!dbConfig.classList.contains("show")) { + dbConfig.innerHTML = ""; } + }, 400); + } +} + +const secret = "542ff224606c61fb3024e22f76ef9ac8"; + +function isValidMac(mac) { + const pattern = /^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$|^[0-9A-Fa-f]{12}$/; + return pattern.test(mac); +} + +function showMessage(elementId, message, isError = false) { + const messageDiv = document.getElementById(elementId); + messageDiv.textContent = message; + messageDiv.classList.add("show"); + setTimeout(() => { + messageDiv.classList.remove("show"); + }, 4000); +} + +function showError(message) { + showMessage("error", message, true); +} + +function showSuccess(message) { + showMessage("success", message, false); +} + +function setLoading(isLoading) { + const btnText = document.getElementById("btn-text"); + const btn = document.querySelector(".generate-btn"); + + if (isLoading) { + btnText.innerHTML = 'Generiere...'; + btn.disabled = true; + btn.style.opacity = '0.7'; + } else { + btnText.textContent = 'Lizenz generieren'; + btn.disabled = false; + btn.style.opacity = '1'; + } +} + +async function saveToDatabase(token, tier) { + const description = document.getElementById("description").value.trim(); + const standorte = document.getElementById("standorte").value.trim(); + + try { + const response = await fetch('/api/v1/web/save-token', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + token: token, + description: description || `API-Token Stufe ${tier}`, + standorte: standorte + }) + }); + + if (!response.ok) { + const errorData = await response.json(); + throw new Error(errorData.message || 'Fehler beim Speichern in der Datenbank'); } - const secret = "542ff224606c61fb3024e22f76ef9ac8"; + const result = await response.json(); + return result; + } catch (error) { + // Fallback: Zeige dem Benutzer den SQL-Befehl an, den er manuell ausführen kann + const sql = `INSERT INTO api_tokens (token, description, standorte) VALUES ('${token}', '${description || `API-Token Stufe ${tier}`}', '${standorte}');`; - function isValidMac(mac) { - const pattern = /^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$|^[0-9A-Fa-f]{12}$/; - return pattern.test(mac); + throw new Error(`Automatisches Speichern fehlgeschlagen. Server nicht erreichbar.\n\nFühren Sie folgenden SQL-Befehl manuell aus:\n${sql}`); + } +} + +async function generateLicense() { + const macInput = document.getElementById("mac").value.trim(); + const tierInput = document.getElementById("tier").value.trim(); + const resultDiv = document.getElementById("result"); + const licenseOutput = document.getElementById("license-output"); + const errorDiv = document.getElementById("error"); + const successDiv = document.getElementById("success"); + + // Reset states + resultDiv.classList.remove("show"); + errorDiv.classList.remove("show"); + successDiv.classList.remove("show"); + setLoading(true); + + // Simulate slight delay for better UX + await new Promise(resolve => setTimeout(resolve, 500)); + + try { + if (!isValidMac(macInput)) { + throw new Error("Ungültige MAC-Adresse. Bitte verwenden Sie das Format 00:1A:2B:3C:4D:5E"); } - function showMessage(elementId, message, isError = false) { - const messageDiv = document.getElementById(elementId); - messageDiv.textContent = message; - messageDiv.classList.add("show"); - setTimeout(() => { - messageDiv.classList.remove("show"); - }, 4000); + const mac = macInput.replace(/[:-]/g, "").toUpperCase(); + const tier = parseInt(tierInput); + + if (isNaN(tier) || tier < 1 || tier > 4) { + throw new Error("Lizenzstufe muss eine Zahl zwischen 1 und 4 sein."); } - function showError(message) { - showMessage("error", message, true); - } - - function showSuccess(message) { - showMessage("success", message, false); - } - - function setLoading(isLoading) { - const btnText = document.getElementById("btn-text"); - const btn = document.querySelector(".generate-btn"); - - if (isLoading) { - btnText.innerHTML = 'Generiere...'; - btn.disabled = true; - btn.style.opacity = '0.7'; - } else { - btnText.textContent = 'Lizenz generieren'; - btn.disabled = false; - btn.style.opacity = '1'; - } - } - - async function saveToDatabase(token, tier) { - const description = document.getElementById("description").value.trim(); - const standorte = document.getElementById("standorte").value.trim(); - - try { - const response = await fetch('/api/v1/web/save-token', { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ - token: token, - description: description || `API-Token Stufe ${tier}`, - standorte: standorte - }) - }); - - if (!response.ok) { - const errorData = await response.json(); - throw new Error(errorData.message || 'Fehler beim Speichern in der Datenbank'); - } - - const result = await response.json(); - return result; - } catch (error) { - // Fallback: Zeige dem Benutzer den SQL-Befehl an, den er manuell ausführen kann - const sql = `INSERT INTO api_tokens (token, description, standorte) VALUES ('${token}', '${description || `API-Token Stufe ${tier}`}', '${standorte}');`; - - throw new Error(`Automatisches Speichern fehlgeschlagen. Server nicht erreichbar.\n\nFühren Sie folgenden SQL-Befehl manuell aus:\n${sql}`); - } - } - - async function generateLicense() { - const macInput = document.getElementById("mac").value.trim(); - const tierInput = document.getElementById("tier").value.trim(); - const resultDiv = document.getElementById("result"); - const licenseOutput = document.getElementById("license-output"); - const errorDiv = document.getElementById("error"); - const successDiv = document.getElementById("success"); - - // Reset states - resultDiv.classList.remove("show"); - errorDiv.classList.remove("show"); - successDiv.classList.remove("show"); - setLoading(true); - - // Simulate slight delay for better UX - await new Promise(resolve => setTimeout(resolve, 500)); - - try { - if (!isValidMac(macInput)) { - throw new Error("Ungültige MAC-Adresse. Bitte verwenden Sie das Format 00:1A:2B:3C:4D:5E"); - } - - const mac = macInput.replace(/[:-]/g, "").toUpperCase(); - const tier = parseInt(tierInput); - - if (isNaN(tier) || tier < 1 || tier > 4) { - throw new Error("Lizenzstufe muss eine Zahl zwischen 1 und 4 sein."); - } - // Standort automatisch speichern, falls vorhanden let locationSaved = false; - const locationName = document.getElementById('realLocationName')?.value || document.getElementById('locationSearch')?.value?.trim(); + const locationName = document.getElementById('locationSearch')?.value?.trim(); const latitude = document.getElementById('latitude')?.textContent; const longitude = document.getElementById('longitude')?.textContent; - - if (locationName && latitude && longitude && tier >= 3) { - try { - await saveLocationToDatabase(); - locationSaved = true; - } catch (locationError) { - console.warn('Standort konnte nicht gespeichert werden:', locationError); - // Fahre trotzdem mit der Lizenzgenerierung fort - } - } - const data = `${mac}:${tier}`; - const enc = new TextEncoder(); - const key = await crypto.subtle.importKey( - "raw", - enc.encode(secret), - { name: "HMAC", hash: "SHA-256" }, - false, - ["sign"] - ); - const signature = await crypto.subtle.sign("HMAC", key, enc.encode(data)); - const hex = Array.from(new Uint8Array(signature)) - .map(b => b.toString(16).padStart(2, "0")) - .join("") - .toUpperCase(); - - licenseOutput.textContent = hex; - resultDiv.classList.add("show"); - - // Reset copy button - const copyBtn = document.getElementById("copyButton"); - copyBtn.textContent = "📋 In Zwischenablage kopieren"; - copyBtn.classList.remove("copied"); - - // Bei Stufe 3+ in Datenbank speichern - if (tier >= 3) { - try { - await saveToDatabase(hex, tier); - let successMessage = `✅ Lizenzschlüssel generiert und als API-Token gespeichert!`; - if (locationSaved) { - successMessage += ` Standort wurde ebenfalls gespeichert.`; - } - showSuccess(successMessage); - } catch (dbError) { - showError(`⚠️ Lizenz generiert, aber Datenbank-Fehler: ${dbError.message}`); - } - } else { - let successMessage = `✅ Lizenzschlüssel erfolgreich generiert!`; - if (locationSaved) { - successMessage += ` Standort wurde in der Datenbank gespeichert.`; - } - showSuccess(successMessage); - } - - } catch (error) { - showError(error.message); - } finally { - setLoading(false); - } - } - - async function copyToClipboard() { - const licenseOutput = document.getElementById("license-output"); - const copyBtn = document.getElementById("copyButton"); - + if (locationName && latitude && longitude && tier >= 3) { try { - await navigator.clipboard.writeText(licenseOutput.textContent); - copyBtn.textContent = "✅ Kopiert!"; - copyBtn.classList.add("copied"); - - setTimeout(() => { - copyBtn.textContent = "📋 In Zwischenablage kopieren"; - copyBtn.classList.remove("copied"); - }, 2000); - } catch (err) { - // Fallback for older browsers - const textArea = document.createElement("textarea"); - textArea.value = licenseOutput.textContent; - document.body.appendChild(textArea); - textArea.select(); - document.execCommand('copy'); - document.body.removeChild(textArea); - - copyBtn.textContent = "✅ Kopiert!"; - copyBtn.classList.add("copied"); - - setTimeout(() => { - copyBtn.textContent = "📋 In Zwischenablage kopieren"; - copyBtn.classList.remove("copied"); - }, 2000); + await saveLocationToDatabase(); + locationSaved = true; + } catch (locationError) { + console.warn('Standort konnte nicht gespeichert werden:', locationError); + // Fahre trotzdem mit der Lizenzgenerierung fort } } - // Enter key support - document.addEventListener('keypress', function(e) { - if (e.key === 'Enter') { - generateLicense(); - } - }); + const data = `${mac}:${tier}`; + const enc = new TextEncoder(); + const key = await crypto.subtle.importKey( + "raw", + enc.encode(secret), + { name: "HMAC", hash: "SHA-256" }, + false, + ["sign"] + ); + const signature = await crypto.subtle.sign("HMAC", key, enc.encode(data)); + const hex = Array.from(new Uint8Array(signature)) + .map(b => b.toString(16).padStart(2, "0")) + .join("") + .toUpperCase(); - // Input formatting for MAC address - document.getElementById('mac').addEventListener('input', function(e) { - let value = e.target.value.replace(/[^0-9A-Fa-f]/g, ''); - if (value.length > 12) value = value.substr(0, 12); - - // Add colons every 2 characters - value = value.replace(/(.{2})/g, '$1:').replace(/:$/, ''); - e.target.value = value; - }); + licenseOutput.textContent = hex; + resultDiv.classList.add("show"); - // Input event listener für Lizenzstufe - document.getElementById('tier').addEventListener('input', toggleTokenFields); - - // Standortsuche-Funktionalität - async function searchLocation(buttonElement) { - const locationInput = document.getElementById('locationSearch').value.trim(); - const coordinatesDiv = document.getElementById('coordinates'); - const mapContainer = document.getElementById('mapContainer'); - const latitudeSpan = document.getElementById('latitude'); - const longitudeSpan = document.getElementById('longitude'); - const mapFrame = document.getElementById('mapFrame'); - - if (!locationInput) { - showError('Bitte geben Sie einen Standort ein.'); - return; - } - - let originalText = ''; - let searchBtn = null; + // Reset copy button + const copyBtn = document.getElementById("copyButton"); + copyBtn.textContent = "📋 In Zwischenablage kopieren"; + copyBtn.classList.remove("copied"); + // Bei Stufe 3+ in Datenbank speichern + if (tier >= 3) { try { - // Zeige Ladeanimation - searchBtn = buttonElement || document.querySelector('button[onclick*="searchLocation"]'); - if (searchBtn) { - originalText = searchBtn.innerHTML; - searchBtn.innerHTML = 'Suche...'; - searchBtn.disabled = true; - } - - // API-Abfrage an Nominatim (OpenStreetMap) - const response = await fetch(`https://nominatim.openstreetmap.org/search?format=json&q=${encodeURIComponent(locationInput)}&limit=1`); - - if (!response.ok) { - throw new Error('Fehler bei der API-Abfrage'); - } - - const data = await response.json(); - - if (data.length === 0) { - throw new Error('Standort nicht gefunden. Bitte versuchen Sie eine andere Beschreibung.'); - } - - const location = data[0]; - const lat = parseFloat(location.lat); - const lon = parseFloat(location.lon); - - // Echten Standortnamen aus der API speichern - const realLocationName = location.display_name || location.name || locationInput; - - // Verstecktes Feld für echten Standortnamen erstellen/aktualisieren - let locationNameField = document.getElementById('realLocationName'); - if (!locationNameField) { - locationNameField = document.createElement('input'); - locationNameField.type = 'hidden'; - locationNameField.id = 'realLocationName'; - document.body.appendChild(locationNameField); - } - locationNameField.value = realLocationName; - - // Koordinaten anzeigen - updateCoordinates(lat, lon); - coordinatesDiv.style.display = 'block'; - - // Interaktive Karte erstellen - createInteractiveMap(lat, lon); - mapContainer.style.display = 'block'; - - // Erfolgsmeldung - showSuccess(`✅ Standort "${realLocationName}" erfolgreich gefunden! Klicken Sie auf die Karte, um den Pin zu verschieben.`); - - } catch (error) { - showError(`Fehler bei der Standortsuche: ${error.message}`); - coordinatesDiv.style.display = 'none'; - mapContainer.style.display = 'none'; - } finally { - // Button zurücksetzen - if (searchBtn && originalText) { - searchBtn.innerHTML = originalText; - searchBtn.disabled = false; + await saveToDatabase(hex, tier); + let successMessage = `✅ Lizenzschlüssel generiert und als API-Token gespeichert!`; + if (locationSaved) { + successMessage += ` Standort wurde ebenfalls gespeichert.`; } + showSuccess(successMessage); + } catch (dbError) { + showError(`⚠️ Lizenz generiert, aber Datenbank-Fehler: ${dbError.message}`); } + } else { + let successMessage = `✅ Lizenzschlüssel erfolgreich generiert!`; + if (locationSaved) { + successMessage += ` Standort wurde in der Datenbank gespeichert.`; + } + showSuccess(successMessage); } - // Koordinaten aktualisieren - function updateCoordinates(lat, lon) { - const latitudeSpan = document.getElementById('latitude'); - const longitudeSpan = document.getElementById('longitude'); - - if (latitudeSpan && longitudeSpan) { - latitudeSpan.textContent = lat.toFixed(6); - longitudeSpan.textContent = lon.toFixed(6); - } + } catch (error) { + showError(error.message); + } finally { + setLoading(false); + } +} + +async function copyToClipboard() { + const licenseOutput = document.getElementById("license-output"); + const copyBtn = document.getElementById("copyButton"); + + try { + await navigator.clipboard.writeText(licenseOutput.textContent); + copyBtn.textContent = "✅ Kopiert!"; + copyBtn.classList.add("copied"); + + setTimeout(() => { + copyBtn.textContent = "📋 In Zwischenablage kopieren"; + copyBtn.classList.remove("copied"); + }, 2000); + } catch (err) { + // Fallback for older browsers + const textArea = document.createElement("textarea"); + textArea.value = licenseOutput.textContent; + document.body.appendChild(textArea); + textArea.select(); + document.execCommand('copy'); + document.body.removeChild(textArea); + + copyBtn.textContent = "✅ Kopiert!"; + copyBtn.classList.add("copied"); + + setTimeout(() => { + copyBtn.textContent = "📋 In Zwischenablage kopieren"; + copyBtn.classList.remove("copied"); + }, 2000); + } +} + +// Enter key support +document.addEventListener('keypress', function (e) { + if (e.key === 'Enter') { + generateLicense(); + } +}); + +// Input formatting for MAC address +document.getElementById('mac').addEventListener('input', function (e) { + let value = e.target.value.replace(/[^0-9A-Fa-f]/g, ''); + if (value.length > 12) value = value.substr(0, 12); + + // Add colons every 2 characters + value = value.replace(/(.{2})/g, '$1:').replace(/:$/, ''); + e.target.value = value; +}); + +// Input event listener für Lizenzstufe +document.getElementById('tier').addEventListener('input', toggleTokenFields); + +// Standortsuche-Funktionalität +async function searchLocation(buttonElement) { + const locationInput = document.getElementById('locationSearch').value.trim(); + const coordinatesDiv = document.getElementById('coordinates'); + const mapContainer = document.getElementById('mapContainer'); + const latitudeSpan = document.getElementById('latitude'); + const longitudeSpan = document.getElementById('longitude'); + const mapFrame = document.getElementById('mapFrame'); + + if (!locationInput) { + showError('Bitte geben Sie einen Standort ein.'); + return; + } + + let originalText = ''; + let searchBtn = null; + + try { + // Zeige Ladeanimation + searchBtn = buttonElement || document.querySelector('button[onclick*="searchLocation"]'); + if (searchBtn) { + originalText = searchBtn.innerHTML; + searchBtn.innerHTML = 'Suche...'; + searchBtn.disabled = true; } + // API-Abfrage an Nominatim (OpenStreetMap) + const response = await fetch(`https://nominatim.openstreetmap.org/search?format=json&q=${encodeURIComponent(locationInput)}&limit=1`); + + if (!response.ok) { + throw new Error('Fehler bei der API-Abfrage'); + } + + const data = await response.json(); + + if (data.length === 0) { + throw new Error('Standort nicht gefunden. Bitte versuchen Sie eine andere Beschreibung.'); + } + + const location = data[0]; + const lat = parseFloat(location.lat); + const lon = parseFloat(location.lon); + + // Der Name wird vom User bestimmt - nur Koordinaten aus der API verwenden + // Kein verstecktes Feld nötig, da der User den Namen selbst eingibt + + // Koordinaten anzeigen + updateCoordinates(lat, lon); + coordinatesDiv.style.display = 'block'; + // Interaktive Karte erstellen - function createInteractiveMap(initialLat, initialLon) { - const mapFrame = document.getElementById('mapFrame'); - - // Verwende Leaflet.js für interaktive Karte - const mapHtml = ` + createInteractiveMap(lat, lon); + mapContainer.style.display = 'block'; + + // Erfolgsmeldung + showSuccess(`✅ Koordinaten für "${locationInput}" erfolgreich gefunden! Klicken Sie auf die Karte, um den Pin zu verschieben.`); + + } catch (error) { + showError(`Fehler bei der Standortsuche: ${error.message}`); + coordinatesDiv.style.display = 'none'; + mapContainer.style.display = 'none'; + } finally { + // Button zurücksetzen + if (searchBtn && originalText) { + searchBtn.innerHTML = originalText; + searchBtn.disabled = false; + } + } +} + +// Koordinaten aktualisieren +function updateCoordinates(lat, lon) { + const latitudeSpan = document.getElementById('latitude'); + const longitudeSpan = document.getElementById('longitude'); + + if (latitudeSpan && longitudeSpan) { + latitudeSpan.textContent = lat.toFixed(6); + longitudeSpan.textContent = lon.toFixed(6); + } +} + +// Interaktive Karte erstellen +function createInteractiveMap(initialLat, initialLon) { + const mapFrame = document.getElementById('mapFrame'); + + // Verwende Leaflet.js für interaktive Karte + const mapHtml = `
@@ -392,192 +382,192 @@ function toggleTokenFields() {
`; - - mapFrame.innerHTML = mapHtml; - - // Leaflet.js laden und Karte initialisieren - loadLeafletAndCreateMap(initialLat, initialLon); - } - // Leaflet.js laden und Karte erstellen - function loadLeafletAndCreateMap(initialLat, initialLon) { - // Prüfe ob Leaflet bereits geladen ist - if (typeof L !== 'undefined') { - createMap(initialLat, initialLon); - return; - } + mapFrame.innerHTML = mapHtml; - // Leaflet CSS laden - const leafletCSS = document.createElement('link'); - leafletCSS.rel = 'stylesheet'; - leafletCSS.href = 'https://unpkg.com/leaflet@1.9.4/dist/leaflet.css'; - document.head.appendChild(leafletCSS); + // Leaflet.js laden und Karte initialisieren + loadLeafletAndCreateMap(initialLat, initialLon); +} - // Leaflet JavaScript laden - const leafletScript = document.createElement('script'); - leafletScript.src = 'https://unpkg.com/leaflet@1.9.4/dist/leaflet.js'; - leafletScript.onload = () => createMap(initialLat, initialLon); - document.head.appendChild(leafletScript); - } +// Leaflet.js laden und Karte erstellen +function loadLeafletAndCreateMap(initialLat, initialLon) { + // Prüfe ob Leaflet bereits geladen ist + if (typeof L !== 'undefined') { + createMap(initialLat, initialLon); + return; + } - // Karte mit Leaflet erstellen - function createMap(initialLat, initialLon) { - try { - const map = L.map('map').setView([initialLat, initialLon], 15); - - // OpenStreetMap Tile Layer - L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { - attribution: '© OpenStreetMap contributors' - }).addTo(map); + // Leaflet CSS laden + const leafletCSS = document.createElement('link'); + leafletCSS.rel = 'stylesheet'; + leafletCSS.href = 'https://unpkg.com/leaflet@1.9.4/dist/leaflet.css'; + document.head.appendChild(leafletCSS); - // Marker erstellen - const marker = L.marker([initialLat, initialLon], { - draggable: true, - title: 'Standort' - }).addTo(map); + // Leaflet JavaScript laden + const leafletScript = document.createElement('script'); + leafletScript.src = 'https://unpkg.com/leaflet@1.9.4/dist/leaflet.js'; + leafletScript.onload = () => createMap(initialLat, initialLon); + document.head.appendChild(leafletScript); +} - // Marker-Drag Event - marker.on('dragend', function(event) { - const newLat = event.target.getLatLng().lat; - const newLon = event.target.getLatLng().lng; - updateCoordinates(newLat, newLon); - showSuccess(`📍 Pin auf neue Position verschoben: ${newLat.toFixed(6)}, ${newLon.toFixed(6)}`); - }); +// Karte mit Leaflet erstellen +function createMap(initialLat, initialLon) { + try { + const map = L.map('map').setView([initialLat, initialLon], 15); - // Klick-Event auf die Karte - map.on('click', function(event) { - const newLat = event.latlng.lat; - const newLon = event.latlng.lng; - - // Marker auf neue Position setzen - marker.setLatLng([newLat, newLon]); - - // Koordinaten aktualisieren - updateCoordinates(newLat, newLon); - - // Erfolgsmeldung - showSuccess(`📍 Pin auf neue Position gesetzt: ${newLat.toFixed(6)}, ${newLon.toFixed(6)}`); - }); + // OpenStreetMap Tile Layer + L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { + attribution: '© OpenStreetMap contributors' + }).addTo(map); - // Zoom-Controls hinzufügen - map.zoomControl.setPosition('bottomright'); + // Marker erstellen + const marker = L.marker([initialLat, initialLon], { + draggable: true, + title: 'Standort' + }).addTo(map); - } catch (error) { - console.error('Fehler beim Erstellen der Karte:', error); - // Fallback zu iframe - const mapFrame = document.getElementById('mapFrame'); - const mapUrl = `https://www.openstreetmap.org/export/embed.html?bbox=${initialLon-0.01},${initialLat-0.01},${initialLon+0.01},${initialLat+0.01}&layer=mapnik&marker=${initialLat},${initialLon}`; - mapFrame.innerHTML = ``; - } - } + // Marker-Drag Event + marker.on('dragend', function (event) { + const newLat = event.target.getLatLng().lat; + const newLon = event.target.getLatLng().lng; + updateCoordinates(newLat, newLon); + showSuccess(`📍 Pin auf neue Position verschoben: ${newLat.toFixed(6)}, ${newLon.toFixed(6)}`); + }); + + // Klick-Event auf die Karte + map.on('click', function (event) { + const newLat = event.latlng.lat; + const newLon = event.latlng.lng; + + // Marker auf neue Position setzen + marker.setLatLng([newLat, newLon]); + + // Koordinaten aktualisieren + updateCoordinates(newLat, newLon); + + // Erfolgsmeldung + showSuccess(`📍 Pin auf neue Position gesetzt: ${newLat.toFixed(6)}, ${newLon.toFixed(6)}`); + }); + + // Zoom-Controls hinzufügen + map.zoomControl.setPosition('bottomright'); + + } catch (error) { + console.error('Fehler beim Erstellen der Karte:', error); + // Fallback zu iframe + const mapFrame = document.getElementById('mapFrame'); + const mapUrl = `https://www.openstreetmap.org/export/embed.html?bbox=${initialLon - 0.01},${initialLat - 0.01},${initialLon + 0.01},${initialLat + 0.01}&layer=mapnik&marker=${initialLat},${initialLon}`; + mapFrame.innerHTML = ``; + } +} // Standort in Datenbank speichern async function saveLocationToDatabase() { - const locationName = document.getElementById('realLocationName')?.value || document.getElementById('locationSearch').value.trim(); + const locationName = document.getElementById('locationSearch').value.trim(); const latitude = document.getElementById('latitude').textContent; const longitude = document.getElementById('longitude').textContent; - const saveBtn = document.getElementById('saveLocationBtn'); - - if (!locationName || !latitude || !longitude) { - showError('Bitte suchen Sie zuerst einen Standort.'); - return; - } + const saveBtn = document.getElementById('saveLocationBtn'); - try { - // Button-Status ändern - const originalText = saveBtn.innerHTML; - saveBtn.innerHTML = 'Speichere...'; - saveBtn.disabled = true; + if (!locationName || !latitude || !longitude) { + showError('Bitte suchen Sie zuerst einen Standort.'); + return; + } - // Web-authenticated API für Standortverwaltung aufrufen - const response = await fetch('/api/v1/web/create-location', { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ - name: locationName, - lat: parseFloat(latitude), - lon: parseFloat(longitude) - }) - }); + try { + // Button-Status ändern + const originalText = saveBtn.innerHTML; + saveBtn.innerHTML = 'Speichere...'; + saveBtn.disabled = true; - const result = await response.json(); + // Web-authenticated API für Standortverwaltung aufrufen + const response = await fetch('/api/v1/web/create-location', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + name: locationName, + lat: parseFloat(latitude), + lon: parseFloat(longitude) + }) + }); - if (result.success) { - showSuccess(`✅ Standort "${locationName}" erfolgreich in der Datenbank gespeichert!`); - saveBtn.innerHTML = '✅ Gespeichert!'; - saveBtn.style.background = '#4caf50'; - - // Button nach 3 Sekunden zurücksetzen - setTimeout(() => { - saveBtn.innerHTML = originalText; - saveBtn.disabled = false; - saveBtn.style.background = '#2196f3'; - }, 3000); - } else { - throw new Error(result.message || 'Unbekannter Fehler beim Speichern'); - } + const result = await response.json(); - } catch (error) { - console.error('Fehler beim Speichern:', error); - showError(`Fehler beim Speichern: ${error.message}`); - - // Button zurücksetzen - saveBtn.innerHTML = '💾 Standort in Datenbank speichern'; + if (result.success) { + showSuccess(`✅ Standort "${locationName}" erfolgreich in der Datenbank gespeichert!`); + saveBtn.innerHTML = '✅ Gespeichert!'; + saveBtn.style.background = '#4caf50'; + + // Button nach 3 Sekunden zurücksetzen + setTimeout(() => { + saveBtn.innerHTML = originalText; saveBtn.disabled = false; - } + saveBtn.style.background = '#2196f3'; + }, 3000); + } else { + throw new Error(result.message || 'Unbekannter Fehler beim Speichern'); } - // Zurück zum Dashboard - function goBackToDashboard() { - window.location.href = '/admin-dashboard'; - } + } catch (error) { + console.error('Fehler beim Speichern:', error); + showError(`Fehler beim Speichern: ${error.message}`); - // Logout-Funktion - async function logout() { - try { - const response = await fetch('/api/v1/public/logout', { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - } - }); + // Button zurücksetzen + saveBtn.innerHTML = '💾 Standort in Datenbank speichern'; + saveBtn.disabled = false; + } +} - const result = await response.json(); - - if (result.success) { - window.location.href = '/login'; - } else { - console.error('Fehler beim Abmelden:', result.message); - // Trotzdem zur Login-Seite weiterleiten - window.location.href = '/login'; - } - } catch (error) { - console.error('Fehler beim Abmelden:', error); - // Bei Fehler trotzdem zur Login-Seite weiterleiten - window.location.href = '/login'; - } - } +// Zurück zum Dashboard +function goBackToDashboard() { + window.location.href = '/admin-dashboard'; +} - // Enter-Taste für Standortsuche - document.addEventListener('DOMContentLoaded', function() { - const locationSearch = document.getElementById('locationSearch'); - if (locationSearch) { - locationSearch.addEventListener('keypress', function(e) { - if (e.key === 'Enter') { - searchLocation(); - } - }); - } - - // Add cookie settings button functionality - const cookieSettingsBtn = document.getElementById('cookie-settings-footer'); - if (cookieSettingsBtn) { - cookieSettingsBtn.addEventListener('click', function() { - if (window.cookieConsent) { - window.cookieConsent.resetConsent(); - } - }); +// Logout-Funktion +async function logout() { + try { + const response = await fetch('/api/v1/public/logout', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', } }); + + const result = await response.json(); + + if (result.success) { + window.location.href = '/login'; + } else { + console.error('Fehler beim Abmelden:', result.message); + // Trotzdem zur Login-Seite weiterleiten + window.location.href = '/login'; + } + } catch (error) { + console.error('Fehler beim Abmelden:', error); + // Bei Fehler trotzdem zur Login-Seite weiterleiten + window.location.href = '/login'; + } +} + +// Enter-Taste für Standortsuche +document.addEventListener('DOMContentLoaded', function () { + const locationSearch = document.getElementById('locationSearch'); + if (locationSearch) { + locationSearch.addEventListener('keypress', function (e) { + if (e.key === 'Enter') { + searchLocation(); + } + }); + } + + // Add cookie settings button functionality + const cookieSettingsBtn = document.getElementById('cookie-settings-footer'); + if (cookieSettingsBtn) { + cookieSettingsBtn.addEventListener('click', function () { + if (window.cookieConsent) { + window.cookieConsent.resetConsent(); + } + }); + } +});