@extends('layouts.dashboard')
@section('content')
@php
/**
* Operation Analytics → Kitchen efficiency: how long the kitchen actually takes,
* measured from the per-item prep marks the board records rather than from a target
* somebody typed into settings once.
*
* Two readings, because they lead to two different decisions: WHICH DISH is slow is a
* recipe or a prep-list problem, WHICH HOUR is slow is a rota problem.
*
* @var array $kpis @var array $prepChart @var array $prepMeta @var array $hourChart @var array $hourMeta
* @var array $slowChart @var array $slowMeta @var array $stationChart @var array $stationMeta
* @var array $dishRows @var array $dishPager @var array $stationRows @var bool $hasStations
* @var string|null $avgTicket @var int $ticketCount @var int $targetMinutes @var int $measured
* @var int $rangeDays @var array $rangeLinks
*/
$dishRows = $dishRows ?? [];
$stationRows = $stationRows ?? [];
$hasStations = !empty($hasStations);
$measured = (int) ($measured ?? 0);
$targetMinutes = (int) ($targetMinutes ?? 30);
$ticketCount = (int) ($ticketCount ?? 0);
@endphp
@php /* .qm-d2: the dashboard density standard (app.css §35) */
@endphp
{{ t_raw('dashboard.sec.snapshot') }}
{{ t_raw('vendor.analytics.subtitle_kitchen') }}
@foreach ($rangeLinks['options'] as $val => $text)
@php $on = ((string) $val === $rangeLinks['selected']); @endphp
{{ $text }}
@endforeach
@php /* Nothing has been ticked off yet. Every figure below would be an average of no
measurements, so the page says so once instead of printing a screen of zeros and an
accusation against whichever dish happens to sort first. */
@endphp
@if ($measured < 1)
@else
@partial('kpi-card', ['variant' => 'panel', 'accent' => 'blue', 'icon' => 'fa-stopwatch', 'label' => t_raw('vendor.analytics.kpi_avg_prep'),
'value' => $kpis['avgPrep']['value'] ?? dash(),
'spark' => $kpis['avgPrep']['spark'], 'meta' => $kpis['avgPrep']['meta']])
@php /* The named dish. This is the whole point of the page — a number nobody can act
on becomes a recipe somebody can change. */
@endphp
@partial('kpi-card', ['variant' => 'panel', 'accent' => 'rose', 'icon' => 'fa-hourglass-half', 'label' => t_raw('vendor.analytics.kpi_slowest_dish'),
'value' => $kpis['slowestDish']['value'] ?? dash(), 'meta' => $kpis['slowestDish']['meta'],
'bgImage' => $kpis['slowestDish']['image'] ?? ''])
@partial('kpi-card', ['variant' => 'panel', 'accent' => 'amber', 'icon' => 'fa-clock', 'label' => t_raw('vendor.analytics.kpi_slowest_hour'),
'value' => $kpis['slowestHour']['value'] ?? dash(), 'meta' => $kpis['slowestHour']['meta']])
@partial('kpi-card', ['variant' => 'panel', 'accent' => 'teal', 'icon' => 'fa-utensils', 'label' => t_raw('vendor.analytics.kpi_dishes_prepped'),
'value' => number_format((int) $kpis['dishesPrepped']['value']),
'spark' => $kpis['dishesPrepped']['spark'], 'meta' => $kpis['dishesPrepped']['meta']])
@partial('kpi-card', ['variant' => 'panel', 'accent' => 'violet', 'icon' => 'fa-bullseye', 'label' => t_raw('vendor.analytics.kpi_on_target'),
'value' => $kpis['onTarget']['value'] !== null ? number_format($kpis['onTarget']['value'], 1) . '%' : dash(),
'meta' => $kpis['onTarget']['meta']])
{{ t_raw('dashboard.sec.trends') }}
@partial('chart-card', ['heading' => t_raw('vendor.analytics.chart_prep_speed'), 'sub' => t_raw('vendor.analytics.chart_avg_min_per_day_sub'), 'cfg' => $prepChart, 'meta' => $prepMeta, 'accent' => 'blue', 'icon' => 'fa-stopwatch', 'opts' => ['id' => 'kitchenPrepChart', 'url' => route('vendor.chart-series', ['chart' => 'kitchenPrep']), 'selected' => $rangeLinks['selected'], 'options' => $rangeLinks['options'], 'control' => 'compact']])
@partial('chart-card', ['heading' => t_raw('vendor.analytics.chart_prep_by_hour'), 'sub' => t_raw('vendor.analytics.chart_prep_by_hour_sub'), 'cfg' => $hourChart, 'meta' => $hourMeta, 'icon' => 'fa-clock', 'accent' => 'amber', 'opts' => ['id' => 'kitchenHourChart', 'url' => route('vendor.chart-series', ['chart' => 'kitchenHour']), 'selected' => $rangeLinks['selected'], 'options' => $rangeLinks['options'], 'control' => 'compact']])
@partial('chart-card', ['heading' => t_raw('vendor.analytics.chart_slowest_dishes'), 'sub' => t_raw('vendor.analytics.chart_slowest_dishes_sub'), 'cfg' => $slowChart, 'meta' => $slowMeta, 'icon' => 'fa-hourglass-half', 'accent' => 'rose', 'opts' => ['id' => 'kitchenSlowChart', 'url' => route('vendor.chart-series', ['chart' => 'kitchenSlow']), 'selected' => $rangeLinks['selected'], 'options' => $rangeLinks['options'], 'control' => 'compact']])
@php /* Only where the kitchen is divided: on one undivided board every line belongs
to the same station and the chart would be a single bar. */
@endphp
@if ($hasStations)
@partial('chart-card', ['heading' => t_raw('vendor.analytics.chart_prep_by_station'), 'sub' => t_raw('vendor.analytics.chart_prep_by_station_sub'), 'cfg' => $stationChart, 'meta' => $stationMeta, 'icon' => 'fa-fire', 'accent' => 'violet'])
@endif
{{ t_raw('dashboard.sec.breakdown') }}
{{ t_raw('vendor.analytics.caption_dish_prep_times') }}
| {{ t_raw('vendor.analytics.col_dish') }} |
{{ t_raw('vendor.analytics.col_times_prepped') }} |
{{ t_raw('vendor.analytics.col_avg_prep') }} |
{{ t_raw('vendor.analytics.col_slowest_single') }} |
{{ t_raw('vendor.analytics.col_over_target') }} |
@if ($dishRows)
@foreach ($dishRows as $d)
|
@if ($d['menu_item_id'] > 0)
{{ $d['name'] }}
@else
{{ $d['name'] }}
@endif
|
{{ number_format($d['times']) }} |
@php /* Amber past the target, so the row that needs attention is visible
without reading five numbers first. */
@endphp
{{ (string) round($d['avg_minutes'], 1) }} {{ t_raw('common.min') }}
|
{{ (string) round($d['max_minutes'], 1) }} {{ t_raw('common.min') }} |
@if ($d['over_target'] > 0)
{{ t_raw('vendor.analytics.pill_over_target', [':n' => number_format($d['over_target']), ':pct' => number_format($d['over_rate'] ?? 0, 1)]) }}
@else{{ t_raw('vendor.analytics.pill_all_on_target') }}@endif
|
@endforeach
@else
@partial('table-empty', ['colspan' => 5, 'icon' => 'fa-utensils', 'msg' => t_raw('vendor.analytics.empty_no_prep_data')])
@endif
@partial('table-toolbar', ['pager' => $dishPager, 'base' => '/vendor/analytics/kitchen'])
@if ($hasStations)
{{ t_raw('vendor.analytics.caption_station_prep_times') }}
| {{ t_raw('vendor.menu.station_label') }} |
{{ t_raw('vendor.analytics.col_times_prepped') }} |
{{ t_raw('vendor.analytics.col_avg_prep') }} |
@if ($stationRows)
@foreach ($stationRows as $s)
| {{ $s['name'] }} |
{{ number_format($s['times']) }} |
{{ (string) round($s['avg_minutes'], 1) }} {{ t_raw('common.min') }}
|
@endforeach
@else
@partial('table-empty', ['colspan' => 3, 'icon' => 'fa-fire', 'msg' => t_raw('vendor.analytics.empty_no_prep_data')])
@endif
@endif
@endif
@php /* /.qm-d2 */
@endphp
@endsection