Add Live Queue slide to kiosk rotation
- Added a third kiosk slide showing the active customer queue.
- Customer names are derived from the local-part of their email address.
- Statuses are mapped to friendly labels:
pending -> Received
prompt_ready / songs_uploaded -> Trollgorithm Recording in Studio
revisions_requested -> Waiting for Customer Response
awaiting_payment -> Payment Due
- Completed/delivered statuses are not shown.
- If the queue overflows, a note points customers to the status page.
- Added queue-only mode (kiosk_cycle_seconds = 1) and updated the
cycle logic to rotate QR -> pricing -> queue.
- Updated /admin/settings help text for the new mode.
Bumps version to 0.5.3.
This commit is contained in:
parent
96b6470c25
commit
52558010e8
5 changed files with 129 additions and 19 deletions
|
|
@ -118,6 +118,53 @@
|
|||
font-size:1.3rem;
|
||||
color:#9ca3af;
|
||||
}
|
||||
.queue-card{
|
||||
background:rgba(31,41,55,.85);
|
||||
border:1px solid rgba(96,165,250,.25);
|
||||
border-radius:1.2rem;
|
||||
padding:3vh 4vw;
|
||||
box-shadow:0 15px 50px rgba(0,0,0,.35);
|
||||
width:100%;
|
||||
max-height:62vh;
|
||||
display:flex;
|
||||
flex-direction:column;
|
||||
}
|
||||
.queue-card h2{
|
||||
margin:0 0 2vh 0;
|
||||
font-size:clamp(1.6rem,4vw,2.6rem);
|
||||
color:#fbbf24;
|
||||
}
|
||||
.queue-list{
|
||||
list-style:none;
|
||||
margin:0;
|
||||
padding:0;
|
||||
text-align:left;
|
||||
overflow-y:auto;
|
||||
flex:1;
|
||||
}
|
||||
.queue-list li{
|
||||
display:flex;
|
||||
justify-content:space-between;
|
||||
align-items:center;
|
||||
border-bottom:1px solid rgba(147,197,253,.2);
|
||||
padding:1.4vh 0;
|
||||
font-size:clamp(1.2rem,2.8vw,1.7rem);
|
||||
}
|
||||
.queue-list li:last-child{border-bottom:none;}
|
||||
.queue-list .customer{color:#e5e7eb;font-weight:600;}
|
||||
.queue-list .status{font-weight:700;color:#60a5fa;text-align:right;}
|
||||
.queue-empty{
|
||||
font-size:1.4rem;
|
||||
color:#9ca3af;
|
||||
text-align:center;
|
||||
margin:auto 0;
|
||||
}
|
||||
.queue-note{
|
||||
font-size:1rem;
|
||||
color:#9ca3af;
|
||||
margin-top:1.5vh;
|
||||
text-align:center;
|
||||
}
|
||||
.footer{
|
||||
font-size:1rem;
|
||||
color:#9ca3af;
|
||||
|
|
@ -175,6 +222,25 @@
|
|||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% elif mode == 'queue' %}
|
||||
<div class="slide">
|
||||
<div class="queue-card">
|
||||
<h2>Live Queue</h2>
|
||||
{% if queue %}
|
||||
<ul class="queue-list">
|
||||
{% for item in queue %}
|
||||
<li>
|
||||
<span class="customer">{{ item.name }}</span>
|
||||
<span class="status">{{ item.status }}</span>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
<p class="queue-note">If your request isn't shown, visit the request page and use the status link to check your place.</p>
|
||||
{% else %}
|
||||
<p class="queue-empty">No active requests right now. Be the first!</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="slide" id="slide-qr">
|
||||
<h1>Scan to Order</h1>
|
||||
|
|
@ -198,6 +264,24 @@
|
|||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="slide hidden" id="slide-queue">
|
||||
<div class="queue-card">
|
||||
<h2>Live Queue</h2>
|
||||
{% if queue %}
|
||||
<ul class="queue-list">
|
||||
{% for item in queue %}
|
||||
<li>
|
||||
<span class="customer">{{ item.name }}</span>
|
||||
<span class="status">{{ item.status }}</span>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
<p class="queue-note">If your request isn't shown, visit the request page and use the status link to check your place.</p>
|
||||
{% else %}
|
||||
<p class="queue-empty">No active requests right now. Be the first!</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
|
|
@ -206,30 +290,28 @@
|
|||
<div class="dots">
|
||||
<div class="dot active" id="dot-qr"></div>
|
||||
<div class="dot" id="dot-prices"></div>
|
||||
<div class="dot" id="dot-queue"></div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
(function(){
|
||||
const qr = document.getElementById('slide-qr');
|
||||
const prices = document.getElementById('slide-prices');
|
||||
const queue = document.getElementById('slide-queue');
|
||||
const dotQr = document.getElementById('dot-qr');
|
||||
const dotPrices = document.getElementById('dot-prices');
|
||||
const dotQueue = document.getElementById('dot-queue');
|
||||
const seconds = {{ cycle_seconds }};
|
||||
if (seconds > 0 && qr && prices) {
|
||||
let showingQr = true;
|
||||
const slides = [qr, prices, queue];
|
||||
const dots = [dotQr, dotPrices, dotQueue];
|
||||
if (seconds > 0) {
|
||||
let idx = 0;
|
||||
setInterval(function(){
|
||||
showingQr = !showingQr;
|
||||
if (showingQr) {
|
||||
qr.classList.remove('hidden');
|
||||
prices.classList.add('hidden');
|
||||
dotQr.classList.add('active');
|
||||
dotPrices.classList.remove('active');
|
||||
} else {
|
||||
qr.classList.add('hidden');
|
||||
prices.classList.remove('hidden');
|
||||
dotQr.classList.remove('active');
|
||||
dotPrices.classList.add('active');
|
||||
}
|
||||
slides[idx].classList.add('hidden');
|
||||
dots[idx].classList.remove('active');
|
||||
idx = (idx + 1) % slides.length;
|
||||
slides[idx].classList.remove('hidden');
|
||||
dots[idx].classList.add('active');
|
||||
}, seconds * 1000);
|
||||
}
|
||||
})();
|
||||
|
|
|
|||
Reference in a new issue