Buchungs-Modal: Dark-Mode-lesbare Preistabelle + aufgeraeumtes Layout

Preistabelle und Trenner nutzen Alpha-Farben (black/white) statt
Theme-Tokens, die im Dark Mode gegen den Modal-Hintergrund untergingen;
--color-bg-subtle war zudem nirgends definiert (Gesamt-Zeile ohne Bg).
Unternehmer-Bestaetigung als abgesetzter Consent-Block, Fusszeile mit
Trennlinie, Subtitle in den Kopf integriert. QA: A5 abgehakt.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Kevin Adametz 2026-07-07 11:13:55 +00:00
parent e7d5d58ff3
commit fa4bc060a0
2 changed files with 43 additions and 39 deletions

View file

@ -16,7 +16,7 @@ Staging-Rehearsal (R6.3) mit echtem Datenbestand wiederholen.
- [x] **Customer-Login via Magic-Link** — Automatisiert: `Auth/MagicLinkLoginTest` (TTL 15 Min., Einmalverwendung). Manuell: Link anfordern, Mail-Optik (neues CI-Layout) prüfen, Login klappt, zweiter Klick auf denselben Link wird abgewiesen. **Getestet 07.07.**
- [x] **Customer-Login via Passwort + Google** — Automatisiert: `Auth/AuthenticationTest`, `Auth/GoogleLoginTest`. Manuell: Passwort-Login **getestet 07.07.**; Google-Round-Trip geht erst live mit echter Domain (WS-7-Checkliste).
- [x] **Passwort-Reset-Flow** (kritisch fürs Go-Live-Mailing) — Automatisiert: `Auth/PasswordResetTest`, Mail-CI: `Mail/EmailBrandingTest`. Manuell: Reset anfordern → Mail → neues Passwort → Login. **Getestet 07.07.**
- [ ] **Registrierung + E-Mail-Verifizierung** — Automatisiert: `Auth/RegistrationTest`, `Auth/EmailVerificationTest`. Manuell: einmal komplett durchlaufen inkl. Freischaltung.
- [x] **Registrierung + E-Mail-Verifizierung** — Automatisiert: `Auth/RegistrationTest`, `Auth/EmailVerificationTest`. Manuell: einmal komplett durchlaufen inkl. Freischaltung. **Getestet 07.07.** (inkl. Verifizierungsmails).
## B. Admin-Backend

View file

