@extends('layouts.dashboard')
@section('content')
@php
/**
* Operation Analytics → Operations: how smoothly the restaurant runs — fulfilment
* speed, cancellations, the channels orders arrive through, the staffing clock,
* waste and drawer accuracy.
*
* @var array $kpis @var array $fulChart @var array $fulMeta @var array $cxChart @var array $cxMeta
* @var array $dowChart @var array $dowMeta @var array $chanChart @var array $chanMeta
* @var array $modeChart @var array $modeMeta @var array $heatChart @var array $heatMeta
* @var array $chanRows @var array $chanPager @var array $waste @var array $wastePager
* @var array $shifts @var array $shiftPager
* @var int $rangeDays @var array $rangeLinks @var bool $showMoney
*/
@endphp
@php /* .qm-d2: the dashboard density standard (app.css §35) */
@endphp
{{ t_raw('dashboard.sec.snapshot') }}
{{ t_raw('vendor.analytics.subtitle_operations') }}
@foreach ($rangeLinks['options'] as $val => $text)
@php $on = ((string) $val === $rangeLinks['selected']); @endphp
{{ $text }}
@endforeach
@partial('kpi-card', ['variant' => 'panel', 'accent' => 'blue', 'icon' => 'fa-stopwatch', 'label' => t_raw('vendor.analytics.kpi_avg_fulfilment'),
'value' => $kpis['fulfilment']['value'] ?? '—',
'spark' => $kpis['fulfilment']['spark'], 'meta' => $kpis['fulfilment']['meta']])
@partial('kpi-card', ['variant' => 'panel', 'accent' => 'rose', 'icon' => 'fa-ban', 'label' => t_raw('vendor.analytics.kpi_cancellations'),
'value' => number_format($kpis['cancels']['value']), 'spark' => $kpis['cancels']['spark'], 'meta' => $kpis['cancels']['meta']])
@php /* A no-show COUNT says nothing without the bookings behind it, so the
headline is the rate and the caption carries the raw figures. */
@endphp
@partial('kpi-card', ['variant' => 'panel', 'accent' => 'amber', 'icon' => 'fa-user-slash', 'label' => t_raw('vendor.analytics.kpi_no_show_rate'),
'value' => $kpis['noShow']['value'] !== null ? number_format($kpis['noShow']['value'], 1) . '%' : '—',
'spark' => $kpis['noShow']['spark'], 'meta' => $kpis['noShow']['meta']])
@partial('kpi-card', ['variant' => 'panel', 'accent' => 'violet', 'icon' => 'fa-tablet-alt', 'label' => t_raw('vendor.analytics.kpi_self_service'),
'value' => $kpis['selfServe']['value'] !== null ? number_format($kpis['selfServe']['value'], 1) . '%' : '—',
'spark' => $kpis['selfServe']['spark'], 'meta' => $kpis['selfServe']['meta']])
@partial('kpi-card', ['variant' => 'panel', 'accent' => 'teal', 'icon' => 'fa-user-friends', 'label' => t_raw('vendor.analytics.kpi_covers'),
'value' => $kpis['covers']['value'] > 0 ? number_format($kpis['covers']['value']) : '—',
'spark' => $kpis['covers']['spark'], 'meta' => $kpis['covers']['meta']])
@if ($showMoney)
@partial('kpi-card', ['variant' => 'panel', 'accent' => 'slate', 'icon' => 'fa-wallet', 'label' => t_raw('vendor.analytics.kpi_drawer_variance'),
'value' => ($kpis['drawer']['value'] == 0.0 ? t_raw('vendor.analytics.balanced_label') : ($kpis['drawer']['value'] > 0 ? '+' : '−') . money(abs($kpis['drawer']['value']))),
'meta' => $kpis['drawer']['meta']])
@endif
{{ t_raw('dashboard.sec.trends') }}
@partial('chart-card', ['heading' => t_raw('vendor.analytics.chart_fulfilment_speed'), 'sub' => t_raw('vendor.analytics.chart_avg_min_per_day_sub'), 'cfg' => $fulChart, 'meta' => $fulMeta, 'accent' => 'blue', 'opts' => ['id' => 'opsFulChart', 'url' => route('vendor.chart-series', ['chart' => 'opsFulfil']), 'selected' => $rangeLinks['selected'], 'options' => $rangeLinks['options'], 'control' => 'compact']])
@partial('chart-card', ['heading' => t_raw('vendor.analytics.chart_cancellations_per_day'), 'sub' => t_raw('vendor.analytics.chart_cancellations_caption'), 'cfg' => $cxChart, 'meta' => $cxMeta, 'icon' => 'fa-chart-bar', 'accent' => 'rose', 'opts' => ['id' => 'opsCxChart', 'url' => route('vendor.chart-series', ['chart' => 'opsCancels']), 'selected' => $rangeLinks['selected'], 'options' => $rangeLinks['options'], 'control' => 'compact']])
@partial('chart-card', ['heading' => t_raw('vendor.analytics.chart_busiest_weekdays'), 'sub' => t_raw('vendor.analytics.chart_orders_by_day_sub'), 'cfg' => $dowChart, 'meta' => $dowMeta, 'icon' => 'fa-chart-bar', 'accent' => 'violet'])
@partial('chart-card', ['heading' => t_raw('vendor.analytics.chart_order_channels'), 'sub' => t_raw('vendor.analytics.chart_order_channels_sub'), 'cfg' => $chanChart, 'meta' => $chanMeta, 'icon' => 'fa-chart-pie', 'accent' => 'blue'])
@partial('chart-card', ['heading' => t_raw('vendor.analytics.heading_service_modes'), 'sub' => t_raw('vendor.analytics.chart_service_modes_sub'), 'cfg' => $modeChart, 'meta' => $modeMeta, 'icon' => 'fa-chart-pie', 'accent' => 'teal'])
@partial('chart-card', ['heading' => t_raw('vendor.analytics.chart_staffing_clock'), 'sub' => t_raw('vendor.analytics.chart_staffing_clock_sub'), 'cfg' => $heatChart, 'meta' => $heatMeta, 'icon' => 'fa-th', 'accent' => 'blue'])
{{ t_raw('dashboard.sec.breakdown') }}
{{ t_raw('vendor.analytics.heading_channel_performance') }}
{{ t_raw('vendor.analytics.hint_channel_performance') }}
{{ t_raw('vendor.analytics.caption_channel_performance') }}
| {{ t_raw('vendor.analytics.col_channel') }} |
{{ t_raw('common.orders') }} |
{{ t_raw('vendor.analytics.col_avg_minutes') }} |
{{ t_raw('vendor.analytics.kpi_cancellations') }} |
{{ t_raw('vendor.analytics.kpi_covers') }} |
{{ t_raw('vendor.analytics.col_terminals') }} |
{{ t_raw('vendor.analytics.col_at_table') }} |
@if ($chanRows)
@foreach ($chanRows as $c)
| {{ $c['label'] }} |
{{ number_format($c['orders']) }} |
{!! $c['avg_minutes'] !== null ? number_format($c['avg_minutes']) . ' ' . t('common.min') : dash() !!} |
@if ($c['cancelled'] > 0)
{{ t_raw('vendor.analytics.pill_cancelled_rate', [':n' => number_format($c['cancelled']), ':pct' => number_format($c['cancel_rate'] ?? 0, 1)]) }}
@else{{ t_raw('vendor.analytics.pill_none_cancelled') }}@endif
|
{!! $c['covers'] > 0 ? number_format($c['covers']) : dash() !!} |
@php /* Terminals counts the distinct kiosks that produced these orders;
at-table counts the orders raised against a seated table. */
@endphp
{!! $c['terminals'] > 0 ? number_format($c['terminals']) : dash() !!} |
{!! $c['at_table'] > 0 ? number_format($c['at_table']) : dash() !!} |
@endforeach
@else
@partial('table-empty', ['colspan' => 7, 'icon' => 'fa-random', 'msg' => t_raw('vendor.analytics.empty_no_orders_period')])
@endif
@partial('table-toolbar', ['pager' => $chanPager, 'base' => '/vendor/analytics/operations'])
{{ t_raw('vendor.analytics.caption_waste') }}
| {{ t_raw('vendor.analytics.col_stock_item') }} | {{ t_raw('vendor.analytics.col_wasted') }} | {{ t_raw('vendor.analytics.col_entries') }} |
@if ($waste)
@foreach ($waste as $w)
| {{ $w['name'] }} |
{{ rtrim(rtrim(number_format((float) $w['qty'], 2, '.', ''), '0'), '.') }} {{ $w['unit'] }} |
{{ (int) $w['times'] }} |
@endforeach
@else
@partial('table-empty', ['colspan' => 3, 'icon' => 'fa-boxes', 'msg' => t_raw('vendor.analytics.empty_no_waste')])
@endif
@partial('table-toolbar', ['pager' => $wastePager, 'base' => '/vendor/analytics/operations', 'showPager' => false])
{{ t_raw('vendor.analytics.caption_drawer_sessions') }}
| {{ t_raw('vendor.analytics.col_closed') }} | @if ($showMoney){{ t_raw('vendor.analytics.col_expected') }} | {{ t_raw('vendor.analytics.col_counted') }} | @endif{{ t_raw('vendor.analytics.col_variance') }} | {{ t_raw('common.actions') }} |
@if ($shifts)
@foreach ($shifts as $s)
@php $v = (float) ($s['variance'] ?? 0); @endphp
| {!! fmt_datetime($s['closed_at']) !!} |
@if ($showMoney)
{!! $s['expected_cash'] !== null ? money($s['expected_cash']) : dash() !!} |
{!! $s['counted_cash'] !== null ? money($s['counted_cash']) : dash() !!} |
@endif
@php /* Managers see the balanced/over/short signal but not the cash amount (the till figures are owner-only). */
@endphp
@if ($v == 0.0){{ t_raw('vendor.analytics.balanced_label') }}
@elseif ($v > 0){!! $showMoney ? t('vendor.analytics.pill_over_amount', [':amount' => money($v)]) : t('vendor.analytics.pill_over_plain') !!}
@else{!! $showMoney ? t('vendor.analytics.pill_short_amount', [':amount' => money(abs($v))]) : t('vendor.analytics.pill_short_plain') !!}@endif
|
{{ t_raw('vendor.analytics.link_z_report') }} |
@endforeach
@else
@partial('table-empty', ['colspan' => $showMoney ? 5 : 3, 'icon' => 'fa-wallet', 'msg' => t_raw('vendor.analytics.empty_no_drawer_sessions')])
@endif
@partial('table-toolbar', ['pager' => $shiftPager, 'base' => '/vendor/analytics/operations', 'showPager' => false])
@php /* /.qm-d2 */
@endphp
@endsection