91 lines
5.2 KiB
PHP
91 lines
5.2 KiB
PHP
<div class="mx-auto max-w-[1120px] space-y-6">
|
|
<div class="animate-rise">
|
|
<h1 class="text-2xl font-bold tracking-tight text-ink">{{ __('payment_problems.title') }}</h1>
|
|
<p class="mt-1 max-w-[70ch] text-sm text-muted">{{ __('payment_problems.subtitle') }}</p>
|
|
</div>
|
|
|
|
{{-- 1. Laufende Verträge im Rückstand. --}}
|
|
<div class="space-y-4 rounded-lg border border-line bg-surface p-6 shadow-xs animate-rise">
|
|
<div>
|
|
<h2 class="font-semibold text-ink">{{ __('payment_problems.cases_title') }}</h2>
|
|
<p class="mt-1 text-sm text-muted">{{ __('payment_problems.cases_body') }}</p>
|
|
</div>
|
|
|
|
@if ($cases->isEmpty())
|
|
<p class="text-sm text-muted">{{ __('payment_problems.cases_none') }}</p>
|
|
@else
|
|
<div class="overflow-x-auto">
|
|
<table class="w-full text-sm">
|
|
<thead>
|
|
<tr class="border-b border-line text-left text-xs font-medium text-muted">
|
|
<th class="py-2 pr-4">{{ __('payment_problems.customer') }}</th>
|
|
<th class="py-2 pr-4">{{ __('payment_problems.level') }}</th>
|
|
<th class="py-2 pr-4">{{ __('payment_problems.since') }}</th>
|
|
<th class="py-2">{{ __('payment_problems.next_step') }}</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
@foreach ($cases as $case)
|
|
<tr wire:key="case-{{ $case->id }}" class="border-b border-line last:border-0">
|
|
<td class="py-3 pr-4 text-ink">{{ $case->subscription?->customer?->name ?? '—' }}</td>
|
|
<td class="py-3 pr-4">
|
|
<span @class([
|
|
'rounded-pill border px-2.5 py-0.5 text-xs font-medium',
|
|
'border-danger-border bg-danger-bg text-danger' => $case->isSuspended(),
|
|
'border-warning-border bg-warning-bg text-warning' => ! $case->isSuspended(),
|
|
])>{{ __('payment_problems.level_'.$case->level) }}</span>
|
|
</td>
|
|
{{-- R19: alles, was ein Mensch liest, geht über ->local(). --}}
|
|
<td class="py-3 pr-4 text-muted">{{ $case->opened_at->local()->isoFormat('D. MMM YYYY') }}</td>
|
|
<td class="py-3 text-muted">
|
|
{{ $case->next_step_at?->local()->isoFormat('D. MMM YYYY') ?? '—' }}
|
|
</td>
|
|
</tr>
|
|
@endforeach
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
@endif
|
|
</div>
|
|
|
|
{{-- 2. Käufe, deren Zahlung Tage später geplatzt ist. --}}
|
|
<div class="space-y-4 rounded-lg border border-line bg-surface p-6 shadow-xs animate-rise [animation-delay:30ms]">
|
|
<div>
|
|
<h2 class="font-semibold text-ink">{{ __('payment_problems.failed_title') }}</h2>
|
|
<p class="mt-1 max-w-[70ch] text-sm text-muted">{{ __('payment_problems.failed_body') }}</p>
|
|
</div>
|
|
|
|
@if ($failed->isEmpty())
|
|
<p class="text-sm text-muted">{{ __('payment_problems.failed_none') }}</p>
|
|
@else
|
|
<ul class="space-y-3">
|
|
@foreach ($failed as $problem)
|
|
<li wire:key="failed-{{ $problem->id }}" class="rounded-lg border border-line bg-surface-2 p-4">
|
|
<div class="flex flex-wrap items-start justify-between gap-3">
|
|
<div class="min-w-0">
|
|
<p class="text-sm font-medium text-ink">{{ $problem->name ?: $problem->email }}</p>
|
|
<p class="mt-0.5 font-mono text-xs text-muted">{{ $problem->email }}</p>
|
|
<p class="mt-1 text-xs text-muted">
|
|
{{ $problem->plan ?? '—' }} ·
|
|
{{ number_format($problem->amount_cents / 100, 2, ',', '.') }} {{ $problem->currency }} ·
|
|
{{ $problem->failed_at->local()->isoFormat('D. MMM YYYY, HH:mm') }}
|
|
</p>
|
|
</div>
|
|
|
|
{{-- R20: die Begründung wird im Modal eingetippt, nicht
|
|
in der Zeile. Ein Feld hier liesse die Zeile
|
|
wachsen und die Nachbarn springen — und ein
|
|
Knopf, der eine Methode am Seiten-Bauteil ruft,
|
|
ist der Inline-Editor unter anderem Namen. --}}
|
|
<x-ui.button variant="secondary" class="shrink-0"
|
|
x-on:click="$dispatch('openModal', { component: 'admin.resolve-failed-checkout', arguments: { id: {{ $problem->id }} } })">
|
|
{{ __('payment_problems.resolve') }}
|
|
</x-ui.button>
|
|
</div>
|
|
</li>
|
|
@endforeach
|
|
</ul>
|
|
@endif
|
|
</div>
|
|
</div>
|