@extends('layouts.dashboard') @section('content') @php /** * Operation Analytics → Menu: menu engineering. Every dish is placed by what it * sells AND what it earns, so the four classic quadrants (Star, Plough-horse, * Puzzle, Dog) fall out of the restaurant's own numbers rather than a hunch. * * @var array $kpis @var array $trendChart @var array $trendMeta @var array $catChart @var array $catMeta * @var array $topChart @var array $topMeta @var array $marginChart @var array $marginMeta * @var array $chanChart @var array $chanMeta @var array $engChart @var array $engMeta * @var array $dishes @var array $dishPager @var int $totalUnits @var int $costed * @var int $rangeDays @var array $rangeLinks @var bool $showMoney */ // Margin is money, so a manager sees popularity only — the quadrant a dish sits in // is derived from its margin and travels with it. $quadrants = [ 'star' => ['label' => t_raw('vendor.analytics.quadrant_star'), 'tone' => 'green'], 'plough_horse' => ['label' => t_raw('vendor.analytics.quadrant_plough_horse'), 'tone' => 'blue'], 'puzzle' => ['label' => t_raw('vendor.analytics.quadrant_puzzle'), 'tone' => 'amber'], 'dog' => ['label' => t_raw('vendor.analytics.quadrant_dog'), 'tone' => 'grey'], ]; $cols = 9 + ($showMoney ? 4 : 0); @endphp @php /* .qm-d2: the dashboard density standard (app.css §35) */ @endphp

{{ t_raw('dashboard.sec.snapshot') }}

{{ t_raw('vendor.analytics.subtitle_menu') }}

@foreach ($rangeLinks['options'] as $val => $text) @php $on = ((string) $val === $rangeLinks['selected']); @endphp {{ $text }} @endforeach
@partial('kpi-card', ['variant' => 'panel', 'accent' => 'blue', 'icon' => 'fa-utensils', 'label' => t_raw('vendor.analytics.kpi_dishes_sold'), 'value' => number_format($kpis['dishes']['value']), 'spark' => $kpis['dishes']['spark'], 'meta' => $kpis['dishes']['meta']]) @partial('kpi-card', ['variant' => 'panel', 'accent' => 'green', 'icon' => 'fa-shopping-basket', 'label' => t_raw('common.units'), 'value' => number_format($kpis['units']['value']), 'spark' => $kpis['units']['spark'], 'meta' => $kpis['units']['meta']]) @partial('kpi-card', ['variant' => 'panel', 'accent' => 'rose', 'icon' => 'fa-crown', 'label' => t_raw('vendor.analytics.kpi_best_seller'), 'value' => $kpis['top']['value'] !== null ? $kpis['top']['value'] : '—', 'meta' => $kpis['top']['meta'], 'bgImage' => $kpis['top']['image'] ?? '']) @if ($showMoney) @partial('kpi-card', ['variant' => 'panel', 'accent' => 'teal', 'icon' => 'fa-coins', 'label' => t_raw('common.revenue'), 'value' => money($kpis['revenue']['value']), 'spark' => $kpis['revenue']['spark'], 'meta' => $kpis['revenue']['meta']]) @php /* Margin and food cost only count the dishes whose cost has been keyed in; the caption says how many that is so the figure is never read as the whole menu. */ @endphp @partial('kpi-card', ['variant' => 'panel', 'accent' => 'violet', 'icon' => 'fa-hand-holding-usd', 'label' => t_raw('vendor.analytics.kpi_gross_margin'), 'value' => $kpis['margin']['value'] !== null ? money($kpis['margin']['value']) : '—', 'spark' => $kpis['margin']['spark'], 'meta' => $kpis['margin']['meta']]) @partial('kpi-card', ['variant' => 'panel', 'accent' => 'amber', 'icon' => 'fa-percentage', 'label' => t_raw('vendor.analytics.kpi_food_cost'), 'value' => $kpis['foodCost']['value'] !== null ? number_format($kpis['foodCost']['value'], 1) . '%' : '—', 'spark' => $kpis['foodCost']['spark'], 'meta' => $kpis['foodCost']['meta']]) @endif

{{ t_raw('dashboard.sec.trends') }}

