forked from Simnation/Main
341 lines
11 KiB
JavaScript
341 lines
11 KiB
JavaScript
let currentLicense = null;
|
|
let isCardFlipped = false;
|
|
let cameraStream = null;
|
|
|
|
// Event Listener für Nachrichten von FiveM
|
|
window.addEventListener('message', function(event) {
|
|
const data = event.data;
|
|
|
|
switch(data.action) {
|
|
case 'showLicense':
|
|
showLicense(data.data);
|
|
break;
|
|
case 'hideLicense':
|
|
closeLicense();
|
|
break;
|
|
case 'openCamera':
|
|
openCamera();
|
|
break;
|
|
}
|
|
});
|
|
|
|
// In der showLicense Funktion in script.js
|
|
function showLicense(data) {
|
|
currentLicense = data;
|
|
const container = document.getElementById('license-container');
|
|
const card = document.getElementById('license-card');
|
|
|
|
// Loading anzeigen
|
|
showLoading();
|
|
|
|
setTimeout(() => {
|
|
// Lizenztyp-spezifische Klasse hinzufügen
|
|
card.className = 'license-card ' + data.license.license_type;
|
|
|
|
// Header befüllen
|
|
document.getElementById('license-title').textContent = data.config.label;
|
|
document.getElementById('license-icon').className = 'license-icon ' + data.config.icon;
|
|
|
|
// Persönliche Daten
|
|
document.getElementById('license-name').textContent = data.license.name || 'N/A';
|
|
document.getElementById('license-birthday').textContent = formatDate(data.license.birthday) || 'N/A';
|
|
document.getElementById('license-gender').textContent = formatGender(data.license.gender) || 'N/A';
|
|
|
|
// Dokument-Informationen
|
|
document.getElementById('license-issue').textContent = formatDate(data.license.issue_date) || 'N/A';
|
|
document.getElementById('license-expire').textContent = formatDate(data.license.expire_date) || 'N/A';
|
|
document.getElementById('license-id').textContent = '#' + (data.license.id || '000000').toString().padStart(6, '0');
|
|
document.getElementById('license-issuer').textContent = data.license.issued_by_name || 'Behörde';
|
|
|
|
// Foto anzeigen
|
|
displayPlayerPhoto(data.license);
|
|
|
|
// Klassen anzeigen (nur bei Führerschein)
|
|
displayLicenseClasses(data.license);
|
|
|
|
// Status und Gültigkeit
|
|
displayLicenseStatus(data.license);
|
|
displayValidityIndicator(data.license);
|
|
|
|
// Rückseite vorbereiten
|
|
prepareBackSide(data.license);
|
|
|
|
// Container anzeigen
|
|
hideLoading();
|
|
container.classList.remove('hidden');
|
|
|
|
// Sound-Effekt
|
|
playSound('card-flip-sound');
|
|
|
|
// Notification
|
|
showNotification('Lizenz geladen', 'success');
|
|
}, 500);
|
|
}
|
|
|
|
// Erweitere die prepareBackSide Funktion um Bemerkungen anzuzeigen
|
|
function prepareBackSide(license) {
|
|
const classesGrid = document.getElementById('classes-grid');
|
|
const restrictionsList = document.getElementById('restrictions-list');
|
|
const notesText = document.getElementById('notes-text');
|
|
|
|
// Klassen-Grid für Führerschein
|
|
if (license.license_type === 'drivers_license' && license.classes) {
|
|
try {
|
|
const classes = Array.isArray(license.classes) ? license.classes : JSON.parse(license.classes);
|
|
classesGrid.innerHTML = '';
|
|
|
|
const classDescriptions = {
|
|
'A': 'Motorräder',
|
|
'A1': 'Leichte Motorräder',
|
|
'A2': 'Mittlere Motorräder',
|
|
'B': 'PKW',
|
|
'BE': 'PKW mit Anhänger',
|
|
'C': 'LKW',
|
|
'CE': 'LKW mit Anhänger',
|
|
'D': 'Bus',
|
|
'DE': 'Bus mit Anhänger'
|
|
};
|
|
|
|
if (classes && classes.length > 0) {
|
|
classes.forEach(cls => {
|
|
const classItem = document.createElement('div');
|
|
classItem.className = 'class-item';
|
|
classItem.innerHTML = `
|
|
<div class="class-letter">${cls}</div>
|
|
<div class="class-description">${classDescriptions[cls] || 'Unbekannt'}</div>
|
|
`;
|
|
classesGrid.appendChild(classItem);
|
|
});
|
|
} else {
|
|
classesGrid.innerHTML = '<p>Keine Klassen verfügbar</p>';
|
|
}
|
|
} catch (e) {
|
|
classesGrid.innerHTML = '<p>Keine Klassen verfügbar</p>';
|
|
}
|
|
} else {
|
|
classesGrid.innerHTML = '<p>Nicht zutreffend</p>';
|
|
}
|
|
|
|
// Beschränkungen (Beispiel)
|
|
restrictionsList.innerHTML = '<li>Keine besonderen Beschränkungen</li>';
|
|
|
|
// Bemerkungen
|
|
notesText.textContent = license.notes || 'Keine besonderen Bemerkungen';
|
|
}
|
|
|
|
|
|
// Karte drehen
|
|
function flipCard() {
|
|
const frontSide = document.querySelector('.license-content, .license-footer');
|
|
const backSide = document.getElementById('license-back');
|
|
|
|
isCardFlipped = !isCardFlipped;
|
|
|
|
if (isCardFlipped) {
|
|
// Zur Rückseite
|
|
document.querySelector('.license-content').classList.add('hidden');
|
|
document.querySelector('.license-footer').classList.add('hidden');
|
|
backSide.classList.remove('hidden');
|
|
} else {
|
|
// Zur Vorderseite
|
|
document.querySelector('.license-content').classList.remove('hidden');
|
|
document.querySelector('.license-footer').classList.remove('hidden');
|
|
backSide.classList.add('hidden');
|
|
}
|
|
|
|
playSound('card-flip-sound');
|
|
}
|
|
|
|
// Kamera öffnen
|
|
async function openCamera() {
|
|
const container = document.getElementById('camera-container');
|
|
const video = document.getElementById('camera-video');
|
|
|
|
try {
|
|
cameraStream = await navigator.mediaDevices.getUserMedia({
|
|
video: {
|
|
width: 640,
|
|
height: 480,
|
|
facingMode: 'user'
|
|
}
|
|
});
|
|
|
|
video.srcObject = cameraStream;
|
|
container.classList.remove('hidden');
|
|
|
|
showNotification('Kamera geöffnet', 'info');
|
|
} catch (err) {
|
|
console.error('Kamera-Zugriff fehlgeschlagen:', err);
|
|
showNotification('Kamera-Zugriff fehlgeschlagen', 'error');
|
|
}
|
|
}
|
|
|
|
// Foto aufnehmen
|
|
function takePhoto() {
|
|
const video = document.getElementById('camera-video');
|
|
const canvas = document.getElementById('camera-canvas');
|
|
const ctx = canvas.getContext('2d');
|
|
|
|
canvas.width = video.videoWidth;
|
|
canvas.height = video.videoHeight;
|
|
ctx.drawImage(video, 0, 0);
|
|
|
|
const photoData = canvas.toDataURL('image/jpeg', 0.8);
|
|
|
|
// Sound-Effekt
|
|
playSound('camera-shutter-sound');
|
|
|
|
// An FiveM senden
|
|
fetch(`https://${GetParentResourceName()}/savePhoto`, {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
},
|
|
body: JSON.stringify({
|
|
photo: photoData,
|
|
citizenid: currentLicense?.license?.citizenid
|
|
})
|
|
}).then(() => {
|
|
showNotification('Foto gespeichert', 'success');
|
|
closeCamera();
|
|
}).catch(err => {
|
|
console.error('Fehler beim Speichern:', err);
|
|
showNotification('Fehler beim Speichern', 'error');
|
|
});
|
|
}
|
|
|
|
// Kamera schließen
|
|
function closeCamera() {
|
|
const container = document.getElementById('camera-container');
|
|
|
|
if (cameraStream) {
|
|
cameraStream.getTracks().forEach(track => track.stop());
|
|
cameraStream = null;
|
|
}
|
|
|
|
container.classList.add('hidden');
|
|
}
|
|
|
|
// Lizenz schließen
|
|
function closeLicense() {
|
|
const container = document.getElementById('license-container');
|
|
container.classList.add('hidden');
|
|
|
|
// Karte zurücksetzen
|
|
isCardFlipped = false;
|
|
document.querySelector('.license-content').classList.remove('hidden');
|
|
document.querySelector('.license-footer').classList.remove('hidden');
|
|
document.getElementById('license-back').classList.add('hidden');
|
|
|
|
// Callback an FiveM
|
|
fetch(`https://${GetParentResourceName()}/closeLicense`, {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
},
|
|
body: JSON.stringify({})
|
|
}).catch(() => {}); // Fehler ignorieren
|
|
}
|
|
|
|
// Hilfsfunktionen
|
|
function formatGender(gender) {
|
|
const genderMap = {
|
|
'male': 'Männlich',
|
|
'female': 'Weiblich',
|
|
'other': 'Divers',
|
|
'm': 'Männlich',
|
|
'f': 'Weiblich'
|
|
};
|
|
return genderMap[gender?.toLowerCase()] || gender || 'Unbekannt';
|
|
}
|
|
|
|
function formatDate(dateString) {
|
|
if (!dateString) return null;
|
|
|
|
try {
|
|
const date = new Date(dateString);
|
|
return date.toLocaleDateString('de-DE');
|
|
} catch (e) {
|
|
return dateString;
|
|
}
|
|
}
|
|
|
|
function showLoading() {
|
|
document.getElementById('loading-overlay').classList.remove('hidden');
|
|
}
|
|
|
|
function hideLoading() {
|
|
document.getElementById('loading-overlay').classList.add('hidden');
|
|
}
|
|
|
|
function playSound(soundId) {
|
|
const audio = document.getElementById(soundId);
|
|
if (audio) {
|
|
audio.volume = 0.3;
|
|
audio.play().catch(() => {}); // Fehler ignorieren
|
|
}
|
|
}
|
|
|
|
function showNotification(message, type = 'info') {
|
|
const container = document.getElementById('notification-container');
|
|
const notification = document.createElement('div');
|
|
|
|
notification.className = `notification ${type}`;
|
|
notification.innerHTML = `
|
|
<div class="notification-content">
|
|
<i class="notification-icon fas ${getNotificationIcon(type)}"></i>
|
|
<span class="notification-text">${message}</span>
|
|
</div>
|
|
<button class="notification-close" onclick="this.parentElement.remove()">
|
|
<i class="fas fa-times"></i>
|
|
</button>
|
|
`;
|
|
|
|
container.appendChild(notification);
|
|
|
|
// Auto-remove nach 5 Sekunden
|
|
setTimeout(() => {
|
|
if (notification.parentElement) {
|
|
notification.remove();
|
|
}
|
|
}, 5000);
|
|
}
|
|
|
|
function getNotificationIcon(type) {
|
|
const icons = {
|
|
'success': 'fa-check-circle',
|
|
'error': 'fa-exclamation-circle',
|
|
'warning': 'fa-exclamation-triangle',
|
|
'info': 'fa-info-circle'
|
|
};
|
|
return icons[type] || icons.info;
|
|
}
|
|
|
|
// Event Listeners
|
|
document.addEventListener('keydown', function(event) {
|
|
if (event.key === 'Escape') {
|
|
if (!document.getElementById('camera-container').classList.contains('hidden')) {
|
|
closeCamera();
|
|
} else if (!document.getElementById('license-container').classList.contains('hidden')) {
|
|
closeLicense();
|
|
}
|
|
}
|
|
|
|
if (event.key === 'f' || event.key === 'F') {
|
|
if (!document.getElementById('license-container').classList.contains('hidden')) {
|
|
flipCard();
|
|
}
|
|
}
|
|
});
|
|
|
|
// Klick außerhalb zum Schließen
|
|
document.getElementById('license-container').addEventListener('click', function(event) {
|
|
if (event.target.classList.contains('license-overlay')) {
|
|
closeLicense();
|
|
}
|
|
});
|
|
|
|
// Initialisierung
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
console.log('License System UI geladen');
|
|
});
|