@extends('layouts.dashboard') @section('content') @php /** * Vendor → POS settings: the deck of fastest-selling dishes pinned above the till's menu grid. * * ONE card, not two. The whole feature is an ordered list of at most ten ids, and it had been given * a full dashboard table — thumbnail, price and actions columns — plus a second card below it, for * a job the till itself draws as one row of tiles. The deck is now that same row: draggable chips * in the order the cashier sees them, sitting directly above the menu they are chosen from. * Ticking, unticking and arranging all edit one hidden field (assets/js/pos-settings.js), which is * what the controller stores in restaurants.pos_quick_keys. * * Arranging is the shared assets/js/qm-row-order.js — the same grip Dishes and Menu structure use, * drag or Up/Down on the handle. It is not table-only: it sets draggable on whatever row it is given. * * @var array $categories this restaurant's categories (MenuTree::picker) * @var array $items every dish the deck may draw on, same read * @var array $chosen the pinned dishes, resolved and in the operator's order * @var int $max how many keys a deck holds (QuickKeys::MAX) * @var array $restaurant this restaurant's row — the Kiosk, KDS and QR panels read their saved values from it * @var array $panels the tabs this install offers (PosSettingsController::panels), in strip order */ /* The Kiosk, KDS and QR panels below read $r, and nothing defined it: VendorController::render() passes the row as $restaurant, so every one of those controls fell through to its ?? default on every load. A switch turned on and saved came back off, and saving that tab again wrote the default straight over the stored value — the settings were being kept, the screen just never showed them. Same alias, same place in the file, as vendor/settings.php. */ $r = $restaurant ?? []; /* FOUR SERVICES, FOUR SWITCHES — a tab belongs to whichever one is on. All four tabs used to be drawn unconditionally, so an install with kiosk, QR or the kitchen display switched off still saw their tabs, still saved them ("Settings saved." and the value survived a reload), and was still offered the QR panel's link to a page that now refuses. The controller decides which services this install offers; this page draws exactly those, and the first of them opens. */ $dsPanels = $panels ?? ['pos', 'kiosk', 'qr', 'kds']; $dsFirst = $dsPanels[0] ?? ''; /** Is this tab offered? Used for both its button and its panel, so the two can never disagree. */ $dsOn = static fn (string $panel): bool => in_array($panel, $dsPanels, true); /** The `is-active` the tab strip and the panels open on — the first tab this install has. */ $dsActive = static fn (string $panel): string => $dsFirst === $panel ? ' is-active' : ''; $qkChosenIds = array_map(static fn (array $r): int => (int) $r['id'], $chosen); $qkByCat = []; foreach ($items as $qkIt) { $qkByCat[(int) $qkIt['menu_category_id']][] = $qkIt; } /** The data a chip needs, carried on the chooser's checkbox so there is one source for it. */ $qkData = static function (array $it): string { return ' data-qk-id="' . (int) $it['id'] . '"' . ' data-qk-name="' . e((string) $it['name']) . '"' . ' data-qk-price="' . e(money($it['price'])) . '"' . ' data-qk-img="' . e(media($it['image'] ?? '', 'assets/client/dish/dish-1.png')) . '"'; }; @endphp @php /* .qm-d2: the dashboard density standard (app.css §35) */ @endphp
@php // The phrases pos-settings.js writes ride on the form as :placeholder templates, so the script // stays translated without a lang key having to be published to JS. @endphp @php /* Same shell as Restaurant profile: one .qm-settings-nav, one panel per tab, driven by the shared qm-tabs.js. POS settings is the first tab; the next device surface added here is a button and a section, not a new mechanism. */ @endphp
@if ($dsOn('pos'))
@csrf @php /* No data-order-input. The shared arranger keeps one for lists that are a PAGE of a longer set; this deck is never paged or filtered, so the DOM is the whole truth and pos-settings.js rewrites this field from it at submit — whichever of the two moved a chip. */ @endphp

{{ t_raw('vendor.quickkeys.deck_heading') }}

{{ t_raw('vendor.quickkeys.count_of_max', [':n' => count($qkChosenIds), ':max' => (int) $max]) }}
@php /* The deck, drawn the way the till draws it: left to right, in cashier order. */ @endphp
@foreach ($chosen as $it)
{{ (string) $it['name'] }}
@endforeach @php // Shown only while the deck is empty; pos-settings.js hides it on the first pin. @endphp

{{ t_raw('vendor.quickkeys.empty') }}

@if ($items)
@php $qkFirst = true; @endphp @foreach ($categories as $c) @php $cid = (int) $c['id']; @endphp @continue(empty($qkByCat[$cid])) @php $qkFirst = false; @endphp @endforeach
@php $qkFirst = true; @endphp @foreach ($categories as $c) @php $cid = (int) $c['id']; @endphp @continue(empty($qkByCat[$cid]))
@foreach ($qkByCat[$cid] as $it) @php $on = in_array((int) $it['id'], $qkChosenIds, true); @endphp
@endforeach
@php $qkFirst = false; @endphp @endforeach
@else
@php // The page's own icon, the one the nav row already uses. @endphp

{{ t_raw('vendor.quickkeys.no_menu') }}

{{ t_raw('vendor.menu.tab_dishes') }}
@endif
@php /* One card, one mechanism. Each switch posts the element it keeps; whatever is not posted is what gets stored as hidden, so a switch added later is on by default for every restaurant that already exists. */ @endphp

{{ t_raw('vendor.posset.chrome_heading') }}

@php /* One row per element in PosChrome::ELEMENTS, in the order the registry lists them. Seven rows were written out by hand here; the eighth would have been a copy-paste and so would every one after it. The registry already IS the list. */ @endphp @foreach (\App\Services\PosChrome::ELEMENTS as $el) @endforeach
{{ t_raw('common.cancel') }}
@endif @if ($dsOn('kiosk'))
@csrf

{{ t_raw('vendor.settings.devices_kiosk_tab') }}

@php $kioskHeader = (int) ($r['kiosk_header_enabled'] ?? 1) === 1; @endphp @php $kioskSidebar = (int) ($r['kiosk_sidebar_enabled'] ?? 0) === 1; @endphp
@php $kioskIdle = (int) ($r['kiosk_idle_seconds'] ?? 30); @endphp @php /* Label left, control right — the same shape as the switch rows above it. A stacked label over a narrow box left the field marooned on the left. */ @endphp
{{ t_raw('vendor.settings.kiosk_idle_label') }}
{{ t_raw('vendor.settings.seconds_idle_unit') }}

{!! t_raw('vendor.settings.kiosk_idle_help') !!}

@endif @if ($dsOn('kds'))
@csrf

{{ t_raw('vendor.settings.devices_kds_tab') }}

{{ t_raw('vendor.settings.kds_help') }}

@php $kdsAutoAccept = (int) ($r['kds_auto_accept'] ?? 0) === 1; @endphp @php $kdsAutoComplete = (int) ($r['kds_auto_complete'] ?? 0) === 1; @endphp
@endif @if ($dsOn('qr'))
@csrf

{{ t_raw('vendor.settings.devices_qr_tab') }}

@php $qrFlow = (string) ($r['qr_flow'] ?? 'order_pay'); @endphp @php /* Label + note left, control right. That is the row shape everywhere in settings; a stacked label over a control on the left is the exception. */ @endphp
{{ t_raw('vendor.settings.qr_flow_label') }} {{ t_raw('vendor.settings.qr_flow_help') }}

{{ t_raw('vendor.settings.print_qr_link') }}

@endif
@php /* /.qm-d2 */ @endphp @endsection