@php use App\Support\Bytes; use Illuminate\Support\Number; $locale = app()->getLocale(); $money = fn (int $cents, string $currency) => Number::currency($cents / 100, in: $currency, locale: $locale); @endphp
{{-- Page head. The same pill the public site uses to label a section, so a customer meets one vocabulary on both sides of the login. --}}

{{ __('dashboard.sheet', ['when' => $asOf->local()->locale($locale)->isoFormat('LL, LT')]) }}

{{ $instance !== null ? __('dashboard.title_running') : ($endedAt !== null ? __('dashboard.title_ended') : __('dashboard.title_pending')) }}

@if ($instance !== null) $instance->status === 'active', 'border-warning-border bg-warning-bg text-warning' => $instance->status !== 'active', ])> {{ __('dashboard.instance_status.'.$instance->status) }} @if ($domain) {{ __('dashboard.cloud.open') }} @endif @endif
{{-- Live provisioning progress (only while a run is in flight) --}} @if ($credentials) {{-- The initial admin password, shown here instead of mailed. Gone the moment the customer confirms they noted it — acknowledgeCredentials() deletes it outright, not just this card. --}}

{{ __('dashboard.credentials.title') }}

{{ __('dashboard.credentials.body') }}

{{ __('dashboard.credentials.address') }}
{{ $credentials['url'] }}
{{ __('dashboard.credentials.user') }}
{{ $credentials['user'] }}
{{ __('dashboard.credentials.password') }}
{{ $credentials['password'] }}
{{ __('dashboard.credentials.acknowledge') }}

{{ __('dashboard.credentials.copied') }}

@endif @if ($ending) {{-- Die Frist, die den Kunden betrifft: wie lange SEIN Zugang noch steht — nicht, wann irgendetwas geloescht wird. Dieselbe Warnfarbe und Bauform wie der Zugangsdaten-Kasten darueber, an derselben Stelle im Fluss: eine Sprache fuer Dringlichkeit auf dieser Seite, nicht zwei. --}}

{{ __('dashboard.ending.title') }}

{{ __('dashboard.ending.until', ['date' => $ending['ends_at']->local()->locale($locale)->isoFormat('LL')]) }} {{ $ending['show_days'] ? trans_choice('dashboard.ending.remaining_days', $ending['days']) : trans_choice('dashboard.ending.remaining_hours', $ending['hours']) }}

{{ __('dashboard.ending.what_then') }}

