📝 "🐛 Backend update: Refactored database connection in myp.db

This commit is contained in:
Till Tomczak 2025-05-30 21:16:58 +02:00
parent c48d586af2
commit 37cd332d67
2 changed files with 83 additions and 57 deletions

Binary file not shown.

View File

@ -558,6 +558,12 @@ let currentPage = 0;
let pageSize = 20;
let totalRequests = 0;
let currentRequestId = null;
let allPrinters = [];
// Prüfung der Admin-Berechtigung - zeige Inline-Aktionen nur für Admins
const userIsAdmin = {{ current_user.is_admin|tojson if current_user.is_authenticated else 'false' }};
const userCanApprove = {{ (current_user.permissions and current_user.permissions.can_approve_jobs)|tojson if current_user.is_authenticated and current_user.permissions else 'false' }};
const showInlineActions = userIsAdmin || userCanApprove;
// Initialisierung
document.addEventListener('DOMContentLoaded', function() {
@ -641,29 +647,24 @@ async function loadGuestRequests() {
const params = new URLSearchParams({
page: currentPage,
page_size: pageSize
page_size: pageSize,
status: status !== 'all' ? status : '',
sort: sort,
search: search
});
if (status !== 'all') params.append('status', status);
if (urgent !== 'all') params.append('urgent', urgent);
if (sort) params.append('sort', sort);
if (search) params.append('search', search);
if (urgent !== 'all') {
params.append('urgent', urgent === 'urgent');
}
const response = await fetch(`/api/admin/guest-requests?${params}`);
// Enhanced error handling for JSON parsing
let data;
try {
const text = await response.text();
if (!text.trim()) {
throw new Error('Leere Antwort vom Server');
}
data = JSON.parse(text);
} catch (parseError) {
console.error('JSON Parse Error:', parseError, 'Response text:', text);
throw new Error(`JSON-Parsing-Fehler beim Laden der Anträge: ${parseError.message}`);
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
const data = await response.json();
if (data.success) {
currentRequests = data.requests;
totalRequests = data.total;
@ -671,11 +672,15 @@ async function loadGuestRequests() {
renderRequestsTable(data.requests);
updatePagination();
} else {
showNotification('Fehler beim Laden der Anträge: ' + (data.message || 'Unbekannter Fehler'), 'error');
throw new Error(data.message || 'Unbekannter Fehler beim Laden der Daten');
}
} catch (error) {
console.error('Fehler beim Laden der Anträge:', error);
showNotification('Fehler beim Laden der Anträge: ' + error.message, 'error');
console.error('Fehler beim Laden der Gastanträge:', error);
showNotification(`Fehler beim Laden der Gastanträge: ${error.message}`, 'error');
// Zeige leere Tabelle bei Fehler
renderRequestsTable([]);
updateStatistics({});
} finally {
showLoading(false);
}
@ -687,6 +692,8 @@ async function loadAvailablePrinters() {
const data = await response.json();
if (data.success) {
allPrinters = data.printers;
const select = document.getElementById('assignedPrinter');
select.innerHTML = '<option value="">Kein Drucker zugewiesen</option>';
@ -772,12 +779,13 @@ function createRequestRow(request) {
<i class="fas fa-clock mr-1"></i>${request.duration_minutes || 0} Min,
<i class="fas fa-copy ml-2 mr-1"></i>${request.copies || 1} Kopien
</div>
${request.reason ? `<div class="text-xs text-gray-400 mt-1">${escapeHtml(request.reason.substring(0, 100))}${request.reason.length > 100 ? '...' : ''}</div>` : ''}
</td>
<td class="px-6 py-4">
<span class="status-badge status-${request.status}">
${getStatusIcon(request.status)} ${getStatusText(request.status)}
</span>
${request.status === 'pending' ? `
${request.status === 'pending' && showInlineActions ? `
<div id="inline-actions-${request.id}" class="mt-2 space-y-2">
<div class="flex space-x-2">
<button onclick="showInlineApproval(${request.id})"
@ -791,8 +799,10 @@ function createRequestRow(request) {
</div>
<!-- Inline Approval Form -->
<div id="approval-form-${request.id}" class="hidden bg-green-50 border border-green-200 rounded p-3">
<h5 class="text-sm font-medium text-green-800 mb-2">Antrag genehmigen</h5>
<div id="approval-form-${request.id}" class="hidden inline-approval-form form-section">
<h5 class="text-sm font-medium text-green-800 mb-2">
<i class="fas fa-check-circle mr-1"></i>Antrag genehmigen
</h5>
<textarea id="approval-notes-${request.id}" rows="2"
class="w-full text-xs border border-green-300 rounded px-2 py-1 focus:outline-none focus:ring-1 focus:ring-green-400"
placeholder="Optionale Genehmigungsnotizen..."></textarea>
@ -800,31 +810,33 @@ function createRequestRow(request) {
class="w-full mt-1 text-xs border border-green-300 rounded px-2 py-1 focus:outline-none focus:ring-1 focus:ring-green-400">
<option value="">Drucker auswählen (optional)</option>
</select>
<div class="flex justify-end space-x-2 mt-2">
<div class="form-actions">
<button onclick="hideInlineApproval(${request.id})"
class="px-2 py-1 text-xs border border-gray-300 rounded text-gray-600 hover:bg-gray-50">
Abbrechen
class="btn-cancel inline-action-btn">
<i class="fas fa-times mr-1"></i>Abbrechen
</button>
<button onclick="submitInlineApproval(${request.id})"
class="px-2 py-1 text-xs bg-green-600 text-white rounded hover:bg-green-700">
class="btn-submit inline-action-btn inline-approve-btn">
<i class="fas fa-check mr-1"></i>Genehmigen
</button>
</div>
</div>
<!-- Inline Rejection Form -->
<div id="rejection-form-${request.id}" class="hidden bg-red-50 border border-red-200 rounded p-3">
<h5 class="text-sm font-medium text-red-800 mb-2">Antrag ablehnen</h5>
<div id="rejection-form-${request.id}" class="hidden inline-rejection-form form-section">
<h5 class="text-sm font-medium text-red-800 mb-2">
<i class="fas fa-times-circle mr-1"></i>Antrag ablehnen
</h5>
<textarea id="rejection-reason-${request.id}" rows="2" required
class="w-full text-xs border border-red-300 rounded px-2 py-1 focus:outline-none focus:ring-1 focus:ring-red-400"
placeholder="Ablehnungsgrund (erforderlich)..."></textarea>
<div class="flex justify-end space-x-2 mt-2">
<div class="form-actions">
<button onclick="hideInlineRejection(${request.id})"
class="px-2 py-1 text-xs border border-gray-300 rounded text-gray-600 hover:bg-gray-50">
Abbrechen
class="btn-cancel inline-action-btn">
<i class="fas fa-times mr-1"></i>Abbrechen
</button>
<button onclick="submitInlineRejection(${request.id})"
class="px-2 py-1 text-xs bg-red-600 text-white rounded hover:bg-red-700">
class="btn-submit inline-action-btn inline-reject-btn">
<i class="fas fa-times mr-1"></i>Ablehnen
</button>
</div>
@ -842,7 +854,7 @@ function createRequestRow(request) {
class="action-button btn-view" title="Details anzeigen">
<i class="fas fa-eye"></i> Details
</button>
${request.status !== 'pending' ? `
${request.status !== 'pending' && showInlineActions ? `
<button onclick="deleteRequest(${request.id})"
class="action-button bg-gray-500 text-white hover:bg-gray-600" title="Löschen">
<i class="fas fa-trash"></i>
@ -1262,6 +1274,13 @@ async function submitInlineApproval(requestId) {
}
try {
// Loading-Zustand anzeigen
const submitBtn = document.querySelector(`#approval-form-${requestId} .inline-approve-btn`);
const originalText = submitBtn.innerHTML;
submitBtn.innerHTML = '<i class="fas fa-spinner fa-spin mr-1"></i>Wird bearbeitet...';
submitBtn.disabled = true;
// KORRIGIERTE API-URL
const response = await fetch(`/api/guest-requests/${requestId}/approve`, {
method: 'POST',
headers: {
@ -1271,29 +1290,29 @@ async function submitInlineApproval(requestId) {
body: JSON.stringify(requestBody)
});
// Enhanced error handling for JSON parsing
let data;
try {
const text = await response.text();
if (!text.trim()) {
throw new Error('Leere Antwort vom Server');
}
data = JSON.parse(text);
} catch (parseError) {
console.error('JSON Parse Error:', parseError, 'Response text:', await response.text());
throw new Error(`JSON-Parsing-Fehler: ${parseError.message}`);
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
const data = await response.json();
if (data.success) {
showNotification(`Antrag erfolgreich genehmigt! OTP-Code: ${data.otp_code}`, 'success');
hideInlineApproval(requestId);
loadGuestRequests(); // Reload table
} else {
showNotification(`Fehler beim Genehmigen: ${data.message || 'Unbekannter Fehler'}`, 'error');
throw new Error(data.message || 'Unbekannter Fehler beim Genehmigen');
}
} catch (error) {
console.error('Fehler beim Genehmigen:', error);
showNotification(`Fehler beim Genehmigen: ${error.message}`, 'error');
// Button-Zustand zurücksetzen
const submitBtn = document.querySelector(`#approval-form-${requestId} .inline-approve-btn`);
if (submitBtn) {
submitBtn.innerHTML = originalText;
submitBtn.disabled = false;
}
}
}
@ -1306,6 +1325,13 @@ async function submitInlineRejection(requestId) {
}
try {
// Loading-Zustand anzeigen
const submitBtn = document.querySelector(`#rejection-form-${requestId} .inline-reject-btn`);
const originalText = submitBtn.innerHTML;
submitBtn.innerHTML = '<i class="fas fa-spinner fa-spin mr-1"></i>Wird bearbeitet...';
submitBtn.disabled = true;
// KORRIGIERTE API-URL
const response = await fetch(`/api/guest-requests/${requestId}/reject`, {
method: 'POST',
headers: {
@ -1315,29 +1341,29 @@ async function submitInlineRejection(requestId) {
body: JSON.stringify({ reason })
});
// Enhanced error handling for JSON parsing
let data;
try {
const text = await response.text();
if (!text.trim()) {
throw new Error('Leere Antwort vom Server');
}
data = JSON.parse(text);
} catch (parseError) {
console.error('JSON Parse Error:', parseError, 'Response text:', await response.text());
throw new Error(`JSON-Parsing-Fehler: ${parseError.message}`);
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
const data = await response.json();
if (data.success) {
showNotification('Antrag erfolgreich abgelehnt', 'success');
hideInlineRejection(requestId);
loadGuestRequests(); // Reload table
} else {
showNotification(`Fehler beim Ablehnen: ${data.message || 'Unbekannter Fehler'}`, 'error');
throw new Error(data.message || 'Unbekannter Fehler beim Ablehnen');
}
} catch (error) {
console.error('Fehler beim Ablehnen:', error);
showNotification(`Fehler beim Ablehnen: ${error.message}`, 'error');
// Button-Zustand zurücksetzen
const submitBtn = document.querySelector(`#rejection-form-${requestId} .inline-reject-btn`);
if (submitBtn) {
submitBtn.innerHTML = originalText;
submitBtn.disabled = false;
}
}
}