@extends('layouts.dashboard') @section('content') @php /** * Vendor → Staff: the restaurant owner manages internal staff sub-accounts. * * @var array $staff array of rows: id, name, email, role, phone, status * (role: any staff role slug; status: active|suspended) * @var array $roles slug => label for every role a member may hold (from the roles table) */ $staff = $staff ?? []; $roles = $roles ?? []; // Only the owner may touch an account whose role can itself manage staff — the same rule // StaffController enforces on save and delete, mirrored here so the UI never offers an // action the server would refuse. $staffAdminRole = static fn (string $slug): bool => in_array('staff.manage', \App\Models\Role::permissionsFor($slug), true); // Only the owner may manage manager accounts; managers see manager rows read-only // and never get the "Manager" role option (server enforces this too). $isOwner = $isOwner ?? \App\Support\Auth::is('vendor'); // Re-fill values + field error when a save was rejected (modal auto-re-opens). $formData = $formData ?? []; $formError = (string) ($formError ?? ''); $reopen = $formError !== ''; $fd = static fn (string $k, string $def = ''): string => (string) ($formData[$k] ?? $def); // Filter-bar state (mirrors the admin Users page): role / status / search. $frole = $frole ?? ''; $fstatus = $fstatus ?? ''; $fq = $fq ?? ''; $hasFilters = $frole !== '' || $fstatus !== '' || $fq !== ''; @endphp @php /* .qm-d2: the dashboard density standard (app.css §35) */ @endphp
@php // Page primary action → top-bar subheader slot (leaves the table card header for the // title + any table-scoped utility). ob_start captures the button HTML for the layout slot. ob_start(); @endphp @php \App\Support\View::slot('subhead', ob_get_clean()); @endphp

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

@if (!empty($pager['total'])){{ t_raw('vendor.staff.total_pill', [':count' => (int) $pager['total']]) }}@endif
@partial('filter-collapse')
@if (count($staff)) @foreach ($staff as $row) @php $sid = (int) $row['id']; $role = (string) $row['role']; $status = (string) $row['status']; @endphp @endforeach @else {!! partial('table-empty', [ 'colspan' => 5, 'icon' => 'fa-user-friends', // Role / status / search can all empty this table on a restaurant that has plenty of // staff. Saying "No staff yet" there is simply untrue, and it hides the Reset link's // purpose — the operator is told there is nothing to reset to. 'msg' => $hasFilters ? t_raw('vendor.staff.empty_filtered') : t_raw('vendor.staff.empty_no_staff'), ]) !!} @endif
{{ t_raw('vendor.staff.list_heading') }}
{{ t_raw('common.name') }}{{ t_raw('vendor.staff.col_role') }}{{ t_raw('common.status') }}{{ t_raw('common.joined') }}{{ t_raw('common.actions') }}
{!! brandmark_html($row['avatar'] ?? null, (string) $row['name'], 'md', 'qm-brandmark--round') !!}
{{ $row['name'] }} {{ $row['email'] }} @if (!empty($row['phone'])){{ $row['phone'] }}@endif
{!! role_pill($role) !!} {!! $status === 'active' ? t('common.active') : t('common.status_suspended') !!} {!! fmt_day($row['created_at']) !!} @if ($isOwner || !$staffAdminRole($role)) @endif @if ($isOwner || !$staffAdminRole($role))
@csrf
@endif
@partial('table-toolbar', ['pager' => $pager, 'base' => '/vendor/staff'])
@php /* ====================================================== STAFF MODAL */ @endphp
@php /* /.qm-d2 */ @endphp @endsection