484 lines
24 KiB
Twig
484 lines
24 KiB
Twig
<!DOCTYPE html>
|
|
<html lang="de">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title><?= $title ?> - Webshop Admin</title>
|
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
|
|
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet">
|
|
<style>
|
|
.form-section {
|
|
background: white;
|
|
border-radius: 0.5rem;
|
|
padding: 2rem;
|
|
margin-bottom: 2rem;
|
|
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
|
|
}
|
|
.form-section h5 {
|
|
color: #667eea;
|
|
border-bottom: 2px solid #f8f9fa;
|
|
padding-bottom: 0.5rem;
|
|
margin-bottom: 1.5rem;
|
|
}
|
|
.required-field::after {
|
|
content: " *";
|
|
color: #dc3545;
|
|
}
|
|
.help-text {
|
|
font-size: 0.875rem;
|
|
color: #6c757d;
|
|
margin-top: 0.25rem;
|
|
}
|
|
.domain-preview {
|
|
background: #f8f9fa;
|
|
border: 1px solid #dee2e6;
|
|
border-radius: 0.375rem;
|
|
padding: 0.75rem;
|
|
margin-top: 0.5rem;
|
|
font-family: monospace;
|
|
}
|
|
.ssl-status {
|
|
display: inline-block;
|
|
width: 12px;
|
|
height: 12px;
|
|
border-radius: 50%;
|
|
margin-right: 0.5rem;
|
|
}
|
|
.ssl-enabled { background-color: #28a745; }
|
|
.ssl-disabled { background-color: #dc3545; }
|
|
</style>
|
|
</head>
|
|
<body class="bg-light">
|
|
<div class="container-fluid">
|
|
<div class="row">
|
|
<!-- Sidebar -->
|
|
<nav class="col-md-3 col-lg-2 d-md-block bg-light sidebar">
|
|
<div class="position-sticky pt-3">
|
|
<ul class="nav flex-column">
|
|
<li class="nav-item">
|
|
<a class="nav-link" href="/admin/dashboard">
|
|
<i class="fas fa-tachometer-alt me-2"></i>Dashboard
|
|
</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a class="nav-link active" href="/admin/shop">
|
|
<i class="fas fa-store me-2"></i>Shop-Verwaltung
|
|
</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a class="nav-link" href="/admin/products">
|
|
<i class="fas fa-box me-2"></i>Produkte
|
|
</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a class="nav-link" href="/admin/orders">
|
|
<i class="fas fa-shopping-cart me-2"></i>Bestellungen
|
|
</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a class="nav-link" href="/admin/customers">
|
|
<i class="fas fa-users me-2"></i>Kunden
|
|
</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">
|
|
<i class="fas fa-plus me-2"></i>Neuen Shop erstellen
|
|
</h1>
|
|
<div class="btn-toolbar mb-2 mb-md-0">
|
|
<a href="/admin/shop" class="btn btn-sm btn-outline-secondary">
|
|
<i class="fas fa-arrow-left me-1"></i>Zurück zur Übersicht
|
|
</a>
|
|
</div>
|
|
</div>
|
|
|
|
<form method="POST" action="/admin/shop/create" id="createShopForm">
|
|
<!-- CSRF Token -->
|
|
<input type="hidden" name="csrf_token" value="<?= generateCSRFToken('shop_create') ?>">
|
|
|
|
<!-- Grundinformationen -->
|
|
<div class="form-section">
|
|
<h5>
|
|
<i class="fas fa-info-circle me-2"></i>Grundinformationen
|
|
</h5>
|
|
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<div class="mb-3">
|
|
<label for="name" class="form-label required-field">Shop-Name</label>
|
|
<input type="text" class="form-control" id="name" name="name" required
|
|
placeholder="z.B. Mein Webshop">
|
|
<div class="help-text">Der Name wird in der Shop-Navigation und E-Mails angezeigt.</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-md-6">
|
|
<div class="mb-3">
|
|
<label for="sort_order" class="form-label">Sortierreihenfolge</label>
|
|
<input type="number" class="form-control" id="sort_order" name="sort_order"
|
|
value="0" min="0" max="999">
|
|
<div class="help-text">Niedrigere Zahlen werden zuerst angezeigt.</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="mb-3">
|
|
<label for="description" class="form-label">Beschreibung</label>
|
|
<textarea class="form-control" id="description" name="description" rows="3"
|
|
placeholder="Kurze Beschreibung des Shops..."></textarea>
|
|
<div class="help-text">Optionale Beschreibung für interne Verwaltung.</div>
|
|
</div>
|
|
|
|
<div class="mb-3">
|
|
<div class="form-check">
|
|
<input class="form-check-input" type="checkbox" id="active" name="active" checked>
|
|
<label class="form-check-label" for="active">
|
|
Shop ist aktiv
|
|
</label>
|
|
<div class="help-text">Inaktive Shops sind nicht öffentlich zugänglich.</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Domain & SSL -->
|
|
<div class="form-section">
|
|
<h5>
|
|
<i class="fas fa-globe me-2"></i>Domain & SSL
|
|
</h5>
|
|
|
|
<div class="row">
|
|
<div class="col-md-8">
|
|
<div class="mb-3">
|
|
<label for="domain" class="form-label">Domain</label>
|
|
<input type="text" class="form-control" id="domain" name="domain"
|
|
placeholder="shop.example.com">
|
|
<div class="help-text">Leer lassen für Standard-Domain. Format: subdomain.domain.com</div>
|
|
|
|
<div id="domainPreview" class="domain-preview" style="display: none;">
|
|
<strong>Vorschau:</strong> <span id="previewUrl"></span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-md-4">
|
|
<div class="mb-3">
|
|
<label class="form-label">SSL-Status</label>
|
|
<div class="d-flex align-items-center">
|
|
<span class="ssl-status ssl-disabled" id="sslStatus"></span>
|
|
<span id="sslStatusText">Nicht konfiguriert</span>
|
|
</div>
|
|
<div class="help-text">SSL wird automatisch erkannt.</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<div class="mb-3">
|
|
<div class="form-check">
|
|
<input class="form-check-input" type="checkbox" id="ssl_enabled" name="ssl_enabled">
|
|
<label class="form-check-label" for="ssl_enabled">
|
|
SSL aktiviert
|
|
</label>
|
|
<div class="help-text">HTTPS für diesen Shop erzwingen.</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-md-6">
|
|
<div class="mb-3">
|
|
<div class="form-check">
|
|
<input class="form-check-input" type="checkbox" id="force_ssl" name="force_ssl">
|
|
<label class="form-check-label" for="force_ssl">
|
|
SSL erzwingen
|
|
</label>
|
|
<div class="help-text">HTTP auf HTTPS umleiten.</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Standard-Konfiguration -->
|
|
<div class="form-section">
|
|
<h5>
|
|
<i class="fas fa-cog me-2"></i>Standard-Konfiguration
|
|
</h5>
|
|
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<div class="mb-3">
|
|
<label for="default_currency" class="form-label">Standard-Währung</label>
|
|
<select class="form-select" id="default_currency" name="default_currency">
|
|
<option value="EUR" selected>Euro (€)</option>
|
|
<option value="USD">US Dollar ($)</option>
|
|
<option value="GBP">British Pound (£)</option>
|
|
<option value="CHF">Swiss Franc (CHF)</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-md-6">
|
|
<div class="mb-3">
|
|
<label for="default_language" class="form-label">Standard-Sprache</label>
|
|
<select class="form-select" id="default_language" name="default_language">
|
|
<option value="de" selected>Deutsch</option>
|
|
<option value="en">English</option>
|
|
<option value="fr">Français</option>
|
|
<option value="es">Español</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<div class="mb-3">
|
|
<label for="default_country" class="form-label">Standard-Land</label>
|
|
<select class="form-select" id="default_country" name="default_country">
|
|
<option value="DE" selected>Deutschland</option>
|
|
<option value="AT">Österreich</option>
|
|
<option value="CH">Schweiz</option>
|
|
<option value="US">United States</option>
|
|
<option value="GB">United Kingdom</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-md-6">
|
|
<div class="mb-3">
|
|
<label for="default_timezone" class="form-label">Zeitzone</label>
|
|
<select class="form-select" id="default_timezone" name="default_timezone">
|
|
<option value="Europe/Berlin" selected>Europe/Berlin</option>
|
|
<option value="Europe/Vienna">Europe/Vienna</option>
|
|
<option value="Europe/Zurich">Europe/Zurich</option>
|
|
<option value="America/New_York">America/New_York</option>
|
|
<option value="Europe/London">Europe/London</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Erweiterte Einstellungen -->
|
|
<div class="form-section">
|
|
<h5>
|
|
<i class="fas fa-sliders-h me-2"></i>Erweiterte Einstellungen
|
|
</h5>
|
|
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<div class="mb-3">
|
|
<label for="tax_rate" class="form-label">Standard-Steuersatz (%)</label>
|
|
<input type="number" class="form-control" id="tax_rate" name="tax_rate"
|
|
value="19.00" step="0.01" min="0" max="100">
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-md-6">
|
|
<div class="mb-3">
|
|
<label for="shipping_cost" class="form-label">Standard-Versandkosten (€)</label>
|
|
<input type="number" class="form-control" id="shipping_cost" name="shipping_cost"
|
|
value="5.90" step="0.01" min="0">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<div class="mb-3">
|
|
<label for="free_shipping_threshold" class="form-label">Kostenloser Versand ab (€)</label>
|
|
<input type="number" class="form-control" id="free_shipping_threshold" name="free_shipping_threshold"
|
|
value="50.00" step="0.01" min="0">
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-md-6">
|
|
<div class="mb-3">
|
|
<label for="stock_warning" class="form-label">Lagerbestand-Warnung</label>
|
|
<input type="number" class="form-control" id="stock_warning" name="stock_warning"
|
|
value="5" min="0">
|
|
<div class="help-text">Warnung bei niedrigem Lagerbestand.</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<div class="mb-3">
|
|
<div class="form-check">
|
|
<input class="form-check-input" type="checkbox" id="reviews_enabled" name="reviews_enabled" checked>
|
|
<label class="form-check-label" for="reviews_enabled">
|
|
Produktbewertungen aktiviert
|
|
</label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-md-6">
|
|
<div class="mb-3">
|
|
<div class="form-check">
|
|
<input class="form-check-input" type="checkbox" id="newsletter_enabled" name="newsletter_enabled" checked>
|
|
<label class="form-check-label" for="newsletter_enabled">
|
|
Newsletter aktiviert
|
|
</label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Aktionen -->
|
|
<div class="form-section">
|
|
<div class="d-flex justify-content-between align-items-center">
|
|
<div>
|
|
<button type="submit" class="btn btn-primary">
|
|
<i class="fas fa-save me-2"></i>Shop erstellen
|
|
</button>
|
|
<a href="/admin/shop" class="btn btn-outline-secondary ms-2">
|
|
<i class="fas fa-times me-2"></i>Abbrechen
|
|
</a>
|
|
</div>
|
|
|
|
<div class="form-check">
|
|
<input class="form-check-input" type="checkbox" id="create_and_configure" name="create_and_configure">
|
|
<label class="form-check-label" for="create_and_configure">
|
|
Nach Erstellung zur Konfiguration
|
|
</label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</main>
|
|
</div>
|
|
</div>
|
|
|
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
|
|
<script>
|
|
// Domain-Vorschau
|
|
document.getElementById('domain').addEventListener('input', function() {
|
|
const domain = this.value.trim();
|
|
const preview = document.getElementById('domainPreview');
|
|
const previewUrl = document.getElementById('previewUrl');
|
|
|
|
if (domain) {
|
|
previewUrl.textContent = `https://${domain}`;
|
|
preview.style.display = 'block';
|
|
} else {
|
|
preview.style.display = 'none';
|
|
}
|
|
});
|
|
|
|
// SSL-Status prüfen
|
|
document.getElementById('domain').addEventListener('blur', function() {
|
|
const domain = this.value.trim();
|
|
if (domain) {
|
|
checkSSLStatus(domain);
|
|
}
|
|
});
|
|
|
|
function checkSSLStatus(domain) {
|
|
// Simulierte SSL-Prüfung
|
|
const sslStatus = document.getElementById('sslStatus');
|
|
const sslStatusText = document.getElementById('sslStatusText');
|
|
|
|
// In der Praxis würde hier eine echte SSL-Prüfung stattfinden
|
|
setTimeout(() => {
|
|
const hasSSL = Math.random() > 0.5; // Simulierte Prüfung
|
|
|
|
if (hasSSL) {
|
|
sslStatus.className = 'ssl-status ssl-enabled';
|
|
sslStatusText.textContent = 'SSL verfügbar';
|
|
document.getElementById('ssl_enabled').checked = true;
|
|
} else {
|
|
sslStatus.className = 'ssl-status ssl-disabled';
|
|
sslStatusText.textContent = 'SSL nicht verfügbar';
|
|
document.getElementById('ssl_enabled').checked = false;
|
|
}
|
|
}, 1000);
|
|
}
|
|
|
|
// Form-Validierung
|
|
document.getElementById('createShopForm').addEventListener('submit', function(e) {
|
|
const name = document.getElementById('name').value.trim();
|
|
|
|
if (!name) {
|
|
e.preventDefault();
|
|
alert('Bitte geben Sie einen Shop-Namen ein.');
|
|
document.getElementById('name').focus();
|
|
return;
|
|
}
|
|
|
|
const domain = document.getElementById('domain').value.trim();
|
|
if (domain && !isValidDomain(domain)) {
|
|
e.preventDefault();
|
|
alert('Bitte geben Sie eine gültige Domain ein.');
|
|
document.getElementById('domain').focus();
|
|
return;
|
|
}
|
|
});
|
|
|
|
function isValidDomain(domain) {
|
|
const domainRegex = /^[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/;
|
|
return domainRegex.test(domain);
|
|
}
|
|
|
|
// Auto-Save Draft
|
|
let autoSaveTimer;
|
|
const formInputs = document.querySelectorAll('input, textarea, select');
|
|
|
|
formInputs.forEach(input => {
|
|
input.addEventListener('input', function() {
|
|
clearTimeout(autoSaveTimer);
|
|
autoSaveTimer = setTimeout(saveDraft, 2000);
|
|
});
|
|
});
|
|
|
|
function saveDraft() {
|
|
const formData = new FormData(document.getElementById('createShopForm'));
|
|
const draft = {};
|
|
|
|
for (let [key, value] of formData.entries()) {
|
|
draft[key] = value;
|
|
}
|
|
|
|
localStorage.setItem('shop_create_draft', JSON.stringify(draft));
|
|
}
|
|
|
|
// Draft laden
|
|
window.addEventListener('load', function() {
|
|
const draft = localStorage.getItem('shop_create_draft');
|
|
if (draft) {
|
|
const data = JSON.parse(draft);
|
|
|
|
for (let key in data) {
|
|
const element = document.querySelector(`[name="${key}"]`);
|
|
if (element) {
|
|
if (element.type === 'checkbox') {
|
|
element.checked = data[key] === 'on';
|
|
} else {
|
|
element.value = data[key];
|
|
}
|
|
}
|
|
}
|
|
|
|
// Domain-Vorschau aktualisieren
|
|
const domainInput = document.getElementById('domain');
|
|
if (domainInput.value) {
|
|
domainInput.dispatchEvent(new Event('input'));
|
|
}
|
|
}
|
|
});
|
|
|
|
// Draft löschen nach erfolgreichem Submit
|
|
document.getElementById('createShopForm').addEventListener('submit', function() {
|
|
localStorage.removeItem('shop_create_draft');
|
|
});
|
|
</script>
|
|
</body>
|
|
</html> |