@php // Pre-compute defaults so the form opens with sensible values: // send-date = today in the workspace tz, send-time = now + 30min. // The schedule fields stay hidden until the operator clicks // "Schedule for later" — JS toggles `[data-sched]` visibility. $tz = $defaultTz ?? config('app.timezone', 'UTC'); $defaultDate = \Illuminate\Support\Carbon::now($tz)->format('Y-m-d'); $defaultTime = \Illuminate\Support\Carbon::now($tz)->addMinutes(30)->format('H:i'); // Group categories of WaTemplate buckets so the preview can show // the right Marketing/Utility chip on the right. $templates = $templates ?? collect(); $devices = $devices ?? collect(); $contacts = $contacts ?? collect(); $groups = $groups ?? collect(); $timezones = $timezones ?? [config('app.timezone', 'UTC')]; @endphp
{{ __('Broadcasts / New') }}
{{ __('Create new') }} {{ __('broadcast') }}
{{ __('Draft / unsaved') }}
@if (session('error'))
{{ session('error') }}
@endif @if (isset($errors) && $errors->any())
{{ $errors->first() }}
@endif
@csrf
01 {{ __('Broadcast setup') }} {{ __('template message') }}
{{ __('Internal label used in broadcast reports.') }}
@php $wsEngine = \App\Services\WorkspaceEngine::for( auth()->user()->current_workspace_id ?? 0, ); $isTwilioWs = $wsEngine === 'twilio'; @endphp @if ($templates->isEmpty())
{{ __('No approved templates yet.') }} {{ __('Create one →') }}
@elseif ($isTwilioWs)
{{ __('Twilio compliant sends require a Content SID per template — flag a template as "Twilio ready" via /templates/{id}/edit. Templates without a ContentSid will send as plain text (loses Meta template approval).') }}
@else
{{ __('Broadcasts send approved templates only.') }}
@endif
{{-- Device picker — multi-device aware. With one device we render a single hidden input. With 2+ we render a checkbox list and the controller fans out into N broadcasts at save time. --}}
@if ($devices->count() === 0)
{{ __('No connected devices.') }} {{ __('Connect one →') }}
@elseif ($devices->count() === 1) @php $only = $devices->first(); @endphp
{{ $only['label'] }} {{ $only['phone'] }}
@else {{-- Multi-device picker. Operator ticks devices and (when 2+ are ticked) sets per-device share weights so they control HOW the audience is split. Weights are positive numbers; the server normalises them so an audience of N contacts gets `round(N * weight_i / sum_weights)` per device. Equal weights = even split (legacy round-robin). 70 / 30 = bigger device takes 70% of the audience. --}}
@foreach ($devices as $d) @endforeach
{{ __('Tick devices and set share weights — e.g.') }} 7 / 3 sends 70% of contacts via the first device and 30% via the second. Equal weights split evenly.
@endif

{{ __('Who do you want to send it to?') }}

{{ __('Pick contacts directly or pick a contact group.') }}

0 selected
@if ($groups->isNotEmpty())
{{ __('Groups') }} @foreach ($groups as $g) @endforeach
@endif
@forelse ($contacts as $c) @php // Build display name from whatever fields exist — // `name` is the catch-all; some imports only have // first/last. Phone uses `mobile` + optional // `country_code` (legacy schema kept them split). $cname = trim((string) ($c->name ?? '')) ?: trim(($c->first_name ?? '') . ' ' . ($c->last_name ?? '')) ?: 'Contact #' . $c->id; $cdial = trim((string) ($c->country_code ?? '')); $cphone = trim((string) ($c->mobile ?? '')); $cfull = $cphone === '' ? '' : ($cdial !== '' ? '+' . ltrim($cdial, '+') . ' ' . $cphone : $cphone); @endphp @empty @endforelse
{{ __('Name') }} {{ __('Phone') }}
{{ $cname }}
{{ $cfull ?: '—' }}
{{ __('No contacts yet.') }} {{ __('Add some →') }}

{{ __('When do you want to send your broadcast?') }}

{{ __('Send immediately or pick a future date / time.') }}

{{-- Schedule fields are hidden by default and revealed when "Schedule for later" is picked. Avoids the form looking cluttered for the common "send now" path. --}}