This commit is contained in:
2026-05-29 07:44:27 +02:00
parent d374723fd6
commit 583021915a
3 changed files with 147 additions and 17 deletions

View File

@@ -7,9 +7,15 @@ require_once __DIR__ . '/resolve_table_operator.php';
$kdsSecret = 'karczma_kuchnia';
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
function verifyKdsSecret(): bool
{
global $kdsSecret;
$secret = isset($_GET['kds_secret']) ? trim((string) $_GET['kds_secret']) : '';
if ($secret !== $kdsSecret) {
return $secret === $kdsSecret;
}
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
if (!verifyKdsSecret()) {
http_response_code(403);
echo json_encode([
'status' => 'error',
@@ -28,20 +34,25 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') {
message_text,
otwierajacy_imie,
otwierajacy_nazwisko,
api_sent,
status_kds,
created_at
created_at,
updated_at
FROM guest_action_queue
WHERE status_kds = 0
AND created_at >= DATE_SUB(NOW(), INTERVAL 12 HOUR)
ORDER BY created_at ASC
LIMIT 50
LIMIT 100
");
$rows = $stmt->fetchAll();
foreach ($rows as &$row) {
$row['id'] = (int) $row['id'];
}
unset($row);
echo json_encode([
'status' => 'success',
'count' => count($rows),
'polled_at' => date('Y-m-d H:i:s'),
'poll_interval_seconds' => 30,
'data' => $rows,
], JSON_UNESCAPED_UNICODE);
} catch (Throwable $e) {
@@ -54,6 +65,70 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') {
exit;
}
if ($_SERVER['REQUEST_METHOD'] === 'PATCH') {
if (!verifyKdsSecret()) {
http_response_code(403);
echo json_encode([
'status' => 'error',
'message' => 'Forbidden',
], JSON_UNESCAPED_UNICODE);
exit;
}
$rawBody = file_get_contents('php://input');
$data = json_decode($rawBody, true);
if (!is_array($data)) {
http_response_code(400);
echo json_encode([
'status' => 'error',
'message' => 'Invalid JSON payload',
], JSON_UNESCAPED_UNICODE);
exit;
}
$id = isset($data['id']) ? (int) $data['id'] : 0;
if ($id < 1) {
http_response_code(422);
echo json_encode([
'status' => 'error',
'message' => 'id is required',
], JSON_UNESCAPED_UNICODE);
exit;
}
try {
$pdo = getAnalyticsPdo();
$stmt = $pdo->prepare("
UPDATE guest_action_queue
SET status_kds = 1
WHERE id = :id
AND status_kds = 0
");
$stmt->execute([':id' => $id]);
if ($stmt->rowCount() === 0) {
http_response_code(404);
echo json_encode([
'status' => 'error',
'message' => 'Queue item not found or already dismissed',
], JSON_UNESCAPED_UNICODE);
exit;
}
echo json_encode([
'status' => 'success',
'id' => $id,
], JSON_UNESCAPED_UNICODE);
} catch (Throwable $e) {
http_response_code(500);
echo json_encode([
'status' => 'error',
'message' => 'Queue dismiss failed',
], JSON_UNESCAPED_UNICODE);
}
exit;
}
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
http_response_code(405);
echo json_encode([

View File

@@ -100,7 +100,7 @@ requireAdminAuth(true);
<div class="card col-12">
<h3>Ostatnie otwarcia stron stolików</h3>
<table>
<thead><tr><th>Kiedy</th><th>Stolik</th><th>Strefa</th><th>Menu</th><th>Urządzenie</th><th>Przeglądarka</th><th>IP</th></tr></thead>
<thead><tr><th>Kiedy</th><th>Stolik</th><th>Strefa</th><th>W aplikacji</th><th>Urządzenie</th><th>Przeglądarka</th><th>IP</th></tr></thead>
<tbody id="recentOpensBody"><tr><td colspan="7" class="muted">Ładowanie...</td></tr></tbody>
</table>
</div>
@@ -129,7 +129,7 @@ requireAdminAuth(true);
<li><strong>Przywołania kelnera</strong> - ile razy gość poprosił o podejście obsługi.</li>
<li><strong>Top stoliki</strong> - które stoliki są najczęściej otwierane i używane.</li>
<li><strong>Lejek użycia</strong> - droga użytkownika: wejście -> start aplikacji -> menu -> rachunek.</li>
<li><strong>Kolumna Menu (✓/✗)</strong> - ✓ oznacza wejście do menu w tej sesji; ✗ oznacza brak wejścia do menu (w tym zatrzymanie na geo).</li>
<li><strong>Kolumna W aplikacji (✓/✗)</strong> - ✓ oznacza przejście przez ekran lokalizacji (widok statusu zamówień); ✗ oznacza zatrzymanie na geo.</li>
</ul>
</div>
</div>
@@ -200,15 +200,11 @@ requireAdminAuth(true);
const when = dt && !Number.isNaN(dt.getTime()) ? dt.toLocaleString("pl-PL") : (r.created_at || "-");
const device = r.device_type || "-";
const browser = r.browser || "-";
const enteredMenu = Number(r.entered_menu) === 1;
const reachedApp = Number(r.reached_app) === 1;
let menuCell = `<span class="status-fail" title="Zatrzymano na ekranie lokalizacji">✗</span>`;
if (enteredMenu) {
menuCell = `<span class="status-ok" title="Wszedł do menu"></span>`;
} else if (reachedApp) {
menuCell = `<span class="status-fail" title="Wszedł do aplikacji, ale nie otworzył menu">✗</span>`;
}
return `<tr><td>${when}</td><td>${r.table_id || "-"}</td><td>${r.zone || "-"}</td><td>${menuCell}</td><td>${device}</td><td>${browser}</td><td>${r.ip_address || "-"}</td></tr>`;
const appCell = reachedApp
? `<span class="status-ok" title="Przeszedł lokalizację — widok statusu zamówień">✓</span>`
: `<span class="status-fail" title="Zatrzymano na ekranie lokalizacji"></span>`;
return `<tr><td>${when}</td><td>${r.table_id || "-"}</td><td>${r.zone || "-"}</td><td>${appCell}</td><td>${device}</td><td>${browser}</td><td>${r.ip_address || "-"}</td></tr>`;
}).join("")
: `<tr><td colspan="7" class="muted">Brak danych</td></tr>`;

View File

@@ -0,0 +1,59 @@
<?php
require_once __DIR__ . '/../config/database.php';
$pdo = getAnalyticsPdo();
try {
$pdo->exec('DROP TABLE IF EXISTS kds_orders');
echo "Usunięto tabelę kds_orders (jeśli istniała).\n";
} catch (Throwable $e) {
echo "Uwaga: nie udało się usunąć kds_orders: {$e->getMessage()}\n";
}
$pdo->exec("DELETE FROM guest_action_queue WHERE message_text LIKE '[DEMO]%'");
$stmt = $pdo->prepare("
INSERT INTO guest_action_queue (
table_id,
message_type,
message_text,
otwierajacy_imie,
otwierajacy_nazwisko,
api_sent,
status_kds,
created_at
) VALUES (
:table_id,
:message_type,
:message_text,
:otwierajacy_imie,
:otwierajacy_nazwisko,
0,
0,
NOW(3)
)
");
$samples = [
[
'table_id' => '12',
'message_type' => 'waiter_call',
'message_text' => '[DEMO] Przywołanie kelnera',
'otwierajacy_imie' => 'Jan',
'otwierajacy_nazwisko' => 'Kowalski',
],
[
'table_id' => 'taras 5',
'message_type' => 'bill_request',
'message_text' => '[DEMO] Prośba o rachunek | forma płatności: karta | dokument: paragon',
'otwierajacy_imie' => 'Anna',
'otwierajacy_nazwisko' => 'Nowak',
],
];
foreach ($samples as $sample) {
$stmt->execute($sample);
echo "Wstawiono demo: {$sample['message_type']} / stolik {$sample['table_id']}\n";
}
echo "KDS feed: GET api/guest_action_queue.php?kds_secret=karczma_kuchnia\n";