presseportale/resources/views/components/customer/status-menu.blade.php
Kevin Adametz 4ab746077c Status-Widget: immer verfuegbarer Buchungsueberblick in der Topbar
Ein Header-Dropdown oben rechts (Desktop) bzw. im Mobile-Header zeigt
fuer alle Kunden-Panel-User den aktuellen Status: aktuelle Buchung/Tarif,
verbleibendes PM-Kontingent und Credit-Guthaben. Ohne aktive Buchung
weist es direkt auf die noetige Buchung hin und verlinkt die Buchungsseite.

CustomerStatusSummary buendelt die Anzeige-Werte ueber die oeffentliche
User-API (Gating bleibt Single Source of Truth im Modell); die anonyme
Blade-Komponente x-customer.status-menu rendert das Dropdown.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-18 13:03:25 +00:00

84 lines
4.7 KiB
PHP

@props(['user' => null])
@php
$user ??= auth()->user();
$status = $user ? \App\Services\Customer\CustomerStatusSummary::fromUser($user) : null;
@endphp
@if ($status)
<flux:dropdown position="bottom" align="end">
{{-- Trigger: kompaktes Status-Badge in der Topbar --}}
<button
type="button"
class="inline-flex items-center gap-2 rounded-full border border-[color:var(--color-bg-rule)] bg-[color:var(--color-bg-card)] px-3 py-1.5 text-[12px] font-semibold text-[color:var(--color-ink)] transition-colors hover:border-[color:var(--color-hub)] hover:text-[color:var(--color-hub)]"
aria-label="{{ __('Mein Status & Guthaben') }}"
>
<flux:icon name="wallet" variant="micro" class="size-3.5 text-[color:var(--color-hub)]" />
<span class="whitespace-nowrap font-mono">{{ $status->badgeLabel() }}</span>
<flux:icon name="chevron-down" variant="micro" class="size-3 text-[color:var(--color-ink-3)]" />
</button>
<flux:menu class="w-[268px]">
{{-- Aktuelle Buchung --}}
<div class="px-3 pt-2 pb-1">
<div class="mb-1 text-[10px] font-semibold uppercase tracking-[0.16em] text-[color:var(--color-ink-3)]">
{{ __('Aktuelle Buchung') }}
</div>
<div class="flex items-center justify-between gap-2">
<span class="text-[13.5px] font-semibold text-[color:var(--color-ink)]">
{{ $status->bookingLabel() }}
@if ($status->billingIntervalLabel())
<span class="font-normal text-[color:var(--color-ink-3)]">· {{ $status->billingIntervalLabel() }}</span>
@endif
</span>
@if ($status->hasActiveBooking)
<span class="inline-flex items-center gap-1 text-[11px] font-semibold text-[color:var(--color-ok)]">
<span class="size-1.5 rounded-full bg-[color:var(--color-ok)]"></span>{{ __('aktiv') }}
</span>
@else
<span class="text-[11px] font-semibold text-[color:var(--color-warn)]">{{ __('keine') }}</span>
@endif
</div>
</div>
<flux:menu.separator />
{{-- Kennzahlen: PM-Kontingent & Credits --}}
<div class="grid grid-cols-2 gap-px bg-[color:var(--color-bg-rule)] mx-3 my-1 rounded-[5px] overflow-hidden border border-[color:var(--color-bg-rule)]">
<div class="bg-[color:var(--color-bg-card)] p-2.5">
<div class="text-[10px] font-semibold uppercase tracking-[0.14em] text-[color:var(--color-ink-3)]">
{{ __('PMs frei') }}
</div>
<div class="mt-0.5 text-[18px] font-bold leading-none text-[color:var(--color-ink)]">
@if ($status->unlimitedQuota)
∞
@else
{{ $status->quotaRemaining }}<span class="text-[12px] font-medium text-[color:var(--color-ink-3)]"> / {{ $status->quotaTotal }}</span>
@endif
</div>
</div>
<div class="bg-[color:var(--color-bg-card)] p-2.5">
<div class="text-[10px] font-semibold uppercase tracking-[0.14em] text-[color:var(--color-ink-3)]">
{{ __('Guthaben') }}
</div>
<div class="mt-0.5 text-[18px] font-bold leading-none text-[color:var(--color-ink)]">
{{ $status->creditBalance }}<span class="text-[12px] font-medium text-[color:var(--color-ink-3)]"> Cr</span>
</div>
</div>
</div>
@unless ($status->hasActiveBooking)
<div class="mx-3 my-1.5 flex items-start gap-1.5 rounded-[4px] border border-[color:color-mix(in_srgb,var(--color-warn)_45%,transparent)] bg-[color:var(--color-warn-soft,transparent)] px-2.5 py-2 text-[11px] leading-[1.45] text-[color:var(--color-ink-2)]">
<flux:icon name="exclamation-triangle" variant="micro" class="mt-0.5 size-3.5 flex-shrink-0 text-[color:var(--color-warn)]" />
<span>{{ __('Zum Veröffentlichen brauchst du eine Buchung.') }}</span>
</div>
@endunless
<flux:menu.separator />
<flux:menu.item :href="route('me.bookings.index')" icon="shopping-bag" wire:navigate>
{{ __('Buchungen & Add-ons') }}
</flux:menu.item>
</flux:menu>
</flux:dropdown>
@endif