@aglyn/plugins-commerce 1.0.0-beta.232 → 1.0.0-beta.234
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +13 -13
- package/src/lib/components/cart-extras.d.ts +6 -0
- package/src/lib/components/cart-extras.js +4 -1
- package/src/lib/components/cart-extras.js.map +1 -1
- package/src/lib/components/cart-fulfillment.d.ts +117 -0
- package/src/lib/components/cart-fulfillment.js +367 -0
- package/src/lib/components/cart-fulfillment.js.map +1 -0
- package/src/lib/components/cart.js +52 -10
- package/src/lib/components/cart.js.map +1 -1
- package/src/lib/components/commerce-console-page.js +42 -1
- package/src/lib/components/commerce-console-page.js.map +1 -1
- package/src/lib/components/console/host-orders-card.component.js +38 -10
- package/src/lib/components/console/host-orders-card.component.js.map +1 -1
- package/src/lib/components/console/local-delivery-settings-card.component.d.ts +37 -0
- package/src/lib/components/console/local-delivery-settings-card.component.js +542 -0
- package/src/lib/components/console/local-delivery-settings-card.component.js.map +1 -0
- package/src/lib/components/console/locations-card.component.js +177 -3
- package/src/lib/components/console/locations-card.component.js.map +1 -1
- package/src/lib/components/console/order-detail-dialog.component.js +10 -0
- package/src/lib/components/console/order-detail-dialog.component.js.map +1 -1
- package/src/lib/components/console/order-local-fulfillment-panel.component.d.ts +44 -0
- package/src/lib/components/console/order-local-fulfillment-panel.component.js +265 -0
- package/src/lib/components/console/order-local-fulfillment-panel.component.js.map +1 -0
- package/src/lib/components/console/order-offline-notice.component.d.ts +12 -0
- package/src/lib/components/console/order-offline-notice.component.js +53 -0
- package/src/lib/components/console/order-offline-notice.component.js.map +1 -0
- package/src/lib/components/console/pickup-delivery-queue-card.component.d.ts +35 -0
- package/src/lib/components/console/pickup-delivery-queue-card.component.js +222 -0
- package/src/lib/components/console/pickup-delivery-queue-card.component.js.map +1 -0
- package/src/lib/components/console/pos/pos-api.d.ts +24 -1
- package/src/lib/components/console/pos/pos-api.js +13 -0
- package/src/lib/components/console/pos/pos-api.js.map +1 -1
- package/src/lib/components/console/pos/pos-item-dialog.component.d.ts +12 -0
- package/src/lib/components/console/pos/pos-item-dialog.component.js +10 -8
- package/src/lib/components/console/pos/pos-item-dialog.component.js.map +1 -1
- package/src/lib/components/console/pos/pos-kiosk-queue.component.d.ts +22 -0
- package/src/lib/components/console/pos/pos-kiosk-queue.component.js +168 -0
- package/src/lib/components/console/pos/pos-kiosk-queue.component.js.map +1 -0
- package/src/lib/components/console/pos/pos-tender-dialogs.component.d.ts +18 -0
- package/src/lib/components/console/pos/pos-tender-dialogs.component.js +116 -1
- package/src/lib/components/console/pos/pos-tender-dialogs.component.js.map +1 -1
- package/src/lib/components/console/pos/pos-tender-panel.component.d.ts +8 -0
- package/src/lib/components/console/pos/pos-tender-panel.component.js +77 -18
- package/src/lib/components/console/pos/pos-tender-panel.component.js.map +1 -1
- package/src/lib/components/console/pos/use-pos-display.d.ts +5 -2
- package/src/lib/components/console/pos/use-pos-display.js +3 -2
- package/src/lib/components/console/pos/use-pos-display.js.map +1 -1
- package/src/lib/components/console/pos-devices-card.component.js +2 -2
- package/src/lib/components/console/pos-devices-card.component.js.map +1 -1
- package/src/lib/components/console/pos-display/pairing-screen.d.ts +5 -2
- package/src/lib/components/console/pos-display/pairing-screen.js +7 -5
- package/src/lib/components/console/pos-display/pairing-screen.js.map +1 -1
- package/src/lib/components/console/pos-display/pos-display-api.d.ts +7 -1
- package/src/lib/components/console/pos-display/pos-display-api.js +7 -2
- package/src/lib/components/console/pos-display/pos-display-api.js.map +1 -1
- package/src/lib/components/console/pos-kiosk/kiosk-checkout.d.ts +41 -0
- package/src/lib/components/console/pos-kiosk/kiosk-checkout.js +275 -0
- package/src/lib/components/console/pos-kiosk/kiosk-checkout.js.map +1 -0
- package/src/lib/components/console/pos-kiosk/kiosk-menu.d.ts +32 -0
- package/src/lib/components/console/pos-kiosk/kiosk-menu.js +344 -0
- package/src/lib/components/console/pos-kiosk/kiosk-menu.js.map +1 -0
- package/src/lib/components/console/pos-kiosk/kiosk-staff.d.ts +12 -0
- package/src/lib/components/console/pos-kiosk/kiosk-staff.js +257 -0
- package/src/lib/components/console/pos-kiosk/kiosk-staff.js.map +1 -0
- package/src/lib/components/console/pos-kiosk/pos-kiosk-api.d.ts +114 -0
- package/src/lib/components/console/pos-kiosk/pos-kiosk-api.js +189 -0
- package/src/lib/components/console/pos-kiosk/pos-kiosk-api.js.map +1 -0
- package/src/lib/components/console/pos-kiosk/use-kiosk-idle.d.ts +16 -0
- package/src/lib/components/console/pos-kiosk/use-kiosk-idle.js +80 -0
- package/src/lib/components/console/pos-kiosk/use-kiosk-idle.js.map +1 -0
- package/src/lib/components/console/pos-kiosk-page.component.d.ts +28 -0
- package/src/lib/components/console/pos-kiosk-page.component.js +791 -0
- package/src/lib/components/console/pos-kiosk-page.component.js.map +1 -0
- package/src/lib/components/console/pos-offline/pos-offline-api.d.ts +44 -0
- package/src/lib/components/console/pos-offline/pos-offline-api.js +69 -0
- package/src/lib/components/console/pos-offline/pos-offline-api.js.map +1 -0
- package/src/lib/components/console/pos-offline/pos-offline-banner.component.d.ts +7 -0
- package/src/lib/components/console/pos-offline/pos-offline-banner.component.js +135 -0
- package/src/lib/components/console/pos-offline/pos-offline-banner.component.js.map +1 -0
- package/src/lib/components/console/pos-offline/pos-offline-checkout.component.d.ts +32 -0
- package/src/lib/components/console/pos-offline/pos-offline-checkout.component.js +287 -0
- package/src/lib/components/console/pos-offline/pos-offline-checkout.component.js.map +1 -0
- package/src/lib/components/console/pos-offline/pos-offline-store.d.ts +63 -0
- package/src/lib/components/console/pos-offline/pos-offline-store.js +145 -0
- package/src/lib/components/console/pos-offline/pos-offline-store.js.map +1 -0
- package/src/lib/components/console/pos-offline/register-offline.d.ts +24 -0
- package/src/lib/components/console/pos-offline/register-offline.js +24 -0
- package/src/lib/components/console/pos-offline/register-offline.js.map +1 -0
- package/src/lib/components/console/pos-offline/use-pos-offline.d.ts +85 -0
- package/src/lib/components/console/pos-offline/use-pos-offline.js +542 -0
- package/src/lib/components/console/pos-offline/use-pos-offline.js.map +1 -0
- package/src/lib/components/console/pos-ops/pos-shift-history-card.component.js +72 -17
- package/src/lib/components/console/pos-ops/pos-shift-history-card.component.js.map +1 -1
- package/src/lib/components/console/pos-page.component.js +174 -27
- package/src/lib/components/console/pos-page.component.js.map +1 -1
- package/src/lib/components/console/products-hub-card.component.js +35 -10
- package/src/lib/components/console/products-hub-card.component.js.map +1 -1
- package/src/lib/components/console/shipping-settings-card.component.js +1 -1
- package/src/lib/components/console/shipping-settings-card.component.js.map +1 -1
- package/src/lib/components/console/stock-movements-card.component.js +48 -16
- package/src/lib/components/console/stock-movements-card.component.js.map +1 -1
- package/src/lib/components/console/store-zones.d.ts +8 -1
- package/src/lib/components/console/store-zones.js +11 -1
- package/src/lib/components/console/store-zones.js.map +1 -1
- package/src/lib/components/order-status.js +66 -0
- package/src/lib/components/order-status.js.map +1 -1
- package/src/lib/components/product-detail.js +42 -15
- package/src/lib/components/product-detail.js.map +1 -1
- package/src/lib/constants/local-fulfillment-list-query.d.ts +48 -0
- package/src/lib/constants/local-fulfillment-list-query.js +84 -0
- package/src/lib/constants/local-fulfillment-list-query.js.map +1 -0
- package/src/lib/constants/orders-list-query.d.ts +7 -2
- package/src/lib/constants/orders-list-query.js +89 -8
- package/src/lib/constants/orders-list-query.js.map +1 -1
- package/src/lib/constants/pos-shift-list-query.d.ts +22 -0
- package/src/lib/constants/pos-shift-list-query.js +115 -0
- package/src/lib/constants/pos-shift-list-query.js.map +1 -0
- package/src/lib/constants/product-list-query.d.ts +6 -1
- package/src/lib/constants/product-list-query.js +77 -8
- package/src/lib/constants/product-list-query.js.map +1 -1
- package/src/lib/constants/stock-movement-query.d.ts +3 -2
- package/src/lib/constants/stock-movement-query.js +52 -8
- package/src/lib/constants/stock-movement-query.js.map +1 -1
- package/src/lib/model/buyer-notifications.d.ts +5 -3
- package/src/lib/model/buyer-notifications.js +25 -4
- package/src/lib/model/buyer-notifications.js.map +1 -1
- package/src/lib/model/commerce-orders.d.ts +59 -0
- package/src/lib/model/commerce-orders.js.map +1 -1
- package/src/lib/model/commerce-pos-kiosk.d.ts +175 -0
- package/src/lib/model/commerce-pos-kiosk.js +147 -0
- package/src/lib/model/commerce-pos-kiosk.js.map +1 -0
- package/src/lib/model/commerce-pos-offline.d.ts +234 -0
- package/src/lib/model/commerce-pos-offline.js +301 -0
- package/src/lib/model/commerce-pos-offline.js.map +1 -0
- package/src/lib/model/commerce-pos-ops.d.ts +16 -6
- package/src/lib/model/commerce-pos-ops.js +12 -4
- package/src/lib/model/commerce-pos-ops.js.map +1 -1
- package/src/lib/model/commerce-pos.d.ts +13 -1
- package/src/lib/model/commerce-pos.js +5 -4
- package/src/lib/model/commerce-pos.js.map +1 -1
- package/src/lib/model/commerce-stock-holds.d.ts +24 -3
- package/src/lib/model/commerce-stock-holds.js +26 -8
- package/src/lib/model/commerce-stock-holds.js.map +1 -1
- package/src/lib/model/commerce.d.ts +3 -0
- package/src/lib/model/commerce.js.map +1 -1
- package/src/lib/model/index.d.ts +4 -0
- package/src/lib/model/index.js +4 -0
- package/src/lib/model/index.js.map +1 -1
- package/src/lib/model/local-fulfillment-settings.d.ts +178 -0
- package/src/lib/model/local-fulfillment-settings.js +361 -0
- package/src/lib/model/local-fulfillment-settings.js.map +1 -0
- package/src/lib/model/order-list-fields.d.ts +10 -1
- package/src/lib/model/order-list-fields.js +1 -0
- package/src/lib/model/order-list-fields.js.map +1 -1
- package/src/lib/model/order-local-fulfillment.d.ts +131 -0
- package/src/lib/model/order-local-fulfillment.js +125 -0
- package/src/lib/model/order-local-fulfillment.js.map +1 -0
- package/src/lib/model/order-shipping-export.js +4 -0
- package/src/lib/model/order-shipping-export.js.map +1 -1
- package/src/lib/model/order-status-view.d.ts +20 -1
- package/src/lib/model/order-status-view.js +60 -6
- package/src/lib/model/order-status-view.js.map +1 -1
- package/src/lib/plugin-config.js +6 -2
- package/src/lib/plugin-config.js.map +1 -1
- package/src/lib/plugin.js +8 -0
- package/src/lib/plugin.js.map +1 -1
- package/src/lib/pos-kiosk-config.d.ts +26 -0
- package/src/lib/pos-kiosk-config.js +59 -0
- package/src/lib/pos-kiosk-config.js.map +1 -0
- package/src/lib/server/api-v1/openapi.js +8 -0
- package/src/lib/server/api-v1/openapi.js.map +1 -1
- package/src/lib/server/api-v1/order-view.d.ts +19 -0
- package/src/lib/server/api-v1/order-view.js +35 -0
- package/src/lib/server/api-v1/order-view.js.map +1 -1
- package/src/lib/server/billing-webhook.js +238 -87
- package/src/lib/server/billing-webhook.js.map +1 -1
- package/src/lib/server/cart-checkout.d.ts +2 -0
- package/src/lib/server/cart-checkout.js +173 -13
- package/src/lib/server/cart-checkout.js.map +1 -1
- package/src/lib/server/checkout-extras.js +18 -4
- package/src/lib/server/checkout-extras.js.map +1 -1
- package/src/lib/server/checkout.js +71 -14
- package/src/lib/server/checkout.js.map +1 -1
- package/src/lib/server/local-fulfillment-status.d.ts +86 -0
- package/src/lib/server/local-fulfillment-status.js +379 -0
- package/src/lib/server/local-fulfillment-status.js.map +1 -0
- package/src/lib/server/local-fulfillment.d.ts +190 -0
- package/src/lib/server/local-fulfillment.js +580 -0
- package/src/lib/server/local-fulfillment.js.map +1 -0
- package/src/lib/server/membership-register.js +3 -1
- package/src/lib/server/membership-register.js.map +1 -1
- package/src/lib/server/order-notifications.js +61 -0
- package/src/lib/server/order-notifications.js.map +1 -1
- package/src/lib/server/pos-display.d.ts +27 -1
- package/src/lib/server/pos-display.js +50 -9
- package/src/lib/server/pos-display.js.map +1 -1
- package/src/lib/server/pos-kiosk-principal.d.ts +29 -0
- package/src/lib/server/pos-kiosk-principal.js +42 -0
- package/src/lib/server/pos-kiosk-principal.js.map +1 -0
- package/src/lib/server/pos-kiosk.d.ts +54 -0
- package/src/lib/server/pos-kiosk.js +972 -0
- package/src/lib/server/pos-kiosk.js.map +1 -0
- package/src/lib/server/pos-offline-sync.d.ts +85 -0
- package/src/lib/server/pos-offline-sync.js +765 -0
- package/src/lib/server/pos-offline-sync.js.map +1 -0
- package/src/lib/server/pos-order.js +22 -4
- package/src/lib/server/pos-order.js.map +1 -1
- package/src/lib/server/pos-payment.d.ts +6 -0
- package/src/lib/server/pos-payment.js +225 -6
- package/src/lib/server/pos-payment.js.map +1 -1
- package/src/lib/server/pos-print.js +5 -0
- package/src/lib/server/pos-print.js.map +1 -1
- package/src/lib/server/pos-return.js +27 -0
- package/src/lib/server/pos-return.js.map +1 -1
- package/src/lib/server/pos-sale.d.ts +6 -0
- package/src/lib/server/pos-sale.js +2 -0
- package/src/lib/server/pos-sale.js.map +1 -1
- package/src/lib/server/pos-shift.js +8 -1
- package/src/lib/server/pos-shift.js.map +1 -1
- package/src/lib/server/refund.js +3 -0
- package/src/lib/server/refund.js.map +1 -1
- package/src/lib/server/stock-hold.d.ts +9 -1
- package/src/lib/server/stock-hold.js +15 -7
- package/src/lib/server/stock-hold.js.map +1 -1
- package/src/lib/server.js +16 -0
- package/src/lib/server.js.map +1 -1
- package/src/lib/tenant-emails.js +161 -0
- package/src/lib/tenant-emails.js.map +1 -1
|
@@ -0,0 +1,791 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Aglyn LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/ 'use client';
|
|
17
|
+
import { _ as _extends } from "@swc/helpers/_/_extends";
|
|
18
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
19
|
+
import Alert from "@mui/material/Alert";
|
|
20
|
+
import Box from "@mui/material/Box";
|
|
21
|
+
import Button from "@mui/material/Button";
|
|
22
|
+
import CircularProgress from "@mui/material/CircularProgress";
|
|
23
|
+
import Container from "@mui/material/Container";
|
|
24
|
+
import Dialog from "@mui/material/Dialog";
|
|
25
|
+
import DialogActions from "@mui/material/DialogActions";
|
|
26
|
+
import DialogContent from "@mui/material/DialogContent";
|
|
27
|
+
import DialogContentText from "@mui/material/DialogContentText";
|
|
28
|
+
import DialogTitle from "@mui/material/DialogTitle";
|
|
29
|
+
import Stack from "@mui/material/Stack";
|
|
30
|
+
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
31
|
+
import * as CommerceModel from "../../model/index.js";
|
|
32
|
+
import { newAttemptKey, posNativeBridge } from "./pos/pos-api.js";
|
|
33
|
+
import { PosItemDialog, posItemNeedsChoice } from "./pos/pos-item-dialog.component.js";
|
|
34
|
+
import { PosDisplayBrandMark, PosDisplayBrandScreen } from "./pos-display/brand-screen.js";
|
|
35
|
+
import { PosDisplayPairingScreen } from "./pos-display/pairing-screen.js";
|
|
36
|
+
import { displayMoney } from "./pos-display/pos-display-api.js";
|
|
37
|
+
import { PosDisplayReceiptScreen } from "./pos-display/receipt-screen.js";
|
|
38
|
+
import { PosDisplayTipScreen, posDisplayTouchSx } from "./pos-display/tip-screen.js";
|
|
39
|
+
import { KioskDone, KioskPaying, KioskReview } from "./pos-kiosk/kiosk-checkout.js";
|
|
40
|
+
import { KioskMenu } from "./pos-kiosk/kiosk-menu.js";
|
|
41
|
+
import { KioskStaffControl } from "./pos-kiosk/kiosk-staff.js";
|
|
42
|
+
import { clearKioskCustomerStorage, kioskApi, readKioskToken, storeKioskToken } from "./pos-kiosk/pos-kiosk-api.js";
|
|
43
|
+
import { useKioskIdle } from "./pos-kiosk/use-kiosk-idle.js";
|
|
44
|
+
/** How often the kiosk asks after a card payment in flight. */ export const POS_KIOSK_PAYMENT_POLL_MS = 1500;
|
|
45
|
+
/** A product as the register's item sheet takes it, from the kiosk's catalog. */ export function kioskItemProduct(product) {
|
|
46
|
+
return {
|
|
47
|
+
$id: product.id,
|
|
48
|
+
name: product.name,
|
|
49
|
+
slug: product.id,
|
|
50
|
+
type: 'physical',
|
|
51
|
+
status: 'active',
|
|
52
|
+
options: product.options,
|
|
53
|
+
modifierGroups: product.modifierGroups,
|
|
54
|
+
variants: product.variants.map((variant)=>({
|
|
55
|
+
id: variant.id,
|
|
56
|
+
options: variant.options,
|
|
57
|
+
priceUsd: variant.priceCents / 100,
|
|
58
|
+
// A sold-out variant reads as zero on hand; anything else as untracked,
|
|
59
|
+
// so the kiosk never learns or shows a stock count.
|
|
60
|
+
inventory: variant.soldOut ? 0 : null
|
|
61
|
+
}))
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
/** The cart line a choice makes: same item and choices merge. */ export function kioskCartLine(product, choice) {
|
|
65
|
+
var _product_variants_find;
|
|
66
|
+
const variant = (_product_variants_find = product.variants.find((candidate)=>candidate.id === choice.variant.id)) != null ? _product_variants_find : product.variants[0];
|
|
67
|
+
const picked = choice.modifiers.map((pick)=>{
|
|
68
|
+
const group = product.modifierGroups.find((candidate)=>candidate.id === pick.groupId);
|
|
69
|
+
return group == null ? void 0 : group.options.find((option)=>option.id === pick.optionId);
|
|
70
|
+
}).filter((option)=>Boolean(option));
|
|
71
|
+
const label = CommerceModel.lineLabelWithModifiers(Object.keys(variant.options).length ? Object.values(variant.options).join(' / ') : undefined, picked);
|
|
72
|
+
return _extends({
|
|
73
|
+
key: `${product.id}:${variant.id}:${CommerceModel.modifierSelectionKey(choice.modifiers)}`,
|
|
74
|
+
productId: product.id
|
|
75
|
+
}, variant.id !== 'default' || product.variants.length > 1 ? {
|
|
76
|
+
variantId: variant.id
|
|
77
|
+
} : {}, {
|
|
78
|
+
quantity: Math.min(CommerceModel.POS_KIOSK_MAX_QUANTITY, choice.quantity)
|
|
79
|
+
}, choice.modifiers.length ? {
|
|
80
|
+
modifiers: choice.modifiers
|
|
81
|
+
} : {}, {
|
|
82
|
+
name: product.name
|
|
83
|
+
}, label ? {
|
|
84
|
+
label
|
|
85
|
+
} : {}, {
|
|
86
|
+
unitCents: variant.priceCents + picked.reduce((sum, option)=>sum + option.priceCents, 0)
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* The self-service kiosk (AGL-3623), served at `/kiosk/commerce/pos-kiosk`
|
|
91
|
+
* with no staff session: a customer builds their own order and pays on the
|
|
92
|
+
* register's card reader or Tap to Pay, or sends it to the counter.
|
|
93
|
+
*
|
|
94
|
+
* It holds one secret — the kiosk token from pairing — and everything the
|
|
95
|
+
* customer chooses or types lives in this component's memory only. The idle
|
|
96
|
+
* reset (and "Done", and "Start over") voids an unpaid order, drops the
|
|
97
|
+
* cart, the tip and any email or phone, sweeps the kiosk's storage keys, and
|
|
98
|
+
* remounts every screen, so the next customer finds nothing of the last.
|
|
99
|
+
*/ export default function PosKioskPage(_props) {
|
|
100
|
+
var _ref, _ref1, _ref2, _ref3, _idle_warning;
|
|
101
|
+
const [token, setToken] = useState(undefined);
|
|
102
|
+
const [context, setContext] = useState(null);
|
|
103
|
+
const [catalog, setCatalog] = useState(null);
|
|
104
|
+
const [catalogLoading, setCatalogLoading] = useState(false);
|
|
105
|
+
const [categoryId, setCategoryId] = useState(null);
|
|
106
|
+
const [phase, setPhase] = useState({
|
|
107
|
+
kind: 'start'
|
|
108
|
+
});
|
|
109
|
+
const [lines, setLines] = useState([]);
|
|
110
|
+
const [itemProduct, setItemProduct] = useState(null);
|
|
111
|
+
const [cartOpen, setCartOpen] = useState(false);
|
|
112
|
+
const [sale, setSale] = useState(null);
|
|
113
|
+
const [tip, setTip] = useState({
|
|
114
|
+
tipChoice: 'none'
|
|
115
|
+
});
|
|
116
|
+
const [busy, setBusy] = useState(false);
|
|
117
|
+
const [notice, setNotice] = useState(null);
|
|
118
|
+
const [offline, setOffline] = useState(false);
|
|
119
|
+
// Bumped by every reset: keys every screen, so inputs never carry over.
|
|
120
|
+
const [turn, setTurn] = useState(0);
|
|
121
|
+
// One attempt per cart, and one per press of a payment button.
|
|
122
|
+
const checkoutKey = useRef(null);
|
|
123
|
+
const payKey = useRef(null);
|
|
124
|
+
const saleRef = useRef(sale);
|
|
125
|
+
saleRef.current = sale;
|
|
126
|
+
const phaseRef = useRef(phase);
|
|
127
|
+
phaseRef.current = phase;
|
|
128
|
+
useEffect(()=>{
|
|
129
|
+
setToken(readKioskToken());
|
|
130
|
+
}, []);
|
|
131
|
+
const unpaired = useCallback(()=>{
|
|
132
|
+
storeKioskToken(null);
|
|
133
|
+
clearKioskCustomerStorage();
|
|
134
|
+
setToken(null);
|
|
135
|
+
setContext(null);
|
|
136
|
+
setCatalog(null);
|
|
137
|
+
setSale(null);
|
|
138
|
+
setLines([]);
|
|
139
|
+
setPhase({
|
|
140
|
+
kind: 'start'
|
|
141
|
+
});
|
|
142
|
+
}, []);
|
|
143
|
+
/** A response that says the kiosk is no longer paired ends the session. */ const lost = useCallback((status)=>{
|
|
144
|
+
if (status === 401) {
|
|
145
|
+
unpaired();
|
|
146
|
+
return true;
|
|
147
|
+
}
|
|
148
|
+
return false;
|
|
149
|
+
}, [
|
|
150
|
+
unpaired
|
|
151
|
+
]);
|
|
152
|
+
// The kiosk's settings and the menu: read when paired, and again every
|
|
153
|
+
// ten minutes while idle on the start screen, so an edit reaches it.
|
|
154
|
+
const refresh = useCallback(async ()=>{
|
|
155
|
+
if (!token) return;
|
|
156
|
+
const result = await kioskApi.context(token);
|
|
157
|
+
if (lost(result.status)) return;
|
|
158
|
+
setOffline(!result.ok && result.status === 0);
|
|
159
|
+
if (result.ok && result.value) setContext(result.value);
|
|
160
|
+
}, [
|
|
161
|
+
token,
|
|
162
|
+
lost
|
|
163
|
+
]);
|
|
164
|
+
useEffect(()=>{
|
|
165
|
+
void refresh();
|
|
166
|
+
const timer = setInterval(()=>{
|
|
167
|
+
if (phaseRef.current.kind === 'start') void refresh();
|
|
168
|
+
}, 10 * 60 * 1000);
|
|
169
|
+
return ()=>clearInterval(timer);
|
|
170
|
+
}, [
|
|
171
|
+
refresh
|
|
172
|
+
]);
|
|
173
|
+
useEffect(()=>{
|
|
174
|
+
if (!token) return undefined;
|
|
175
|
+
let active = true;
|
|
176
|
+
setCatalogLoading(true);
|
|
177
|
+
void kioskApi.catalog(token, categoryId).then((result)=>{
|
|
178
|
+
if (!active) return;
|
|
179
|
+
setCatalogLoading(false);
|
|
180
|
+
if (lost(result.status)) return;
|
|
181
|
+
if (result.ok && result.value) setCatalog(result.value);
|
|
182
|
+
else setOffline(result.status === 0);
|
|
183
|
+
});
|
|
184
|
+
return ()=>{
|
|
185
|
+
active = false;
|
|
186
|
+
};
|
|
187
|
+
}, [
|
|
188
|
+
token,
|
|
189
|
+
categoryId,
|
|
190
|
+
turn,
|
|
191
|
+
lost
|
|
192
|
+
]);
|
|
193
|
+
const currency = (_ref = (_ref1 = context == null ? void 0 : context.currency) != null ? _ref1 : catalog == null ? void 0 : catalog.currency) != null ? _ref : 'usd';
|
|
194
|
+
const money = useCallback((cents)=>displayMoney(cents, currency), [
|
|
195
|
+
currency
|
|
196
|
+
]);
|
|
197
|
+
/**
|
|
198
|
+
* THE RESET: the unpaid order voided, every customer detail dropped from
|
|
199
|
+
* memory and storage, and the screens remounted on the start screen.
|
|
200
|
+
*/ const reset = useCallback(()=>{
|
|
201
|
+
const open = saleRef.current;
|
|
202
|
+
if (token && open && open.status === 'open') void kioskApi.abandon(token, open.orderId);
|
|
203
|
+
setSale(null);
|
|
204
|
+
setLines([]);
|
|
205
|
+
setTip({
|
|
206
|
+
tipChoice: 'none'
|
|
207
|
+
});
|
|
208
|
+
setItemProduct(null);
|
|
209
|
+
setCartOpen(false);
|
|
210
|
+
setNotice(null);
|
|
211
|
+
setCategoryId(null);
|
|
212
|
+
checkoutKey.current = null;
|
|
213
|
+
payKey.current = null;
|
|
214
|
+
clearKioskCustomerStorage();
|
|
215
|
+
setPhase({
|
|
216
|
+
kind: 'start'
|
|
217
|
+
});
|
|
218
|
+
setTurn((value)=>value + 1);
|
|
219
|
+
}, [
|
|
220
|
+
token
|
|
221
|
+
]);
|
|
222
|
+
const idle = useKioskIdle({
|
|
223
|
+
// Never while a card is being collected: the customer is at the reader.
|
|
224
|
+
active: Boolean(token) && phase.kind !== 'start' && phase.kind !== 'paying',
|
|
225
|
+
idleSeconds: (_ref2 = context == null ? void 0 : context.idleSeconds) != null ? _ref2 : CommerceModel.POS_KIOSK_IDLE_SECONDS_DEFAULT,
|
|
226
|
+
warningSeconds: CommerceModel.POS_KIOSK_IDLE_WARNING_SECONDS,
|
|
227
|
+
onExpire: reset
|
|
228
|
+
});
|
|
229
|
+
// The order-number screen returns to the start on its own.
|
|
230
|
+
useEffect(()=>{
|
|
231
|
+
if (phase.kind !== 'done') return undefined;
|
|
232
|
+
const timer = setTimeout(reset, CommerceModel.POS_KIOSK_DONE_SECONDS * 1000);
|
|
233
|
+
return ()=>clearTimeout(timer);
|
|
234
|
+
}, [
|
|
235
|
+
phase.kind,
|
|
236
|
+
reset
|
|
237
|
+
]);
|
|
238
|
+
const addChoice = useCallback((product, choice)=>{
|
|
239
|
+
const line = kioskCartLine(product, choice);
|
|
240
|
+
checkoutKey.current = null;
|
|
241
|
+
setLines((current)=>{
|
|
242
|
+
const existing = current.find((candidate)=>candidate.key === line.key);
|
|
243
|
+
if (existing) {
|
|
244
|
+
return current.map((candidate)=>candidate.key === line.key ? _extends({}, candidate, {
|
|
245
|
+
quantity: Math.min(CommerceModel.POS_KIOSK_MAX_QUANTITY, candidate.quantity + line.quantity)
|
|
246
|
+
}) : candidate);
|
|
247
|
+
}
|
|
248
|
+
if (current.length >= CommerceModel.POS_KIOSK_MAX_LINES) return current;
|
|
249
|
+
return [
|
|
250
|
+
...current,
|
|
251
|
+
line
|
|
252
|
+
];
|
|
253
|
+
});
|
|
254
|
+
}, []);
|
|
255
|
+
const tapProduct = useCallback((product)=>{
|
|
256
|
+
var _product_variants_;
|
|
257
|
+
const asItem = kioskItemProduct(product);
|
|
258
|
+
if (posItemNeedsChoice(asItem)) {
|
|
259
|
+
setItemProduct(product);
|
|
260
|
+
return;
|
|
261
|
+
}
|
|
262
|
+
const variant = asItem.variants[0];
|
|
263
|
+
if (!variant || ((_product_variants_ = product.variants[0]) == null ? void 0 : _product_variants_.soldOut)) return;
|
|
264
|
+
addChoice(product, {
|
|
265
|
+
variant,
|
|
266
|
+
modifiers: [],
|
|
267
|
+
quantity: 1
|
|
268
|
+
});
|
|
269
|
+
}, [
|
|
270
|
+
addChoice
|
|
271
|
+
]);
|
|
272
|
+
const checkout = useCallback(async ()=>{
|
|
273
|
+
var _result_value;
|
|
274
|
+
if (!token || busy || lines.length === 0) return;
|
|
275
|
+
if (!checkoutKey.current) checkoutKey.current = newAttemptKey();
|
|
276
|
+
setBusy(true);
|
|
277
|
+
setNotice(null);
|
|
278
|
+
const result = await kioskApi.checkout(token, lines.map(({ productId, variantId, quantity, modifiers })=>_extends({
|
|
279
|
+
productId
|
|
280
|
+
}, variantId ? {
|
|
281
|
+
variantId
|
|
282
|
+
} : {}, {
|
|
283
|
+
quantity
|
|
284
|
+
}, modifiers ? {
|
|
285
|
+
modifiers
|
|
286
|
+
} : {})), checkoutKey.current);
|
|
287
|
+
setBusy(false);
|
|
288
|
+
if (lost(result.status)) return;
|
|
289
|
+
if (!result.ok || !((_result_value = result.value) == null ? void 0 : _result_value.sale)) {
|
|
290
|
+
var _result_error;
|
|
291
|
+
// A refused cart is changed before it is tried again.
|
|
292
|
+
checkoutKey.current = null;
|
|
293
|
+
setNotice((_result_error = result.error) != null ? _result_error : 'Your order could not be priced. Try again.');
|
|
294
|
+
return;
|
|
295
|
+
}
|
|
296
|
+
setSale(result.value.sale);
|
|
297
|
+
setCartOpen(false);
|
|
298
|
+
setPhase({
|
|
299
|
+
kind: 'review'
|
|
300
|
+
});
|
|
301
|
+
}, [
|
|
302
|
+
token,
|
|
303
|
+
busy,
|
|
304
|
+
lines,
|
|
305
|
+
lost
|
|
306
|
+
]);
|
|
307
|
+
const backToMenu = useCallback(()=>{
|
|
308
|
+
const open = saleRef.current;
|
|
309
|
+
if (token && open && open.status === 'open') void kioskApi.abandon(token, open.orderId);
|
|
310
|
+
setSale(null);
|
|
311
|
+
checkoutKey.current = null;
|
|
312
|
+
setNotice(null);
|
|
313
|
+
setPhase({
|
|
314
|
+
kind: 'menu'
|
|
315
|
+
});
|
|
316
|
+
}, [
|
|
317
|
+
token
|
|
318
|
+
]);
|
|
319
|
+
const sendToCounter = useCallback(async ()=>{
|
|
320
|
+
var _result_value;
|
|
321
|
+
const open = saleRef.current;
|
|
322
|
+
if (!token || !open) return;
|
|
323
|
+
setBusy(true);
|
|
324
|
+
const result = await kioskApi.counter(token, open.orderId);
|
|
325
|
+
setBusy(false);
|
|
326
|
+
if (lost(result.status)) return;
|
|
327
|
+
if (!result.ok || !((_result_value = result.value) == null ? void 0 : _result_value.sale)) {
|
|
328
|
+
var _result_error;
|
|
329
|
+
setNotice((_result_error = result.error) != null ? _result_error : 'Your order could not be sent to the counter.');
|
|
330
|
+
return;
|
|
331
|
+
}
|
|
332
|
+
setSale(result.value.sale);
|
|
333
|
+
setLines([]);
|
|
334
|
+
setPhase({
|
|
335
|
+
kind: 'done'
|
|
336
|
+
});
|
|
337
|
+
}, [
|
|
338
|
+
token,
|
|
339
|
+
lost
|
|
340
|
+
]);
|
|
341
|
+
const startPayment = useCallback(async (method, answer)=>{
|
|
342
|
+
var _ref;
|
|
343
|
+
const open = saleRef.current;
|
|
344
|
+
if (!token || !open) return;
|
|
345
|
+
if (!payKey.current) payKey.current = newAttemptKey();
|
|
346
|
+
setBusy(true);
|
|
347
|
+
setNotice(null);
|
|
348
|
+
const result = await kioskApi.pay(token, _extends({
|
|
349
|
+
orderId: open.orderId,
|
|
350
|
+
method
|
|
351
|
+
}, answer), payKey.current);
|
|
352
|
+
if (lost(result.status)) return setBusy(false);
|
|
353
|
+
if (!result.ok || !result.value) {
|
|
354
|
+
var _result_error;
|
|
355
|
+
setBusy(false);
|
|
356
|
+
payKey.current = null;
|
|
357
|
+
setNotice((_result_error = result.error) != null ? _result_error : 'The card payment could not be started.');
|
|
358
|
+
setPhase({
|
|
359
|
+
kind: 'review'
|
|
360
|
+
});
|
|
361
|
+
return;
|
|
362
|
+
}
|
|
363
|
+
const { sale: next, paymentId, clientSecret, paymentIntentId } = result.value;
|
|
364
|
+
setSale(next);
|
|
365
|
+
const tipCents = CommerceModel.posKioskTipCents(answer.tipChoice, {
|
|
366
|
+
baseCents: open.dueCents,
|
|
367
|
+
enabled: true,
|
|
368
|
+
percentages: (_ref = context == null ? void 0 : context.tipping.percentages) != null ? _ref : [],
|
|
369
|
+
percent: answer.tipPercent,
|
|
370
|
+
cents: answer.tipCents
|
|
371
|
+
});
|
|
372
|
+
const chargeCents = open.dueCents + (tipCents != null ? tipCents : 0);
|
|
373
|
+
setPhase({
|
|
374
|
+
kind: 'paying',
|
|
375
|
+
method,
|
|
376
|
+
paymentId: paymentId != null ? paymentId : null,
|
|
377
|
+
chargeCents,
|
|
378
|
+
failure: null
|
|
379
|
+
});
|
|
380
|
+
setBusy(false);
|
|
381
|
+
if (method === 'tap') {
|
|
382
|
+
const bridge = posNativeBridge();
|
|
383
|
+
if (!bridge || !clientSecret || !paymentIntentId) {
|
|
384
|
+
setPhase({
|
|
385
|
+
kind: 'paying',
|
|
386
|
+
method,
|
|
387
|
+
paymentId: paymentId != null ? paymentId : null,
|
|
388
|
+
chargeCents,
|
|
389
|
+
failure: 'Tap to Pay is not available on this device.'
|
|
390
|
+
});
|
|
391
|
+
return;
|
|
392
|
+
}
|
|
393
|
+
const collected = await bridge.collectCardPayment({
|
|
394
|
+
paymentIntentId,
|
|
395
|
+
clientSecret,
|
|
396
|
+
amountCents: chargeCents
|
|
397
|
+
}).catch(()=>({
|
|
398
|
+
status: 'failed',
|
|
399
|
+
message: undefined
|
|
400
|
+
}));
|
|
401
|
+
if (collected.status !== 'collected') {
|
|
402
|
+
var _collected_message;
|
|
403
|
+
setPhase({
|
|
404
|
+
kind: 'paying',
|
|
405
|
+
method,
|
|
406
|
+
paymentId: paymentId != null ? paymentId : null,
|
|
407
|
+
chargeCents,
|
|
408
|
+
failure: collected.status === 'canceled' ? 'The payment was canceled.' : (_collected_message = collected.message) != null ? _collected_message : 'The card was not read.'
|
|
409
|
+
});
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
}, [
|
|
413
|
+
token,
|
|
414
|
+
lost,
|
|
415
|
+
context
|
|
416
|
+
]);
|
|
417
|
+
// The card in flight, asked after until it is paid or it fails.
|
|
418
|
+
const paymentId = phase.kind === 'paying' ? phase.paymentId : null;
|
|
419
|
+
const paymentFailed = phase.kind === 'paying' ? Boolean(phase.failure) : false;
|
|
420
|
+
useEffect(()=>{
|
|
421
|
+
if (!token || !paymentId || paymentFailed) return undefined;
|
|
422
|
+
const open = saleRef.current;
|
|
423
|
+
if (!open) return undefined;
|
|
424
|
+
let active = true;
|
|
425
|
+
const timer = setInterval(async ()=>{
|
|
426
|
+
var _result_value, _next_payment;
|
|
427
|
+
const result = await kioskApi.paymentStatus(token, open.orderId, paymentId);
|
|
428
|
+
if (!active) return;
|
|
429
|
+
if (lost(result.status)) return;
|
|
430
|
+
const next = (_result_value = result.value) == null ? void 0 : _result_value.sale;
|
|
431
|
+
if (!next) return;
|
|
432
|
+
setSale(next);
|
|
433
|
+
if (next.status === 'paid') {
|
|
434
|
+
clearInterval(timer);
|
|
435
|
+
setLines([]);
|
|
436
|
+
payKey.current = null;
|
|
437
|
+
setPhase({
|
|
438
|
+
kind: 'receipt'
|
|
439
|
+
});
|
|
440
|
+
return;
|
|
441
|
+
}
|
|
442
|
+
const status = ((_next_payment = next.payment) == null ? void 0 : _next_payment.id) === paymentId ? next.payment.status : '';
|
|
443
|
+
if (status === 'failed' || status === 'canceled') {
|
|
444
|
+
clearInterval(timer);
|
|
445
|
+
payKey.current = null;
|
|
446
|
+
setPhase((current)=>{
|
|
447
|
+
var _ref;
|
|
448
|
+
var _next_payment;
|
|
449
|
+
return current.kind === 'paying' ? _extends({}, current, {
|
|
450
|
+
failure: (_ref = (_next_payment = next.payment) == null ? void 0 : _next_payment.failureMessage) != null ? _ref : 'The card was declined.'
|
|
451
|
+
}) : current;
|
|
452
|
+
});
|
|
453
|
+
}
|
|
454
|
+
}, POS_KIOSK_PAYMENT_POLL_MS);
|
|
455
|
+
return ()=>{
|
|
456
|
+
active = false;
|
|
457
|
+
clearInterval(timer);
|
|
458
|
+
};
|
|
459
|
+
}, [
|
|
460
|
+
token,
|
|
461
|
+
paymentId,
|
|
462
|
+
paymentFailed,
|
|
463
|
+
lost
|
|
464
|
+
]);
|
|
465
|
+
const cancelPayment = useCallback(async ()=>{
|
|
466
|
+
var _fresh_value, _fresh_value1;
|
|
467
|
+
const open = saleRef.current;
|
|
468
|
+
if (!token || !open || phase.kind !== 'paying') return;
|
|
469
|
+
setBusy(true);
|
|
470
|
+
if (phase.paymentId && !phase.failure) await kioskApi.cancelPayment(token, open.orderId, phase.paymentId);
|
|
471
|
+
const fresh = await kioskApi.sale(token, open.orderId);
|
|
472
|
+
setBusy(false);
|
|
473
|
+
payKey.current = null;
|
|
474
|
+
if ((_fresh_value = fresh.value) == null ? void 0 : _fresh_value.sale) setSale(fresh.value.sale);
|
|
475
|
+
if (((_fresh_value1 = fresh.value) == null ? void 0 : _fresh_value1.sale.status) === 'paid') {
|
|
476
|
+
setPhase({
|
|
477
|
+
kind: 'receipt'
|
|
478
|
+
});
|
|
479
|
+
return;
|
|
480
|
+
}
|
|
481
|
+
setPhase({
|
|
482
|
+
kind: 'review'
|
|
483
|
+
});
|
|
484
|
+
}, [
|
|
485
|
+
token,
|
|
486
|
+
phase
|
|
487
|
+
]);
|
|
488
|
+
const answerReceipt = useCallback(async (answer)=>{
|
|
489
|
+
const paid = saleRef.current;
|
|
490
|
+
if (!token || !paid || !answer.receiptChannel) return;
|
|
491
|
+
setBusy(true);
|
|
492
|
+
const result = await kioskApi.receipt(token, _extends({
|
|
493
|
+
orderId: paid.orderId,
|
|
494
|
+
channel: answer.receiptChannel
|
|
495
|
+
}, answer.email ? {
|
|
496
|
+
to: answer.email
|
|
497
|
+
} : {}, answer.phone ? {
|
|
498
|
+
to: answer.phone
|
|
499
|
+
} : {}, answer.marketingOptIn ? {
|
|
500
|
+
marketingOptIn: true
|
|
501
|
+
} : {}));
|
|
502
|
+
setBusy(false);
|
|
503
|
+
if (lost(result.status)) return;
|
|
504
|
+
if (!result.ok) {
|
|
505
|
+
var _result_error;
|
|
506
|
+
setNotice((_result_error = result.error) != null ? _result_error : 'Your receipt could not be sent. Ask at the counter.');
|
|
507
|
+
}
|
|
508
|
+
setPhase({
|
|
509
|
+
kind: 'done'
|
|
510
|
+
});
|
|
511
|
+
}, [
|
|
512
|
+
token,
|
|
513
|
+
lost
|
|
514
|
+
]);
|
|
515
|
+
const pay = useMemo(()=>({
|
|
516
|
+
reader: Boolean((context == null ? void 0 : context.payments.cardPresent) && context.payments.reader),
|
|
517
|
+
tap: Boolean((context == null ? void 0 : context.payments.cardPresent) && posNativeBridge()),
|
|
518
|
+
counter: Boolean(context == null ? void 0 : context.payments.payAtCounter)
|
|
519
|
+
}), [
|
|
520
|
+
context
|
|
521
|
+
]);
|
|
522
|
+
const choosePay = useCallback((method)=>{
|
|
523
|
+
if (context == null ? void 0 : context.tipping.enabled) {
|
|
524
|
+
setPhase({
|
|
525
|
+
kind: 'tip',
|
|
526
|
+
method
|
|
527
|
+
});
|
|
528
|
+
return;
|
|
529
|
+
}
|
|
530
|
+
setTip({
|
|
531
|
+
tipChoice: 'none'
|
|
532
|
+
});
|
|
533
|
+
void startPayment(method, {
|
|
534
|
+
tipChoice: 'none'
|
|
535
|
+
});
|
|
536
|
+
}, [
|
|
537
|
+
context,
|
|
538
|
+
startPayment
|
|
539
|
+
]);
|
|
540
|
+
if (token === undefined) {
|
|
541
|
+
return /*#__PURE__*/ _jsx(Box, {
|
|
542
|
+
sx: {
|
|
543
|
+
minHeight: '100dvh',
|
|
544
|
+
display: 'grid',
|
|
545
|
+
placeItems: 'center'
|
|
546
|
+
},
|
|
547
|
+
children: /*#__PURE__*/ _jsx(CircularProgress, {
|
|
548
|
+
"aria-label": "Loading"
|
|
549
|
+
})
|
|
550
|
+
});
|
|
551
|
+
}
|
|
552
|
+
if (!token) {
|
|
553
|
+
return /*#__PURE__*/ _jsx(PosDisplayPairingScreen, {
|
|
554
|
+
mode: "kiosk",
|
|
555
|
+
onPaired: (next)=>{
|
|
556
|
+
storeKioskToken(next);
|
|
557
|
+
setToken(next);
|
|
558
|
+
}
|
|
559
|
+
});
|
|
560
|
+
}
|
|
561
|
+
const branding = (_ref3 = context == null ? void 0 : context.branding) != null ? _ref3 : null;
|
|
562
|
+
let screen;
|
|
563
|
+
if (phase.kind === 'start') {
|
|
564
|
+
screen = /*#__PURE__*/ _jsx(PosDisplayBrandScreen, {
|
|
565
|
+
branding: branding,
|
|
566
|
+
message: (branding == null ? void 0 : branding.message) || 'Order here',
|
|
567
|
+
children: /*#__PURE__*/ _jsx(Button, {
|
|
568
|
+
variant: "contained",
|
|
569
|
+
size: "large",
|
|
570
|
+
onClick: ()=>setPhase({
|
|
571
|
+
kind: 'menu'
|
|
572
|
+
}),
|
|
573
|
+
sx: (theme)=>_extends({}, posDisplayTouchSx(theme), {
|
|
574
|
+
px: 6
|
|
575
|
+
}),
|
|
576
|
+
children: 'Start order'
|
|
577
|
+
})
|
|
578
|
+
});
|
|
579
|
+
} else if (phase.kind === 'menu') {
|
|
580
|
+
screen = /*#__PURE__*/ _jsxs(_Fragment, {
|
|
581
|
+
children: [
|
|
582
|
+
notice ? /*#__PURE__*/ _jsx(Alert, {
|
|
583
|
+
severity: "warning",
|
|
584
|
+
onClose: ()=>setNotice(null),
|
|
585
|
+
sx: {
|
|
586
|
+
m: 2,
|
|
587
|
+
mb: 0
|
|
588
|
+
},
|
|
589
|
+
children: notice
|
|
590
|
+
}) : null,
|
|
591
|
+
/*#__PURE__*/ _jsx(KioskMenu, {
|
|
592
|
+
catalog: catalog,
|
|
593
|
+
loading: catalogLoading && !catalog,
|
|
594
|
+
categoryId: categoryId,
|
|
595
|
+
onCategory: setCategoryId,
|
|
596
|
+
onProduct: tapProduct,
|
|
597
|
+
lines: lines,
|
|
598
|
+
currency: currency,
|
|
599
|
+
onReview: ()=>void checkout(),
|
|
600
|
+
onQuantity: (key, quantity)=>{
|
|
601
|
+
checkoutKey.current = null;
|
|
602
|
+
setLines((current)=>quantity <= 0 ? current.filter((line)=>line.key !== key) : current.map((line)=>line.key === key ? _extends({}, line, {
|
|
603
|
+
quantity
|
|
604
|
+
}) : line));
|
|
605
|
+
},
|
|
606
|
+
cartOpen: cartOpen,
|
|
607
|
+
onCartOpen: setCartOpen,
|
|
608
|
+
busy: busy
|
|
609
|
+
})
|
|
610
|
+
]
|
|
611
|
+
});
|
|
612
|
+
} else if (phase.kind === 'review' && sale) {
|
|
613
|
+
screen = /*#__PURE__*/ _jsx(KioskReview, {
|
|
614
|
+
sale: sale,
|
|
615
|
+
currency: currency,
|
|
616
|
+
pay: pay,
|
|
617
|
+
busy: busy,
|
|
618
|
+
notice: notice,
|
|
619
|
+
onPay: choosePay,
|
|
620
|
+
onCounter: ()=>void sendToCounter(),
|
|
621
|
+
onBack: backToMenu
|
|
622
|
+
});
|
|
623
|
+
} else if (phase.kind === 'tip' && sale && context) {
|
|
624
|
+
screen = /*#__PURE__*/ _jsx(Container, {
|
|
625
|
+
maxWidth: "md",
|
|
626
|
+
sx: {
|
|
627
|
+
py: 4
|
|
628
|
+
},
|
|
629
|
+
children: /*#__PURE__*/ _jsxs(Stack, {
|
|
630
|
+
spacing: 4,
|
|
631
|
+
sx: {
|
|
632
|
+
alignItems: 'center'
|
|
633
|
+
},
|
|
634
|
+
children: [
|
|
635
|
+
/*#__PURE__*/ _jsx(PosDisplayBrandMark, {
|
|
636
|
+
branding: branding
|
|
637
|
+
}),
|
|
638
|
+
/*#__PURE__*/ _jsx(PosDisplayTipScreen, {
|
|
639
|
+
tip: {
|
|
640
|
+
baseCents: sale.dueCents,
|
|
641
|
+
percentages: context.tipping.percentages,
|
|
642
|
+
allowCustom: true
|
|
643
|
+
},
|
|
644
|
+
promptId: `kiosk-${sale.orderId}`,
|
|
645
|
+
busy: busy,
|
|
646
|
+
currency: currency,
|
|
647
|
+
onAnswer: (answer)=>{
|
|
648
|
+
var _answer_tipChoice, _answer_tipCents;
|
|
649
|
+
const next = _extends({
|
|
650
|
+
tipChoice: (_answer_tipChoice = answer.tipChoice) != null ? _answer_tipChoice : 'none'
|
|
651
|
+
}, answer.tipPercent ? {
|
|
652
|
+
tipPercent: answer.tipPercent
|
|
653
|
+
} : {}, answer.tipChoice === 'custom' ? {
|
|
654
|
+
tipCents: (_answer_tipCents = answer.tipCents) != null ? _answer_tipCents : 0
|
|
655
|
+
} : {});
|
|
656
|
+
setTip(next);
|
|
657
|
+
void startPayment(phase.method, next);
|
|
658
|
+
}
|
|
659
|
+
}),
|
|
660
|
+
/*#__PURE__*/ _jsx(Button, {
|
|
661
|
+
onClick: ()=>setPhase({
|
|
662
|
+
kind: 'review'
|
|
663
|
+
}),
|
|
664
|
+
disabled: busy,
|
|
665
|
+
children: 'Back'
|
|
666
|
+
})
|
|
667
|
+
]
|
|
668
|
+
})
|
|
669
|
+
});
|
|
670
|
+
} else if (phase.kind === 'paying' && sale) {
|
|
671
|
+
screen = /*#__PURE__*/ _jsx(KioskPaying, {
|
|
672
|
+
chargeCents: phase.chargeCents,
|
|
673
|
+
currency: currency,
|
|
674
|
+
method: phase.method,
|
|
675
|
+
failure: phase.failure,
|
|
676
|
+
testMode: Boolean((context == null ? void 0 : context.testMode) && phase.method === 'reader'),
|
|
677
|
+
busy: busy,
|
|
678
|
+
onCancel: ()=>void cancelPayment(),
|
|
679
|
+
onRetry: ()=>void startPayment(phase.method, tip),
|
|
680
|
+
onCounter: pay.counter ? ()=>void sendToCounter() : null,
|
|
681
|
+
onSimulate: phase.paymentId ? ()=>void kioskApi.simulate(token, sale.orderId, phase.paymentId) : null
|
|
682
|
+
});
|
|
683
|
+
} else if (phase.kind === 'receipt' && sale && context) {
|
|
684
|
+
screen = /*#__PURE__*/ _jsx(Container, {
|
|
685
|
+
maxWidth: "md",
|
|
686
|
+
sx: {
|
|
687
|
+
py: 4
|
|
688
|
+
},
|
|
689
|
+
children: /*#__PURE__*/ _jsxs(Stack, {
|
|
690
|
+
spacing: 4,
|
|
691
|
+
sx: {
|
|
692
|
+
alignItems: 'center'
|
|
693
|
+
},
|
|
694
|
+
children: [
|
|
695
|
+
/*#__PURE__*/ _jsx(PosDisplayBrandMark, {
|
|
696
|
+
branding: branding
|
|
697
|
+
}),
|
|
698
|
+
/*#__PURE__*/ _jsx(PosDisplayReceiptScreen, {
|
|
699
|
+
receipt: {
|
|
700
|
+
channels: context.receipts,
|
|
701
|
+
offerMarketing: context.offerMarketing
|
|
702
|
+
},
|
|
703
|
+
promptId: `kiosk-${sale.orderId}`,
|
|
704
|
+
busy: busy,
|
|
705
|
+
onAnswer: (answer)=>void answerReceipt(answer)
|
|
706
|
+
})
|
|
707
|
+
]
|
|
708
|
+
})
|
|
709
|
+
});
|
|
710
|
+
} else if (phase.kind === 'done' && sale) {
|
|
711
|
+
screen = /*#__PURE__*/ _jsx(KioskDone, {
|
|
712
|
+
sale: sale,
|
|
713
|
+
currency: currency,
|
|
714
|
+
onDone: reset
|
|
715
|
+
});
|
|
716
|
+
} else {
|
|
717
|
+
screen = /*#__PURE__*/ _jsx(PosDisplayBrandScreen, {
|
|
718
|
+
branding: branding,
|
|
719
|
+
busy: true
|
|
720
|
+
});
|
|
721
|
+
}
|
|
722
|
+
return /*#__PURE__*/ _jsxs(Box, {
|
|
723
|
+
sx: {
|
|
724
|
+
position: 'relative',
|
|
725
|
+
minHeight: '100dvh'
|
|
726
|
+
},
|
|
727
|
+
children: [
|
|
728
|
+
offline ? /*#__PURE__*/ _jsx(Alert, {
|
|
729
|
+
severity: "warning",
|
|
730
|
+
sx: {
|
|
731
|
+
position: 'fixed',
|
|
732
|
+
top: 0,
|
|
733
|
+
left: 0,
|
|
734
|
+
right: 0,
|
|
735
|
+
zIndex: (theme)=>theme.zIndex.modal + 1
|
|
736
|
+
},
|
|
737
|
+
children: 'Reconnecting…'
|
|
738
|
+
}) : null,
|
|
739
|
+
screen,
|
|
740
|
+
/*#__PURE__*/ _jsx(PosItemDialog, {
|
|
741
|
+
product: itemProduct ? kioskItemProduct(itemProduct) : null,
|
|
742
|
+
onClose: ()=>setItemProduct(null),
|
|
743
|
+
onConfirm: (choice)=>{
|
|
744
|
+
const product = itemProduct;
|
|
745
|
+
setItemProduct(null);
|
|
746
|
+
if (product) addChoice(product, choice);
|
|
747
|
+
},
|
|
748
|
+
formatMoney: money,
|
|
749
|
+
blockSoldOut: true,
|
|
750
|
+
maxQuantity: CommerceModel.POS_KIOSK_MAX_QUANTITY
|
|
751
|
+
}),
|
|
752
|
+
/*#__PURE__*/ _jsxs(Dialog, {
|
|
753
|
+
open: idle.warning !== null,
|
|
754
|
+
onClose: idle.stillHere,
|
|
755
|
+
maxWidth: "xs",
|
|
756
|
+
fullWidth: true,
|
|
757
|
+
children: [
|
|
758
|
+
/*#__PURE__*/ _jsx(DialogTitle, {
|
|
759
|
+
children: 'Still there?'
|
|
760
|
+
}),
|
|
761
|
+
/*#__PURE__*/ _jsx(DialogContent, {
|
|
762
|
+
children: /*#__PURE__*/ _jsx(DialogContentText, {
|
|
763
|
+
children: `This order will be cleared in ${(_idle_warning = idle.warning) != null ? _idle_warning : 0} seconds.`
|
|
764
|
+
})
|
|
765
|
+
}),
|
|
766
|
+
/*#__PURE__*/ _jsxs(DialogActions, {
|
|
767
|
+
children: [
|
|
768
|
+
/*#__PURE__*/ _jsx(Button, {
|
|
769
|
+
onClick: reset,
|
|
770
|
+
children: 'Start over'
|
|
771
|
+
}),
|
|
772
|
+
/*#__PURE__*/ _jsx(Button, {
|
|
773
|
+
variant: "contained",
|
|
774
|
+
onClick: idle.stillHere,
|
|
775
|
+
children: 'I’m still here'
|
|
776
|
+
})
|
|
777
|
+
]
|
|
778
|
+
})
|
|
779
|
+
]
|
|
780
|
+
}),
|
|
781
|
+
phase.kind === 'start' || phase.kind === 'menu' ? /*#__PURE__*/ _jsx(KioskStaffControl, {
|
|
782
|
+
token: token,
|
|
783
|
+
onExit: unpaired,
|
|
784
|
+
onUnauthorized: unpaired
|
|
785
|
+
}) : null
|
|
786
|
+
]
|
|
787
|
+
}, turn);
|
|
788
|
+
}
|
|
789
|
+
PosKioskPage.displayName = 'PosKioskPage';
|
|
790
|
+
|
|
791
|
+
//# sourceMappingURL=pos-kiosk-page.component.js.map
|