Newwebshop/templates/admin/payment/index.html.twig

357 lines
17 KiB
Twig

<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Zahlungsverwaltung - Webshop Admin</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.0/font/bootstrap-icons.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
</head>
<body>
<div class="container-fluid">
<div class="row">
<!-- Sidebar -->
<nav class="col-md-3 col-lg-2 d-md-block bg-dark sidebar collapse">
<div class="position-sticky pt-3">
<ul class="nav flex-column">
<li class="nav-item">
<a class="nav-link text-white" href="/admin/dashboard">
<i class="bi bi-speedometer2"></i> Dashboard
</a>
</li>
<li class="nav-item">
<a class="nav-link text-white" href="/admin/products">
<i class="bi bi-box"></i> Produkte
</a>
</li>
<li class="nav-item">
<a class="nav-link text-white" href="/admin/orders">
<i class="bi bi-cart"></i> Bestellungen
</a>
</li>
<li class="nav-item">
<a class="nav-link text-white" href="/admin/customers">
<i class="bi bi-people"></i> Kunden
</a>
</li>
<li class="nav-item">
<a class="nav-link active text-white" href="/admin/payment">
<i class="bi bi-credit-card"></i> Zahlungen
</a>
</li>
<li class="nav-item">
<a class="nav-link text-white" href="/admin/settings">
<i class="bi bi-gear"></i> Einstellungen
</a>
</li>
</ul>
</div>
</nav>
<!-- Main content -->
<main class="col-md-9 ms-sm-auto col-lg-10 px-md-4">
<div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">
<h1 class="h2">Zahlungsverwaltung</h1>
<div class="btn-toolbar mb-2 mb-md-0">
<div class="btn-group me-2">
<a href="/admin/payment/transactions" class="btn btn-sm btn-outline-secondary">
<i class="bi bi-list"></i> Transaktionen
</a>
</div>
</div>
</div>
<!-- Flash Messages -->
{% if success_messages %}
{% for message in success_messages %}
<div class="alert alert-success alert-dismissible fade show" role="alert">
{{ message }}
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
</div>
{% endfor %}
{% endif %}
{% if error_messages %}
{% for message in error_messages %}
<div class="alert alert-danger alert-dismissible fade show" role="alert">
{{ message }}
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
</div>
{% endfor %}
{% endif %}
<!-- Payment Provider Cards -->
<div class="row mb-4">
<div class="col-md-4">
<div class="card">
<div class="card-body">
<div class="d-flex justify-content-between align-items-center">
<div>
<h5 class="card-title">PayPal</h5>
<p class="card-text text-muted">Online-Zahlungen</p>
</div>
<div class="text-end">
<span class="badge {% if provider_status.paypal %}bg-success{% else %}bg-danger{% endif %}">
{% if provider_status.paypal %}Aktiv{% else %}Inaktiv{% endif %}
</span>
</div>
</div>
<a href="/admin/payment/paypal" class="btn btn-primary btn-sm">
<i class="bi bi-gear"></i> Konfigurieren
</a>
</div>
</div>
</div>
<div class="col-md-4">
<div class="card">
<div class="card-body">
<div class="d-flex justify-content-between align-items-center">
<div>
<h5 class="card-title">Stripe</h5>
<p class="card-text text-muted">Kreditkarten-Zahlungen</p>
</div>
<div class="text-end">
<span class="badge {% if provider_status.stripe %}bg-success{% else %}bg-danger{% endif %}">
{% if provider_status.stripe %}Aktiv{% else %}Inaktiv{% endif %}
</span>
</div>
</div>
<a href="/admin/payment/stripe" class="btn btn-primary btn-sm">
<i class="bi bi-gear"></i> Konfigurieren
</a>
</div>
</div>
</div>
<div class="col-md-4">
<div class="card">
<div class="card-body">
<div class="d-flex justify-content-between align-items-center">
<div>
<h5 class="card-title">SEPA-Lastschrift</h5>
<p class="card-text text-muted">Banküberweisungen</p>
</div>
<div class="text-end">
<span class="badge {% if provider_status.sepa %}bg-success{% else %}bg-danger{% endif %}">
{% if provider_status.sepa %}Aktiv{% else %}Inaktiv{% endif %}
</span>
</div>
</div>
<a href="/admin/payment/sepa" class="btn btn-primary btn-sm">
<i class="bi bi-gear"></i> Konfigurieren
</a>
</div>
</div>
</div>
</div>
<!-- Payment Statistics -->
<div class="row mb-4">
<div class="col-md-6">
<div class="card">
<div class="card-header">
<h5 class="card-title mb-0">Zahlungsstatistiken</h5>
</div>
<div class="card-body">
<canvas id="paymentChart" width="400" height="200"></canvas>
</div>
</div>
</div>
<div class="col-md-6">
<div class="card">
<div class="card-header">
<h5 class="card-title mb-0">Aktuelle Transaktionen</h5>
</div>
<div class="card-body">
<div class="table-responsive">
<table class="table table-sm">
<thead>
<tr>
<th>Provider</th>
<th>Betrag</th>
<th>Status</th>
</tr>
</thead>
<tbody>
{% for stat in statistics %}
<tr>
<td>
<span class="badge bg-primary">{{ stat.provider|upper }}</span>
</td>
<td>{{ stat.total_amount|number_format(2, ',', '.') }} €</td>
<td>
<span class="badge bg-success">{{ stat.successful_transactions }}</span>
<span class="badge bg-danger">{{ stat.failed_transactions }}</span>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
<!-- Quick Actions -->
<div class="row">
<div class="col-12">
<div class="card">
<div class="card-header">
<h5 class="card-title mb-0">Schnellaktionen</h5>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-3">
<a href="/admin/payment/transactions" class="btn btn-outline-primary w-100 mb-2">
<i class="bi bi-list"></i> Alle Transaktionen
</a>
</div>
<div class="col-md-3">
<button class="btn btn-outline-success w-100 mb-2" onclick="testAllProviders()">
<i class="bi bi-check-circle"></i> Alle Provider testen
</button>
</div>
<div class="col-md-3">
<a href="/admin/payment/statistics" class="btn btn-outline-info w-100 mb-2">
<i class="bi bi-graph-up"></i> Detaillierte Statistiken
</a>
</div>
<div class="col-md-3">
<button class="btn btn-outline-warning w-100 mb-2" onclick="exportTransactions()">
<i class="bi bi-download"></i> Export
</button>
</div>
</div>
</div>
</div>
</div>
</div>
</main>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
<script>
// Payment Chart
const ctx = document.getElementById('paymentChart').getContext('2d');
const paymentChart = new Chart(ctx, {
type: 'doughnut',
data: {
labels: [
{% for stat in statistics %}
'{{ stat.provider|upper }}',
{% endfor %}
],
datasets: [{
data: [
{% for stat in statistics %}
{{ stat.total_amount }},
{% endfor %}
],
backgroundColor: [
'#007bff',
'#28a745',
'#ffc107',
'#dc3545'
],
borderWidth: 2,
borderColor: '#fff'
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
position: 'bottom'
},
tooltip: {
callbacks: {
label: function(context) {
const label = context.label || '';
const value = context.parsed;
return label + ': ' + value.toFixed(2) + ' €';
}
}
}
}
}
});
// Test all payment providers
function testAllProviders() {
const providers = ['paypal', 'stripe', 'sepa'];
let results = {};
providers.forEach(provider => {
fetch('/admin/payment/test-provider', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: 'provider=' + provider + '&csrf_token={{ csrf_token }}'
})
.then(response => response.json())
.then(data => {
results[provider] = data.status;
updateProviderStatus(provider, data.status);
})
.catch(error => {
console.error('Fehler beim Testen von ' + provider + ':', error);
results[provider] = false;
updateProviderStatus(provider, false);
});
});
}
// Update provider status badges
function updateProviderStatus(provider, status) {
const badge = document.querySelector(`[data-provider="${provider}"]`);
if (badge) {
badge.className = `badge ${status ? 'bg-success' : 'bg-danger'}`;
badge.textContent = status ? 'Aktiv' : 'Inaktiv';
}
}
// Export transactions
function exportTransactions() {
const date = new Date().toISOString().split('T')[0];
const filename = `transactions_${date}.csv`;
fetch('/admin/payment/export-transactions')
.then(response => response.blob())
.then(blob => {
const url = window.URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = filename;
document.body.appendChild(a);
a.click();
window.URL.revokeObjectURL(url);
document.body.removeChild(a);
})
.catch(error => {
console.error('Export Fehler:', error);
alert('Fehler beim Export der Transaktionen');
});
}
// Auto-refresh statistics every 30 seconds
setInterval(() => {
fetch('/admin/payment/statistics')
.then(response => response.json())
.then(data => {
// Update chart data
paymentChart.data.labels = data.map(stat => stat.provider.toUpperCase());
paymentChart.data.datasets[0].data = data.map(stat => stat.total_amount);
paymentChart.update();
})
.catch(error => console.error('Statistik-Update Fehler:', error));
}, 30000);
</script>
</body>
</html>