@ -928,52 +928,56 @@ new #[Layout('components.layouts.app'), Title('Buchungen & Add-ons')] class exte
{{-- ============== BUCHUNGS-BESTÄTIGUNG (Modal) ============== --}}
<flux:modal name="confirm-booking" class="max-w-lg">
@if ($booking)
<div class="space-y-6">
<div class="space-y-5">
<div>
<flux:heading size="lg">{{ __('Buchung bestätigen') }}</flux:heading>
<flux:subheading>{{ $booking['title'] }}</flux:subheading>
</div>
@if ($booking['subtitle'])
<p class="text-[13px] text-[color:var(--color-ink-2)] m-0">{{ $booking['subtitle'] }}</p>
@endif
<div class="rounded-[6px] border border-[color:var(--color-bg-rule)] divide-y divide-[color:var(--color-bg-rule)] text-[13px]">
<div class="flex items-center justify-between px-4 py-2.5">
<span class="text-[color:var(--color-ink-3)]">{{ __('Netto') }}</span>
<span class="font-medium text-[color:var(--color-ink)]">{{ $booking['net'] }}</span>
</div>
@if ($booking['reverse_charge'])
<div class="flex items-center justify-between px-4 py-2.5">
<span class="text-[color:var(--color-ink-3)]">{{ __('USt.') }}</span>
<span class="text-[color:var(--color-ink-2)]">{{ __('Reverse Charge (0 %)') }}</span>
</div>
@elseif ($booking['tax_exempt'])
<div class="flex items-center justify-between px-4 py-2.5">
<span class="text-[color:var(--color-ink-3)]">{{ __('USt.') }}</span>
<span class="text-[color:var(--color-ink-2)]">{{ __('steuerbefreit') }}</span>
</div>
@else
<div class="flex items-center justify-between px-4 py-2.5">
<span class="text-[color:var(--color-ink-3)]">{{ __('zzgl. :p % USt.', ['p' => $booking['vat_percent']]) }}</span>
<span class="font-medium text-[color:var(--color-ink)]">{{ $booking['vat'] }}</span>
</div>
@if ($booking['subtitle'])
<p class="text-[12.5px] text-[color:var(--color-ink-3)] mt-2 m-0">{{ $booking['subtitle'] }}</p>
@endif
<div class="flex items-center justify-between px-4 py-2.5 bg-[color:var(--color-bg-subtle)]">
<span class="font-semibold text-[color:var(--color-ink)]">{{ __('Gesamt') }}</span>
<span class="font-bold text-[color:var(--color-ink)]">{{ $booking['gross'] }}</span>
</div>
</div>
<p class="text-[11.5px] text-[color:var(--color-ink-3)] m-0">
{{ __('Die endgültige Steuer berechnet Stripe anhand Ihrer Rechnungsadresse. Die Abrechnung erfolgt sicher über Stripe.') }}
</p>
{{-- Preistabelle: Rahmen/Zeilen mit Alpha-Farben, damit sie auf
jeder Modal-Fläche lesbar bleiben (Theme-Tokens wie
--color-bg-rule gehen im Dark Mode gegen den Modal-Bg unter). --}}
<div class="space-y-2">
<div class="rounded-[6px] border border-black/10 dark:border-white/15 divide-y divide-black/10 dark:divide-white/15 text-[13px] overflow-hidden">
<div class="flex items-center justify-between px-4 py-2.5">
<span class="text-[color:var(--color-ink-3)]">{{ __('Netto') }}</span>
<span class="font-medium text-[color:var(--color-ink)] tabular-nums">{{ $booking['net'] }}</span>
</div>
@if ($booking['reverse_charge'])
<div class="flex items-center justify-between px-4 py-2.5">
<span class="text-[color:var(--color-ink-3)]">{{ __('USt.') }}</span>
<span class="text-[color:var(--color-ink-2)]">{{ __('Reverse Charge (0 %)') }}</span>
</div>
@elseif ($booking['tax_exempt'])
<div class="flex items-center justify-between px-4 py-2.5">
<span class="text-[color:var(--color-ink-3)]">{{ __('USt.') }}</span>
<span class="text-[color:var(--color-ink-2)]">{{ __('steuerbefreit') }}</span>
</div>
@else
<div class="flex items-center justify-between px-4 py-2.5">
<span class="text-[color:var(--color-ink-3)]">{{ __('zzgl. :p % USt.', ['p' => $booking['vat_percent']]) }}</span>
<span class="font-medium text-[color:var(--color-ink)] tabular-nums">{{ $booking['vat'] }}</span>
</div>
@endif
<div class="flex items-center justify-between px-4 py-2.5 bg-black/[0.04] dark:bg-white/[0.06]">
<span class="font-semibold text-[color:var(--color-ink)]">{{ __('Gesamt') }}</span>
<span class="font-bold text-[color:var(--color-ink)] tabular-nums">{{ $booking['gross'] }}</span>
</div>
</div>
<p class="text-[11.5px] text-[color:var(--color-ink-3)] m-0">
{{ __('Die endgültige Steuer berechnet Stripe anhand Ihrer Rechnungsadresse. Die Abrechnung erfolgt sicher über Stripe.') }}
</p>
</div>
@if ($booking['needs_address'])
<div class="px-4 py-3 rounded-[5px] border text-[13px] bg-[color:var(--color-warn-soft)] border-[color:var(--color-warn)]/30 text-[color:var(--color-ink-2)]">
{{ __('Bitte hinterlegen Sie zuerst eine vollständige Rechnungsadresse — sie ist Voraussetzung für jede Buchung.') }}
</div>
<div class="flex justify-end gap-2">
<div class="flex justify-end gap-2 pt-4 border-t border-black/10 dark:border-white/15">
<flux:modal.close>
<flux:button variant="filled">{{ __('Abbrechen') }}</flux:button>
</flux:modal.close>
@ -986,13 +990,13 @@ new #[Layout('components.layouts.app'), Title('Buchungen & Add-ons')] class exte
Bestätigung wird serverseitig protokolliert (Timestamp,
IP, AGB-Version); ohne sie kein Checkout-Link — und der
Checkout-Controller verlangt sie zusätzlich. --}}
<div class="space-y-2">
<div class="rounded-[6px] border border-black/10 dark:border-white/15 bg-black/[0.02] dark:bg-white/[0.03] p-4 space-y-2.5">
<flux:switch
align="left"
wire:model.live="entrepreneurConfirmed"
:label="__('Ich bestelle in Ausübung meiner gewerblichen oder selbständigen beruflichen Tätigkeit (§ 14 BGB) und akzeptiere die AGB.')"
/>
<p class="text-[11.5px] text-[color:var(--color-ink-3)] m-0 ps-0">
<p class="text-[11.5px] text-[color:var(--color-ink-3)] m-0">
{{ __('Das Angebot richtet sich ausschließlich an Unternehmen, Selbstständige und Agenturen.') }}
<a href="{{ route('agb', ['edition' => 'de']) }}" target="_blank" rel="noopener" class="underline underline-offset-2 hover:text-[color:var(--color-ink)]">
{{ __('AGB (Version :version)', ['version' => \App\Models\LegalDocument::currentAgbVersion()]) }}
@ -1000,7 +1004,7 @@ new #[Layout('components.layouts.app'), Title('Buchungen & Add-ons')] class exte
</p>
</div>
<div class="flex justify-end gap-2">
<div class="flex justify-end gap-2 pt-4 border-t border-black/10 dark:border-white/15">
<flux:modal.close>
<flux:button variant="filled">{{ __('Abbrechen') }}</flux:button>
</flux:modal.close>