@php // Three possible states the Setup tab caters for: // meta = Meta Commerce catalog connected → full sync UI // baileys = no Meta but a Baileys device is paired → ready // none = no device at all → prompt to /devices $state = $catalog ? 'meta' : ($hasBaileysDevice ? 'baileys' : 'none'); @endphp @if ($state === 'none') {{-- ───────────────────── NONE ─────────────────────── --}}
{{ __('Connect a device first') }}

{{ __('Catalog sending needs at least one WhatsApp device on this account — either an Unofficial API QR pair (free) or a Meta-verified WABA number. Open') }} /devices to pair one in 30 seconds.

Go to devices
@elseif ($state === 'baileys') {{-- ───────────────────── BAILEYS READY ─────────────── --}}
✓ Ready to send
{{ __('Unofficial API carousel mode') }}

You have {{ $devices->count() }} {{ \Illuminate\Support\Str::plural('device', $devices->count()) }} connected. Catalog sends work right now via native WhatsApp carousels through the Unofficial API — no Meta setup, no waiting for approval. Head to the Send tab to push products to any customer's number.

Open Send tab
{{-- Connected devices summary --}}
{{ __('Connected devices') }}
@foreach ($devices as $d) @php $phone = trim(($d->country_code ?? '') . ' ' . ($d->phone_number ?? '')); @endphp
{{ $d->device_name ?: 'Device #' . $d->id }}
{{ $phone ?: 'No number' }}
{{ $d->status }}
@endforeach
{{-- Quick stats --}}
{{ __('Products') }}
{{ number_format($totalProducts) }}
{{ __('Manage →') }}
{{ __('Shops') }}
{{ $shops->count() }}
{{ __('Manage →') }}
{{ __('Recent sends') }}
{{ $recentSends->count() }}
{{ __('View →') }}
{{-- Optional: connect Meta Commerce --}}
{{ __('Optional · advanced') }}
{{ __('Also link a Meta Commerce Catalog') }}
Unlocks the official catalog button on your WhatsApp Business profile + cart + the "order placed" webhook. Only needed if you're on a verified WABA. The Unofficial API works fine without it.
@include('user.catalog._connect-form', ['compact' => true])
@else {{-- ───────────────────── META CONNECTED ────────────── --}} @php $synced = (int) ($statusBuckets['synced'] ?? 0); $pending = (int) ($statusBuckets['pending'] ?? 0); $failed = (int) ($statusBuckets['failed'] ?? 0); $unsynced = (int) ($statusBuckets['unsynced'] ?? 0); @endphp
Connected · {{ strtoupper(str_replace('_', ' ', $catalog->provider)) }}
{{ $catalog->catalog_name ?: 'Meta Commerce Catalog' }}
ID {{ $catalog->catalog_id }}
{{ __('Send products →') }}
@csrf
{{ __('Total') }}
{{ number_format($totalProducts) }}
{{ __('Synced') }}
{{ number_format($synced) }}
{{ __('Pending') }}
{{ number_format($pending) }}
{{ __('Failed') }}
{{ number_format($failed) }}
{{-- ── Catalog health ── A product with no image / no price / a sync error never shows to buyers — pure lost sales. Score = share of sellable rows; the list lets the operator fix the offenders. --}} @if (!empty($health) && (int) ($health['total'] ?? 0) > 0) @php $score = (int) $health['score']; $scoreCls = $score >= 90 ? 'text-wa-deep' : ($score >= 70 ? 'text-accent-amber' : 'text-accent-coral'); $barCls = $score >= 90 ? 'bg-wa-deep' : ($score >= 70 ? 'bg-accent-amber' : 'bg-accent-coral'); $ringCls = $score >= 90 ? 'border-wa-deep' : ($score >= 70 ? 'border-accent-amber' : 'border-accent-coral'); @endphp
{{ $score }}
{{ __('Catalog health') }}
@if (($health['flagged'] ?? 0) > 0) {{ trans_choice('{1}:count product needs attention before it can sell.|[2,*]:count products need attention before they can sell.', $health['flagged'], ['count' => number_format($health['flagged'])]) }} @else {{ __('Every product is catalog-ready. Nice.') }} @endif
@if (($health['no_image'] ?? 0) > 0) {{ number_format($health['no_image']) }} {{ __('no image') }} @endif @if (($health['no_price'] ?? 0) > 0) {{ number_format($health['no_price']) }} {{ __('no price') }} @endif @if (($health['errored'] ?? 0) > 0) {{ number_format($health['errored']) }} {{ __('sync error') }} @endif
@if ($health['samples']->isNotEmpty())
{{ __('Show products to fix') }}
@endif
@endif
{{ __('Sync products to Meta') }}
Pushes up to 1000 per request, loops until done. {{ $unsynced + $failed }} waiting.
@csrf
{{ __('Commerce settings') }}
{{-- Automation: cart-order acknowledgement + inbound concierge --}} @php $auto = is_array($catalog->meta_json) ? $catalog->meta_json : []; @endphp
@csrf
{{ __('Automation') }}
{{-- Order acknowledgement (C1) --}}
{{-- Concierge (C5) --}}
{{-- Products table — sync status per row --}}

{{ __('Products') }}

{{ __('Most recently updated · click') }} Refresh status to poll Meta.
{{ __('Manage products →') }}
@forelse ($products as $p) @php $status = $p->meta_sync_status ?: 'unsynced'; $cls = [ 'unsynced' => 'bg-paper-50 text-ink-500', 'pending' => 'bg-accent-amber/15 text-accent-amber', 'synced' => 'bg-wa-mint text-wa-deep', 'failed' => 'bg-accent-coral/15 text-accent-coral', ]; @endphp @empty @endforelse
{{ __('Product') }} {{ __('SKU') }} {{ __('Price') }} {{ __('Availability') }} {{ __('Meta status') }}
@php $boxSvg = ''; @endphp @if ($p->image_url) @else {!! str_replace('"', '"', $boxSvg) !!} @endif
{{ $p->name }}
@if ($p->category)
{{ $p->category }}
@endif
{{ $p->sku ?: '—' }} {{ $p->price_display }} {{ $p->effective_availability }} {{ $status }} @if ($p->meta_last_error)
{{ \Illuminate\Support\Str::limit($p->meta_last_error, 60) }}
@endif
{{ __('No products yet.') }} {{ __('Add one →') }}
@endif