// Globale Variablen
let currentData = null;
let currentTargetId = null;
let currentLicenseType = null;
let formData = {};
// Utility-Funktionen
function showLoading() {
document.getElementById('loadingOverlay').style.display = 'flex';
}
function hideLoading() {
document.getElementById('loadingOverlay').style.display = 'none';
}
function showError(message) {
// Hier könnte eine Toast-Notification implementiert werden
console.error(message);
alert(message); // Temporär
}
function showSuccess(message) {
// Hier könnte eine Toast-Notification implementiert werden
console.log(message);
}
// Validierungsfunktionen
function validateDate(dateString) {
const regex = /^\d{2}\.\d{2}\.\d{4}$/;
if (!regex.test(dateString)) return false;
const [day, month, year] = dateString.split('.').map(Number);
const date = new Date(year, month - 1, day);
return date.getFullYear() === year &&
date.getMonth() === month - 1 &&
date.getDate() === day &&
year >= 1900 && year <= 2100;
}
function validateUrl(url) {
if (!url || url.trim() === '') return true; // Optional
try {
new URL(url);
return url.startsWith('http://') || url.startsWith('https://');
} catch {
return false;
}
}
function validateEmail(email) {
const regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return regex.test(email);
}
// NUI Message Handler
window.addEventListener('message', function(event) {
const data = event.data;
switch(data.action) {
case 'openMainMenu':
openMainMenu(data.data);
break;
case 'openCustomLicenseForm':
openCustomLicenseForm(data.data);
break;
case 'showLicense':
showLicense(data.data);
break;
case 'showMyLicense':
showMyLicense(data.data);
break;
case 'showPlayerLicenses':
showPlayerLicenses(data.data);
break;
}
});
// Hauptmenü öffnen
function openMainMenu(data) {
currentData = data;
currentTargetId = data.targetId;
// Target-Sektion anzeigen/verstecken
const targetSection = document.getElementById('targetSection');
const targetDistance = document.getElementById('targetDistance');
if (data.hasTarget) {
targetSection.style.display = 'block';
targetDistance.textContent = data.targetDistance.toFixed(1);
// Lizenz-Buttons generieren
generateLicenseButtons(data.licenseTypes);
} else {
targetSection.style.display = 'none';
}
document.getElementById('mainMenu').style.display = 'flex';
}
// Lizenz-Buttons generieren
function generateLicenseButtons(licenseTypes) {
const container = document.getElementById('licenseButtons');
container.innerHTML = '';
Object.keys(licenseTypes).forEach(licenseType => {
const config = licenseTypes[licenseType];
const button = document.createElement('button');
button.className = 'menu-btn';
button.style.background = `linear-gradient(135deg, ${config.color} 0%, ${adjustColor(config.color, -20)} 100%)`;
button.onclick = () => openLicenseCreation(licenseType);
button.innerHTML = `
${config.label}
`;
container.appendChild(button);
});
}
// Farbe anpassen (für Gradient)
function adjustColor(color, amount) {
const usePound = color[0] === '#';
const col = usePound ? color.slice(1) : color;
const num = parseInt(col, 16);
let r = (num >> 16) + amount;
let g = (num >> 8 & 0x00FF) + amount;
let b = (num & 0x0000FF) + amount;
r = r > 255 ? 255 : r < 0 ? 0 : r;
g = g > 255 ? 255 : g < 0 ? 0 : g;
b = b > 255 ? 255 : b < 0 ? 0 : b;
return (usePound ? '#' : '') + (r << 16 | g << 8 | b).toString(16).padStart(6, '0');
}
// Erweiterte Lizenz-Erstellung öffnen
function openCustomLicenseForm(data) {
currentData = data;
currentTargetId = data.targetId;
currentLicenseType = data.licenseType;
formData = {};
const config = data.config;
// Titel setzen
document.getElementById('formTitle').textContent = `${config.label} erstellen`;
// Inhaber-Name setzen (würde normalerweise vom Server kommen)
document.getElementById('holderName').value = 'Spieler Name'; // Placeholder
// Benutzerdefinierte Felder generieren
generateCustomFields(config.custom_fields || []);
// Klassen-Sektion (falls vorhanden)
if (config.classes) {
generateClassesSection(config.classes);
document.getElementById('classesSection').style.display = 'block';
} else {
document.getElementById('classesSection').style.display = 'none';
}
// Vorschau initialisieren
updatePreview();
// Form-Event-Listener
setupFormEventListeners();
document.getElementById('customLicenseForm').style.display = 'flex';
}
// Benutzerdefinierte Felder generieren
function generateCustomFields(fields) {
const container = document.getElementById('customFields');
container.innerHTML = '';
fields.forEach(field => {
const fieldDiv = document.createElement('div');
fieldDiv.className = 'form-group';
const label = document.createElement('label');
label.textContent = field.label + (field.required ? ' *' : '');
label.setAttribute('for', field.name);
let input;
switch(field.type) {
case 'text':
case 'date':
case 'number':
case 'url':
case 'email':
input = document.createElement('input');
input.type = field.type === 'date' ? 'text' : field.type;
input.placeholder = field.placeholder || '';
break;
case 'textarea':
input = document.createElement('textarea');
input.placeholder = field.placeholder || '';
input.rows = 3;
break;
case 'select':
input = document.createElement('select');
const defaultOption = document.createElement('option');
defaultOption.value = '';
defaultOption.textContent = 'Bitte wählen...';
input.appendChild(defaultOption);
field.options.forEach(option => {
const optionElement = document.createElement('option');
optionElement.value = option.value;
optionElement.textContent = option.label;
input.appendChild(optionElement);
});
break;
}
input.id = field.name;
input.name = field.name;
input.required = field.required || false;
// Event-Listener für Live-Validierung
input.addEventListener('input', () => {
validateField(field, input);
updatePreview();
});
input.addEventListener('blur', () => {
validateField(field, input);
});
fieldDiv.appendChild(label);
fieldDiv.appendChild(input);
// Spezielle Behandlung für Bild-URL
if (field.type === 'url' && field.name.includes('photo') || field.name.includes('logo')) {
const imagePreview = document.createElement('div');
imagePreview.className = 'image-preview';
imagePreview.id = field.name + '_preview';
const placeholder = document.createElement('div');
placeholder.className = 'image-placeholder';
placeholder.innerHTML = '
Vorschau';
imagePreview.appendChild(placeholder);
fieldDiv.appendChild(imagePreview);
// Bild-Validierung
input.addEventListener('input', () => {
validateImageUrl(input.value, field.name);
});
}
container.appendChild(fieldDiv);
});
}
// Klassen-Sektion generieren
function generateClassesSection(classes) {
const container = document.getElementById('classesContainer');
container.innerHTML = '';
const checkboxGroup = document.createElement('div');
checkboxGroup.className = 'checkbox-group';
Object.keys(classes).forEach(classKey => {
const checkboxItem = document.createElement('div');
checkboxItem.className = 'checkbox-item';
const checkbox = document.createElement('input');
checkbox.type = 'checkbox';
checkbox.id = 'class_' + classKey;
checkbox.name = 'classes';
checkbox.value = classKey;
const label = document.createElement('label');
label.setAttribute('for', 'class_' + classKey);
label.textContent = `${classKey} - ${classes[classKey]}`;
checkbox.addEventListener('change', updatePreview);
checkboxItem.appendChild(checkbox);
checkboxItem.appendChild(label);
checkboxGroup.appendChild(checkboxItem);
});
container.appendChild(checkboxGroup);
}
// Feld-Validierung
function validateField(field, input) {
const value = input.value.trim();
const formGroup = input.closest('.form-group');
// Vorherige Fehlermeldungen entfernen
const existingError = formGroup.querySelector('.error-message');
if (existingError) {
existingError.remove();
}
formGroup.classList.remove('error');
// Pflichtfeld-Prüfung
if (field.required && !value) {
showFieldError(formGroup, 'Dieses Feld ist erforderlich');
return false;
}
if (!value) return true; // Optional und leer
// Typ-spezifische Validierung
let isValid = true;
let errorMessage = '';
switch(field.type) {
case 'date':
isValid = validateDate(value);
errorMessage = 'Ungültiges Datum (Format: TT.MM.JJJJ)';
break;
case 'url':
isValid = validateUrl(value);
errorMessage = 'Ungültige URL (muss mit http:// oder https:// beginnen)';
break;
case 'email':
isValid = validateEmail(value);
errorMessage = 'Ungültige E-Mail-Adresse';
break;
case 'number':
isValid = !isNaN(value) && value > 0;
errorMessage = 'Muss eine positive Zahl sein';
break;
}
if (!isValid) {
showFieldError(formGroup, errorMessage);
return false;
}
// Erfolg anzeigen
showFieldSuccess(formGroup);
return true;
}
// Feld-Fehler anzeigen
function showFieldError(formGroup, message) {
formGroup.classList.add('error');
const errorDiv = document.createElement('div');
errorDiv.className = 'error-message';
errorDiv.innerHTML = ` ${message}`;
formGroup.appendChild(errorDiv);
}
// Feld-Erfolg anzeigen
function showFieldSuccess(formGroup) {
const successDiv = document.createElement('div');
successDiv.className = 'success-message';
successDiv.innerHTML = ` Gültig`;
formGroup.appendChild(successDiv);
// Nach 2 Sekunden entfernen
setTimeout(() => {
if (successDiv.parentNode) {
successDiv.remove();
}
}, 2000);
}
// Bild-URL validieren
function validateImageUrl(url, fieldName) {
const previewContainer = document.getElementById(fieldName + '_preview');
if (!previewContainer) return;
if (!url || url.trim() === '') {
previewContainer.innerHTML = '
Ausgestellt: ${formatDate(license.issue_date)}
${license.expire_date ? `Gültig bis: ${formatDate(license.expire_date)}
` : 'Unbegrenzt gültig
'}${config.description || 'Offizielle Lizenz'}