🔧 Fix location name logic: User determines name, API only provides coordinates

- 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
This commit is contained in:
2025-09-08 21:44:18 +02:00
parent 7d88ad036d
commit b610d85313

View File

@@ -3,7 +3,7 @@ function toggleTokenFields() {
const tierInput = document.getElementById("tier"); const tierInput = document.getElementById("tier");
const dbConfig = document.getElementById("dbConfig"); const dbConfig = document.getElementById("dbConfig");
const tier = parseInt(tierInput.value); const tier = parseInt(tierInput.value);
if (tier >= 3 && !isNaN(tier)) { if (tier >= 3 && !isNaN(tier)) {
dbConfig.innerHTML = ` dbConfig.innerHTML = `
<h3>🗄️ Token-Informationen (für Stufe 3+)</h3> <h3>🗄️ Token-Informationen (für Stufe 3+)</h3>
@@ -59,332 +59,322 @@ function toggleTokenFields() {
📝 Standorte werden in der lokalen PostgreSQL-Datenbank gespeichert 📝 Standorte werden in der lokalen PostgreSQL-Datenbank gespeichert
</div> </div>
`; `;
dbConfig.classList.add("show"); dbConfig.classList.add("show");
} else { } else {
dbConfig.classList.remove("show"); dbConfig.classList.remove("show");
setTimeout(() => { setTimeout(() => {
if (!dbConfig.classList.contains("show")) { if (!dbConfig.classList.contains("show")) {
dbConfig.innerHTML = ""; dbConfig.innerHTML = "";
}
}, 400);
} }
}, 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 = '<span class="loading"></span>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) { throw new Error(`Automatisches Speichern fehlgeschlagen. Server nicht erreichbar.\n\nFühren Sie folgenden SQL-Befehl manuell aus:\n${sql}`);
const pattern = /^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$|^[0-9A-Fa-f]{12}$/; }
return pattern.test(mac); }
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 mac = macInput.replace(/[:-]/g, "").toUpperCase();
const messageDiv = document.getElementById(elementId); const tier = parseInt(tierInput);
messageDiv.textContent = message;
messageDiv.classList.add("show"); if (isNaN(tier) || tier < 1 || tier > 4) {
setTimeout(() => { throw new Error("Lizenzstufe muss eine Zahl zwischen 1 und 4 sein.");
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 = '<span class="loading"></span>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 // Standort automatisch speichern, falls vorhanden
let locationSaved = false; 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 latitude = document.getElementById('latitude')?.textContent;
const longitude = document.getElementById('longitude')?.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}`; if (locationName && latitude && longitude && tier >= 3) {
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");
try { try {
await navigator.clipboard.writeText(licenseOutput.textContent); await saveLocationToDatabase();
copyBtn.textContent = "✅ Kopiert!"; locationSaved = true;
copyBtn.classList.add("copied"); } catch (locationError) {
console.warn('Standort konnte nicht gespeichert werden:', locationError);
setTimeout(() => { // Fahre trotzdem mit der Lizenzgenerierung fort
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 const data = `${mac}:${tier}`;
document.addEventListener('keypress', function(e) { const enc = new TextEncoder();
if (e.key === 'Enter') { const key = await crypto.subtle.importKey(
generateLicense(); "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 licenseOutput.textContent = hex;
document.getElementById('mac').addEventListener('input', function(e) { resultDiv.classList.add("show");
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 // Reset copy button
document.getElementById('tier').addEventListener('input', toggleTokenFields); const copyBtn = document.getElementById("copyButton");
copyBtn.textContent = "📋 In Zwischenablage kopieren";
// Standortsuche-Funktionalität copyBtn.classList.remove("copied");
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;
// Bei Stufe 3+ in Datenbank speichern
if (tier >= 3) {
try { try {
// Zeige Ladeanimation await saveToDatabase(hex, tier);
searchBtn = buttonElement || document.querySelector('button[onclick*="searchLocation"]'); let successMessage = `✅ Lizenzschlüssel generiert und als API-Token gespeichert!`;
if (searchBtn) { if (locationSaved) {
originalText = searchBtn.innerHTML; successMessage += ` Standort wurde ebenfalls gespeichert.`;
searchBtn.innerHTML = '<span class="loading"></span>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;
} }
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 } catch (error) {
function updateCoordinates(lat, lon) { showError(error.message);
const latitudeSpan = document.getElementById('latitude'); } finally {
const longitudeSpan = document.getElementById('longitude'); setLoading(false);
}
if (latitudeSpan && longitudeSpan) { }
latitudeSpan.textContent = lat.toFixed(6);
longitudeSpan.textContent = lon.toFixed(6); 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 = '<span class="loading"></span>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 // Interaktive Karte erstellen
function createInteractiveMap(initialLat, initialLon) { createInteractiveMap(lat, lon);
const mapFrame = document.getElementById('mapFrame'); mapContainer.style.display = 'block';
// Verwende Leaflet.js für interaktive Karte // Erfolgsmeldung
const mapHtml = ` 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 = `
<div id="interactiveMap" style="width: 100%; height: 100%; position: relative;"> <div id="interactiveMap" style="width: 100%; height: 100%; position: relative;">
<div id="map" style="width: 100%; height: 100%; border-radius: 10px;"></div> <div id="map" style="width: 100%; height: 100%; border-radius: 10px;"></div>
<div style="position: absolute; top: 10px; right: 10px; background: white; padding: 8px; border-radius: 6px; box-shadow: 0 2px 8px rgba(0,0,0,0.2); font-size: 12px; color: #666;"> <div style="position: absolute; top: 10px; right: 10px; background: white; padding: 8px; border-radius: 6px; box-shadow: 0 2px 8px rgba(0,0,0,0.2); font-size: 12px; color: #666;">
@@ -392,192 +382,192 @@ function toggleTokenFields() {
</div> </div>
</div> </div>
`; `;
mapFrame.innerHTML = mapHtml;
// Leaflet.js laden und Karte initialisieren
loadLeafletAndCreateMap(initialLat, initialLon);
}
// Leaflet.js laden und Karte erstellen mapFrame.innerHTML = mapHtml;
function loadLeafletAndCreateMap(initialLat, initialLon) {
// Prüfe ob Leaflet bereits geladen ist
if (typeof L !== 'undefined') {
createMap(initialLat, initialLon);
return;
}
// Leaflet CSS laden // Leaflet.js laden und Karte initialisieren
const leafletCSS = document.createElement('link'); loadLeafletAndCreateMap(initialLat, initialLon);
leafletCSS.rel = 'stylesheet'; }
leafletCSS.href = 'https://unpkg.com/leaflet@1.9.4/dist/leaflet.css';
document.head.appendChild(leafletCSS);
// Leaflet JavaScript laden // Leaflet.js laden und Karte erstellen
const leafletScript = document.createElement('script'); function loadLeafletAndCreateMap(initialLat, initialLon) {
leafletScript.src = 'https://unpkg.com/leaflet@1.9.4/dist/leaflet.js'; // Prüfe ob Leaflet bereits geladen ist
leafletScript.onload = () => createMap(initialLat, initialLon); if (typeof L !== 'undefined') {
document.head.appendChild(leafletScript); createMap(initialLat, initialLon);
} return;
}
// Karte mit Leaflet erstellen // Leaflet CSS laden
function createMap(initialLat, initialLon) { const leafletCSS = document.createElement('link');
try { leafletCSS.rel = 'stylesheet';
const map = L.map('map').setView([initialLat, initialLon], 15); leafletCSS.href = 'https://unpkg.com/leaflet@1.9.4/dist/leaflet.css';
document.head.appendChild(leafletCSS);
// OpenStreetMap Tile Layer
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
}).addTo(map);
// Marker erstellen // Leaflet JavaScript laden
const marker = L.marker([initialLat, initialLon], { const leafletScript = document.createElement('script');
draggable: true, leafletScript.src = 'https://unpkg.com/leaflet@1.9.4/dist/leaflet.js';
title: 'Standort' leafletScript.onload = () => createMap(initialLat, initialLon);
}).addTo(map); document.head.appendChild(leafletScript);
}
// Marker-Drag Event // Karte mit Leaflet erstellen
marker.on('dragend', function(event) { function createMap(initialLat, initialLon) {
const newLat = event.target.getLatLng().lat; try {
const newLon = event.target.getLatLng().lng; const map = L.map('map').setView([initialLat, initialLon], 15);
updateCoordinates(newLat, newLon);
showSuccess(`📍 Pin auf neue Position verschoben: ${newLat.toFixed(6)}, ${newLon.toFixed(6)}`);
});
// Klick-Event auf die Karte // OpenStreetMap Tile Layer
map.on('click', function(event) { L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
const newLat = event.latlng.lat; attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
const newLon = event.latlng.lng; }).addTo(map);
// 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 // Marker erstellen
map.zoomControl.setPosition('bottomright'); const marker = L.marker([initialLat, initialLon], {
draggable: true,
title: 'Standort'
}).addTo(map);
} catch (error) { // Marker-Drag Event
console.error('Fehler beim Erstellen der Karte:', error); marker.on('dragend', function (event) {
// Fallback zu iframe const newLat = event.target.getLatLng().lat;
const mapFrame = document.getElementById('mapFrame'); const newLon = event.target.getLatLng().lng;
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}`; updateCoordinates(newLat, newLon);
mapFrame.innerHTML = `<iframe src="${mapUrl}" width="100%" height="100%" frameborder="0" scrolling="no" marginheight="0" marginwidth="0" title="Standort auf der Karte"></iframe>`; 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 = `<iframe src="${mapUrl}" width="100%" height="100%" frameborder="0" scrolling="no" marginheight="0" marginwidth="0" title="Standort auf der Karte"></iframe>`;
}
}
// Standort in Datenbank speichern // Standort in Datenbank speichern
async function saveLocationToDatabase() { 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 latitude = document.getElementById('latitude').textContent;
const longitude = document.getElementById('longitude').textContent; const longitude = document.getElementById('longitude').textContent;
const saveBtn = document.getElementById('saveLocationBtn'); const saveBtn = document.getElementById('saveLocationBtn');
if (!locationName || !latitude || !longitude) {
showError('Bitte suchen Sie zuerst einen Standort.');
return;
}
try { if (!locationName || !latitude || !longitude) {
// Button-Status ändern showError('Bitte suchen Sie zuerst einen Standort.');
const originalText = saveBtn.innerHTML; return;
saveBtn.innerHTML = '<span class="loading"></span>Speichere...'; }
saveBtn.disabled = true;
// Web-authenticated API für Standortverwaltung aufrufen try {
const response = await fetch('/api/v1/web/create-location', { // Button-Status ändern
method: 'POST', const originalText = saveBtn.innerHTML;
headers: { saveBtn.innerHTML = '<span class="loading"></span>Speichere...';
'Content-Type': 'application/json', saveBtn.disabled = true;
},
body: JSON.stringify({
name: locationName,
lat: parseFloat(latitude),
lon: parseFloat(longitude)
})
});
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) { const result = await response.json();
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');
}
} catch (error) { if (result.success) {
console.error('Fehler beim Speichern:', error); showSuccess(`✅ Standort "${locationName}" erfolgreich in der Datenbank gespeichert!`);
showError(`Fehler beim Speichern: ${error.message}`); saveBtn.innerHTML = '✅ Gespeichert!';
saveBtn.style.background = '#4caf50';
// Button zurücksetzen
saveBtn.innerHTML = '💾 Standort in Datenbank speichern'; // Button nach 3 Sekunden zurücksetzen
setTimeout(() => {
saveBtn.innerHTML = originalText;
saveBtn.disabled = false; saveBtn.disabled = false;
} saveBtn.style.background = '#2196f3';
}, 3000);
} else {
throw new Error(result.message || 'Unbekannter Fehler beim Speichern');
} }
// Zurück zum Dashboard } catch (error) {
function goBackToDashboard() { console.error('Fehler beim Speichern:', error);
window.location.href = '/admin-dashboard'; showError(`Fehler beim Speichern: ${error.message}`);
}
// Logout-Funktion // Button zurücksetzen
async function logout() { saveBtn.innerHTML = '💾 Standort in Datenbank speichern';
try { saveBtn.disabled = false;
const response = await fetch('/api/v1/public/logout', { }
method: 'POST', }
headers: {
'Content-Type': 'application/json',
}
});
const result = await response.json(); // Zurück zum Dashboard
function goBackToDashboard() {
if (result.success) { window.location.href = '/admin-dashboard';
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 // Logout-Funktion
document.addEventListener('DOMContentLoaded', function() { async function logout() {
const locationSearch = document.getElementById('locationSearch'); try {
if (locationSearch) { const response = await fetch('/api/v1/public/logout', {
locationSearch.addEventListener('keypress', function(e) { method: 'POST',
if (e.key === 'Enter') { headers: {
searchLocation(); 'Content-Type': 'application/json',
}
});
}
// Add cookie settings button functionality
const cookieSettingsBtn = document.getElementById('cookie-settings-footer');
if (cookieSettingsBtn) {
cookieSettingsBtn.addEventListener('click', function() {
if (window.cookieConsent) {
window.cookieConsent.resetConsent();
}
});
} }
}); });
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();
}
});
}
});