@extends('layouts.dashboard')
@section('content')
@php
/**
* Operation Analytics → Sales: what the restaurant took, how it arrived and who
* handled it — money over time, tenders, order channels, the money clock, and
* the discounts given away against them.
*
* @var array $kpis headline metrics: ['value', 'spark', 'meta'] per card
* @var array $revChart @var array $revMeta @var array $tenderChart @var array $tenderMeta
* @var array $sourceChart @var array $sourceMeta @var array $modeChart @var array $modeMeta
* @var array $discChart @var array $discMeta @var array $heatChart @var array $heatMeta
* @var array $mixRows @var array $mixPager @var array $byStaff @var array $staffPager
* @var array $discRows @var array $discPager
* @var int $rangeDays @var array $rangeLinks
*/
@endphp
@php /* .qm-d2: the dashboard density standard (app.css §35) */
@endphp
{{ t_raw('dashboard.sec.snapshot') }}
{{ t_raw('vendor.analytics.subtitle_sales') }}
@php /* Period picker and download are one right-aligned action group: the file IS the window
currently selected, so it belongs beside the control that selects it. The wrapper is
copied from vendor/staff-analytics.php, the other analytics head that pairs a period
picker with a button — app.css §.qm-ops-head > .d-flex already lays that shape out at
every width. The button itself carries the icon and label every other list export uses. */
@endphp
@partial('kpi-card', ['variant' => 'panel', 'accent' => 'green', 'icon' => 'fa-coins', 'label' => t_raw('common.revenue'),
'value' => money($kpis['revenue']['value']), 'spark' => $kpis['revenue']['spark'], 'meta' => $kpis['revenue']['meta']])
@partial('kpi-card', ['variant' => 'panel', 'accent' => 'blue', 'icon' => 'fa-receipt', 'label' => t_raw('common.paid_orders'),
'value' => number_format($kpis['paid']['value']), 'spark' => $kpis['paid']['spark'], 'meta' => $kpis['paid']['meta']])
@partial('kpi-card', ['variant' => 'panel', 'accent' => 'violet', 'icon' => 'fa-chart-line', 'label' => t_raw('common.average_order'),
'value' => money($kpis['aov']['value']), 'spark' => $kpis['aov']['spark'], 'meta' => $kpis['aov']['meta']])
@partial('kpi-card', ['variant' => 'panel', 'accent' => 'blue', 'icon' => 'fa-shopping-basket', 'label' => t_raw('vendor.analytics.kpi_items_per_order'),
'value' => number_format($kpis['ipt']['value'], 1), 'spark' => $kpis['ipt']['spark'], 'meta' => $kpis['ipt']['meta']])
@php /* Spend per head is only meaningful once the covers were keyed in at the
till; with none recorded the card shows an em-dash rather than a guess. */
@endphp
@partial('kpi-card', ['variant' => 'panel', 'accent' => 'teal', 'icon' => 'fa-user-friends', 'label' => t_raw('vendor.analytics.kpi_spend_per_head'),
'value' => $kpis['perHead']['value'] !== null ? money($kpis['perHead']['value']) : '—',
'spark' => $kpis['perHead']['spark'], 'meta' => $kpis['perHead']['meta']])
@partial('kpi-card', ['variant' => 'panel', 'accent' => 'amber', 'icon' => 'fa-tags', 'label' => t_raw('vendor.analytics.kpi_discounts_given'),
'value' => money($kpis['discounts']['value']), 'spark' => $kpis['discounts']['spark'], 'meta' => $kpis['discounts']['meta']])
@partial('kpi-card', ['variant' => 'panel', 'accent' => 'orange', 'icon' => 'fa-hand-holding-usd', 'label' => t_raw('vendor.analytics.kpi_tips'),
'value' => money($kpis['tips']['value']), 'spark' => $kpis['tips']['spark'], 'meta' => $kpis['tips']['meta']])
@partial('kpi-card', ['variant' => 'panel', 'accent' => 'slate', 'icon' => 'fa-undo', 'label' => t_raw('common.refunded'),
'value' => money($kpis['refunds']['value']), 'spark' => $kpis['refunds']['spark'], 'meta' => $kpis['refunds']['meta']])
{{ t_raw('dashboard.sec.trends') }}
@partial('chart-card', ['heading' => t_raw('vendor.analytics.chart_revenue_over_time'), 'sub' => t_raw('vendor.analytics.chart_revenue_over_time_caption'), 'cfg' => $revChart, 'meta' => $revMeta, 'accent' => 'green', 'opts' => ['id' => 'revChart', 'url' => route('vendor.chart-series', ['chart' => 'salesRevenue']), 'selected' => $rangeLinks['selected'], 'options' => $rangeLinks['options'], 'control' => 'compact']])
@partial('chart-card', ['heading' => t_raw('vendor.dashboard.chart_tender_title'), 'sub' => t_raw('vendor.analytics.chart_net_of_refunds_sub'), 'cfg' => $tenderChart, 'meta' => $tenderMeta, 'icon' => 'fa-chart-pie', 'accent' => 'blue'])
@partial('chart-card', ['heading' => t_raw('vendor.analytics.chart_order_channels'), 'sub' => t_raw('vendor.analytics.chart_order_channels_sub'), 'cfg' => $sourceChart, 'meta' => $sourceMeta, 'icon' => 'fa-chart-pie', 'accent' => 'violet'])
@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_discount_sources'), 'sub' => t_raw('vendor.analytics.chart_discount_sources_sub'), 'cfg' => $discChart, 'meta' => $discMeta, 'icon' => 'fa-chart-bar', 'accent' => 'amber', 'opts' => ['id' => 'salesDiscChart', 'url' => route('vendor.chart-series', ['chart' => 'salesDisc']), 'selected' => $rangeLinks['selected'], 'options' => $rangeLinks['options'], 'control' => 'compact']])
@partial('chart-card', ['heading' => t_raw('vendor.analytics.chart_money_clock'), 'sub' => t_raw('vendor.analytics.chart_money_clock_sub'), 'cfg' => $heatChart, 'meta' => $heatMeta, 'icon' => 'fa-th', 'accent' => 'rose'])
{{ t_raw('dashboard.sec.breakdown') }}
{{ t_raw('vendor.analytics.heading_channel_mix') }}
{{ t_raw('vendor.analytics.caption_channel_mix') }}
| {{ t_raw('vendor.analytics.col_channel') }} |
{{ t_raw('admin.analytics_sales.col_mode') }} |
{{ t_raw('common.orders') }} |
{{ t_raw('vendor.analytics.kpi_covers') }} |
{{ t_raw('common.collected') }} |
{{ t_raw('common.average_order') }} |
{{ t_raw('vendor.analytics.col_per_head') }} |
@if ($mixRows)
@foreach ($mixRows as $m)
| {{ $m['source_label'] }} |
{{ $m['mode_label'] }} |
{{ number_format($m['orders']) }} |
{!! $m['covers'] > 0 ? number_format($m['covers']) : dash() !!} |
{{ money($m['revenue']) }} |
{!! $m['orders'] > 0 ? money($m['revenue'] / $m['orders']) : dash() !!} |
{!! $m['covers'] > 0 ? money($m['revenue'] / $m['covers']) : dash() !!} |
@endforeach
@else
@partial('table-empty', ['colspan' => 7, 'icon' => 'fa-chart-bar', 'msg' => t_raw('vendor.analytics.empty_no_orders_period')])
@endif
@partial('table-toolbar', ['pager' => $mixPager, 'base' => '/vendor/analytics/sales'])
{{ t_raw('vendor.analytics.heading_who_took_money') }}
{{ t_raw('vendor.analytics.hint_who_took_money') }}
{{ t_raw('vendor.analytics.caption_who_took_money') }}
| {{ t_raw('vendor.analytics.col_taken_by') }} |
{{ t_raw('vendor.analytics.col_payments_taken') }} |
{{ t_raw('common.refunded') }} |
{{ t_raw('vendor.analytics.col_net_collected') }} |
{{ t_raw('vendor.analytics.col_last_taken') }} |
@if ($byStaff)
@foreach ($byStaff as $s)
@php $named = ($s['uid'] !== null && ($s['name'] ?? '') !== ''); @endphp
@if ($named)
{!! brandmark_html($s['avatar'] ?? null, (string) $s['name'], 'md', 'qm-brandmark--round') !!}
{{ (string) $s['name'] }}
@if (!empty($s['role'])){{ role_label((string) $s['role']) }}@endif
@else
@php /* Online gateway captures carry no till operator - nobody handled them. */
@endphp
{{ t_raw('vendor.analytics.taken_online') }}
@endif
|
{{ number_format((int) $s['taken']) }} |
{!! (int) $s['refunded'] > 0 ? number_format((int) $s['refunded']) : dash() !!} |
{{ money($s['net']) }} |
{!! fmt_datetime($s['last_at']) !!} |
@endforeach
@else
@partial('table-empty', ['colspan' => 5, 'icon' => 'fa-cash-register', 'msg' => t_raw('vendor.analytics.empty_no_payments_period')])
@endif
@partial('table-toolbar', ['pager' => $staffPager, 'base' => '/vendor/analytics/sales', 'showPager' => false])
{{ t_raw('vendor.analytics.heading_discounts_given') }}
{{ t_raw('vendor.analytics.caption_discounts_given') }}
| {{ t_raw('vendor.analytics.col_discount_source') }} |
{{ t_raw('common.type') }} |
{{ t_raw('common.orders') }} |
{{ t_raw('common.discount') }} |
{{ t_raw('vendor.analytics.col_avg_per_order') }} |
@if ($discRows)
@foreach ($discRows as $d)
| {{ $d['label'] }} |
@if ($d['kind'] === 'coupon'){{ t_raw('vendor.analytics.discount_kind_coupon') }}
@elseif ($d['kind'] === 'manual'){{ t_raw('vendor.analytics.discount_kind_manual') }}
@elseif ($d['kind'] === 'loyalty'){{ t_raw('vendor.analytics.discount_kind_loyalty') }}
@else{{ t_raw('common.other') }}@endif
|
{{ number_format($d['orders']) }} |
{{ money($d['amount']) }} |
{!! $d['orders'] > 0 ? money($d['amount'] / $d['orders']) : dash() !!} |
@endforeach
@else
@partial('table-empty', ['colspan' => 5, 'icon' => 'fa-tags', 'msg' => t_raw('vendor.analytics.empty_no_discounts')])
@endif
@partial('table-toolbar', ['pager' => $discPager, 'base' => '/vendor/analytics/sales', 'showPager' => false])
@php /* /.qm-d2 */
@endphp
@endsection