{{-- Aufgabe 4: dieselbe Frage wie beim Kuendigen, hier mit der Moeglichkeit, sie sich anders zu ueberlegen — bis zum Laufzeitende (setExportWish() prueft das selbst nach). Bewusst DIESELBEN zwei Auswahlfelder wie im Kuendigungsdialog (livewire/confirm-cancel-package), nicht der Schalter, der hier stand. `export_wish` fuehrt drei Zustaende, ein Schalter kennt zwei — und `(bool) null` ist `false`, also stand unter dem Streifen „Kein Export gewuenscht" als Antwort eines Menschen, den niemand gefragt hatte. Ein unbeantworteter Zustand zeigt hier schlicht keine Auswahl an und fragt darueber im Klartext nach. --}}

{{ __('dashboard.ending.export_label') }}

{{ $instance->export_wish === null ? __('dashboard.ending.export_open') : __('dashboard.ending.export_hint') }}

@endif @if ($instance === null && $endedAt !== null) {{-- Die abgelaufene Laufzeit — der dritte Fall, den es hier bisher nicht gab. Ein Kunde, dessen Instanz auf `ended` steht, holt Dashboard::render() nicht mehr; er fiel damit in den Zweig darunter und las „Ihre Cloud wird eingerichtet." samt „Paket buchen". Fuer jemanden, dem eben die Adresse eingezogen wurde (EndInstanceService), ist das die falscheste Zeile der Seite. Kein Kunde ohne Paket, sondern einer, dessen Paket vorbei ist — mit dem Datum, an dem es endete. --}}

{{ __('dashboard.ended.label') }}

{{ __('dashboard.ended.body', ['date' => $endedAt->local()->locale($locale)->isoFormat('LL')]) }}

{{ __('dashboard.nav.support') }} {{ __('dashboard.ended.order_again') }}
@elseif ($instance === null) {{-- Said plainly rather than papered over with an empty record: a page of dashes reads as broken, and "we are still setting it up" and "you have not ordered yet" are different things. --}}

{{ __('dashboard.no_instance_label') }}

{{ __('dashboard.no_instance_body') }}

{{-- Booking first, because "you have not ordered yet" now has an answer on this site: pick a package, pay, and the cloud builds itself. Before self-service the only honest next step was to write to somebody. --}}
{{ __('dashboard.no_instance_order') }} {{ __('dashboard.nav.support') }}
@else {{-- ── The four cards, in the template's order and form ────────── Speicher · Benutzer · Datenvolumen · Verfügbarkeit. Figure, unit beside it, a line of context, the visual — ring, bar, sparkline. Every number below is measured; nothing is drawn at a level nobody read. --}}
@if ($disk) @elseif ($instance->quota_gb) @endif @if ($seats['total'])
{{-- R4: width is data, not decoration. --}}
@endif @if ($seatBreakdown !== [])

{{ collect($seatBreakdown) ->map(fn (int $n, string $role) => trans_choice('users.role_count.'.$role, $n, ['count' => $n])) ->join(' · ') }}

@endif
@if ($traffic) @php $state = $traffic->state(); @endphp @if (count($trend) > 2) {{-- Orange because this is the metric with an action attached: when it runs out, something can be done about it. Observed figures stay grey. --}} @endif @if ($state !== 'ok') {{ __('dashboard.traffic.buy') }} @endif @endif {{-- Availability, counted from our own monitoring answers. Absent rather than 100 % when nothing has been checked: reporting an unmonitored instance as perfect is the single most dishonest number this page could carry. --}} @if ($availability !== null) @if (count($availabilityTrend) > 2) @endif @elseif ($location) @endif
{{-- ── The proof register ────────────────────────────────────── --}}

{{ __('dashboard.proofs.label') }}

{{ __('dashboard.proofs.all') }}
@if ($proofs === [])

{{ __('dashboard.proofs.empty') }}

@else
@foreach ($proofs as $proof) @endforeach
{{ __('dashboard.proofs.item.'.$proof['key']) }} {{ $proof['at']?->local()->locale($locale)->isoFormat('DD.MM. HH:mm') ?? '—' }}@if ($proof['note']) · {{ $proof['note'] }}@endif $proof['state'] === 'ok', 'border-info-border bg-info-bg text-info' => $proof['state'] === 'planned', 'border-danger-border bg-danger-bg text-danger' => $proof['state'] === 'attention', ])> {{ __('dashboard.proofs.state.'.$proof['state']) }}
@endif
{{-- ── The contract ───────────────────────────────────────── --}}

{{ __('dashboard.master.label') }}

{{ __('dashboard.master.package') }}
{{ __('billing.plan.'.($instance->plan ?: 'team')) }} @if ($planPrice) {{ __('dashboard.master.per_'.($planPrice['term'] === 'yearly' ? 'year' : 'month'), ['amount' => $money($planPrice['cents'], $planPrice['currency'])]) }} @endif
@if ($contract?->performance)
{{ __('dashboard.master.operation') }}
{{ __('billing.perf.'.$contract->performance) }}
@endif @if ($domain)
{{ __('dashboard.master.address') }}
{{ $domain }}
@endif
@if ($nextInvoice)

{{ __('dashboard.invoice.label') }}

@if ($nextInvoice['addons'] > 0) {{-- Broken out only when there is something to break out: a "Module 0,00 €" line on every other customer's sheet is noise. --}}
{{ __('dashboard.invoice.plan') }}
{{ $money($nextInvoice['plan'], $nextInvoice['currency']) }}
{{ __('dashboard.invoice.addons') }}
{{ $money($nextInvoice['addons'], $nextInvoice['currency']) }}
@endif
{{ __('dashboard.invoice.amount') }}
{{ $money($nextInvoice['total'], $nextInvoice['currency']) }} {{ __('dashboard.invoice.net') }}
{{ __('dashboard.invoice.due') }}
{{ $nextInvoice['due']?->local()->locale($locale)->isoFormat('LL') ?? '—' }}
{{ __('dashboard.invoice.all') }}
@endif @if ($openTasks > 0) {{-- Only while there is something outstanding. A permanently green checklist is furniture; one with work left on it is a reason to open this page. --}} @endif
{{-- ── The three things customers come here to do ─────────────────── --}}
@foreach ([ ['users', 'users', 'add_user'], ['backups', 'rotate-ccw', 'restore'], ['billing', 'plus', 'grow'], ] as [$route, $icon, $key]) {{ __('dashboard.quick.'.$key.'_title') }} {{ __('dashboard.quick.'.$key.'_body') }} @endforeach
@endif