@extends('layouts.dashboard') @section('content') @php /** * Vendor → Staff analytics (bird's-eye view) for one reporting window. Shows, per * staff member, the real work recorded in the order + reservation audit trails and * the money they settled at the till: orders pushed through the kitchen, items * prepared, reservations handled, tables seated, sales taken, tips and average * check. Every number is computed in StaffController::activityMetrics(). * * @var array $staff the current pager window of members, each with a ['stats'] block (owner first) * @var array $pager paginate() metadata for the leaderboard * @var array $totals staff roll-up: members/orders/items/reservations/seated/guests/sales/tips/avg_check * @var array $roles role => ['label'] (context label; colour via role_pill_class()) * @var array $rangeLinks ['options' => [days => label], 'selected' => string] * @var int $rangeDays the selected window, in days * @var bool $showMoney false for a manager: takings stay with the owner * @var array $workChart @var array $workMeta team activity per day * @var array $moneyChart @var array $moneyMeta sales taken (or items prepared) per day * @var array $ordersByMemberChart @var array $ordersByMemberMeta * @var array $rankChart @var array $rankMeta sales (or items) per member * @var array $hoursChart @var array $hoursMeta hour-of-day work pattern * @var array $kpiSparks per-metric daily series for the KPI mini trends * @var bool $hasActivity true when anyone logged work in the window */ $roleOf = static fn (string $r): array => $roles[$r] ?? ['label' => role_label($r)]; $kpiSparks = $kpiSparks ?? []; $showMoney = $showMoney ?? true; @endphp @php /* .qm-d2: the dashboard density standard (app.css §35) */ @endphp

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

{{ t_raw('vendor.staff.subtitle_analytics') }}

@foreach ($rangeLinks['options'] as $val => $text) @php $on = ((string) $val === $rangeLinks['selected']); @endphp {{ $text }} @endforeach
{{ t_raw('vendor.staff.link_manage_staff') }}
@if (!$hasActivity)

{{ t_raw('vendor.staff.empty_title_no_activity') }}

{{ t_raw('vendor.staff.empty_text_in_window') }}

@else
@partial('kpi-card', ['variant' => 'panel', 'accent' => 'teal', 'icon' => 'fa-users', 'label' => t_raw('vendor.staff.kpi_staff_members'), 'value' => number_format((int) $totals['members']), 'href' => route('vendor.staff'), 'meta' => '' . t('vendor.staff.meta_owner_staff') . '']) @partial('kpi-card', ['variant' => 'panel', 'accent' => 'blue', 'icon' => 'fa-receipt', 'label' => t_raw('vendor.staff.kpi_orders_handled'), 'value' => number_format((int) $totals['orders']), 'href' => route('vendor.orders'), 'spark' => $kpiSparks['orders'] ?? [], 'meta' => '' . t('vendor.staff.meta_progressed_in_window', [':days' => (int) $rangeDays]) . '']) @if ($showMoney) @partial('kpi-card', ['variant' => 'panel', 'accent' => 'green', 'icon' => 'fa-cash-register', 'label' => t_raw('vendor.staff.kpi_sales_taken'), 'value' => money($totals['sales']), 'spark' => $kpiSparks['sales'] ?? [], 'meta' => '' . t('vendor.staff.meta_settled_at_till') . '']) @partial('kpi-card', ['variant' => 'panel', 'accent' => 'pink', 'icon' => 'fa-hand-holding-usd', 'label' => t_raw('vendor.staff.kpi_tips'), 'value' => money($totals['tips']), 'meta' => '' . t('vendor.staff.meta_tips_on_settled') . '']) @partial('kpi-card', ['variant' => 'panel', 'accent' => 'slate', 'icon' => 'fa-balance-scale', 'label' => t_raw('vendor.staff.kpi_avg_check'), 'value' => (int) $totals['orders_paid'] > 0 ? money($totals['avg_check']) : '—', 'meta' => '' . t('vendor.staff.meta_across_n_bills', [':n' => number_format((int) $totals['orders_paid'])]) . '']) @endif @partial('kpi-card', ['variant' => 'panel', 'accent' => 'amber', 'icon' => 'fa-utensils', 'label' => t_raw('vendor.staff.kpi_items_prepared'), 'value' => number_format((int) $totals['items']), 'href' => route('vendor.kitchen'), 'spark' => $kpiSparks['items'] ?? [], 'meta' => '' . t('vendor.staff.meta_through_kitchen') . '']) @partial('kpi-card', ['variant' => 'panel', 'accent' => 'violet', 'icon' => 'fa-calendar-check', 'label' => t_raw('vendor.staff.kpi_reservations'), 'value' => number_format((int) $totals['reservations']), 'href' => route('vendor.reservations'), 'spark' => $kpiSparks['reservations'] ?? [], 'meta' => '' . t('vendor.staff.meta_bookings_managed') . '']) @partial('kpi-card', ['variant' => 'panel', 'accent' => 'orange', 'icon' => 'fa-chair', 'label' => t_raw('vendor.staff.kpi_guests_seated'), 'value' => number_format((int) $totals['guests']), 'href' => route('vendor.reservations'), 'spark' => $kpiSparks['guests'] ?? [], 'meta' => '' . t('vendor.staff.meta_covers_seated') . ''])
@php /* Trends: what the team did day by day, beside the money (or, for a manager, the volume) it produced. Each card's caption and its accessible summary are the same sentence, so the two can never drift apart. */ @endphp
@partial('chart-card', ['heading' => t_raw('vendor.staff.chart_team_activity'), 'sub' => t_raw('vendor.staff.sub_team_activity'), 'cfg' => $workChart, 'meta' => $workMeta, 'accent' => 'blue', 'icon' => 'fa-chart-line'])
@partial('chart-card', [ 'heading' => $showMoney ? t_raw('vendor.staff.chart_sales_taken') : t_raw('vendor.staff.kpi_items_prepared'), 'sub' => t_raw('vendor.staff.sub_sales_taken'), 'cfg' => $moneyChart, 'meta' => $moneyMeta, 'accent' => $showMoney ? 'green' : 'amber', 'icon' => $showMoney ? 'fa-cash-register' : 'fa-utensils'])
@php /* Breakdown: who carried the load, who took the money, and when the floor is busiest. */ @endphp
@partial('chart-card', ['heading' => t_raw('vendor.staff.chart_orders_by_member'), 'sub' => t_raw('vendor.staff.sub_orders_by_member'), 'cfg' => $ordersByMemberChart, 'meta' => $ordersByMemberMeta, 'accent' => 'blue', 'icon' => 'fa-chart-bar'])
@partial('chart-card', [ 'heading' => $showMoney ? t_raw('vendor.staff.chart_sales_by_member') : t_raw('vendor.staff.chart_items_by_member'), 'sub' => t_raw('vendor.staff.sub_rank_by_member'), 'cfg' => $rankChart, 'meta' => $rankMeta, 'accent' => $showMoney ? 'green' : 'amber', 'icon' => 'fa-chart-bar'])
@partial('chart-card', ['heading' => t_raw('vendor.staff.chart_hours_pattern'), 'sub' => t_raw('vendor.staff.sub_hours_pattern'), 'cfg' => $hoursChart, 'meta' => $hoursMeta, 'accent' => 'violet', 'icon' => 'fa-clock'])