@partial('chart-card', ['heading' => t_raw('vendor.analytics.chart_units_over_time'), 'sub' => t_raw('vendor.analytics.chart_units_over_time_sub'), 'cfg' => $trendChart, 'meta' => $trendMeta, 'accent' => 'green', 'opts' => ['id' => 'menuTrendChart', 'url' => route('vendor.chart-series', ['chart' => 'menuUnits']), 'selected' => $rangeLinks['selected'], 'options' => $rangeLinks['options'], 'control' => 'compact']])
@partial('chart-card', ['heading' => t_raw('vendor.analytics.chart_category_share'), 'sub' => t_raw('vendor.analytics.chart_units_by_category_sub'), 'cfg' => $catChart, 'meta' => $catMeta, 'icon' => 'fa-chart-pie', 'accent' => 'teal'])
@partial('chart-card', ['heading' => t_raw('vendor.analytics.chart_top_sellers'), 'sub' => t_raw('vendor.analytics.chart_top_sellers_caption'), 'cfg' => $topChart, 'meta' => $topMeta, 'icon' => 'fa-chart-bar', 'accent' => 'violet', 'opts' => ['id' => 'menuTopChart', 'url' => route('vendor.chart-series', ['chart' => 'menuTop']), 'selected' => $rangeLinks['selected'], 'options' => $rangeLinks['options'], 'control' => 'compact']])
@php /* The owner's second slot is the profit view; a manager, who never sees money, gets the operational counterpart — what is failing to move. */ @endphp @if ($showMoney) @partial('chart-card', ['heading' => t_raw('vendor.analytics.chart_margin_leaders'), 'sub' => t_raw('vendor.analytics.chart_margin_leaders_sub'), 'cfg' => $marginChart, 'meta' => $marginMeta, 'icon' => 'fa-chart-bar', 'accent' => 'green', 'opts' => ['id' => 'menuMarginChart', 'url' => route('vendor.chart-series', ['chart' => 'menuMargin']), 'selected' => $rangeLinks['selected'], 'options' => $rangeLinks['options'], 'control' => 'compact']]) @else @partial('chart-card', ['heading' => t_raw('vendor.analytics.chart_slow_movers'), 'sub' => t_raw('vendor.analytics.chart_slow_movers_sub'), 'cfg' => $slowChart, 'meta' => $slowMeta, 'icon' => 'fa-chart-bar', 'accent' => 'amber', 'opts' => ['id' => 'menuSlowChart', 'url' => route('vendor.chart-series', ['chart' => 'menuSlow']), 'selected' => $rangeLinks['selected'], 'options' => $rangeLinks['options'], 'control' => 'compact']]) @endif
@partial('chart-card', ['heading' => t_raw('vendor.analytics.chart_units_by_channel'), 'sub' => t_raw('vendor.analytics.chart_units_by_channel_sub'), 'cfg' => $chanChart, 'meta' => $chanMeta, 'icon' => 'fa-chart-pie', 'accent' => 'blue'])
@if ($showMoney)
@partial('chart-card', ['heading' => t_raw('vendor.analytics.heading_menu_engineering'), 'sub' => t_raw('vendor.analytics.chart_menu_engineering_sub'), 'cfg' => $engChart, 'meta' => $engMeta, 'icon' => 'fa-braille', 'accent' => 'violet'])

{{ t_raw('vendor.analytics.hint_menu_engineering') }}

@endif

{{ t_raw('dashboard.sec.breakdown') }}

{{ t_raw('vendor.analytics.heading_all_dishes') }}

@if ($showMoney)

{{ t_raw('vendor.analytics.hint_cost_missing', [':n' => number_format($costed)]) }}

@endif
@if ($showMoney) @endif @if ($showMoney) @endif @if ($dishes) @foreach ($dishes as $d) @php $units = (int) $d['units']; $q = $d['quadrant'] ?? null; @endphp @if ($showMoney) @php /* A dish with no cost recorded reports nothing rather than a zero — zero cost would flatter every margin figure beside it. */ @endphp @endif @if ($showMoney) @endif @endforeach @else @partial('table-empty', ['colspan' => $cols, 'icon' => 'fa-utensils', 'msg' => t_raw('vendor.analytics.empty_no_dishes')]) @endif
{{ t_raw('vendor.analytics.caption_all_dishes') }}
{{ t_raw('vendor.analytics.col_dish') }} {{ t_raw('vendor.analytics.col_category') }} {{ t_raw('common.price') }}{{ t_raw('vendor.analytics.col_cost') }} {{ t_raw('vendor.analytics.col_food_cost_pct') }}{{ t_raw('common.units') }} {{ t_raw('vendor.analytics.col_share') }}{{ t_raw('common.revenue') }} {{ t_raw('vendor.analytics.col_margin') }}{{ t_raw('vendor.analytics.col_menu_class') }} {{ t_raw('vendor.analytics.col_last_sold') }} {{ t_raw('vendor.analytics.col_on_sale') }} {{ t_raw('common.actions') }}
{{ $d['name'] }}
{!! !empty($d['category_name']) ? e((string) $d['category_name']) : t('vendor.analytics.uncategorised') !!} {{ money($d['price']) }}{!! $d['cost'] !== null ? money($d['cost']) : dash() !!} {!! $d['food_cost_pct'] !== null ? number_format((float) $d['food_cost_pct'], 1) . '%' : dash() !!}{{ number_format($units) }} {!! $totalUnits > 0 ? number_format(100 * $units / $totalUnits, 1) . '%' : dash() !!}{{ money($d['revenue']) }} {!! $d['margin_total'] !== null ? money($d['margin_total']) : dash() !!} @if ($q !== null && isset($quadrants[$q])) {{ $quadrants[$q]['label'] }} @else{!! dash() !!}@endif {!! fmt_day($d['last_sold']) !!} {!! (int) $d['is_available'] === 1 ? t('common.yes') : t('common.no') !!}
@partial('table-toolbar', ['pager' => $dishPager, 'base' => '/vendor/analytics/menu'])
@php /* /.qm-d2 */ @endphp @endsection