payfrit-works/kds/test-modifiers.html
John Mizerek 0765dc1e27 Add business portal, Stripe Connect, beacon APIs, and task system
Portal:
- New business portal UI (portal/index.html, portal.css, portal.js)
- Dashboard with real-time stats (orders today, revenue, pending, menu items)
- Business info endpoint (api/businesses/get.cfm)
- Portal stats endpoint (api/portal/stats.cfm)
- Menu page links to existing full-featured menu editor

Stripe Connect:
- Onboarding endpoint (api/stripe/onboard.cfm)
- Status check endpoint (api/stripe/status.cfm)
- Payment intent creation (api/stripe/createPaymentIntent.cfm)
- Webhook handler (api/stripe/webhook.cfm)

Beacon APIs:
- List all beacons (api/beacons/list_all.cfm)
- Get business from beacon (api/beacons/getBusinessFromBeacon.cfm)

Task System:
- List pending tasks (api/tasks/listPending.cfm)
- Accept task (api/tasks/accept.cfm)

Other:
- HUD interface for quick order status display
- KDS debug/test pages
- Updated Application.cfm with public endpoint allowlist
- Order status check improvements

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-01 23:38:26 -08:00

225 lines
6.2 KiB
HTML
Raw Permalink 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.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>KDS Modifier Test</title>
<link rel="stylesheet" href="index.html">
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
background: #1a1a1a;
color: #fff;
padding: 20px;
}
.order-card {
background: #2a2a2a;
border-radius: 12px;
padding: 20px;
max-width: 600px;
margin: 20px auto;
}
.line-item {
margin-bottom: 15px;
padding: 12px;
background: #1a1a1a;
border-radius: 8px;
}
.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;
}
.item-qty {
font-size: 18px;
font-weight: 700;
color: #3b82f6;
margin-left: 10px;
min-width: 30px;
text-align: right;
}
.modifiers {
margin-left: 15px;
margin-top: 8px;
}
.modifier {
font-size: 14px;
color: #aaa;
margin-bottom: 4px;
padding-left: 12px;
border-left: 2px solid #3a3a3a;
}
</style>
</head>
<body>
<h1 style="text-align: center; margin-bottom: 20px;">Modifier Rendering Test</h1>
<div id="output"></div>
<script>
// Mock data with nested modifiers
const mockOrder = {
"OrderID": 999,
"OrderStatusID": 1,
"LineItems": [
// Root item: Burger
{
"OrderLineItemID": 1000,
"OrderLineItemParentOrderLineItemID": 0,
"ItemName": "Custom Burger",
"OrderLineItemQuantity": 1,
"OrderLineItemPrice": 12.99
},
// Level 1 modifier: Add Cheese
{
"OrderLineItemID": 1001,
"OrderLineItemParentOrderLineItemID": 1000,
"ItemName": "Add Cheese",
"OrderLineItemQuantity": 1,
"OrderLineItemPrice": 1.50
},
// Level 2 modifier: Extra Cheese (child of Add Cheese)
{
"OrderLineItemID": 1002,
"OrderLineItemParentOrderLineItemID": 1001,
"ItemName": "Extra Cheese",
"OrderLineItemQuantity": 1,
"OrderLineItemPrice": 0.50
},
// Level 3 modifier: Melt Well Done (child of Extra Cheese)
{
"OrderLineItemID": 1003,
"OrderLineItemParentOrderLineItemID": 1002,
"ItemName": "Melt Well Done",
"OrderLineItemQuantity": 1,
"OrderLineItemPrice": 0.00
},
// Level 1 modifier: Add Bacon
{
"OrderLineItemID": 1004,
"OrderLineItemParentOrderLineItemID": 1000,
"ItemName": "Add Bacon",
"OrderLineItemQuantity": 1,
"OrderLineItemPrice": 2.00
},
// Level 2 modifier: Crispy (child of Add Bacon)
{
"OrderLineItemID": 1005,
"OrderLineItemParentOrderLineItemID": 1004,
"ItemName": "Crispy",
"OrderLineItemQuantity": 1,
"OrderLineItemPrice": 0.00
},
// Another root item: Fries
{
"OrderLineItemID": 2000,
"OrderLineItemParentOrderLineItemID": 0,
"ItemName": "French Fries",
"OrderLineItemQuantity": 2,
"OrderLineItemPrice": 3.99
},
// Level 1 modifier for fries: Extra Salt
{
"OrderLineItemID": 2001,
"OrderLineItemParentOrderLineItemID": 2000,
"ItemName": "Extra Salt",
"OrderLineItemQuantity": 1,
"OrderLineItemPrice": 0.00
}
]
};
function escapeHtml(text) {
const div = document.createElement('div');
div.textContent = text;
return div.innerHTML;
}
// Render all modifiers (flattened, no nested wrappers)
function renderAllModifiers(modifiers, allItems) {
let html = '<div class="modifiers">';
modifiers.forEach(mod => {
html += renderModifierRecursive(mod, allItems, 0);
});
html += '</div>';
return html;
}
// Render modifier recursively with indentation
function renderModifierRecursive(modifier, allItems, level) {
const subModifiers = allItems.filter(mod => mod.OrderLineItemParentOrderLineItemID === modifier.OrderLineItemID);
const indent = level * 20;
console.log(`Level ${level}: ${modifier.ItemName} (ID: ${modifier.OrderLineItemID}), Sub-modifiers: ${subModifiers.length}`);
let html = `<div class="modifier" style="padding-left: ${indent}px;">+ ${escapeHtml(modifier.ItemName)}</div>`;
// Recursively render sub-modifiers
if (subModifiers.length > 0) {
subModifiers.forEach(sub => {
html += renderModifierRecursive(sub, allItems, level + 1);
});
}
return html;
}
// Render line item with modifiers
function renderLineItem(item, allItems) {
const modifiers = allItems.filter(mod => mod.OrderLineItemParentOrderLineItemID === item.OrderLineItemID);
console.log(`Item: ${item.ItemName}, ID: ${item.OrderLineItemID}, Direct modifiers: ${modifiers.length}`);
return `
<div class="line-item">
<div class="line-item-main">
<div class="item-name">${escapeHtml(item.ItemName)}</div>
<div class="item-qty">×${item.OrderLineItemQuantity}</div>
</div>
${modifiers.length > 0 ? renderAllModifiers(modifiers, allItems) : ''}
</div>
`;
}
// Render the test order
function renderTest() {
const rootItems = mockOrder.LineItems.filter(item => item.OrderLineItemParentOrderLineItemID === 0);
const html = `
<div class="order-card">
<h2>Order #${mockOrder.OrderID}</h2>
<div style="margin-top: 20px;">
${rootItems.map(item => renderLineItem(item, mockOrder.LineItems)).join('')}
</div>
</div>
`;
document.getElementById('output').innerHTML = html;
}
// Run test on load
console.log('=== KDS Modifier Test ===');
console.log('Mock order:', mockOrder);
renderTest();
</script>
</body>
</html>