Files
ladill-pos/resources/views/pos/kitchen/index.blade.php
T
isaaccladandClaude Opus 4.8 d9e4b6e06e
Deploy Ladill POS / deploy (push) Successful in 30s
Add restaurant/café mode: floor, open tabs, and kitchen display (Phase 1)
Gated by a per-location service_style (retail | restaurant). Restaurant mode adds:
- Floor screen with tables (areas, seats, status) — tap a free table to open a
  dine-in tab; takeaway/counter orders open from the same screen.
- Open tickets (tabs): a sale stays pending while items are added; lines persist
  as you go (posTicket Alpine component posts each change to the server).
- Send-to-kitchen fires un-sent lines; a polling Kitchen Display (KDS) shows
  active tickets and bumps items queued → preparing → ready → served.
- Settlement reuses the existing cash / Ladill Pay flow; paying closes the tab
  and frees the table (PosSaleService::closeTicket, wired into both pay paths).
- Settings gains the mode toggle and a tables manager.

Schema is additive (new pos_tables; service_style on locations; order/kitchen
columns on sales + lines). Retail flow is untouched. Sidebar surfaces Floor +
Kitchen only in restaurant mode. New PosRestaurantTest covers the dine-in
lifecycle end to end; suite green (10 passed).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-24 08:38:18 +00:00

54 lines
3.3 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<x-app-layout title="Kitchen">
<div x-data="posKitchen(@js([
'feedUrl' => route('pos.kitchen.feed'),
'bumpUrl' => route('pos.kitchen.bump', ['line' => '__ID__']),
]))" class="space-y-4">
<div class="flex items-center justify-between">
<div>
<h1 class="text-lg font-semibold text-slate-900">Kitchen</h1>
<p class="mt-1 text-sm text-slate-500">Live tickets tap an item to advance it. Refreshes automatically.</p>
</div>
<button type="button" @click="load()" class="rounded-xl border border-slate-200 bg-white px-3 py-2 text-sm font-medium text-slate-600 hover:bg-slate-50">Refresh</button>
</div>
<template x-if="loaded && tickets.length === 0">
<div class="rounded-2xl border border-dashed border-slate-200 bg-white px-6 py-16 text-center">
<p class="text-sm text-slate-500">No active tickets. Fired orders will appear here.</p>
</div>
</template>
<div class="grid gap-4 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4">
<template x-for="t in tickets" :key="t.id">
<div class="flex flex-col overflow-hidden rounded-2xl border border-slate-200 bg-white">
<div class="flex items-center justify-between border-b border-slate-100 bg-slate-50 px-4 py-2.5">
<div>
<p class="text-sm font-semibold text-slate-900" x-text="t.table ? t.table : t.order_type.replace('_',' ')"></p>
<p class="text-[11px] text-slate-400" x-text="t.reference"></p>
</div>
<span class="rounded-full bg-slate-900/5 px-2 py-0.5 text-xs font-medium text-slate-600" x-text="elapsed(t.sent_at)"></span>
</div>
<div class="flex-1 divide-y divide-slate-100">
<template x-for="line in t.lines" :key="line.id">
<div class="flex items-center justify-between gap-2 px-4 py-2.5"
:class="line.state === 'ready' ? 'bg-emerald-50' : (line.state === 'preparing' ? 'bg-amber-50/60' : '')">
<div class="min-w-0">
<p class="text-sm font-medium text-slate-900">
<span x-text="line.quantity + '×'"></span>
<span x-text="line.name"></span>
</p>
<p x-show="line.notes" x-cloak class="text-xs text-rose-600" x-text="line.notes"></p>
<p class="text-[11px] uppercase tracking-wide text-slate-400" x-text="line.state"></p>
</div>
<button type="button" @click="bump(line)"
class="shrink-0 rounded-lg border border-slate-200 bg-white px-2.5 py-1.5 text-xs font-semibold text-slate-700 hover:bg-slate-50"
x-text="nextLabel(line.state)"></button>
</div>
</template>
</div>
</div>
</template>
</div>
</div>
</x-app-layout>