390 lines
23 KiB
PHP
390 lines
23 KiB
PHP
<?php
|
||
|
||
use Livewire\Attributes\Layout;
|
||
use Livewire\Attributes\Title;
|
||
use Livewire\Volt\Component;
|
||
|
||
new #[Layout('components.layouts.app'), Title('Buchungen & Add-ons')] class extends Component
|
||
{
|
||
public function with(): array
|
||
{
|
||
return [
|
||
'creditSummary' => [
|
||
'total' => 17,
|
||
'bonus' => 12,
|
||
'paid' => 5,
|
||
'auto_refill' => __('ab 10 Credits empfohlen'),
|
||
'validity' => __('Bonus-Credits verfallen monatlich, gekaufte Credits bleiben 24 Monate gültig.'),
|
||
],
|
||
'currentPlan' => [
|
||
'name' => 'Starter',
|
||
'price' => '19 €/Mo.',
|
||
'press_releases' => '3 PMs/Monat',
|
||
'bonus_credits' => 12,
|
||
],
|
||
'creditPackages' => [
|
||
['name' => 'Test', 'credits' => 10, 'price' => '10 €', 'rate' => '1,00 €', 'saving' => null],
|
||
['name' => 'Standard', 'credits' => 50, 'price' => '45 €', 'rate' => '0,90 €', 'saving' => '10 %'],
|
||
['name' => 'Plus', 'credits' => 150, 'price' => '120 €', 'rate' => '0,80 €', 'saving' => '20 %'],
|
||
['name' => 'Pro', 'credits' => 500, 'price' => '375 €', 'rate' => '0,75 €', 'saving' => '25 %'],
|
||
['name' => 'Business', 'credits' => 1500, 'price' => '1.050 €', 'rate' => '0,70 €', 'saving' => '30 %'],
|
||
],
|
||
'serviceGroups' => [
|
||
[
|
||
'title' => __('Veröffentlichung'),
|
||
'description' => __('Basisleistungen rund um Veröffentlichung, Korrektur und Aktualisierung.'),
|
||
'services' => [
|
||
['name' => __('Standard-PM (Pay-as-you-go)'), 'credits' => '19', 'meta' => __('1 Veröffentlichung')],
|
||
['name' => __('PM-Korrektur'), 'credits' => '8', 'meta' => __('Pfad C')],
|
||
['name' => __('PM-Update'), 'credits' => '4', 'meta' => __('im ersten Jahr ggf. kostenlos')],
|
||
['name' => __('Depublizierung'), 'credits' => '19–25', 'meta' => __('abhängig vom Aufwand')],
|
||
],
|
||
],
|
||
[
|
||
'title' => __('Bilder'),
|
||
'description' => __('Stock- und KI-Bilder für mehr Sichtbarkeit in Listen und Detailseiten.'),
|
||
'services' => [
|
||
['name' => __('Free-Stock'), 'credits' => '0', 'meta' => __('Unsplash, Pexels')],
|
||
['name' => __('Premium-Stock'), 'credits' => '8', 'meta' => __('Adobe, Shutterstock')],
|
||
['name' => __('KI-Bild generieren'), 'credits' => '4', 'meta' => __('neues Motiv')],
|
||
['name' => __('KI-Bild Re-Generation'), 'credits' => '2', 'meta' => __('Variante erzeugen')],
|
||
],
|
||
],
|
||
[
|
||
'title' => __('KI-Textservices'),
|
||
'description' => __('Qualität verbessern, Score-Stufe erreichen und bessere Headlines testen.'),
|
||
'services' => [
|
||
['name' => __('Quality-Check'), 'credits' => '3', 'meta' => __('Stil und Pressestil')],
|
||
['name' => __('Lektorat'), 'credits' => '8', 'meta' => __('sprachliche Prüfung')],
|
||
['name' => __('Pressetext-Optimierung'), 'credits' => '15', 'meta' => __('Headlines und SEO')],
|
||
['name' => __('Headline-Booster'), 'credits' => '5', 'meta' => __('nur Headlines')],
|
||
['name' => __('PM aus Stichworten generieren'), 'credits' => '25', 'meta' => __('Entwurf aus Briefing')],
|
||
['name' => __('Übersetzung DE/EN'), 'credits' => '12', 'meta' => __('pro Sprachrichtung')],
|
||
],
|
||
],
|
||
[
|
||
'title' => __('Distribution'),
|
||
'description' => __('Zusätzliche Formate und externe Reichweite für passende Meldungen.'),
|
||
'services' => [
|
||
['name' => __('PDF-Export mit Branding'), 'credits' => '2', 'meta' => __('für Weitergabe')],
|
||
['name' => __('Social-Snippet-Generierung'), 'credits' => '3', 'meta' => __('Kurztexte')],
|
||
['name' => __('Verteiler-Versand klein'), 'credits' => '39', 'meta' => __('branchenspezifisch')],
|
||
['name' => __('Verteiler-Versand mittel'), 'credits' => '99', 'meta' => __('mehr Empfänger')],
|
||
['name' => __('Verteiler-Versand groß'), 'credits' => '199', 'meta' => __('branchenübergreifend')],
|
||
],
|
||
],
|
||
[
|
||
'title' => __('Account & Profil'),
|
||
'description' => __('Vertrauen, Wiedererkennung und zusätzliche Profilfunktionen.'),
|
||
'services' => [
|
||
['name' => __('Verifiziertes Firmenprofil'), 'credits' => '79', 'meta' => __('einmalig')],
|
||
['name' => __('Custom Subdomain'), 'credits' => '49', 'meta' => __('pro Jahr')],
|
||
['name' => __('Erweiterte Statistiken'), 'credits' => '15', 'meta' => __('pro Monat')],
|
||
],
|
||
],
|
||
],
|
||
'placements' => [
|
||
['name' => __('Highlight Kategorie'), 'credits' => '15', 'duration' => __('3 Tage'), 'tier' => __('Standard'), 'score' => '30+'],
|
||
['name' => __('Highlight Kategorie'), 'credits' => '30', 'duration' => __('7 Tage'), 'tier' => __('Standard'), 'score' => '30+'],
|
||
['name' => __('Startseite-Highlight'), 'credits' => '39', 'duration' => __('24 h'), 'tier' => __('Geprüft'), 'score' => '60+'],
|
||
['name' => __('Startseite-Highlight'), 'credits' => '89', 'duration' => __('3 Tage'), 'tier' => __('Geprüft'), 'score' => '60+'],
|
||
['name' => __('Top-Slot Startseite'), 'credits' => '119', 'duration' => __('24 h'), 'tier' => __('Hochwertig'), 'score' => '80+'],
|
||
['name' => __('Newsletter-Erwähnung'), 'credits' => '59', 'duration' => __('nächster Versand'), 'tier' => __('Geprüft'), 'score' => '60+'],
|
||
['name' => __('Social-Share'), 'credits' => '25', 'duration' => __('offizieller Kanal'), 'tier' => __('Geprüft'), 'score' => '60+'],
|
||
],
|
||
'activeBookings' => [],
|
||
'bookingHistory' => [],
|
||
];
|
||
}
|
||
}; ?>
|
||
|
||
<div class="space-y-8">
|
||
{{-- ============== PAGE HEADER ============== --}}
|
||
<header class="grid items-end gap-8" style="grid-template-columns:1fr auto;">
|
||
<div class="min-w-0">
|
||
<div class="flex items-center gap-3 mb-3 flex-wrap">
|
||
<span class="badge hub dot">{{ __('User Backend') }}</span>
|
||
<span class="eyebrow muted">{{ __('Mein Bereich · Finanzen') }}</span>
|
||
<span class="badge hub">{{ __('Konzeptstand Mai 2026') }}</span>
|
||
</div>
|
||
<h1 class="text-[30px] font-bold tracking-[-0.6px] leading-[1.15] m-0 text-[color:var(--color-ink)]">
|
||
{{ __('Buchungen & Add-ons') }}
|
||
</h1>
|
||
<p class="text-[13px] leading-[1.55] mt-2 m-0 max-w-[640px] text-[color:var(--color-ink-2)]">
|
||
{{ __('Der Marktplatz für Credit-Pakete, KI-Services, Platzierungen und Firmen-Add-ons. Die Preise folgen dem neuen Credit-Modell: 1 Credit entspricht dem Listenwert von 1 €.') }}
|
||
</p>
|
||
</div>
|
||
|
||
<div class="flex items-center gap-2 flex-shrink-0">
|
||
<flux:button size="sm" variant="ghost" icon="document-text" href="{{ route('me.invoices.index') }}" wire:navigate>
|
||
{{ __('Rechnungen') }}
|
||
</flux:button>
|
||
<flux:button size="sm" variant="primary" icon="plus" disabled>
|
||
{{ __('Credits kaufen') }}
|
||
</flux:button>
|
||
</div>
|
||
</header>
|
||
|
||
{{-- ============== CREDIT-ÜBERSICHT ============== --}}
|
||
<section class="grid gap-4 lg:grid-cols-[1.2fr_0.8fr]">
|
||
<article class="panel">
|
||
<div class="panel-head">
|
||
<span class="section-eyebrow">{{ __('Credit-Stand') }}</span>
|
||
<span class="badge ok dot">{{ __('Auto-Refill vorbereitet') }}</span>
|
||
</div>
|
||
<div class="p-5 grid gap-5 md:grid-cols-[0.8fr_1.2fr]">
|
||
<div>
|
||
<div class="text-[42px] font-bold tracking-[-1.2px] leading-none text-[color:var(--color-ink)]">
|
||
{{ $creditSummary['total'] }}
|
||
</div>
|
||
<p class="text-[12.5px] text-[color:var(--color-ink-3)] mt-2 mb-0">
|
||
{{ __('verfügbare Credits') }}
|
||
</p>
|
||
</div>
|
||
|
||
<div class="grid gap-3 sm:grid-cols-2">
|
||
<div class="rounded-[6px] border border-[color:var(--color-bg-rule)] p-4 bg-[color:var(--color-bg-subtle)]">
|
||
<div class="text-[12px] text-[color:var(--color-ink-3)]">{{ __('Bonus-Credits') }}</div>
|
||
<div class="text-[22px] font-semibold text-[color:var(--color-ink)]">{{ $creditSummary['bonus'] }}</div>
|
||
<div class="text-[11.5px] text-[color:var(--color-ink-3)]">{{ __('monatlich verfallend') }}</div>
|
||
</div>
|
||
<div class="rounded-[6px] border border-[color:var(--color-bg-rule)] p-4 bg-[color:var(--color-bg-subtle)]">
|
||
<div class="text-[12px] text-[color:var(--color-ink-3)]">{{ __('Gekaufte Credits') }}</div>
|
||
<div class="text-[22px] font-semibold text-[color:var(--color-ink)]">{{ $creditSummary['paid'] }}</div>
|
||
<div class="text-[11.5px] text-[color:var(--color-ink-3)]">{{ __('24 Monate gültig') }}</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="md:col-span-2 px-4 py-3 rounded-[5px] border text-[12.5px] flex items-start gap-3
|
||
bg-[color:var(--color-hub-soft)] border-[color:var(--color-hub-soft-2)] text-[color:var(--color-ink-2)]">
|
||
<flux:icon.information-circle class="size-[16px] flex-shrink-0 mt-0.5 text-[color:var(--color-hub)]" />
|
||
<div class="flex-1">
|
||
{{ $creditSummary['validity'] }}
|
||
{{ __('Für spätere Checkouts ist Auto-Refill :threshold vorgesehen.', ['threshold' => $creditSummary['auto_refill']]) }}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</article>
|
||
|
||
<article class="panel">
|
||
<div class="panel-head">
|
||
<span class="section-eyebrow">{{ __('Aktueller Tarif') }}</span>
|
||
<span class="badge hub">{{ $currentPlan['name'] }}</span>
|
||
</div>
|
||
<div class="p-5 space-y-4">
|
||
<div>
|
||
<div class="text-[28px] font-bold tracking-[-0.7px] text-[color:var(--color-ink)]">
|
||
{{ $currentPlan['price'] }}
|
||
</div>
|
||
<p class="text-[12.5px] text-[color:var(--color-ink-3)] mt-1 mb-0">
|
||
{{ __('inkl. :credits Bonus-Credits und :pms', [
|
||
'credits' => $currentPlan['bonus_credits'],
|
||
'pms' => $currentPlan['press_releases'],
|
||
]) }}
|
||
</p>
|
||
</div>
|
||
<div class="rounded-[6px] border border-[color:var(--color-bg-rule)] p-4">
|
||
<div class="text-[12px] font-semibold text-[color:var(--color-ink)] mb-1">
|
||
{{ __('Nächster sinnvoller Schritt') }}
|
||
</div>
|
||
<p class="text-[12.5px] text-[color:var(--color-ink-3)] m-0">
|
||
{{ __('Bei mehreren PMs mit KI-Optimierung oder Platzierungen ergänzt das Standard-Paket die monatlichen Bonus-Credits am saubersten.') }}
|
||
</p>
|
||
</div>
|
||
</div>
|
||
</article>
|
||
</section>
|
||
|
||
{{-- ============== CREDIT-PAKETE ============== --}}
|
||
<article class="panel overflow-hidden">
|
||
<div class="panel-head">
|
||
<span class="section-eyebrow">{{ __('Credit-Pakete') }}</span>
|
||
<span class="text-[11.5px] text-[color:var(--color-ink-3)]">{{ __('Volumenrabatt nach Paketgröße') }}</span>
|
||
</div>
|
||
<flux:table>
|
||
<flux:table.columns>
|
||
<flux:table.column>{{ __('Paket') }}</flux:table.column>
|
||
<flux:table.column>{{ __('Credits') }}</flux:table.column>
|
||
<flux:table.column>{{ __('Preis') }}</flux:table.column>
|
||
<flux:table.column>{{ __('Effektiv/Credit') }}</flux:table.column>
|
||
<flux:table.column>{{ __('Ersparnis') }}</flux:table.column>
|
||
<flux:table.column>{{ __('Aktion') }}</flux:table.column>
|
||
</flux:table.columns>
|
||
|
||
@foreach ($creditPackages as $package)
|
||
<flux:table.row wire:key="credit-package-{{ $package['name'] }}">
|
||
<flux:table.cell>
|
||
<span class="text-[13px] font-semibold text-[color:var(--color-ink)]">{{ $package['name'] }}</span>
|
||
</flux:table.cell>
|
||
<flux:table.cell>{{ number_format($package['credits'], 0, ',', '.') }}</flux:table.cell>
|
||
<flux:table.cell>
|
||
<span class="font-semibold text-[color:var(--color-ink)]">{{ $package['price'] }}</span>
|
||
</flux:table.cell>
|
||
<flux:table.cell>{{ $package['rate'] }}</flux:table.cell>
|
||
<flux:table.cell>
|
||
@if ($package['saving'])
|
||
<span class="badge ok">{{ $package['saving'] }}</span>
|
||
@else
|
||
<span class="text-[12px] text-[color:var(--color-ink-3)]">–</span>
|
||
@endif
|
||
</flux:table.cell>
|
||
<flux:table.cell>
|
||
<flux:button size="sm" variant="ghost" disabled>
|
||
{{ __('Kaufen') }}
|
||
</flux:button>
|
||
</flux:table.cell>
|
||
</flux:table.row>
|
||
@endforeach
|
||
</flux:table>
|
||
</article>
|
||
|
||
{{-- ============== PLATZIERUNGEN ============== --}}
|
||
<section class="space-y-4">
|
||
<div>
|
||
<span class="section-eyebrow">{{ __('Boost & Platzierungen') }}</span>
|
||
<h2 class="text-[22px] font-bold tracking-[-0.4px] mt-1 mb-1 text-[color:var(--color-ink)]">
|
||
{{ __('Sichtbarkeit buchen, wenn die Score-Stufe passt') }}
|
||
</h2>
|
||
<p class="text-[12.5px] text-[color:var(--color-ink-3)] max-w-[760px] m-0">
|
||
{{ __('Platzierungen bleiben an Qualitätsstufen gekoppelt: Standard reicht für Kategorie-Highlights, Geprüft für Startseite/Newsletter/Social und Hochwertig für den Top-Slot.') }}
|
||
</p>
|
||
</div>
|
||
|
||
<div class="grid gap-4 md:grid-cols-2 xl:grid-cols-3">
|
||
@foreach ($placements as $placement)
|
||
<article class="panel">
|
||
<div class="p-5 space-y-4">
|
||
<div class="flex items-start justify-between gap-4">
|
||
<div class="flex items-start gap-3">
|
||
<div class="w-10 h-10 rounded-[6px] flex items-center justify-center bg-[color:var(--color-hub-soft)] text-[color:var(--color-hub)]">
|
||
<flux:icon.megaphone class="size-5" />
|
||
</div>
|
||
<div>
|
||
<h3 class="text-[14px] font-semibold text-[color:var(--color-ink)] m-0">
|
||
{{ $placement['name'] }}
|
||
</h3>
|
||
<p class="text-[12px] text-[color:var(--color-ink-3)] mt-1 mb-0">
|
||
{{ $placement['duration'] }}
|
||
</p>
|
||
</div>
|
||
</div>
|
||
<div class="text-right">
|
||
<div class="text-[22px] font-bold text-[color:var(--color-ink)]">{{ $placement['credits'] }}</div>
|
||
<div class="text-[11px] text-[color:var(--color-ink-3)]">{{ __('Credits') }}</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="flex items-center justify-between gap-3 rounded-[6px] border border-[color:var(--color-bg-rule)] p-3">
|
||
<div>
|
||
<div class="text-[11.5px] text-[color:var(--color-ink-3)]">{{ __('Mindeststufe') }}</div>
|
||
<div class="text-[13px] font-semibold text-[color:var(--color-ink)]">{{ $placement['tier'] }}</div>
|
||
</div>
|
||
<flux:tooltip content="{{ __('Interner Score-Schwellenwert: :score', ['score' => $placement['score']]) }}">
|
||
<span class="badge hub">{{ __('Score :score', ['score' => $placement['score']]) }}</span>
|
||
</flux:tooltip>
|
||
</div>
|
||
|
||
<flux:button size="sm" variant="primary" class="w-full" disabled>
|
||
{{ __('Buchung vorbereiten') }}
|
||
</flux:button>
|
||
</div>
|
||
</article>
|
||
@endforeach
|
||
</div>
|
||
</section>
|
||
|
||
{{-- ============== SERVICE-MARKTPLATZ ============== --}}
|
||
<section class="space-y-4">
|
||
<div>
|
||
<span class="section-eyebrow">{{ __('Add-on-Marktplatz') }}</span>
|
||
<h2 class="text-[22px] font-bold tracking-[-0.4px] mt-1 mb-1 text-[color:var(--color-ink)]">
|
||
{{ __('Buchbare Services nach Kategorie') }}
|
||
</h2>
|
||
</div>
|
||
|
||
<div class="grid gap-4 xl:grid-cols-2">
|
||
@foreach ($serviceGroups as $group)
|
||
<article class="panel">
|
||
<div class="panel-head">
|
||
<div class="flex items-center gap-2">
|
||
<flux:icon.sparkles class="size-4 text-[color:var(--color-hub)]" />
|
||
<span class="section-eyebrow">{{ $group['title'] }}</span>
|
||
</div>
|
||
</div>
|
||
<div class="p-5">
|
||
<p class="text-[12.5px] text-[color:var(--color-ink-3)] mt-0 mb-4">
|
||
{{ $group['description'] }}
|
||
</p>
|
||
<div class="divide-y divide-[color:var(--color-bg-rule)]">
|
||
@foreach ($group['services'] as $service)
|
||
<div class="py-3 first:pt-0 last:pb-0 flex items-center justify-between gap-4">
|
||
<div class="min-w-0">
|
||
<div class="text-[13px] font-semibold text-[color:var(--color-ink)]">{{ $service['name'] }}</div>
|
||
<div class="text-[11.5px] text-[color:var(--color-ink-3)]">{{ $service['meta'] }}</div>
|
||
</div>
|
||
<div class="text-right flex-shrink-0">
|
||
<div class="text-[15px] font-bold text-[color:var(--color-ink)]">{{ $service['credits'] }}</div>
|
||
<div class="text-[10.5px] uppercase tracking-[0.08em] text-[color:var(--color-ink-3)]">{{ __('Credits') }}</div>
|
||
</div>
|
||
</div>
|
||
@endforeach
|
||
</div>
|
||
</div>
|
||
</article>
|
||
@endforeach
|
||
</div>
|
||
</section>
|
||
|
||
{{-- ============== AKTIVE BUCHUNGEN / VERLAUF ============== --}}
|
||
<section class="grid gap-4 lg:grid-cols-2">
|
||
<article class="panel">
|
||
<div class="panel-head">
|
||
<span class="section-eyebrow">{{ __('Aktive Buchungen') }}</span>
|
||
<span class="text-[11.5px] text-[color:var(--color-ink-3)]">{{ __('läuft aktuell') }}</span>
|
||
</div>
|
||
<div class="p-5">
|
||
@forelse ($activeBookings as $booking)
|
||
<div>{{ $booking }}</div>
|
||
@empty
|
||
<div class="flex flex-col items-center justify-center px-4 py-10 text-center">
|
||
<div class="w-14 h-14 rounded-[6px] flex items-center justify-center mb-3
|
||
bg-[color:var(--color-hub-soft)] border border-[color:var(--color-hub-soft-2)] text-[color:var(--color-hub)]">
|
||
<flux:icon.calendar-days class="size-6" />
|
||
</div>
|
||
<div class="text-[14px] font-semibold text-[color:var(--color-ink)] mb-1">
|
||
{{ __('Noch keine aktiven Buchungen') }}
|
||
</div>
|
||
<p class="text-[12px] text-[color:var(--color-ink-3)] max-w-md m-0">
|
||
{{ __('Gebuchte Highlights, Newsletter-Platzierungen oder Add-ons erscheinen hier mit Laufzeit und zugehöriger Firma.') }}
|
||
</p>
|
||
</div>
|
||
@endforelse
|
||
</div>
|
||
</article>
|
||
|
||
<article class="panel">
|
||
<div class="panel-head">
|
||
<span class="section-eyebrow">{{ __('Verlauf') }}</span>
|
||
<span class="text-[11.5px] text-[color:var(--color-ink-3)]">{{ __('verbrauchte Credits') }}</span>
|
||
</div>
|
||
<div class="p-5">
|
||
@forelse ($bookingHistory as $booking)
|
||
<div>{{ $booking }}</div>
|
||
@empty
|
||
<div class="flex flex-col items-center justify-center px-4 py-10 text-center">
|
||
<div class="w-14 h-14 rounded-[6px] flex items-center justify-center mb-3
|
||
bg-[color:var(--color-bg-subtle)] border border-[color:var(--color-bg-rule)] text-[color:var(--color-ink-3)]">
|
||
<flux:icon.clock class="size-6" />
|
||
</div>
|
||
<div class="text-[14px] font-semibold text-[color:var(--color-ink)] mb-1">
|
||
{{ __('Noch kein Buchungsverlauf') }}
|
||
</div>
|
||
<p class="text-[12px] text-[color:var(--color-ink-3)] max-w-md m-0">
|
||
{{ __('Nach dem ersten Checkout werden Verbrauch, Rechnungsbezug und betroffene Pressemitteilung hier nachvollziehbar.') }}
|
||
</p>
|
||
</div>
|
||
@endforelse
|
||
</div>
|
||
</article>
|
||
</section>
|
||
</div>
|