Buchungskalender eingefügt

This commit is contained in:
2026-05-05 19:18:05 +02:00
parent 4a4517c514
commit c1f07343e3
21 changed files with 931 additions and 187 deletions
+27 -10
View File
@@ -1,4 +1,10 @@
<section class="admin-section narrow-section">
<?php
$priceRates = [];
foreach ($deliveryZoneOptions as $zoneKey => $zone) {
$priceRates[$zoneKey] = (int) $zone['price_cents'];
}
?>
<div class="section-header">
<div>
<p class="eyebrow">Manuelle Buchung</p>
@@ -14,8 +20,9 @@
<div class="flash flash-error"><?= h((string) $flashError) ?></div>
<?php endif; ?>
<form method="post" action="<?= h(url('admin/create')) ?>" class="booking-form admin-form" data-day-rate="<?= h((string) $defaults['price_per_day_cents']) ?>">
<form method="post" action="<?= h(url('admin/create')) ?>" class="booking-form admin-form" data-day-rate="<?= h((string) $defaults['price_per_day_cents']) ?>" data-price-rates="<?= h((string) json_encode($priceRates, JSON_THROW_ON_ERROR)) ?>">
<?= csrfField() ?>
<input type="hidden" name="price_per_day_cents" value="<?= h((string) ($old['price_per_day_cents'] ?? $defaults['price_per_day_cents'])) ?>">
<div class="form-section">
<div class="form-section-header">
<span class="form-step">Verwaltung</span>
@@ -67,10 +74,6 @@
<span>Rückgabedatum</span>
<input type="date" name="end_date" data-booking-end value="<?= h((string) ($old['end_date'] ?? '')) ?>" required>
</label>
<label>
<span>Preis pro Miettag in Cent</span>
<input type="number" name="price_per_day_cents" min="0" value="<?= h((string) ($old['price_per_day_cents'] ?? $defaults['price_per_day_cents'])) ?>" required>
</label>
<label>
<span>Status</span>
<select name="status">
@@ -90,10 +93,20 @@
</label>
<label>
<span>Lieferart</span>
<select name="delivery_mode">
<option value="self_pickup" <?= selected((string) ($old['delivery_mode'] ?? $defaults['delivery_mode']), 'self_pickup') ?>>Selbstabholung</option>
<option value="delivery_setup" <?= selected((string) ($old['delivery_mode'] ?? ''), 'delivery_setup') ?>>Lieferung und Aufbau</option>
<option value="on_site_support" <?= selected((string) ($old['delivery_mode'] ?? ''), 'on_site_support') ?>>Lieferung, Aufbau und Vor-Ort-Betreuung</option>
<select name="delivery_mode" data-delivery-mode>
<?php foreach ($deliveryModeOptions as $value => $label): ?>
<option value="<?= h($value) ?>" <?= selected((string) ($old['delivery_mode'] ?? $defaults['delivery_mode']), $value) ?>><?= h($label) ?></option>
<?php endforeach; ?>
</select>
</label>
<label>
<span>Liefergebiet</span>
<select name="delivery_zone" data-delivery-zone>
<?php foreach ($deliveryZoneOptions as $value => $zone): ?>
<option value="<?= h($value) ?>" <?= selected((string) ($old['delivery_zone'] ?? $defaults['delivery_zone']), $value) ?>>
<?= h($zone['label']) ?> · <?= h(formatCurrency((int) $zone['price_cents'])) ?>
</option>
<?php endforeach; ?>
</select>
</label>
<label>
@@ -112,6 +125,7 @@
<textarea name="internal_notes" rows="4"><?= h((string) ($old['internal_notes'] ?? '')) ?></textarea>
</label>
</div>
<p class="form-help">Preislogik: Abholung <?= h(formatCurrency((int) $deliveryZoneOptions['self_pickup']['price_cents'])) ?>, Hannover <?= h(formatCurrency((int) $deliveryZoneOptions['hannover']['price_cents'])) ?>, Region Hannover <?= h(formatCurrency((int) $deliveryZoneOptions['region_hannover']['price_cents'])) ?>, Hameln/Braunschweig/Hildesheim/Celle <?= h(formatCurrency((int) $deliveryZoneOptions['extended_region']['price_cents'])) ?> pro Miettag.</p>
</div>
<div class="booking-summary-card">
@@ -119,6 +133,10 @@
<span>Mietdauer</span>
<strong data-summary-days>Noch nicht gewählt</strong>
</div>
<div class="summary-line">
<span>Preis pro Miettag</span>
<strong data-summary-rate><?= h(formatCurrency((int) ($old['price_per_day_cents'] ?? $defaults['price_per_day_cents']))) ?></strong>
</div>
<div class="summary-line summary-line-total">
<span>Gesamtpreis</span>
<strong data-summary-total><?= h(formatCurrency((int) $defaults['price_per_day_cents'])) ?></strong>
@@ -128,4 +146,3 @@
<button type="submit" class="button-primary">Buchung speichern</button>
</form>
</section>
+1 -1
View File
@@ -28,6 +28,7 @@
<div><dt>Mietzeitraum</dt><dd><?= h(formatDate($booking['start_date'])) ?> bis <?= h(formatDate($booking['end_date'])) ?></dd></div>
<div><dt>Miettage</dt><dd><?= h((string) $booking['total_days']) ?></dd></div>
<div><dt>Leistung</dt><dd><?= h($booking['delivery_mode_label']) ?></dd></div>
<div><dt>Liefergebiet</dt><dd><?= h($booking['delivery_zone_label'] ?? '-') ?></dd></div>
<div><dt>Zahlungsart</dt><dd><?= h($booking['payment_method_label']) ?></dd></div>
<div><dt>Gesamt</dt><dd><?= h(formatCurrency((int) $booking['subtotal_cents'])) ?></dd></div>
</dl>
@@ -106,4 +107,3 @@
</article>
</div>
</section>
+28 -28
View File
@@ -1,15 +1,14 @@
<section class="hero">
<div class="hero-copy">
<p class="eyebrow">Professionelle Fotobox-Vermietung</p>
<h1>Fotobox mieten für Hochzeiten, Geburtstage und Firmenfeiern.</h1>
<p class="eyebrow">Fotobox-Verleih für <?= h($company['service_area']) ?></p>
<h1>Fotobox mieten für Hochzeit, Geburtstag und Firmenfeier.</h1>
<p class="hero-text">
Hochwertige Technik, klare Preislogik pro Miettag und ein Buchungsablauf,
der auch kaufmännisch sauber funktioniert. Anfrage senden, Bestätigung erhalten,
Bilder digital bekommen.
Professionelle Fotobox mit Spiegelreflexkamera, Studioblitz und digitaler Bildübergabe.
Lieferung oder Selbstabholung möglich. Schon ab <?= h(formatCurrency((int) $dayRate)) ?> pro Miettag bei Selbstabholung.
</p>
<div class="hero-actions">
<a class="button-primary" href="<?= h(url('buchen')) ?>">Verfügbarkeit prüfen</a>
<a class="button-secondary" href="<?= h(url('leistungen')) ?>">Leistungen ansehen</a>
<a class="button-secondary" href="<?= h(url('preise')) ?>">Preise ansehen</a>
</div>
<div class="trust-grid">
<?php foreach ($trustFacts as $fact): ?>
@@ -23,8 +22,8 @@
<aside class="hero-panel">
<div class="hero-panel-top">
<span>Service mit Struktur</span>
<strong>Vom ersten Termin bis zur Rechnung</strong>
<span>Beliebt für Hochzeiten, Geburtstage und Firmenfeiern</span>
<strong>Professionelle Fotos mit wenig Aufwand</strong>
</div>
<div class="device-stage">
<div class="device-glow"></div>
@@ -48,11 +47,11 @@
</div>
<div class="hero-panel-bottom">
<div>
<span>Abholung</span>
<span>Mietbeginn</span>
<strong><?= h($company['pickup_window']) ?></strong>
</div>
<div>
<span>Rückgabe</span>
<span>Mietende</span>
<strong><?= h($company['return_window']) ?></strong>
</div>
</div>
@@ -61,11 +60,11 @@
<section class="section section-tight">
<div class="section-heading">
<p class="eyebrow">Warum diese Seite anders aufgebaut ist</p>
<h2>Kein Party-Prospekt, sondern eine ruhige Buchungsseite für einen echten Mietservice.</h2>
<p class="eyebrow">Warum unsere Fotobox</p>
<h2>Klare Leistungen. Klare Preise. Klare Abläufe.</h2>
<p>
Die Agenten-Recherche hat klar gezeigt: Kundenfreundlich ist eine verständliche Service-Seite
mit Preis, Ablauf, Verfügbarkeit und einem Verwaltungsprozess im Hintergrund.
Sie sehen sofort, was enthalten ist, wie ein Miettag berechnet wird
und wie Ihre Anfrage abläuft. So planen Sie Ihr Event ohne unnötige Rückfragen und ohne Technikstress.
</p>
</div>
<div class="feature-card-grid">
@@ -81,7 +80,7 @@
<section class="section split-section">
<div class="content-card">
<p class="eyebrow">Ablauf</p>
<h2>So läuft Ihre Anfrage ab</h2>
<h2>So einfach mieten Sie die Fotobox</h2>
<ol class="step-list">
<?php foreach ($processSteps as $index => $step): ?>
<li>
@@ -95,8 +94,8 @@
</ol>
</div>
<div class="content-card editorial-card">
<p class="eyebrow">Standards</p>
<h2>Kommerziell gedacht, nicht nur hübsch.</h2>
<p class="eyebrow">Auf einen Blick</p>
<h2>Alles, was für eine entspannte Buchung wichtig ist.</h2>
<ul class="check-list">
<?php foreach ($serviceStandards as $standard): ?>
<li><?= h($standard) ?></li>
@@ -107,8 +106,8 @@
<section class="section">
<div class="section-heading">
<p class="eyebrow">Leistungsmodule</p>
<h2>Technik, Eventbetrieb und Verwaltung greifen ineinander.</h2>
<p class="eyebrow">Leistungen</p>
<h2>Alles drin für eine Fotobox, die sofort einsatzbereit ist.</h2>
</div>
<div class="module-grid">
<?php foreach ($serviceModules as $module): ?>
@@ -127,7 +126,7 @@
<section class="section">
<div class="section-heading">
<p class="eyebrow">Anlässe</p>
<h2>Für Privatfeiern und professionelle Events geeignet.</h2>
<h2>Die passende Fotobox für Ihr Event in <?= h($company['service_area']) ?>.</h2>
</div>
<div class="occasion-grid">
<?php foreach ($occasionCards as $occasion): ?>
@@ -142,8 +141,8 @@
<section class="section split-section">
<div class="content-card">
<p class="eyebrow">Verfügbarkeit</p>
<h2>Aktuell geblockte oder bestätigte Zeiträume</h2>
<p>Die Übersicht stammt direkt aus dem Verwaltungssystem und zeigt belegte Termine.</p>
<h2>Bereits reservierte Termine</h2>
<p>Hier sehen Sie, welche Zeiträume aktuell angefragt, reserviert oder bereits bestätigt sind.</p>
<div class="availability-list">
<?php if ($bookings === []): ?>
<article class="availability-card">
@@ -154,24 +153,25 @@
<?php foreach ($bookings as $booking): ?>
<article class="availability-card">
<div>
<strong><?= h($booking['reference']) ?></strong>
<span><?= h(formatDate($booking['start_date'])) ?> bis <?= h(formatDate($booking['end_date'])) ?></span>
<strong><?= h(formatDate($booking['start_date'])) ?> bis <?= h(formatDate($booking['end_date'])) ?></strong>
<span><?= h((string) ($booking['delivery_zone_label'] ?: $booking['delivery_mode_label'])) ?></span>
</div>
<span class="<?= h(statusPillClass((string) $booking['status'])) ?>"><?= h($booking['status_label']) ?></span>
</article>
<?php endforeach; ?>
</div>
<a class="button-secondary" href="<?= h(url('verfuegbarkeit')) ?>">Gesamte Verfügbarkeit ansehen</a>
<a class="button-secondary" href="<?= h(url('verfuegbarkeit')) ?>">Wunschtermin prüfen</a>
</div>
<div class="content-card emphasis-card">
<p class="eyebrow">Nächster Schritt</p>
<h2>In wenigen Minuten zur Anfrage</h2>
<p class="eyebrow">Jetzt anfragen</p>
<h2>Unverbindlich Verfügbarkeit anfragen</h2>
<ul class="check-list">
<?php foreach ($bookingChecklist as $item): ?>
<li><?= h($item) ?></li>
<?php endforeach; ?>
</ul>
<p>Lieferpreise richten sich nach dem Zielort: Hannover, Region Hannover oder Hameln, Braunschweig, Hildesheim und Celle.</p>
<div class="pricing-example-list">
<?php foreach ($pricingExamples as $example): ?>
<article>
@@ -180,6 +180,6 @@
</article>
<?php endforeach; ?>
</div>
<a class="button-primary button-block" href="<?= h(url('buchen')) ?>">Zur Buchungsanfrage</a>
<a class="button-primary button-block" href="<?= h(url('buchen')) ?>">Wunschtermin anfragen</a>
</div>
</section>
+37 -12
View File
@@ -2,16 +2,15 @@
$app = appConfig();
$company = $app['company'];
$metaTitle = isset($pageTitle) ? $pageTitle . ' | ' . $company['name'] : $company['name'];
$metaDescription = $metaDescription ?? 'Professionelle Fotobox-Vermietung mit klarer Buchungsanfrage und Verwaltungsbereich.';
$metaDescription = $metaDescription ?? 'Professionelle Fotobox-Vermietung mit klaren Preisen, einfacher Anfrage und digitaler Bildübergabe.';
$isAdminArea = str_contains($viewPath, '/admin/');
$styleVersion = is_file(dirname(__DIR__) . '/assets/styles.css') ? (string) filemtime(dirname(__DIR__) . '/assets/styles.css') : '1';
$scriptVersion = is_file(dirname(__DIR__) . '/assets/app.js') ? (string) filemtime(dirname(__DIR__) . '/assets/app.js') : '1';
$currentPath = currentPath();
$publicNav = [
['label' => 'Leistungen', 'path' => '/leistungen'],
['label' => 'Fotobox', 'path' => '/fotobox', 'activePaths' => ['/fotobox', '/leistungen']],
['label' => 'Preise', 'path' => '/preise'],
['label' => 'Verfügbarkeit', 'path' => '/verfuegbarkeit'],
['label' => 'Ablauf', 'path' => '/ablauf'],
['label' => 'FAQ', 'path' => '/faq'],
['label' => 'Kontakt', 'path' => '/kontakt'],
@@ -78,14 +77,40 @@ $adminNav = [
</form>
</div>
<?php else: ?>
<nav class="site-nav site-nav-public" aria-label="Hauptnavigation">
<?php foreach ($publicNav as $item): ?>
<a class="<?= $currentPath === $item['path'] ? 'is-active' : '' ?>" href="<?= h(url($item['path'])) ?>"><?= h($item['label']) ?></a>
<?php endforeach; ?>
</nav>
<div class="header-actions">
<a class="button-secondary" href="<?= h(url('kontakt')) ?>">Kontakt</a>
<a class="button-primary" href="<?= h(url('buchen')) ?>">Buchungsanfrage</a>
<div class="public-header-shell">
<button
type="button"
class="nav-toggle"
data-nav-toggle
aria-expanded="false"
aria-controls="public-navigation"
>
<span class="nav-toggle-box" aria-hidden="true">
<span></span>
<span></span>
<span></span>
</span>
<span>Menü</span>
</button>
<div class="public-header-controls" id="public-navigation" data-nav-menu>
<nav class="site-nav site-nav-public" aria-label="Hauptnavigation">
<?php foreach ($publicNav as $item): ?>
<?php $isActive = in_array($currentPath, $item['activePaths'] ?? [$item['path']], true); ?>
<a class="<?= $isActive ? 'is-active' : '' ?>" href="<?= h(url($item['path'])) ?>"><?= h($item['label']) ?></a>
<?php endforeach; ?>
</nav>
<div class="menu-meta">
<span><?= h($company['service_area']) ?></span>
<a href="mailto:<?= h($company['email']) ?>"><?= h($company['email']) ?></a>
</div>
<div class="header-actions header-actions-public">
<a class="contact-chip" href="tel:<?= h($company['phone']) ?>">
<span>Telefon</span>
<strong><?= h($company['phone']) ?></strong>
</a>
<a class="button-primary" href="<?= h(url('verfuegbarkeit')) ?>">Verfügbarkeit prüfen</a>
</div>
</div>
</div>
<?php endif; ?>
</div>
@@ -112,7 +137,7 @@ $adminNav = [
</div>
<div>
<h3>Seiten</h3>
<a href="<?= h(url('leistungen')) ?>">Leistungen</a>
<a href="<?= h(url('fotobox')) ?>">Fotobox</a>
<a href="<?= h(url('preise')) ?>">Preise</a>
<a href="<?= h(url('buchen')) ?>">Buchen</a>
<a href="<?= h(url('faq')) ?>">FAQ</a>
+8 -8
View File
@@ -1,7 +1,7 @@
<section class="page-hero">
<p class="eyebrow">Ablauf</p>
<h1>Von der Anfrage bis zur Rückgabe klar geführt.</h1>
<p>Die Seite ist so gebaut, dass Privatkunden und Firmenkunden denselben klaren Ablauf erleben.</p>
<h1>So einfach mieten Sie Ihre Fotobox</h1>
<p>Von der Anfrage bis zur Rückgabe: In wenigen Schritten zu Ihrer Fotobox.</p>
</section>
<section class="section">
@@ -22,21 +22,21 @@
<section class="section split-section">
<article class="content-card">
<h2>Abholung und Rückgabe</h2>
<h2>Abholung oder Lieferung</h2>
<ul class="check-list">
<li><?= h($company['pickup_window']) ?></li>
<li><?= h($company['return_window']) ?></li>
<li>Bei der Abholung erhalten Sie eine kurze Einweisung in die Fotobox.</li>
<li>Lieferung und Aufbau können im Anfrageprozess gewählt werden.</li>
<li>Der Mietzeitraum wird immer über Übernachtungen berechnet.</li>
</ul>
</article>
<article class="content-card">
<h2>Verwaltung im Hintergrund</h2>
<h2>Was nach Ihrer Anfrage passiert</h2>
<ul class="check-list">
<li>Anfragen werden im Backend geprüft und bestätigt.</li>
<li>Für bestätigte Aufträge können Rechnungen mit Kundendaten erstellt werden.</li>
<li>Zahlungsstatus und interne Notizen bleiben jederzeit nachvollziehbar.</li>
<li>Wir prüfen die Verfügbarkeit Ihres Wunschtermins.</li>
<li>Sie erhalten eine Rückmeldung zum Termin und zum weiteren Ablauf.</li>
<li>Auf Wunsch erstellen wir eine Rechnung mit Ihren Kundendaten.</li>
</ul>
</article>
</section>
+7 -5
View File
@@ -1,15 +1,18 @@
<section class="page-hero">
<p class="eyebrow">Buchungsanfrage</p>
<h1>Fotobox jetzt anfragen.</h1>
<h1>Verfügbarkeit Ihrer Fotobox prüfen</h1>
<p>
Wählen Sie Ihren Zeitraum, legen Sie Leistungsart und Zahlungsart fest und senden Sie Ihre Anfrage direkt an die Verwaltung.
Wählen Sie Abhol- und Rückgabetag und senden Sie uns Ihre unverbindliche Anfrage.
Ein Miettag entspricht immer einer Übernachtung.
Selbstabholung kostet <?= h(formatCurrency((int) $dayRate)) ?> pro Miettag, Lieferungen werden je nach Zielort berechnet.
</p>
</section>
<section class="section split-section">
<article class="content-card emphasis-card">
<p class="eyebrow">Vor dem Absenden</p>
<h2>Was wir für eine saubere Bearbeitung brauchen</h2>
<p class="eyebrow">In 2 Minuten zur Anfrage</p>
<h2>Diese Angaben benötigen wir für Ihre Anfrage</h2>
<p>Mit Ihren Angaben prüfen wir den Termin, erfassen die Rechnungsdaten und melden uns zeitnah mit einer Bestätigung oder Rückfrage.</p>
<ul class="check-list">
<?php foreach ($bookingChecklist as $item): ?>
<li><?= h($item) ?></li>
@@ -25,4 +28,3 @@
<?php require dirname(__DIR__) . '/partials/public-booking-form.php'; ?>
</article>
</section>
+2 -3
View File
@@ -1,7 +1,7 @@
<section class="page-hero">
<p class="eyebrow">FAQ</p>
<h1>Häufige Fragen vor der Anfrage.</h1>
<p>Hier finden Sie die Punkte, die in Vermietung, Zahlung und Rückgabe am häufigsten geklärt werden müssen.</p>
<h1>Häufige Fragen zur Fotobox-Miete</h1>
<p>Hier finden Sie Antworten zu Mietdauer, Zahlung, Lieferung, Rückgabe und digitaler Bildübergabe.</p>
</section>
<section class="section">
@@ -14,4 +14,3 @@
<?php endforeach; ?>
</div>
</section>
+4 -5
View File
@@ -1,7 +1,7 @@
<section class="page-hero">
<p class="eyebrow">Kontakt</p>
<h1>Direkt erreichbar für Fragen zu Termin, Lieferung und Rechnung.</h1>
<p>Wenn Sie vor der Anfrage noch etwas abstimmen möchten, erreichen Sie uns über die folgenden Kontaktwege.</p>
<h1>Wir beraten Sie gerne persönlich.</h1>
<p>Wenn Sie vor Ihrer Anfrage noch Fragen zu Termin, Lieferung oder Zahlungsart haben, erreichen Sie uns direkt über die folgenden Kontaktwege.</p>
</section>
<section class="section split-section">
@@ -16,14 +16,13 @@
</div>
</article>
<article class="content-card emphasis-card">
<h2>Was wir schnell beantworten können</h2>
<h2>Wobei wir Sie unterstützen</h2>
<ul class="check-list">
<li>Prüfung von Wunschterminen</li>
<li>Lieferung, Aufbau und regionale Einsatzorte</li>
<li>Fragen zu Rechnung, Zahlungsart und Mietdauer</li>
<li>Abstimmung von Firmenveranstaltungen und Sonderfällen</li>
</ul>
<a class="button-primary" href="<?= h(url('buchen')) ?>">Zur Buchungsanfrage</a>
<a class="button-primary" href="<?= h(url('buchen')) ?>">Jetzt unverbindlich anfragen</a>
</article>
</section>
+9 -9
View File
@@ -1,9 +1,10 @@
<section class="page-hero">
<p class="eyebrow">Leistungen & Ausstattung</p>
<h1>Eine Fotobox, die technisch überzeugt und organisatorisch mitdenkt.</h1>
<p class="eyebrow">Fotobox & Leistungen</p>
<h1>Professionelle Fotobox für Hochzeit, Geburtstag und Firmenfeier.</h1>
<p>
Diese Seite zeigt nicht nur die Technik, sondern den gesamten Service:
Bildqualität, Bedienbarkeit, Logistik, digitale Übergabe und die kaufmännische Abwicklung.
Hochwertige Bilder, einfache Bedienung und eine klare Abwicklung.
Hier sehen Sie, was im Preis enthalten ist und welche Leistungen zusätzlich möglich sind.
Von der Spiegelreflexkamera bis zum WLAN-Download ist alles auf eine einfache Nutzung ausgelegt.
</p>
</section>
@@ -33,10 +34,9 @@
<section class="section cta-band">
<div>
<p class="eyebrow">Buchung</p>
<h2>Sie wissen schon, was Sie brauchen?</h2>
<p>Dann prüfen Sie direkt Ihren Zeitraum und senden Sie Ihre Anfrage digital.</p>
<p class="eyebrow">Wunschtermin</p>
<h2>Prüfen Sie direkt die Verfügbarkeit Ihrer Fotobox.</h2>
<p>Senden Sie uns Ihre Anfrage unverbindlich online. Wir melden uns zeitnah zurück.</p>
</div>
<a class="button-primary" href="<?= h(url('buchen')) ?>">Jetzt anfragen</a>
<a class="button-primary" href="<?= h(url('verfuegbarkeit')) ?>">Verfügbarkeit prüfen</a>
</section>
+1 -2
View File
@@ -15,7 +15,7 @@
</article>
<article class="legal-card">
<h2>3. Zahlung</h2>
<p>Zahlungen sind per Rechnung / Überweisung oder per PayPal möglich. Die gewählte Zahlungsart wird bei der Anfrage erfasst und kann im Verwaltungsprozess hinterlegt werden.</p>
<p>Zahlungen sind per Rechnung / Überweisung oder per PayPal möglich. Die gewünschte Zahlungsart wird direkt in Ihrer Anfrage angegeben.</p>
</article>
<article class="legal-card">
<h2>4. Übergabe und Rückgabe</h2>
@@ -26,4 +26,3 @@
<p>Bitte melden Sie Störungen oder Schäden unverzüglich. Für einen verbindlichen gewerblichen Einsatz sollten Haftungs- und Ausfallregelungen vor dem Live-Start individuell ergänzt werden.</p>
</article>
</section>
+31 -21
View File
@@ -1,36 +1,47 @@
<section class="page-hero">
<p class="eyebrow">Preise & Mietlogik</p>
<h1>Klare Preise ohne versteckte Logik.</h1>
<h1>Fotobox-Preise auf einen Blick</h1>
<p>
Der Standardpreis beträgt <strong><?= h(formatCurrency((int) $dayRate)) ?></strong> pro Miettag.
Ein Miettag entspricht immer einer Übernachtung.
<strong>Abholung ab <?= h(formatCurrency((int) $dayRate)) ?> pro Miettag.</strong>
Lieferpreise richten sich nach dem Zielort. Ein Miettag entspricht immer einer Übernachtung.
</p>
</section>
<section class="section split-section">
<article class="content-card emphasis-card">
<p class="eyebrow">Grundpreis</p>
<h2><?= h(formatCurrency((int) $dayRate)) ?> pro Miettag</h2>
<p>Montag bis Dienstag = 1 Miettag. Freitag bis Sonntag = 2 Miettage.</p>
<p class="eyebrow">Preis je Liefergebiet</p>
<h2>Abholung oder Lieferung nach Region</h2>
<p>Ein Miettag entspricht einer Übernachtung. Montag bis Dienstag = 1 Miettag. Freitag bis Sonntag = 2 Miettage.</p>
<ul class="check-list">
<li>Technikpaket mit DSLR-Kamera, Blitz und Softbox</li>
<li>Digitale Bildübergabe inklusive</li>
<li>Zahlung per Rechnung, Überweisung oder PayPal</li>
<li>Verbindlichkeit erst nach Bestätigung Ihrer Anfrage</li>
<?php foreach ($pricingExamples as $example): ?>
<li><strong><?= h($example['title']) ?>:</strong> <?= h($example['text']) ?></li>
<?php endforeach; ?>
</ul>
</article>
<article class="content-card">
<p class="eyebrow">Preisbeispiele</p>
<p class="eyebrow">Was im Preis enthalten ist</p>
<div class="pricing-example-list">
<?php foreach ($pricingExamples as $example): ?>
<article>
<strong><?= h($example['title']) ?></strong>
<span><?= h($example['text']) ?></span>
</article>
<?php endforeach; ?>
<article>
<strong>Technik</strong>
<span>Fotobox, Spiegelreflexkamera, Studioblitz und Softbox</span>
</article>
<article>
<strong>Bilder</strong>
<span>Alle Fotos digital inklusive</span>
</article>
<article>
<strong>Abwicklung</strong>
<span>Zahlung per Rechnung / Überweisung oder PayPal</span>
</article>
<article>
<strong>Anfrage</strong>
<span>Verbindlich wird Ihre Buchung erst nach unserer Bestätigung</span>
</article>
</div>
<p class="small-note">
Lieferung, Aufbau oder Vor-Ort-Betreuung werden im Anfrageprozess passend zum Anlass abgestimmt.
Hannover kostet <?= h(formatCurrency((int) $config['pricing']['delivery_rates']['hannover']['price_cents'])) ?>,
die Region Hannover <?= h(formatCurrency((int) $config['pricing']['delivery_rates']['region_hannover']['price_cents'])) ?> und
Hameln, Braunschweig, Hildesheim oder Celle <?= h(formatCurrency((int) $config['pricing']['delivery_rates']['extended_region']['price_cents'])) ?> pro Miettag.
</p>
</article>
</section>
@@ -39,7 +50,7 @@
<div class="section-heading">
<p class="eyebrow">Zahlung</p>
<h2>Rechnung, Überweisung oder PayPal</h2>
<p>Die gewünschte Zahlungsart wird bereits in der Anfrage hinterlegt und kann im Backend verwaltet werden.</p>
<p>Die gewünschte Zahlungsart geben Sie direkt in Ihrer Anfrage an. Auf Wunsch erhalten Sie eine Rechnung mit vollständigen Kundendaten.</p>
</div>
<div class="trust-grid">
<article class="trust-card">
@@ -48,7 +59,7 @@
</article>
<article class="trust-card">
<span>PayPal</span>
<strong>Als Zahlungsart auswählbar</strong>
<strong>Direkt in der Anfrage auswählbar</strong>
</article>
<article class="trust-card">
<span>Steuerhinweis</span>
@@ -56,4 +67,3 @@
</article>
</div>
</section>
+82 -13
View File
@@ -1,27 +1,91 @@
<section class="page-hero">
<p class="eyebrow">Verfügbarkeit</p>
<h1>Geblockte und bereits bestätigte Zeiträume im Blick.</h1>
<h1>Prüfen Sie, ob Ihr Wunschtermin noch frei ist.</h1>
<p>
Die Übersicht zeigt aktuelle Belegungen aus dem Verwaltungssystem.
Für Ihren Wunschtermin senden Sie am besten direkt eine Anfrage.
Hier sehen Sie bereits belegte Termine im Monatskalender.
Ist Ihr Wunschtermin noch frei, senden Sie uns direkt Ihre unverbindliche Anfrage.
</p>
</section>
<section class="section">
<div class="section-heading">
<p class="eyebrow">Buchungskalender</p>
<h2>Belegte Termine auf einen Blick</h2>
<p>Die Kalenderansicht zeigt angefragte, reservierte und bestätigte Zeiträume für die nächsten Monate.</p>
</div>
<div class="calendar-legend" aria-label="Legende zur Verfügbarkeit">
<span class="status-pill status-requested">Anfrage</span>
<span class="status-pill status-reserved">Reserviert</span>
<span class="status-pill status-confirmed">Bestätigt</span>
</div>
<div class="public-calendar-grid">
<?php foreach ($availabilityCalendarMonths as $month): ?>
<article class="calendar-month-card">
<div class="calendar-month-header">
<h2><?= h($month['label']) ?></h2>
<span><?= h((string) $month['entry_count']) ?> Termine</span>
</div>
<div class="calendar-weekdays" aria-hidden="true">
<span>Mo</span>
<span>Di</span>
<span>Mi</span>
<span>Do</span>
<span>Fr</span>
<span>Sa</span>
<span>So</span>
</div>
<div class="calendar-days">
<?php foreach ($month['days'] as $day): ?>
<?php if (!empty($day['is_padding'])): ?>
<div class="calendar-day calendar-day-empty" aria-hidden="true"></div>
<?php else: ?>
<div class="calendar-day<?= !empty($day['is_booked']) ? ' is-booked calendar-day-' . h((string) $day['status']) : '' ?><?= !empty($day['is_today']) ? ' is-today' : '' ?>">
<span class="calendar-day-number"><?= h((string) $day['day']) ?></span>
<?php if (!empty($day['is_booked'])): ?>
<span class="calendar-day-state"><?= h((string) $day['status_label']) ?></span>
<?php endif; ?>
</div>
<?php endif; ?>
<?php endforeach; ?>
</div>
<div class="calendar-entry-list">
<?php if ($month['entries'] === []): ?>
<article class="calendar-entry">
<strong>Derzeit kein belegter Zeitraum.</strong>
<span>Dieser Monat ist aktuell noch frei.</span>
</article>
<?php else: ?>
<?php foreach ($month['entries'] as $entry): ?>
<article class="calendar-entry">
<div>
<strong><?= h($entry['date_label']) ?></strong>
<span><?= h($entry['delivery_label']) ?> · <?= h($entry['day_count_label']) ?></span>
</div>
<span class="<?= h(statusPillClass((string) $entry['status'])) ?>"><?= h($entry['status_label']) ?></span>
</article>
<?php endforeach; ?>
<?php endif; ?>
</div>
</article>
<?php endforeach; ?>
</div>
</section>
<section class="section split-section">
<article class="content-card">
<h2>Aktuelle Belegung</h2>
<div class="availability-list">
<?php if ($bookings === []): ?>
<?php if ($availabilityBookings === []): ?>
<article class="availability-card">
<strong>Momentan gibt es keine festen Einträge.</strong>
<span>Ihre Anfrage kann direkt neu aufgenommen werden.</span>
</article>
<?php endif; ?>
<?php foreach ($bookings as $booking): ?>
<?php foreach ($availabilityBookings as $booking): ?>
<article class="availability-card">
<div>
<strong><?= h($booking['reference']) ?></strong>
<span><?= h(formatDate($booking['start_date'])) ?> bis <?= h(formatDate($booking['end_date'])) ?></span>
<strong><?= h(formatDate($booking['start_date'])) ?> bis <?= h(formatDate($booking['end_date'])) ?></strong>
<span><?= h((string) ($booking['delivery_zone_label'] ?: $booking['delivery_mode_label'])) ?> · <?= h((string) $booking['total_days']) ?> <?= $booking['total_days'] === 1 ? 'Miettag' : 'Miettage' ?></span>
</div>
<span class="<?= h(statusPillClass((string) $booking['status'])) ?>"><?= h($booking['status_label']) ?></span>
</article>
@@ -29,13 +93,18 @@
</div>
</article>
<article class="content-card emphasis-card">
<h2>Direkt zur Anfrage</h2>
<h2>Jetzt unverbindlich anfragen</h2>
<ul class="check-list">
<li>Zeitraum nach Übernachtungen wählen</li>
<li>Lieferart und Zahlungsart festlegen</li>
<li>Kundendaten für Rechnung und Rückfragen erfassen</li>
<li>Wunschtermin auswählen</li>
<li>Leistungsart, Liefergebiet und Zahlungsart festlegen</li>
<li>Kontaktdaten und Veranstaltungsort eintragen</li>
</ul>
<a class="button-primary button-block" href="<?= h(url('buchen')) ?>">Jetzt Termin anfragen</a>
<p class="small-note">
Selbstabholung: <?= h(formatCurrency((int) $config['pricing']['delivery_rates']['self_pickup']['price_cents'])) ?> ·
Hannover: <?= h(formatCurrency((int) $config['pricing']['delivery_rates']['hannover']['price_cents'])) ?> ·
Region Hannover: <?= h(formatCurrency((int) $config['pricing']['delivery_rates']['region_hannover']['price_cents'])) ?> ·
Hameln, Braunschweig, Hildesheim oder Celle: <?= h(formatCurrency((int) $config['pricing']['delivery_rates']['extended_region']['price_cents'])) ?>
</p>
<a class="button-primary button-block" href="<?= h(url('buchen')) ?>">Wunschtermin anfragen</a>
</article>
</section>
+30 -10
View File
@@ -1,5 +1,9 @@
<?php
$oldData = is_array($old ?? null) ? $old : [];
$priceRates = [];
foreach ($deliveryZoneOptions as $zoneKey => $zone) {
$priceRates[$zoneKey] = (int) $zone['price_cents'];
}
?>
<div class="booking-form-shell">
<?php if (!empty($flashSuccess)): ?>
@@ -10,7 +14,7 @@ $oldData = is_array($old ?? null) ? $old : [];
<div class="flash flash-error"><?= h((string) $flashError) ?></div>
<?php endif; ?>
<form method="post" action="<?= h(url('book')) ?>" class="booking-form" data-day-rate="<?= h((string) $dayRate) ?>">
<form method="post" action="<?= h(url('book')) ?>" class="booking-form" data-day-rate="<?= h((string) $dayRate) ?>" data-price-rates="<?= h((string) json_encode($priceRates, JSON_THROW_ON_ERROR)) ?>">
<?= csrfField() ?>
<input type="hidden" name="price_per_day_cents" value="<?= h((string) $dayRate) ?>">
@@ -35,15 +39,25 @@ $oldData = is_array($old ?? null) ? $old : [];
<div class="form-section">
<div class="form-section-header">
<span class="form-step">Schritt 2</span>
<h3>Leistung und Zahlung festlegen</h3>
<h3>Paket und Zahlung wählen</h3>
</div>
<div class="form-grid form-grid-two">
<label>
<span>Leistungsart</span>
<select name="delivery_mode">
<option value="self_pickup" <?= selected((string) ($oldData['delivery_mode'] ?? 'self_pickup'), 'self_pickup') ?>>Selbstabholung</option>
<option value="delivery_setup" <?= selected((string) ($oldData['delivery_mode'] ?? ''), 'delivery_setup') ?>>Lieferung und Aufbau</option>
<option value="on_site_support" <?= selected((string) ($oldData['delivery_mode'] ?? ''), 'on_site_support') ?>>Lieferung, Aufbau und Vor-Ort-Betreuung</option>
<select name="delivery_mode" data-delivery-mode>
<?php foreach ($deliveryModeOptions as $value => $label): ?>
<option value="<?= h($value) ?>" <?= selected((string) ($oldData['delivery_mode'] ?? 'self_pickup'), $value) ?>><?= h($label) ?></option>
<?php endforeach; ?>
</select>
</label>
<label>
<span>Liefergebiet</span>
<select name="delivery_zone" data-delivery-zone>
<?php foreach ($deliveryZoneOptions as $value => $zone): ?>
<option value="<?= h($value) ?>" <?= selected((string) ($oldData['delivery_zone'] ?? 'self_pickup'), $value) ?>>
<?= h($zone['label']) ?> · <?= h(formatCurrency((int) $zone['price_cents'])) ?>
</option>
<?php endforeach; ?>
</select>
</label>
<label>
@@ -54,12 +68,18 @@ $oldData = is_array($old ?? null) ? $old : [];
</select>
</label>
</div>
<p class="form-help">
Abholung kostet <?= h(formatCurrency((int) $deliveryZoneOptions['self_pickup']['price_cents'])) ?> pro Miettag.
Lieferung nach Hannover kostet <?= h(formatCurrency((int) $deliveryZoneOptions['hannover']['price_cents'])) ?>,
in die Region Hannover <?= h(formatCurrency((int) $deliveryZoneOptions['region_hannover']['price_cents'])) ?> und
nach Hameln, Braunschweig, Hildesheim oder Celle <?= h(formatCurrency((int) $deliveryZoneOptions['extended_region']['price_cents'])) ?> pro Miettag.
</p>
</div>
<div class="form-section">
<div class="form-section-header">
<span class="form-step">Schritt 3</span>
<h3>Kundendaten erfassen</h3>
<h3>Kontaktdaten und Veranstaltungsort</h3>
</div>
<div class="form-grid">
<label>
@@ -112,7 +132,7 @@ $oldData = is_array($old ?? null) ? $old : [];
</div>
<div class="summary-line">
<span>Preis pro Miettag</span>
<strong><?= h(formatCurrency((int) $dayRate)) ?></strong>
<strong data-summary-rate><?= h(formatCurrency((int) $dayRate)) ?></strong>
</div>
<div class="summary-line summary-line-total">
<span>Voraussichtlicher Gesamtpreis</span>
@@ -131,7 +151,7 @@ $oldData = is_array($old ?? null) ? $old : [];
</label>
</div>
<button type="submit" class="button-primary button-block">Buchungsanfrage senden</button>
<p class="form-note">Keine Sofortabbuchung. Ihr Auftrag wird erst nach persönlicher Bestätigung verbindlich.</p>
<button type="submit" class="button-primary button-block">Buchungsanfrage unverbindlich senden</button>
<p class="form-note">Sie erhalten schnell eine Rückmeldung zur Verfügbarkeit und zum weiteren Ablauf.</p>
</form>
</div>