@php $money = fn (?float $v, string $null = 'Not estimated'): string => $v === null ? __($null) : trim($base.' '.number_format($v, 2)); $periodWord = mb_strtolower(__($periods[$period])); $closed = $outcomes['won'] + $outcomes['lost']; $kpis = [ ['label' => __('Active pipeline'), 'value' => $money($pipeline['value_base']), 'icon' => 'funnel', 'accent' => '#6366f1', 'sub' => $pipeline['not_estimated'] > 0 ? __(':n open · :m not estimated', ['n' => $pipeline['count'], 'm' => $pipeline['not_estimated']]) : __(':n open', ['n' => $pipeline['count']]), 'href' => route('crm.reports.show', 'pipeline-by-stage')], ['label' => __('Newly qualified'), 'value' => number_format($qualified), 'icon' => 'check-circle', 'accent' => '#10b981', 'sub' => __('First time, :period', ['period' => $periodWord]), 'href' => route('crm.reports.show', ['report' => 'qualified-by-originator', 'period' => $period])], ['label' => __('Win rate'), 'value' => $winRate === null ? __('Not applicable') : number_format($winRate * 100, 1).'%', 'icon' => 'trophy', 'accent' => '#0ea5e9', 'sub' => $closed === 0 ? __('No closed opportunities') : __(':won won, :lost lost', ['won' => $outcomes['won'], 'lost' => $outcomes['lost']]), 'href' => route('crm.reports.show', ['report' => 'won-opportunities', 'period' => $period])], ['label' => __('Needs attention'), 'value' => number_format($flagged), 'icon' => 'eye', 'accent' => '#f59e0b', 'sub' => __('Flagged opportunities'), 'href' => route('crm.pipeline-monitor', $officerId ? ['officer' => $officerId] : [])], ['label' => __('Overdue tasks'), 'value' => number_format($overdueTasks), 'icon' => 'bell-alert', 'accent' => '#e11d48', 'sub' => $overdueTasks > 0 ? __('Follow-up required') : __('All on time'), 'href' => route('crm.reports.show', 'overdue-follow-ups')], ]; $stageFigure = fn (array $figures): float => $stageMode === 'value' ? (float) ($figures['value_base'] ?? 0) : (float) $figures['count']; $maxStage = max(1.0, (float) max(array_map($stageFigure, $pipeline['by_stage']) ?: [0])); $initials = function (string $name): string { $parts = preg_split('/\s+/', trim($name)) ?: []; $letters = array_map(fn (string $p): string => mb_strtoupper(mb_substr($p, 0, 1)), array_slice(array_filter($parts), 0, 2)); return implode('', $letters) ?: '?'; }; $actions = [ ['tone' => 'rose', 'icon' => 'clock', 'count' => $overdueTasks, 'text' => trans_choice(':n overdue task|:n overdue tasks', $overdueTasks, ['n' => number_format($overdueTasks)]), 'link' => __('Review tasks'), 'href' => route('crm.tasks.index', ['view' => 'overdue'])], ['tone' => 'amber', 'icon' => 'flag', 'count' => $flagged, 'text' => trans_choice(':n flagged opportunity|:n flagged opportunities', $flagged, ['n' => number_format($flagged)]), 'link' => __('Review pipeline'), 'href' => route('crm.pipeline-monitor', $officerId ? ['officer' => $officerId] : [])], ]; $actionTones = [ 'rose' => 'bg-rose-50 text-rose-600 ring-rose-100', 'amber' => 'bg-amber-50 text-amber-600 ring-amber-100', 'sky' => 'bg-sky-50 text-sky-600 ring-sky-100', ]; @endphp
{{ __('Report Centre') }} {{ __('Pipeline Monitor') }} {{-- Period and officer filters --}}
@foreach ($periods as $key => $label) @endforeach
{{-- Headline figures --}}
@foreach ($kpis as $m)

{{ $m['label'] }}

{{ $m['value'] }}

{{ $m['sub'] }}
@endforeach
{{-- Team performance --}}

{{ __('Team performance') }}

{{ __('Pipeline ownership and activity for the selected period.') }}

{{ __('View performance') }}
@forelse ($rows as $row) @empty @endforelse @if ($rows->total() > 0) @endif
{{ __('Officer') }} {{ __('Open') }} {{ __('Pipeline value') }} {{ __('Outreach') }} {{ __('Meetings') }} {{ __('Qualified') }} {{ __('Won') }} {{ __('Flagged') }}
@if ($row['user']->hasProfilePhoto()) @else {{ $initials($row['user']->name) }} @endif {{ $row['user']->name }} {{ $row['open'] }}
{{ $money($row['value']) }}
{{ $row['outreach'] }} {{ $row['meetings'] }} {{ $row['qualified'] }} {{ $row['won'] }} {{ $row['flagged'] }}
{{ $officerId ? __('Total') : __('Team total') }} {{ $totals['open'] }}
{{ $money($totals['value']) }}
{{ $totals['outreach'] }} {{ $totals['meetings'] }} {{ $totals['qualified'] }} {{ $totals['won'] }} {{ $totals['flagged'] }}
@if ($rows->hasPages())
{{ $rows->links() }}
@endif
{{ __('Pipeline belongs to the owner, activity belongs to the person who logged it.') }}
{{-- Below xl the side cards take a full row (two-up from md), so the action centre's sentences never wrap into three lines. --}}
{{-- Pipeline by stage --}}

{{ __('Pipeline by stage') }}

@foreach ($stageModes as $key => $label) @endforeach
@foreach ($pipeline['by_stage'] as $stage => $figures) @php $figure = $stageFigure($figures); @endphp
{{ __($stageLabels[$stage]) }}
{{ $stageMode === 'value' ? ($figures['value_base'] === null ? ($figures['count'] ? __('Not estimated') : $money(0.0)) : $money($figures['value_base'])) : $figures['count'] }}
@endforeach
{{ trans_choice(':n open opportunity|:n open opportunities', $pipeline['count'], ['n' => number_format($pipeline['count'])]) }} · {{ __(':n stalled over :d days', ['n' => number_format($stale), 'd' => $staleDays]) }}
{{-- Action centre --}}

{{ __('Action centre') }}

    @foreach ($actions as $a)
  • {{ $a['text'] }} {{ $a['link'] }}
  • @endforeach
  • {{ $completeness === null ? __('Record completeness not applicable') : __(':pct% record completeness', ['pct' => number_format($completeness, 1)]) }}

    @if ($completeness !== null) @endif
    {{ __('Complete records') }}
{{-- Recent wins --}}

{{ __('Recent wins') }}

{{ __('Open Sales Tracker') }}
    @forelse ($wins as $win) @php $f = $sales->of($win); @endphp
  • {{ $win->title }}

    {{ $win->customer?->name }} · {{ __('Originated by :o, managed by :m', ['o' => $win->originator?->name ?? __('nobody recorded'), 'm' => $win->owner?->name ?? __('nobody recorded')]) }}

    {{ $money($f['confirmed'], 'Not available') }}
  • @empty
  • @endforelse
@if ($wins->hasPages())
{{ $wins->links() }}
@endif
{{-- Left-aligned: the Ask launcher owns the bottom-right corner. --}}
{{ __('Last updated :time', ['time' => $updatedAt->format('H:i')]) }}