{{-- Right-sidebar Return-label status card. Renders when the active ticket has a ReturnLabel row. Read-only — no operator actions on this card. Polling + auto-reship live entirely server-side; the operator observes the lifecycle here. States (driven by `ReturnLabelStatus` enum): - Waiting : sky pill, "Awaiting first courier scan", last checked / next check / countdown to 30-day abandon. - Scanned : amber pill, transient — reship has been authorised, Shopify order is being created. - Reshipped : lime pill, links to the Shopify order name from the reship_authorisations ledger. - Abandoned : zinc pill, "Customer did not drop off". - Failed : red pill, last_error surfaced. Tenant safety: $label comes from $this->activeReturnLabel which is filtered by AccountScope. Cross-account rows are invisible. Locked to ReturnLabelStatus enum cases — adding a new status case is the only way to extend the badge colour matrix. --}} @php /** @var \App\Models\ReturnLabel|null $label */ $label = $this->activeReturnLabel; @endphp @if ($label !== null)
{{ __('Return label') }}
{{ $label->tracking_number ?? __('No tracking number') }} @php $badge = $label->status?->badgeColor() ?? 'zinc'; $statusLabel = $label->status?->label() ?? __('Unknown'); $badgeClasses = match ($badge) { 'sky' => 'bg-sky-100 text-sky-800 dark:bg-sky-900/50 dark:text-sky-200', 'amber' => 'bg-amber-100 text-amber-800 dark:bg-amber-900/50 dark:text-amber-200', 'lime' => 'bg-lime-100 text-lime-800 dark:bg-lime-900/50 dark:text-lime-200', 'red' => 'bg-red-100 text-red-800 dark:bg-red-900/50 dark:text-red-200', default => 'bg-zinc-100 text-zinc-700 dark:bg-zinc-800 dark:text-zinc-300', }; @endphp {{ $statusLabel }}
{{-- Tracking link — Royal Mail tracking number is the most useful direct affordance the agent has on this card. --}} @if ($label->tracking_number) @endif {{-- Waiting state: show timing context. --}} @if ($label->status === \App\Enums\ReturnLabelStatus::Waiting)
{{ __('Last checked') }}
{{ $label->last_checked_at ? $label->last_checked_at->diffForHumans() : __('Not yet') }}
{{ __('Next check') }}
{{ $label->next_check_at ? $label->next_check_at->diffForHumans() : __('Pending') }}
@php $abandonsAt = $label->created_at ? $label->created_at->copy()->addDays(\App\Models\ReturnLabel::ABANDON_AFTER_DAYS) : null; @endphp @if ($abandonsAt !== null)
{{ __('Abandons') }}
{{ $abandonsAt->diffForHumans() }}
@endif
@endif {{-- Reshipped state: link to the Shopify replacement order from the dedup ledger. --}} @if ($label->status === \App\Enums\ReturnLabelStatus::Reshipped && $label->reshipAuthorisation) @php $auth = $label->reshipAuthorisation; @endphp
{{ __('Replacement order created') }}
@if ($auth->shopify_order_name)
{{ $auth->shopify_order_name }}
@endif @if ($auth->triggered_at)
{{ $auth->triggered_at->diffForHumans() }}
@endif
@endif {{-- Failed state: surface operator-safe error. --}} @if ($label->status === \App\Enums\ReturnLabelStatus::Failed && $label->last_error)
{{ __('Reship failed') }}
{{ $label->last_error }}
@endif {{-- Abandoned state: explanatory copy. --}} @if ($label->status === \App\Enums\ReturnLabelStatus::Abandoned)
{{ __('No movement after 30 days. Polling stopped.') }}
@endif {{-- Captured replacement variant footer — small, quiet, lives on every card so the operator can see what the auto-reship will (or did) send. --}} @if ($label->correct_variant_id)
{{ __('Variant') }} {{ $label->correct_variant_id }} × {{ $label->correct_quantity ?? 1 }}
@endif
@endif