feat: change email template + add list of items
This commit is contained in:
+48
-12
@@ -17,12 +17,38 @@ let token = '';
|
||||
let cursor: string | null = null;
|
||||
let venueId = '';
|
||||
let registrationCode = '';
|
||||
const openTabs: Map<string, { customerName: string; version: number; totalInCents: number; itemCount: number }> = new Map();
|
||||
type TabLine = { productName: string; quantity: number; unitPriceInCents: number };
|
||||
type SimTab = { customerName: string; version: number; items: TabLine[] };
|
||||
|
||||
const openTabs: Map<string, SimTab> = new Map();
|
||||
let pendingCommands: Array<{ id: string; type: string; tabId: string; expectedVersion: number; paymentMethod: string }> = [];
|
||||
let tabCounter = 0;
|
||||
let plannedNames: string[] = [];
|
||||
let plannedIndex = 0;
|
||||
|
||||
// A small bar menu to fill tabs with
|
||||
const MENU: Array<{ productName: string; unitPriceInCents: number }> = [
|
||||
{ productName: 'Cola', unitPriceInCents: 250 },
|
||||
{ productName: 'Jupiler', unitPriceInCents: 280 },
|
||||
{ productName: 'Duvel', unitPriceInCents: 450 },
|
||||
{ productName: 'Spa rood', unitPriceInCents: 230 },
|
||||
{ productName: 'Koffie', unitPriceInCents: 250 },
|
||||
{ productName: 'Chips', unitPriceInCents: 200 },
|
||||
];
|
||||
|
||||
const tabTotal = (tab: SimTab) => tab.items.reduce((sum, line) => sum + line.quantity * line.unitPriceInCents, 0);
|
||||
const tabItemCount = (tab: SimTab) => tab.items.reduce((sum, line) => sum + line.quantity, 0);
|
||||
const euro = (cents: number) => `€${(cents / 100).toFixed(2)}`;
|
||||
|
||||
/** 1 to 3 different products, 1 to 4 of each. */
|
||||
function randomLines(): TabLine[] {
|
||||
const shuffled = [...MENU].sort(() => Math.random() - 0.5);
|
||||
return shuffled.slice(0, Math.floor(Math.random() * 3) + 1).map((product) => ({
|
||||
...product,
|
||||
quantity: Math.floor(Math.random() * 4) + 1,
|
||||
}));
|
||||
}
|
||||
|
||||
// ── API helpers ──────────────────────────────────────────
|
||||
async function api<T = any>(endpoint: string, options: RequestInit = {}): Promise<T> {
|
||||
const { headers: customHeaders, ...rest } = options;
|
||||
@@ -42,7 +68,12 @@ async function api<T = any>(endpoint: string, options: RequestInit = {}): Promis
|
||||
// The server treats openTabs as the complete set: tabs left out are considered closed
|
||||
function buildTabsPayload() {
|
||||
return Array.from(openTabs.entries()).map(([id, t]) => ({
|
||||
id, customerName: t.customerName, version: t.version, totalInCents: t.totalInCents, itemCount: t.itemCount,
|
||||
id,
|
||||
customerName: t.customerName,
|
||||
version: t.version,
|
||||
totalInCents: tabTotal(t),
|
||||
itemCount: tabItemCount(t),
|
||||
items: t.items,
|
||||
}));
|
||||
}
|
||||
|
||||
@@ -100,10 +131,10 @@ function addTab() {
|
||||
const names = plannedNames.length > 0 ? plannedNames : fallbackNames;
|
||||
const name = names[plannedIndex % names.length];
|
||||
plannedIndex++;
|
||||
const items = Math.floor(Math.random() * 5) + 1;
|
||||
const total = items * (Math.floor(Math.random() * 10) + 5) * 100;
|
||||
openTabs.set(tabId, { customerName: name, version: 1, totalInCents: total, itemCount: items });
|
||||
console.log(` 📋 Tab added: ${name} — €${(total / 100).toFixed(2)} (${items} items) [${tabId.substring(0, 8)}]`);
|
||||
const tab: SimTab = { customerName: name, version: 1, items: randomLines() };
|
||||
openTabs.set(tabId, tab);
|
||||
const lines = tab.items.map((line) => `${line.quantity}x ${line.productName}`).join(', ');
|
||||
console.log(` 📋 Tab added: ${name} — ${euro(tabTotal(tab))} (${lines}) [${tabId.substring(0, 8)}]`);
|
||||
}
|
||||
|
||||
async function sync() {
|
||||
@@ -151,11 +182,13 @@ async function ackAll() {
|
||||
});
|
||||
console.log(` ✅ Acked ${cmd.id.substring(0, 8)} as ${status}`);
|
||||
|
||||
// If completed, remove the tab from local state
|
||||
if (status === 'completed') {
|
||||
openTabs.delete(cmd.tabId);
|
||||
console.log(` Removed tab ${cmd.tabId.substring(0, 8)} from local state`);
|
||||
} else {
|
||||
// Like the real app, closing settles the tab: its lines are cleared but the tab stays open
|
||||
const settled = openTabs.get(cmd.tabId);
|
||||
if (status === 'completed' && settled) {
|
||||
settled.items = [];
|
||||
settled.version++;
|
||||
console.log(` Settled tab ${cmd.tabId.substring(0, 8)} (now empty, v${settled.version})`);
|
||||
} else if (status !== 'completed') {
|
||||
// Bump version on failed close
|
||||
const tab = openTabs.get(cmd.tabId);
|
||||
if (tab) {
|
||||
@@ -177,7 +210,10 @@ function listTabs() {
|
||||
}
|
||||
console.log(`\n 📋 Open Tabs (${openTabs.size}):`);
|
||||
Array.from(openTabs.entries()).forEach(([id, t]) => {
|
||||
console.log(` ${id.substring(0, 8)} — ${t.customerName} — €${(t.totalInCents / 100).toFixed(2)} (v${t.version})`);
|
||||
console.log(` ${id.substring(0, 8)} — ${t.customerName} — ${euro(tabTotal(t))} (v${t.version})`);
|
||||
for (const line of t.items) {
|
||||
console.log(` ${line.quantity}x ${line.productName} ${euro(line.quantity * line.unitPriceInCents)}`);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user