{{ t_raw('vendor.staff.heading_leaderboard') }}

{{ t_raw('vendor.staff.leaderboard_sub_window', [':days' => (int) $rangeDays]) }}

@php /* Last active renders a relative phrase ("3 days ago"), which Date.parse() cannot read, so that cell carries the raw timestamp in data-sort-value instead. */ @endphp @if ($showMoney) @endif @foreach ($staff as $mem) @php $s = $mem['stats']; $r = $roleOf((string) $mem['role']); @endphp @if ($showMoney) @endif @endforeach
{{ t_raw('vendor.staff.caption_leaderboard') }}
{{ t_raw('vendor.staff.col_member') }} {{ t_raw('common.orders') }}{{ t_raw('vendor.staff.kpi_sales_taken') }} {{ t_raw('vendor.staff.kpi_tips') }} {{ t_raw('vendor.staff.kpi_avg_check') }}{{ t_raw('vendor.staff.col_items_prepd') }} {{ t_raw('vendor.staff.kpi_reservations') }} {{ t_raw('vendor.staff.col_tables_seated') }} {{ t_raw('vendor.staff.col_guests') }} {{ t_raw('vendor.staff.col_last_active') }}
{!! brandmark_html($mem['avatar'] ?? null, (string) $mem['name'], 'md', 'qm-brandmark--round') !!}
{{ $mem['name'] }} {{ $r['label'] }}
{!! (int) $s['orders_touched'] > 0 ? number_format((int) $s['orders_touched']) : dash() !!}{!! (float) $s['sales'] != 0.0 ? money($s['sales']) : dash() !!} {!! (float) $s['tips'] != 0.0 ? money($s['tips']) : dash() !!} {!! (int) $s['orders_paid'] > 0 ? money($s['avg_check']) : dash() !!}{!! (int) $s['items'] > 0 ? number_format((int) $s['items']) : dash() !!} {!! (int) $s['reservations'] > 0 ? number_format((int) $s['reservations']) : dash() !!} {!! (int) $s['seated'] > 0 ? number_format((int) $s['seated']) : dash() !!} {!! (int) $s['guests'] > 0 ? number_format((int) $s['guests']) : dash() !!} {!! $s['last_at'] ? e(time_ago((string) $s['last_at'])) : dash() !!}
@partial('table-toolbar', ['pager' => $pager, 'base' => '/vendor/staff/analytics'])
@endif
@php /* /.qm-d2 */ @endphp @endsection