/** * Mercedes-Benz MYP Admin Guest Requests Management * Moderne Verwaltung von Gastaufträgen mit Live-Updates */ // Vereinfachte minimierte Version mit korrigierten API-URLs const API_BASE_URL = document.location.origin; let csrfToken = document.querySelector('meta[name="csrf-token"]')?.getAttribute('content') || ''; let currentRequests = []; let filteredRequests = []; document.addEventListener('DOMContentLoaded', function() { console.log('🎯 Admin Guest Requests Manager geladen'); initEventListeners(); loadGuestRequests(); startAutoRefresh(); }); function initEventListeners() { document.getElementById('search-requests')?.addEventListener('input', handleSearch); document.getElementById('status-filter')?.addEventListener('change', handleFilterChange); document.getElementById('sort-order')?.addEventListener('change', handleSortChange); document.getElementById('refresh-btn')?.addEventListener('click', loadGuestRequests); document.getElementById('export-btn')?.addEventListener('click', handleExport); document.getElementById('bulk-actions-btn')?.addEventListener('click', showBulkActionsModal); document.getElementById('select-all')?.addEventListener('change', handleSelectAll); } async function loadGuestRequests() { try { showLoading(true); const url = `${API_BASE_URL}/api/admin/requests`; const response = await fetch(url, { method: 'GET', headers: { 'Content-Type': 'application/json', 'X-CSRFToken': csrfToken } }); if (!response.ok) { throw new Error(`HTTP ${response.status}: ${response.statusText}`); } const data = await response.json(); if (data.success) { currentRequests = data.requests || []; updateStats(data.stats || {}); applyFiltersAndSort(); console.log(`✅ ${currentRequests.length} Gastaufträge geladen`); } else { throw new Error(data.message || 'Fehler beim Laden der Gastaufträge'); } } catch (error) { console.error('Fehler beim Laden der Gastaufträge:', error); showNotification('❌ Fehler beim Laden der Gastaufträge: ' + error.message, 'error'); showEmptyState(); } finally { showLoading(false); } } async function approveRequest(requestId) { const notes = prompt('Genehmigungsnotizen (optional):'); if (notes === null) return; try { showLoading(true); const url = `${API_BASE_URL}/api/requests/${requestId}/approve`; const response = await fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-CSRFToken': csrfToken }, body: JSON.stringify({ notes: notes || '' }) }); const data = await response.json(); if (data.success) { showNotification('✅ Gastauftrag erfolgreich genehmigt', 'success'); if (data.otp) { showNotification(`🔑 OTP-Code für Gast: ${data.otp}`, 'info'); } loadGuestRequests(); } else { throw new Error(data.message || 'Fehler beim Genehmigen'); } } catch (error) { console.error('Fehler beim Genehmigen:', error); showNotification('❌ Fehler beim Genehmigen: ' + error.message, 'error'); } finally { showLoading(false); } } async function rejectRequest(requestId) { const reason = prompt('Grund für die Ablehnung (erforderlich):'); if (!reason || reason.trim() === '') { showNotification('⚠️ Ablehnungsgrund ist erforderlich', 'warning'); return; } try { showLoading(true); const url = `${API_BASE_URL}/api/requests/${requestId}/deny`; const response = await fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-CSRFToken': csrfToken }, body: JSON.stringify({ reason: reason.trim() }) }); const data = await response.json(); if (data.success) { showNotification('✅ Gastauftrag erfolgreich abgelehnt', 'success'); loadGuestRequests(); } else { throw new Error(data.message || 'Fehler beim Ablehnen'); } } catch (error) { console.error('Fehler beim Ablehnen:', error); showNotification('❌ Fehler beim Ablehnen: ' + error.message, 'error'); } finally { showLoading(false); } } async function deleteRequest(requestId) { if (!confirm('Möchten Sie diesen Gastauftrag wirklich löschen? Diese Aktion kann nicht rückgängig gemacht werden.')) return; try { showLoading(true); const url = `${API_BASE_URL}/api/admin/requests/${requestId}`; const response = await fetch(url, { method: 'DELETE', headers: { 'Content-Type': 'application/json', 'X-CSRFToken': csrfToken } }); const data = await response.json(); if (data.success) { showNotification('✅ Gastauftrag erfolgreich gelöscht', 'success'); loadGuestRequests(); } else { throw new Error(data.message || 'Fehler beim Löschen'); } } catch (error) { console.error('Fehler beim Löschen:', error); showNotification('❌ Fehler beim Löschen: ' + error.message, 'error'); } finally { showLoading(false); } } // Utility Functions function updateStats(stats) { document.getElementById('pending-count').textContent = stats.pending || 0; document.getElementById('approved-count').textContent = stats.approved || 0; document.getElementById('rejected-count').textContent = stats.denied || 0; document.getElementById('total-count').textContent = stats.total || 0; } function applyFiltersAndSort() { const searchTerm = document.getElementById('search-requests')?.value.toLowerCase() || ''; const statusFilter = document.getElementById('status-filter')?.value || 'all'; const sortOrder = document.getElementById('sort-order')?.value || 'newest'; let requests = [...currentRequests]; if (searchTerm) { requests = requests.filter(req => (req.name || '').toLowerCase().includes(searchTerm) || (req.email || '').toLowerCase().includes(searchTerm) || (req.file_name || '').toLowerCase().includes(searchTerm) ); } if (statusFilter !== 'all') { requests = requests.filter(req => req.status === statusFilter); } requests.sort((a, b) => { if (sortOrder === 'oldest') { return new Date(a.created_at) - new Date(b.created_at); } return new Date(b.created_at) - new Date(a.created_at); }); filteredRequests = requests; renderRequestsTable(); } function renderRequestsTable() { const tableBody = document.getElementById('requests-table-body'); if (!tableBody) return; if (filteredRequests.length === 0) { tableBody.innerHTML = '