KDS: Dark minimal theme matching HUD, fix updateStatus column names
- Redesign KDS with HUD-matching dark theme (pure black background) - Header styling identical to HUD: position, font, clock format - Status indicator moved to bottom-right corner like HUD - Remove business ID config - now uses portal localStorage only - Keep station toggle functionality - Fix updateStatus.cfm: use correct column names for dev DB (sp.Name instead of sp.ServicePointName, sp.ID instead of sp.ServicePointID) - Use relative API URL instead of hardcoded production URL Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
17d17071d1
commit
8c247eb000
3 changed files with 108 additions and 159 deletions
|
|
@ -36,9 +36,9 @@
|
||||||
|
|
||||||
<cftry>
|
<cftry>
|
||||||
<!--- Verify order exists and get details --->
|
<!--- Verify order exists and get details --->
|
||||||
<cfset qOrder = queryTimed("
|
<cfset qOrder = queryExecute("
|
||||||
SELECT o.ID, o.StatusID, o.BusinessID, o.ServicePointID,
|
SELECT o.ID, o.StatusID, o.BusinessID, o.ServicePointID,
|
||||||
sp.Name AS Name
|
sp.Name
|
||||||
FROM Orders o
|
FROM Orders o
|
||||||
LEFT JOIN ServicePoints sp ON sp.ID = o.ServicePointID
|
LEFT JOIN ServicePoints sp ON sp.ID = o.ServicePointID
|
||||||
WHERE o.ID = ?
|
WHERE o.ID = ?
|
||||||
|
|
@ -52,7 +52,7 @@
|
||||||
<cfset oldStatusID = qOrder.StatusID>
|
<cfset oldStatusID = qOrder.StatusID>
|
||||||
|
|
||||||
<!--- Update status --->
|
<!--- Update status --->
|
||||||
<cfset queryTimed("
|
<cfset queryExecute("
|
||||||
UPDATE Orders
|
UPDATE Orders
|
||||||
SET StatusID = ?,
|
SET StatusID = ?,
|
||||||
LastEditedOn = ?
|
LastEditedOn = ?
|
||||||
|
|
@ -90,13 +90,13 @@
|
||||||
<cfif NewStatusID EQ 3 AND oldStatusID NEQ 3>
|
<cfif NewStatusID EQ 3 AND oldStatusID NEQ 3>
|
||||||
<cftry>
|
<cftry>
|
||||||
<!--- Check if task already exists for this order to prevent duplicates --->
|
<!--- Check if task already exists for this order to prevent duplicates --->
|
||||||
<cfset qExisting = queryTimed("
|
<cfset qExisting = queryExecute("
|
||||||
SELECT ID FROM Tasks WHERE ID = ? LIMIT 1
|
SELECT ID FROM Tasks WHERE ID = ? LIMIT 1
|
||||||
", [ { value = OrderID, cfsqltype = "cf_sql_integer" } ], { datasource = "payfrit" })>
|
", [ { value = OrderID, cfsqltype = "cf_sql_integer" } ], { datasource = "payfrit" })>
|
||||||
|
|
||||||
<cfif qExisting.recordCount EQ 0>
|
<cfif qExisting.recordCount EQ 0>
|
||||||
<!--- Get order type --->
|
<!--- Get order type --->
|
||||||
<cfset qOrderDetails = queryTimed("
|
<cfset qOrderDetails = queryExecute("
|
||||||
SELECT o.OrderTypeID
|
SELECT o.OrderTypeID
|
||||||
FROM Orders o
|
FROM Orders o
|
||||||
WHERE o.ID = ?
|
WHERE o.ID = ?
|
||||||
|
|
@ -123,7 +123,7 @@
|
||||||
</cfif>
|
</cfif>
|
||||||
|
|
||||||
<cfif len(taskTitle)>
|
<cfif len(taskTitle)>
|
||||||
<cfset queryTimed("
|
<cfset queryExecute("
|
||||||
INSERT INTO Tasks (
|
INSERT INTO Tasks (
|
||||||
BusinessID,
|
BusinessID,
|
||||||
OrderID,
|
OrderID,
|
||||||
|
|
|
||||||
140
kds/index.html
140
kds/index.html
|
|
@ -3,67 +3,82 @@
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>Payfrit KDS - Kitchen Display System</title>
|
<title>Payfrit KDS</title>
|
||||||
<style>
|
<style>
|
||||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||||
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; background: #1a1a1a; color: #fff; padding: 20px; }
|
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; background: #000; color: #fff; height: 100vh; overflow-x: hidden; }
|
||||||
.header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 30px; padding: 20px; background: #2a2a2a; border-radius: 8px; }
|
|
||||||
.header h1 { font-size: 28px; font-weight: 600; }
|
/* Header - identical to HUD */
|
||||||
.header .status { display: flex; gap: 10px; align-items: center; }
|
.header { position: absolute; top: 20px; left: 20px; right: 20px; display: flex; justify-content: space-between; align-items: center; z-index: 100; }
|
||||||
.status-dot { width: 12px; height: 12px; border-radius: 50%; background: #4ade80; animation: pulse 2s ease-in-out infinite; }
|
.header h1 { font-size: 14px; font-weight: 300; color: #666; letter-spacing: 2px; text-transform: uppercase; margin: 0; }
|
||||||
|
.clock { font-size: 24px; font-weight: 200; color: #444; }
|
||||||
|
.btn-config { background: transparent; border: 1px solid #444; color: #666; padding: 8px 12px; border-radius: 6px; cursor: pointer; font-size: 14px; transition: all 0.2s; margin-left: 16px; }
|
||||||
|
.btn-config:hover { border-color: #666; color: #888; }
|
||||||
|
|
||||||
|
/* Status indicator - identical to HUD */
|
||||||
|
.status-indicator { position: fixed; bottom: 10px; right: 10px; width: 8px; height: 8px; border-radius: 50%; background: #22c55e; }
|
||||||
|
.status-indicator.disconnected { background: #ef4444; animation: pulse 1s infinite; }
|
||||||
@keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.5; } }
|
@keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.5; } }
|
||||||
.status-dot.error { background: #ef4444; }
|
|
||||||
.orders-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(350px, 1fr)); gap: 20px; }
|
/* Orders grid */
|
||||||
.order-card { background: #2a2a2a; border-radius: 12px; padding: 20px; border: 3px solid transparent; transition: all 0.3s ease; }
|
.orders-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); gap: 15px; padding: 80px 20px 40px 20px; }
|
||||||
.order-card.new { border-color: #3b82f6; box-shadow: 0 0 20px rgba(59, 130, 246, 0.3); }
|
|
||||||
.order-card.preparing { border-color: #f59e0b; box-shadow: 0 0 20px rgba(245, 158, 11, 0.3); }
|
/* Order cards - subtle, dark */
|
||||||
.order-card.ready { border-color: #10b981; box-shadow: 0 0 20px rgba(16, 185, 129, 0.3); }
|
.order-card { background: #111; border-radius: 8px; padding: 16px; border-left: 3px solid #333; transition: all 0.3s ease; }
|
||||||
.order-header { display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 15px; padding-bottom: 15px; border-bottom: 1px solid #3a3a3a; }
|
.order-card.new { border-left-color: #3b82f6; }
|
||||||
.order-number { font-size: 24px; font-weight: 700; }
|
.order-card.preparing { border-left-color: #f59e0b; }
|
||||||
|
.order-card.ready { border-left-color: #22c55e; }
|
||||||
|
|
||||||
|
.order-header { display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 12px; padding-bottom: 12px; border-bottom: 1px solid #222; }
|
||||||
|
.order-number { font-size: 18px; font-weight: 600; color: #888; }
|
||||||
.order-time { text-align: right; }
|
.order-time { text-align: right; }
|
||||||
.elapsed-time { font-size: 20px; font-weight: 600; margin-bottom: 5px; }
|
.elapsed-time { font-size: 16px; font-weight: 500; color: #555; margin-bottom: 2px; }
|
||||||
.elapsed-time.warning { color: #f59e0b; }
|
.elapsed-time.warning { color: #f59e0b; }
|
||||||
.elapsed-time.critical { color: #ef4444; animation: blink 1s ease-in-out infinite; }
|
.elapsed-time.critical { color: #ef4444; animation: blink 1s ease-in-out infinite; }
|
||||||
@keyframes blink { 0%, 100% { opacity: 1; } 50% { opacity: 0.6; } }
|
@keyframes blink { 0%, 100% { opacity: 1; } 50% { opacity: 0.5; } }
|
||||||
.submit-time { font-size: 12px; color: #888; }
|
.submit-time { font-size: 11px; color: #444; }
|
||||||
.order-info { margin-bottom: 15px; font-size: 14px; color: #aaa; }
|
|
||||||
.order-info div { margin-bottom: 5px; }
|
.order-info { margin-bottom: 12px; font-size: 13px; color: #555; }
|
||||||
.line-items { margin-bottom: 20px; }
|
.order-info div { margin-bottom: 3px; }
|
||||||
.line-item { margin-bottom: 15px; padding: 12px; background: #1a1a1a; border-radius: 8px; }
|
.order-info strong { color: #666; }
|
||||||
.line-item-main { display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 8px; }
|
|
||||||
.item-name { font-size: 16px; font-weight: 600; flex: 1; }
|
.line-items { margin-bottom: 15px; }
|
||||||
.item-qty { font-size: 18px; font-weight: 700; color: #3b82f6; margin-left: 10px; min-width: 30px; text-align: right; }
|
.line-item { margin-bottom: 10px; padding: 10px; background: #0a0a0a; border-radius: 6px; }
|
||||||
.modifiers { margin-left: 15px; margin-top: 8px; }
|
.line-item-main { display: flex; justify-content: space-between; align-items: flex-start; }
|
||||||
.modifier { font-size: 14px; color: #aaa; margin-bottom: 4px; padding-left: 12px; border-left: 2px solid #3a3a3a; }
|
.item-name { font-size: 14px; font-weight: 500; color: #aaa; flex: 1; }
|
||||||
.item-remark { margin-top: 8px; padding: 8px; background: #f59e0b22; border-left: 3px solid #f59e0b; font-size: 14px; color: #fbbf24; font-style: italic; }
|
.item-qty { font-size: 14px; font-weight: 600; color: #666; margin-left: 10px; }
|
||||||
.order-remarks { margin-bottom: 15px; padding: 10px; background: #ef444422; border-left: 3px solid #ef4444; font-size: 14px; color: #fca5a5; font-style: italic; }
|
.modifiers { margin-left: 12px; margin-top: 6px; }
|
||||||
.action-buttons { display: flex; gap: 10px; }
|
.modifier { font-size: 12px; color: #555; margin-bottom: 3px; padding-left: 10px; border-left: 1px solid #333; }
|
||||||
.btn { flex: 1; padding: 12px; border: none; border-radius: 8px; font-size: 14px; font-weight: 600; cursor: pointer; transition: all 0.2s ease; }
|
.item-remark { margin-top: 6px; padding: 6px 8px; background: #1a1500; border-left: 2px solid #f59e0b; font-size: 12px; color: #a58a2a; font-style: italic; }
|
||||||
.btn:hover { transform: translateY(-2px); box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3); }
|
.order-remarks { margin-bottom: 12px; padding: 8px; background: #1a0a0a; border-left: 2px solid #ef4444; font-size: 12px; color: #a55; font-style: italic; }
|
||||||
|
|
||||||
|
.action-buttons { display: flex; gap: 8px; }
|
||||||
|
.btn { flex: 1; padding: 10px; border: none; border-radius: 6px; font-size: 12px; font-weight: 600; cursor: pointer; transition: all 0.2s ease; }
|
||||||
|
.btn:hover { transform: translateY(-1px); }
|
||||||
.btn:active { transform: translateY(0); }
|
.btn:active { transform: translateY(0); }
|
||||||
.btn-start { background: #f59e0b; color: #000; }
|
.btn-start { background: #2a2000; color: #f59e0b; border: 1px solid #f59e0b33; }
|
||||||
.btn-ready { background: #10b981; color: #000; }
|
.btn-start:hover { background: #3a2a00; }
|
||||||
.btn-complete { background: #3b82f6; color: #fff; }
|
.btn-ready { background: #002a10; color: #22c55e; border: 1px solid #22c55e33; }
|
||||||
.empty-state { text-align: center; padding: 60px 20px; color: #666; }
|
.btn-ready:hover { background: #003a15; }
|
||||||
.empty-state svg { width: 80px; height: 80px; margin-bottom: 20px; opacity: 0.5; }
|
.btn-complete { background: #001a2a; color: #3b82f6; border: 1px solid #3b82f633; }
|
||||||
.empty-state h2 { font-size: 24px; margin-bottom: 10px; }
|
.btn-complete:hover { background: #002a3a; }
|
||||||
.empty-state p { font-size: 16px; }
|
|
||||||
.config-panel { position: fixed; top: 20px; right: 20px; background: #2a2a2a; padding: 15px; border-radius: 8px; display: none; z-index: 100; }
|
.empty-state { position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); text-align: center; color: #333; }
|
||||||
.config-panel.show { display: block; }
|
.empty-state svg { width: 60px; height: 60px; margin-bottom: 15px; opacity: 0.3; }
|
||||||
.config-panel label { display: block; margin-bottom: 8px; font-size: 14px; }
|
.empty-state h2 { font-size: 18px; margin-bottom: 8px; font-weight: 400; }
|
||||||
.config-panel input, .config-panel select { width: 100%; padding: 8px; margin-bottom: 12px; background: #1a1a1a; border: 1px solid #3a3a3a; border-radius: 4px; color: #fff; }
|
.empty-state p { font-size: 14px; color: #444; }
|
||||||
.btn-config { background: #3a3a3a; color: #fff; padding: 8px 16px; border: none; border-radius: 4px; cursor: pointer; }
|
|
||||||
/* Station Selection Overlay */
|
/* Station Selection Overlay */
|
||||||
.station-overlay { position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: rgba(0, 0, 0, 0.95); display: flex; flex-direction: column; align-items: center; justify-content: center; z-index: 1000; }
|
.station-overlay { position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: #000; display: flex; flex-direction: column; align-items: center; justify-content: center; z-index: 1000; }
|
||||||
.station-overlay.hidden { display: none; }
|
.station-overlay.hidden { display: none; }
|
||||||
.station-overlay h1 { font-size: 36px; margin-bottom: 10px; color: #fff; }
|
.station-overlay h1 { font-size: 14px; font-weight: 300; color: #666; letter-spacing: 2px; text-transform: uppercase; margin-bottom: 8px; }
|
||||||
.station-overlay p { font-size: 18px; color: #888; margin-bottom: 40px; }
|
.station-overlay p { font-size: 14px; color: #444; margin-bottom: 40px; }
|
||||||
.station-buttons { display: flex; flex-wrap: wrap; gap: 20px; justify-content: center; max-width: 800px; }
|
.station-buttons { display: flex; flex-wrap: wrap; gap: 15px; justify-content: center; max-width: 600px; }
|
||||||
.station-btn { width: 200px; height: 150px; border: none; border-radius: 16px; font-size: 24px; font-weight: 700; cursor: pointer; transition: all 0.2s ease; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 10px; }
|
.station-btn { width: 150px; height: 100px; border: 1px solid #333; background: #111; border-radius: 8px; font-size: 14px; font-weight: 500; color: #888; cursor: pointer; transition: all 0.2s ease; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 8px; }
|
||||||
.station-btn:hover { transform: scale(1.05); box-shadow: 0 8px 30px rgba(0, 0, 0, 0.5); }
|
.station-btn:hover { border-color: #555; color: #fff; background: #1a1a1a; }
|
||||||
.station-btn.all-stations { background: linear-gradient(135deg, #3b82f6, #1d4ed8); color: #fff; }
|
.station-btn.all-stations { border-color: #3b82f633; color: #3b82f6; }
|
||||||
.station-btn svg { width: 40px; height: 40px; }
|
.station-btn.all-stations:hover { border-color: #3b82f6; background: #001a2a; }
|
||||||
.station-name-display { padding: 4px 12px; border-radius: 20px; font-size: 12px; font-weight: 600; margin-left: 10px; }
|
.station-btn svg { width: 24px; height: 24px; opacity: 0.5; }
|
||||||
|
.station-name-display { font-size: 11px; color: #555; margin-left: 8px; text-transform: uppercase; letter-spacing: 1px; }
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
@ -75,23 +90,14 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="header">
|
<div class="header">
|
||||||
<div>
|
<h1>Payfrit KDS<span id="businessName"></span><span id="stationBadge"></span></h1>
|
||||||
<h1><span id="businessName">Kitchen Display System</span> <span id="stationBadge"></span></h1>
|
<div style="display: flex; align-items: center;">
|
||||||
</div>
|
<div class="clock" id="clock">--:--:--</div>
|
||||||
<div class="status">
|
<button class="btn-config" onclick="showStationSelection()">Station</button>
|
||||||
<div class="status-dot" id="statusDot"></div>
|
|
||||||
<span id="statusText">Connected</span>
|
|
||||||
<button class="btn-config" onclick="showStationSelection()">Switch Station</button>
|
|
||||||
<button class="btn-config" onclick="toggleConfig()">Settings</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="config-panel" id="configPanel">
|
<div class="status-indicator" id="statusIndicator"></div>
|
||||||
<label>Business ID: <input type="number" id="businessIdInput" placeholder="Enter Business ID" /></label>
|
|
||||||
<label>Service Point ID (optional): <input type="number" id="servicePointIdInput" placeholder="Leave blank for all" /></label>
|
|
||||||
<label>Refresh Interval (seconds): <input type="number" id="refreshIntervalInput" value="5" min="1" max="60" /></label>
|
|
||||||
<button class="btn-config" onclick="saveConfig()" style="width: 100%; background: #3b82f6;">Save & Reload</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="orders-grid" id="ordersGrid">
|
<div class="orders-grid" id="ordersGrid">
|
||||||
<div class="empty-state">
|
<div class="empty-state">
|
||||||
|
|
@ -103,6 +109,6 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script src="kds.js?v=2"></script>
|
<script src="kds.js?v=5"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
115
kds/kds.js
115
kds/kds.js
|
|
@ -1,8 +1,7 @@
|
||||||
// Configuration
|
// Configuration
|
||||||
let config = {
|
let config = {
|
||||||
apiBaseUrl: 'https://biz.payfrit.com/api',
|
apiBaseUrl: '/api',
|
||||||
businessId: null,
|
businessId: parseInt(localStorage.getItem('payfrit_portal_business')) || 0,
|
||||||
servicePointId: null,
|
|
||||||
stationId: null,
|
stationId: null,
|
||||||
stationName: null,
|
stationName: null,
|
||||||
stationColor: null,
|
stationColor: null,
|
||||||
|
|
@ -22,45 +21,40 @@ const STATUS_NAMES = { 1: 'New', 2: 'Preparing', 3: 'Ready', 4: 'Completed' };
|
||||||
document.addEventListener('DOMContentLoaded', () => {
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
loadConfig();
|
loadConfig();
|
||||||
checkStationSelection();
|
checkStationSelection();
|
||||||
|
updateClock();
|
||||||
|
setInterval(updateClock, 1000);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Update clock display
|
||||||
|
function updateClock() {
|
||||||
|
const now = new Date();
|
||||||
|
const hours = String(now.getHours()).padStart(2, '0');
|
||||||
|
const minutes = String(now.getMinutes()).padStart(2, '0');
|
||||||
|
const seconds = String(now.getSeconds()).padStart(2, '0');
|
||||||
|
document.getElementById('clock').textContent = `${hours}:${minutes}:${seconds}`;
|
||||||
|
}
|
||||||
|
|
||||||
// Load config from localStorage
|
// Load config from localStorage
|
||||||
function loadConfig() {
|
function loadConfig() {
|
||||||
// Get business ID from portal's shared localStorage (same key portal uses)
|
// Load KDS-specific settings (station, refresh interval)
|
||||||
const portalBusinessId = localStorage.getItem('payfrit_portal_business');
|
|
||||||
if (portalBusinessId && !isNaN(parseInt(portalBusinessId))) {
|
|
||||||
config.businessId = parseInt(portalBusinessId);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load KDS-specific settings
|
|
||||||
const saved = localStorage.getItem('kds_config');
|
const saved = localStorage.getItem('kds_config');
|
||||||
if (saved) {
|
if (saved) {
|
||||||
try {
|
try {
|
||||||
const parsed = JSON.parse(saved);
|
const parsed = JSON.parse(saved);
|
||||||
config.servicePointId = parsed.servicePointId || null;
|
config.stationId = parsed.stationId !== undefined ? parsed.stationId : null;
|
||||||
config.stationId = parsed.stationId || null;
|
|
||||||
config.stationName = parsed.stationName || null;
|
config.stationName = parsed.stationName || null;
|
||||||
config.stationColor = parsed.stationColor || null;
|
config.stationColor = parsed.stationColor || null;
|
||||||
config.refreshInterval = (parsed.refreshInterval || 5) * 1000;
|
config.refreshInterval = (parsed.refreshInterval || 5) * 1000;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('Failed to load config:', e);
|
console.error('[KDS] Failed to load config:', e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
document.getElementById('businessIdInput').value = config.businessId || '';
|
console.log('[KDS] Config loaded:', config);
|
||||||
document.getElementById('servicePointIdInput').value = config.servicePointId || '';
|
|
||||||
document.getElementById('refreshIntervalInput').value = config.refreshInterval / 1000;
|
|
||||||
|
|
||||||
// If no business ID, show config panel
|
|
||||||
if (!config.businessId) {
|
|
||||||
toggleConfig();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function saveConfigToStorage() {
|
function saveConfigToStorage() {
|
||||||
// Save KDS-specific settings only (businessId comes from portal)
|
|
||||||
localStorage.setItem('kds_config', JSON.stringify({
|
localStorage.setItem('kds_config', JSON.stringify({
|
||||||
servicePointId: config.servicePointId,
|
|
||||||
stationId: config.stationId,
|
stationId: config.stationId,
|
||||||
stationName: config.stationName,
|
stationName: config.stationName,
|
||||||
stationColor: config.stationColor,
|
stationColor: config.stationColor,
|
||||||
|
|
@ -71,7 +65,8 @@ function saveConfigToStorage() {
|
||||||
// Check if station selection is needed
|
// Check if station selection is needed
|
||||||
async function checkStationSelection() {
|
async function checkStationSelection() {
|
||||||
if (!config.businessId) {
|
if (!config.businessId) {
|
||||||
console.log('[KDS] No businessId, cannot start');
|
console.log('[KDS] No businessId - please log in via Portal first');
|
||||||
|
updateStatus(false, 'No business selected - log in via Portal');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -110,11 +105,11 @@ async function loadName() {
|
||||||
body: JSON.stringify({ BusinessID: config.businessId })
|
body: JSON.stringify({ BusinessID: config.businessId })
|
||||||
});
|
});
|
||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
if (data.OK && data.BUSINESS) {
|
if (data.OK && data.BUSINESS && data.BUSINESS.Name) {
|
||||||
document.getElementById('businessName').textContent = data.BUSINESS.Name || 'Kitchen Display System';
|
document.getElementById('businessName').textContent = ' - ' + data.BUSINESS.Name;
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('Failed to load business name:', e);
|
console.error('[KDS] Failed to load business name:', e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -170,19 +165,12 @@ async function showStationSelection() {
|
||||||
|
|
||||||
// Select a station
|
// Select a station
|
||||||
function selectStation(stationId, stationName, stationColor) {
|
function selectStation(stationId, stationName, stationColor) {
|
||||||
config.stationId = stationId || null;
|
config.stationId = stationId;
|
||||||
config.stationName = stationName;
|
config.stationName = stationName;
|
||||||
config.stationColor = stationColor;
|
config.stationColor = stationColor;
|
||||||
|
|
||||||
// Save to localStorage
|
// Save to localStorage
|
||||||
localStorage.setItem('kds_config', JSON.stringify({
|
saveConfigToStorage();
|
||||||
businessId: config.businessId,
|
|
||||||
servicePointId: config.servicePointId,
|
|
||||||
stationId: config.stationId,
|
|
||||||
stationName: config.stationName,
|
|
||||||
stationColor: config.stationColor,
|
|
||||||
refreshInterval: config.refreshInterval / 1000
|
|
||||||
}));
|
|
||||||
|
|
||||||
// Hide overlay and start
|
// Hide overlay and start
|
||||||
document.getElementById('stationOverlay').classList.add('hidden');
|
document.getElementById('stationOverlay').classList.add('hidden');
|
||||||
|
|
@ -193,49 +181,8 @@ function selectStation(stationId, stationName, stationColor) {
|
||||||
// Update station badge in header
|
// Update station badge in header
|
||||||
function updateStationBadge() {
|
function updateStationBadge() {
|
||||||
const badge = document.getElementById('stationBadge');
|
const badge = document.getElementById('stationBadge');
|
||||||
if (config.stationId && config.stationName) {
|
const name = config.stationId && config.stationName ? config.stationName : 'All';
|
||||||
const color = config.stationColor || '#3b82f6';
|
badge.innerHTML = `<span class="station-name-display">/ ${escapeHtml(name)}</span>`;
|
||||||
badge.innerHTML = `<span class="station-name-display" style="background: ${color}; color: #fff;">${escapeHtml(config.stationName)}</span>`;
|
|
||||||
} else {
|
|
||||||
badge.innerHTML = `<span class="station-name-display" style="background: #3b82f6; color: #fff;">All Stations</span>`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Save config to localStorage
|
|
||||||
function saveConfig() {
|
|
||||||
const businessId = parseInt(document.getElementById('businessIdInput').value) || null;
|
|
||||||
const servicePointId = parseInt(document.getElementById('servicePointIdInput').value) || null;
|
|
||||||
const refreshInterval = parseInt(document.getElementById('refreshIntervalInput').value) || 5;
|
|
||||||
|
|
||||||
if (!businessId) {
|
|
||||||
alert('Business ID is required');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
config.businessId = businessId;
|
|
||||||
config.servicePointId = servicePointId;
|
|
||||||
config.refreshInterval = refreshInterval * 1000;
|
|
||||||
config.stationId = null; // Reset station selection when changing business
|
|
||||||
config.stationName = null;
|
|
||||||
config.stationColor = null;
|
|
||||||
|
|
||||||
localStorage.setItem('kds_config', JSON.stringify({
|
|
||||||
businessId: config.businessId,
|
|
||||||
servicePointId: config.servicePointId,
|
|
||||||
stationId: null,
|
|
||||||
stationName: null,
|
|
||||||
stationColor: null,
|
|
||||||
refreshInterval: refreshInterval
|
|
||||||
}));
|
|
||||||
|
|
||||||
toggleConfig();
|
|
||||||
location.reload();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Toggle config panel
|
|
||||||
function toggleConfig() {
|
|
||||||
const panel = document.getElementById('configPanel');
|
|
||||||
panel.classList.toggle('show');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start auto-refresh
|
// Start auto-refresh
|
||||||
|
|
@ -257,7 +204,6 @@ async function loadOrders() {
|
||||||
headers: { 'Content-Type': 'application/json' },
|
headers: { 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
BusinessID: config.businessId,
|
BusinessID: config.businessId,
|
||||||
ServicePointID: config.servicePointId || 0,
|
|
||||||
StationID: config.stationId || 0
|
StationID: config.stationId || 0
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
@ -279,14 +225,11 @@ async function loadOrders() {
|
||||||
|
|
||||||
// Update status indicator
|
// Update status indicator
|
||||||
function updateStatus(isConnected, message) {
|
function updateStatus(isConnected, message) {
|
||||||
const dot = document.getElementById('statusDot');
|
const indicator = document.getElementById('statusIndicator');
|
||||||
const text = document.getElementById('statusText');
|
|
||||||
if (isConnected) {
|
if (isConnected) {
|
||||||
dot.classList.remove('error');
|
indicator.classList.remove('disconnected');
|
||||||
text.textContent = message || 'Connected';
|
|
||||||
} else {
|
} else {
|
||||||
dot.classList.add('error');
|
indicator.classList.add('disconnected');
|
||||||
text.textContent = message || 'Disconnected';
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Reference in a new issue