Files
ladill-queue/resources/views/qms/display/public.blade.php
T
isaaccladandCursor 3d79dfad10
Deploy Ladill Queue / deploy (push) Successful in 39s
Fit public display to viewport and use Ladill Queue logo in footer.
Lock layout to 100dvh without scroll, scale ticket cards with clamp(), and replace powered-by text with the dark wordmark.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-29 23:05:40 +00:00

126 lines
7.2 KiB
PHP

<!DOCTYPE html>
<html lang="en" class="h-full overflow-hidden bg-slate-50">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="csrf-token" content="{{ csrf_token() }}">
<meta name="theme-color" content="#f8fafc">
<title>{{ $screen->name }} · Queue Display</title>
@vite(['resources/css/app.css', 'resources/js/app.js'])
</head>
<body
class="qms-display qms-display__grid-bg overflow-hidden bg-slate-50 text-slate-900"
x-data="displayBoard(@js([
'dataUrl' => $dataUrl,
'playedUrl' => $playedUrl,
'pollMs' => $pollMs,
'csrf' => csrf_token(),
'initial' => $initialPayload,
]))"
x-init="init()"
>
{{-- Voice unlock required by browsers before TTS --}}
<div
x-cloak
x-show="!speechReady"
@click="unlockSpeech()"
@keydown.enter.prevent="unlockSpeech()"
tabindex="0"
class="qms-display__unlock fixed inset-0 z-50 flex cursor-pointer items-center justify-center p-8 text-center outline-none"
role="button"
aria-label="Enable voice announcements"
>
<div class="max-w-lg rounded-3xl border border-slate-200 bg-white px-10 py-12 shadow-xl">
<div class="mx-auto flex h-16 w-16 items-center justify-center rounded-2xl bg-indigo-50 ring-1 ring-indigo-100">
<svg class="h-8 w-8 text-indigo-600" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round" d="M19.114 5.636a9 9 0 0 1 0 12.728M16.463 8.288a5.25 5.25 0 0 1 0 7.424M6.75 8.25l4.72-4.72a.75.75 0 0 1 1.28.53v15.88a.75.75 0 0 1-1.28.53l-4.72-4.72H4.51c-.88 0-1.704-.507-1.938-1.354A9.01 9.01 0 0 1 2.25 12c0-.83.112-1.633.322-2.396C2.806 8.756 3.63 8.25 4.51 8.25H6.75Z" />
</svg>
</div>
<p class="mt-6 text-2xl font-semibold tracking-tight text-slate-900">Tap to enable announcements</p>
<p class="mt-3 text-base text-slate-500">Your browser needs one interaction before this screen can call tickets aloud.</p>
</div>
</div>
<div
x-show="pollError"
x-cloak
class="fixed left-1/2 top-4 z-40 max-w-lg -translate-x-1/2 rounded-xl border border-rose-200 bg-rose-50 px-4 py-3 text-sm text-rose-800 shadow-lg"
x-text="pollError"
></div>
<div class="qms-display__shell">
<header class="qms-display__header border-b border-slate-200/80 bg-white/90 backdrop-blur-md">
<div class="mx-auto flex max-w-6xl items-center justify-between gap-4 px-5 py-4 lg:px-8">
<div class="flex min-w-0 items-center">
<img
src="{{ $logoUrl }}"
alt="{{ $logoAlt }}"
class="h-8 w-auto max-w-[min(100%,240px)] object-contain object-left lg:h-10"
>
</div>
<div class="flex shrink-0 items-center gap-4 text-right">
<div class="inline-flex items-center gap-2 rounded-full border border-emerald-200 bg-emerald-50 px-2.5 py-1 text-xs font-semibold text-emerald-700">
<span class="qms-display__live-dot h-1.5 w-1.5 rounded-full bg-emerald-500"></span>
Live
</div>
<div>
<p class="font-mono text-2xl font-semibold tabular-nums tracking-tight text-slate-900 lg:text-3xl" x-text="clock">--:--</p>
<p class="hidden text-xs text-slate-500 sm:block" x-text="dateLabel"></p>
</div>
</div>
</div>
</header>
<main class="qms-display__main mx-auto w-full max-w-6xl px-5 py-4 lg:px-8 lg:py-6">
<section class="flex min-h-0 flex-1 flex-col">
<div class="mb-3 shrink-0 text-center">
<p class="text-xs font-semibold uppercase tracking-[0.2em] text-indigo-600">Now serving</p>
<p class="mt-1 text-sm text-slate-500">Please proceed to your counter when your number appears</p>
</div>
<div class="qms-display__tickets" x-show="(payload?.now_serving ?? []).length">
<template x-for="item in (payload?.now_serving ?? []).slice(0, 3)" :key="item.ticket_number + (item.counter ?? '')">
<article class="qms-display__ticket rounded-2xl px-6 py-4 text-center lg:rounded-3xl lg:px-8">
<p class="text-xs font-semibold uppercase tracking-[0.2em] text-slate-500">Ticket number</p>
<p class="qms-display__ticket-number mt-2 font-bold" x-text="item.ticket_number"></p>
<p class="mt-2 truncate text-base font-medium text-slate-700 lg:text-lg" x-text="item.queue_name"></p>
<div class="mt-4 inline-flex max-w-full items-center gap-2 rounded-full border border-indigo-100 bg-indigo-50 px-4 py-2">
<span class="text-xs font-semibold uppercase tracking-widest text-indigo-600">Proceed to</span>
<span class="truncate text-lg font-semibold text-indigo-900 lg:text-xl" x-text="item.counter ?? '—'"></span>
</div>
</article>
</template>
</div>
<div
class="qms-display__ticket flex min-h-0 flex-1 flex-col items-center justify-center rounded-2xl px-6 py-8 text-center lg:rounded-3xl"
x-show="!(payload?.now_serving ?? []).length"
>
<div class="flex h-12 w-12 items-center justify-center rounded-2xl bg-slate-100 ring-1 ring-slate-200 lg:h-14 lg:w-14">
<svg class="h-6 w-6 text-slate-400 lg:h-7 lg:w-7" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round" d="M12 6v6h4.5m4.5 0a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" />
</svg>
</div>
<p class="mt-4 text-2xl font-semibold text-slate-900 lg:text-3xl">Please wait</p>
<p class="mt-2 max-w-md text-sm text-slate-500 lg:text-base">Your ticket number will appear here when it is called.</p>
</div>
</section>
</main>
<footer class="qms-display__footer border-t border-slate-200 bg-white/80 px-5 py-3 lg:px-8">
<div class="mx-auto flex max-w-6xl items-center justify-between gap-3">
<div class="flex items-center gap-2">
<span class="text-[10px] font-medium uppercase tracking-wider text-slate-400">Powered by</span>
<img
src="{{ $poweredByLogoUrl }}"
alt="Ladill Queue"
class="h-3.5 w-auto opacity-80"
>
</div>
<p class="text-[10px] text-slate-400" x-show="payload?.updated_at" x-text="payload?.updated_at ? 'Updated ' + new Date(payload.updated_at).toLocaleTimeString() : ''"></p>
</div>
</footer>
</div>
</body>
</html>