@aglyn/plugins-commerce 1.0.0-beta.231 → 1.0.0-beta.233
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/catalog-organization-card.component.js +1 -0
- package/src/lib/components/console/catalog-organization-card.component.js.map +1 -1
- package/src/lib/components/console/host-orders-card.component.js +42 -11
- 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 +228 -51
- package/src/lib/components/console/pos-page.component.js.map +1 -1
- package/src/lib/components/console/pos-zones.d.ts +23 -0
- package/src/lib/components/console/pos-zones.js +31 -0
- package/src/lib/components/console/pos-zones.js.map +1 -0
- package/src/lib/components/console/product-editor-dialog.component.js +10 -64
- package/src/lib/components/console/product-editor-dialog.component.js.map +1 -1
- package/src/lib/components/console/products-hub-card.component.js +46 -30
- 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/console/storefront-tax-summary-card.component.js +1 -0
- package/src/lib/components/console/storefront-tax-summary-card.component.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/declarations.server.js +21 -0
- package/src/lib/declarations.server.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 +103 -1
- package/src/lib/model/commerce-orders.js +2 -1
- 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 +7 -1
- package/src/lib/model/commerce.js.map +1 -1
- package/src/lib/model/index.d.ts +5 -0
- package/src/lib/model/index.js +5 -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/model/product-write.d.ts +186 -0
- package/src/lib/model/product-write.js +116 -0
- package/src/lib/model/product-write.js.map +1 -0
- package/src/lib/plugin-config.js +6 -2
- package/src/lib/plugin-config.js.map +1 -1
- package/src/lib/plugin.js +11 -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/channel-order-updates.d.ts +50 -0
- package/src/lib/server/channel-order-updates.js +290 -0
- package/src/lib/server/channel-order-updates.js.map +1 -0
- package/src/lib/server/channel-orders.d.ts +85 -0
- package/src/lib/server/channel-orders.js +543 -0
- package/src/lib/server/channel-orders.js.map +1 -0
- 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/product-catalog.js +5 -1
- package/src/lib/server/product-catalog.js.map +1 -1
- package/src/lib/server/product-drafts.d.ts +5 -1
- package/src/lib/server/product-drafts.js +3 -3
- package/src/lib/server/product-drafts.js.map +1 -1
- package/src/lib/server/product-writer.d.ts +19 -0
- package/src/lib/server/product-writer.js +261 -0
- package/src/lib/server/product-writer.js.map +1 -0
- package/src/lib/server/products-write.d.ts +61 -0
- package/src/lib/server/products-write.js +375 -0
- package/src/lib/server/products-write.js.map +1 -0
- 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 +21 -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
- package/src/lib/testing/memory-firestore.d.ts +16 -3
- package/src/lib/testing/memory-firestore.js +11 -3
- package/src/lib/testing/memory-firestore.js.map +1 -1
- package/src/lib/transfer/products.server.d.ts +5 -0
- package/src/lib/transfer/products.server.js +2 -2
- package/src/lib/transfer/products.server.js.map +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../../../../libs/plugins/commerce/src/lib/components/console/pos-display/pos-display-api.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type * as CommerceModel from '../../../model'\n\n/**\n * The customer display's half of `/api/commerce/pos-display` (AGL-3608).\n *\n * Every call carries the DISPLAY token, never a staff session: the screen\n * faces the public, and the token opens one register's display state and\n * nothing else. The route answers 401 when the token is unknown or revoked,\n * which the page reads as \"pair again\".\n */\nexport const POS_DISPLAY_ENDPOINT = '/api/commerce/pos-display'\n\n/** Where the paired token lives on the device. */\nexport const POS_DISPLAY_TOKEN_KEY = 'aglyn.posDisplayToken'\n\nexport const POS_DISPLAY_TOKEN_HEADER = 'X-Pos-Display-Token'\n\n/** The store's look for the idle and thank-you screens. */\nexport interface PosDisplayBranding {\n name: string\n logoUrl: string | null\n logoDarkUrl: string | null\n message: string\n}\n\n/** The state as the route hands it to the display. */\nexport type PosDisplayPublicState = Omit<CommerceModel.PosDisplayState, 'response'> & {\n answered: boolean\n}\n\n/** What the customer sends back for the current prompt. */\nexport interface PosDisplayAnswer {\n promptId: string\n tipChoice?: 'percent' | 'custom' | 'none'\n tipPercent?: number\n tipCents?: number\n receiptChannel?: CommerceModel.PosReceiptChannel\n email?: string\n phone?: string\n marketingOptIn?: boolean\n}\n\n/**\n * A call's outcome, with the status the page branches on: `value` when `ok`,\n * `error` when not. One flat shape rather than a union, because the\n * workspace compiles without `strict` and an `ok` check would not narrow one.\n */\nexport interface PosDisplayResult<T> {\n ok: boolean\n /** The HTTP status, or 0 when the request never landed. */\n status: number\n value?: T\n error?: string\n}\n\nexport function readStoredToken(): string | null {\n try {\n return window.localStorage.getItem(POS_DISPLAY_TOKEN_KEY) || null\n } catch {\n return null\n }\n}\n\nexport function storeToken(token: string | null): void {\n try {\n if (token) window.localStorage.setItem(POS_DISPLAY_TOKEN_KEY, token)\n else window.localStorage.removeItem(POS_DISPLAY_TOKEN_KEY)\n } catch {\n // Storage blocked (a private window, a locked-down kiosk browser): the\n // display still works until it reloads, then asks for a code again.\n }\n}\n\nasync function call<T>(\n init: { method: 'GET'; query: string } | { method: 'POST'; body: Record<string, unknown> },\n token: string | null,\n): Promise<PosDisplayResult<T>> {\n const headers: Record<string, string> = {}\n if (token) headers[POS_DISPLAY_TOKEN_HEADER] = token\n if (init.method === 'POST') headers['Content-Type'] = 'application/json'\n try {\n const response = await fetch(\n init.method === 'GET' ? `${POS_DISPLAY_ENDPOINT}?${init.query}` : POS_DISPLAY_ENDPOINT,\n {\n method: init.method,\n headers,\n cache: 'no-store',\n ...(init.method === 'POST' ? { body: JSON.stringify(init.body) } : {}),\n },\n )\n const payload = (await response.json().catch(() => null)) as Record<string, unknown> | null\n if (!response.ok) {\n return {\n ok: false,\n status: response.status,\n error: String(payload?.['error'] ?? 'Something went wrong. Try again.'),\n }\n }\n return { ok: true, status: response.status, value: (payload ?? {}) as T }\n } catch {\n // Offline or the request never landed: status 0, which the poll treats\n // as \"try again next tick\" rather than as a reason to unpair.\n return { ok: false, status: 0, error: 'No connection. Trying again…' }\n }\n}\n\nexport function pairDisplay(code: string) {\n return call<{ token: string; branding: PosDisplayBranding }>(\n {
|
|
1
|
+
{"version":3,"sources":["../../../../../../../../../libs/plugins/commerce/src/lib/components/console/pos-display/pos-display-api.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type * as CommerceModel from '../../../model'\n\n/**\n * The customer display's half of `/api/commerce/pos-display` (AGL-3608).\n *\n * Every call carries the DISPLAY token, never a staff session: the screen\n * faces the public, and the token opens one register's display state and\n * nothing else. The route answers 401 when the token is unknown or revoked,\n * which the page reads as \"pair again\".\n */\nexport const POS_DISPLAY_ENDPOINT = '/api/commerce/pos-display'\n\n/** Where the paired token lives on the device. */\nexport const POS_DISPLAY_TOKEN_KEY = 'aglyn.posDisplayToken'\n\nexport const POS_DISPLAY_TOKEN_HEADER = 'X-Pos-Display-Token'\n\n/** The store's look for the idle and thank-you screens. */\nexport interface PosDisplayBranding {\n name: string\n logoUrl: string | null\n logoDarkUrl: string | null\n message: string\n}\n\n/** The state as the route hands it to the display. */\nexport type PosDisplayPublicState = Omit<CommerceModel.PosDisplayState, 'response'> & {\n answered: boolean\n}\n\n/** What the customer sends back for the current prompt. */\nexport interface PosDisplayAnswer {\n promptId: string\n tipChoice?: 'percent' | 'custom' | 'none'\n tipPercent?: number\n tipCents?: number\n receiptChannel?: CommerceModel.PosReceiptChannel\n email?: string\n phone?: string\n marketingOptIn?: boolean\n}\n\n/**\n * A call's outcome, with the status the page branches on: `value` when `ok`,\n * `error` when not. One flat shape rather than a union, because the\n * workspace compiles without `strict` and an `ok` check would not narrow one.\n */\nexport interface PosDisplayResult<T> {\n ok: boolean\n /** The HTTP status, or 0 when the request never landed. */\n status: number\n value?: T\n error?: string\n}\n\nexport function readStoredToken(): string | null {\n try {\n return window.localStorage.getItem(POS_DISPLAY_TOKEN_KEY) || null\n } catch {\n return null\n }\n}\n\nexport function storeToken(token: string | null): void {\n try {\n if (token) window.localStorage.setItem(POS_DISPLAY_TOKEN_KEY, token)\n else window.localStorage.removeItem(POS_DISPLAY_TOKEN_KEY)\n } catch {\n // Storage blocked (a private window, a locked-down kiosk browser): the\n // display still works until it reloads, then asks for a code again.\n }\n}\n\nasync function call<T>(\n init: { method: 'GET'; query: string } | { method: 'POST'; body: Record<string, unknown> },\n token: string | null,\n): Promise<PosDisplayResult<T>> {\n const headers: Record<string, string> = {}\n if (token) headers[POS_DISPLAY_TOKEN_HEADER] = token\n if (init.method === 'POST') headers['Content-Type'] = 'application/json'\n try {\n const response = await fetch(\n init.method === 'GET' ? `${POS_DISPLAY_ENDPOINT}?${init.query}` : POS_DISPLAY_ENDPOINT,\n {\n method: init.method,\n headers,\n cache: 'no-store',\n ...(init.method === 'POST' ? { body: JSON.stringify(init.body) } : {}),\n },\n )\n const payload = (await response.json().catch(() => null)) as Record<string, unknown> | null\n if (!response.ok) {\n return {\n ok: false,\n status: response.status,\n error: String(payload?.['error'] ?? 'Something went wrong. Try again.'),\n }\n }\n return { ok: true, status: response.status, value: (payload ?? {}) as T }\n } catch {\n // Offline or the request never landed: status 0, which the poll treats\n // as \"try again next tick\" rather than as a reason to unpair.\n return { ok: false, status: 0, error: 'No connection. Trying again…' }\n }\n}\n\n/**\n * Exchanges a register's code for this device's token. `mode` is the kind of\n * screen this page is — a customer display, or a self-service kiosk\n * (AGL-3623) — and a code made for the other kind is refused.\n */\nexport function pairDisplay(code: string, mode: CommerceModel.PosDeviceMode = 'display') {\n return call<{ token: string; mode?: CommerceModel.PosDeviceMode; branding: PosDisplayBranding }>(\n {\n method: 'POST',\n body: {\n action: 'pair',\n code,\n mode,\n label: mode === 'kiosk' ? 'Self-service kiosk' : 'Customer display',\n },\n },\n null,\n )\n}\n\nexport function pollDisplay(token: string, withBranding: boolean) {\n return call<{ state: PosDisplayPublicState; branding?: PosDisplayBranding }>(\n { method: 'GET', query: `action=poll${withBranding ? '&branding=true' : ''}` },\n token,\n )\n}\n\nexport function respondToDisplay(token: string, response: PosDisplayAnswer) {\n return call<{ ok: true }>({ method: 'POST', body: { action: 'respond', response } }, token)\n}\n\nexport function forgetDisplay(token: string) {\n return call<{ ok: true }>({ method: 'POST', body: { action: 'forget' } }, token)\n}\n\n/**\n * Minor units as the register shows them, in the store's currency (the\n * display state's `currency`; US dollars when a state predates it). A\n * zero-decimal currency (JPY) has no minor unit to divide out.\n */\nexport function displayMoney(cents: number, currency?: string | null): string {\n const code = String(currency || 'usd').toUpperCase()\n const amount = Number(cents) || 0\n try {\n const format = new Intl.NumberFormat('en-US', { style: 'currency', currency: code })\n const digits = format.resolvedOptions().maximumFractionDigits ?? 2\n return format.format(amount / 10 ** digits)\n } catch {\n return `${(amount / 100).toFixed(2)} ${code}`\n }\n}\n\n/**\n * Dollars typed on the display as whole cents, or null when the entry is not\n * an amount (`12`, `12.5` and `$12.50` are; `12.505` and `abc` are not).\n */\nexport function dollarsToCents(input: string): number | null {\n const cleaned = String(input ?? '').trim().replace(/^\\$/, '')\n if (!/^\\d+(\\.\\d{0,2})?$/.test(cleaned)) return null\n return Math.round(Number(cleaned) * 100)\n}\n"],"names":["POS_DISPLAY_ENDPOINT","POS_DISPLAY_TOKEN_KEY","POS_DISPLAY_TOKEN_HEADER","readStoredToken","window","localStorage","getItem","storeToken","token","setItem","removeItem","call","init","headers","method","response","fetch","query","cache","body","JSON","stringify","payload","json","catch","ok","status","error","String","value","pairDisplay","code","mode","action","label","pollDisplay","withBranding","respondToDisplay","forgetDisplay","displayMoney","cents","currency","toUpperCase","amount","Number","format","Intl","NumberFormat","style","digits","resolvedOptions","maximumFractionDigits","toFixed","dollarsToCents","input","cleaned","trim","replace","test","Math","round"],"mappings":"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"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type * as CommerceModel from '../../../model';
|
|
2
|
+
/** How the customer can pay, from the kiosk's context and the device. */
|
|
3
|
+
export interface KioskPayOptions {
|
|
4
|
+
reader: boolean;
|
|
5
|
+
tap: boolean;
|
|
6
|
+
counter: boolean;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* The priced order (AGL-3623): every line, the server's subtotal, discount,
|
|
10
|
+
* tax and total, and the ways to pay. Nothing here was computed on the kiosk.
|
|
11
|
+
*/
|
|
12
|
+
export declare function KioskReview({ sale, currency, pay, busy, notice, onPay, onCounter, onBack, }: {
|
|
13
|
+
sale: CommerceModel.PosKioskSale;
|
|
14
|
+
currency: string;
|
|
15
|
+
pay: KioskPayOptions;
|
|
16
|
+
busy: boolean;
|
|
17
|
+
notice: string | null;
|
|
18
|
+
onPay: (method: 'reader' | 'tap') => void;
|
|
19
|
+
onCounter: () => void;
|
|
20
|
+
onBack: () => void;
|
|
21
|
+
}): import("react").JSX.Element;
|
|
22
|
+
/** Waiting on the card: the reader's prompt, or the device's Tap to Pay. */
|
|
23
|
+
export declare function KioskPaying({ chargeCents, currency, method, failure, testMode, busy, onCancel, onRetry, onCounter, onSimulate, }: {
|
|
24
|
+
/** What the card is charged: the order's balance and the tip chosen. */
|
|
25
|
+
chargeCents: number;
|
|
26
|
+
currency: string;
|
|
27
|
+
method: 'reader' | 'tap';
|
|
28
|
+
failure: string | null;
|
|
29
|
+
testMode: boolean;
|
|
30
|
+
busy: boolean;
|
|
31
|
+
onCancel: () => void;
|
|
32
|
+
onRetry: () => void;
|
|
33
|
+
onCounter: (() => void) | null;
|
|
34
|
+
onSimulate: (() => void) | null;
|
|
35
|
+
}): import("react").JSX.Element;
|
|
36
|
+
/** The order number the customer is called by, paid or to pay at the counter. */
|
|
37
|
+
export declare function KioskDone({ sale, currency, onDone, }: {
|
|
38
|
+
sale: CommerceModel.PosKioskSale;
|
|
39
|
+
currency: string;
|
|
40
|
+
onDone: () => void;
|
|
41
|
+
}): import("react").JSX.Element;
|
|
@@ -0,0 +1,275 @@
|
|
|
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 { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
18
|
+
import Alert from "@mui/material/Alert";
|
|
19
|
+
import Box from "@mui/material/Box";
|
|
20
|
+
import Button from "@mui/material/Button";
|
|
21
|
+
import Container from "@mui/material/Container";
|
|
22
|
+
import Divider from "@mui/material/Divider";
|
|
23
|
+
import Stack from "@mui/material/Stack";
|
|
24
|
+
import Typography from "@mui/material/Typography";
|
|
25
|
+
import { displayMoney } from "../pos-display/pos-display-api.js";
|
|
26
|
+
import { posDisplayTouchSx } from "../pos-display/tip-screen.js";
|
|
27
|
+
function Row({ label, value, strong }) {
|
|
28
|
+
return /*#__PURE__*/ _jsxs(Stack, {
|
|
29
|
+
direction: "row",
|
|
30
|
+
sx: {
|
|
31
|
+
justifyContent: 'space-between'
|
|
32
|
+
},
|
|
33
|
+
children: [
|
|
34
|
+
/*#__PURE__*/ _jsx(Typography, {
|
|
35
|
+
variant: strong ? 'h5' : 'body1',
|
|
36
|
+
component: "span",
|
|
37
|
+
children: label
|
|
38
|
+
}),
|
|
39
|
+
/*#__PURE__*/ _jsx(Typography, {
|
|
40
|
+
variant: strong ? 'h5' : 'body1',
|
|
41
|
+
component: "span",
|
|
42
|
+
children: value
|
|
43
|
+
})
|
|
44
|
+
]
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* The priced order (AGL-3623): every line, the server's subtotal, discount,
|
|
49
|
+
* tax and total, and the ways to pay. Nothing here was computed on the kiosk.
|
|
50
|
+
*/ export function KioskReview({ sale, currency, pay, busy, notice, onPay, onCounter, onBack }) {
|
|
51
|
+
const money = (cents)=>displayMoney(cents, currency);
|
|
52
|
+
const none = !pay.reader && !pay.tap && !pay.counter;
|
|
53
|
+
return /*#__PURE__*/ _jsx(Container, {
|
|
54
|
+
maxWidth: "sm",
|
|
55
|
+
sx: {
|
|
56
|
+
py: 4
|
|
57
|
+
},
|
|
58
|
+
children: /*#__PURE__*/ _jsxs(Stack, {
|
|
59
|
+
spacing: 3,
|
|
60
|
+
children: [
|
|
61
|
+
/*#__PURE__*/ _jsx(Typography, {
|
|
62
|
+
variant: "h4",
|
|
63
|
+
component: "h1",
|
|
64
|
+
children: 'Review your order'
|
|
65
|
+
}),
|
|
66
|
+
/*#__PURE__*/ _jsx(Stack, {
|
|
67
|
+
spacing: 1,
|
|
68
|
+
divider: /*#__PURE__*/ _jsx(Divider, {
|
|
69
|
+
flexItem: true
|
|
70
|
+
}),
|
|
71
|
+
children: sale.lines.map((line, index)=>/*#__PURE__*/ _jsxs(Stack, {
|
|
72
|
+
direction: "row",
|
|
73
|
+
spacing: 2,
|
|
74
|
+
sx: {
|
|
75
|
+
justifyContent: 'space-between'
|
|
76
|
+
},
|
|
77
|
+
children: [
|
|
78
|
+
/*#__PURE__*/ _jsxs(Box, {
|
|
79
|
+
children: [
|
|
80
|
+
/*#__PURE__*/ _jsx(Typography, {
|
|
81
|
+
variant: "subtitle1",
|
|
82
|
+
children: `${line.quantity} × ${line.name}`
|
|
83
|
+
}),
|
|
84
|
+
line.variantLabel ? /*#__PURE__*/ _jsx(Typography, {
|
|
85
|
+
variant: "body2",
|
|
86
|
+
color: "text.secondary",
|
|
87
|
+
children: line.variantLabel
|
|
88
|
+
}) : null
|
|
89
|
+
]
|
|
90
|
+
}),
|
|
91
|
+
/*#__PURE__*/ _jsx(Typography, {
|
|
92
|
+
variant: "subtitle1",
|
|
93
|
+
children: money(line.amountCents)
|
|
94
|
+
})
|
|
95
|
+
]
|
|
96
|
+
}, index))
|
|
97
|
+
}),
|
|
98
|
+
/*#__PURE__*/ _jsx(Divider, {}),
|
|
99
|
+
/*#__PURE__*/ _jsxs(Stack, {
|
|
100
|
+
spacing: 1,
|
|
101
|
+
children: [
|
|
102
|
+
/*#__PURE__*/ _jsx(Row, {
|
|
103
|
+
label: "Subtotal",
|
|
104
|
+
value: money(sale.itemsCents)
|
|
105
|
+
}),
|
|
106
|
+
sale.discountCents > 0 ? /*#__PURE__*/ _jsx(Row, {
|
|
107
|
+
label: "Discount",
|
|
108
|
+
value: `−${money(sale.discountCents)}`
|
|
109
|
+
}) : null,
|
|
110
|
+
/*#__PURE__*/ _jsx(Row, {
|
|
111
|
+
label: "Tax",
|
|
112
|
+
value: money(sale.taxCents)
|
|
113
|
+
}),
|
|
114
|
+
/*#__PURE__*/ _jsx(Row, {
|
|
115
|
+
label: "Total",
|
|
116
|
+
value: money(sale.totalCents),
|
|
117
|
+
strong: true
|
|
118
|
+
})
|
|
119
|
+
]
|
|
120
|
+
}),
|
|
121
|
+
notice ? /*#__PURE__*/ _jsx(Alert, {
|
|
122
|
+
severity: "warning",
|
|
123
|
+
children: notice
|
|
124
|
+
}) : null,
|
|
125
|
+
none ? /*#__PURE__*/ _jsx(Alert, {
|
|
126
|
+
severity: "info",
|
|
127
|
+
children: 'Payment is not set up on this kiosk yet. Please order at the counter.'
|
|
128
|
+
}) : null,
|
|
129
|
+
pay.reader ? /*#__PURE__*/ _jsx(Button, {
|
|
130
|
+
variant: "contained",
|
|
131
|
+
size: "large",
|
|
132
|
+
disabled: busy,
|
|
133
|
+
onClick: ()=>onPay('reader'),
|
|
134
|
+
sx: posDisplayTouchSx,
|
|
135
|
+
children: 'Pay with card'
|
|
136
|
+
}) : null,
|
|
137
|
+
pay.tap ? /*#__PURE__*/ _jsx(Button, {
|
|
138
|
+
variant: pay.reader ? 'outlined' : 'contained',
|
|
139
|
+
size: "large",
|
|
140
|
+
disabled: busy,
|
|
141
|
+
onClick: ()=>onPay('tap'),
|
|
142
|
+
sx: posDisplayTouchSx,
|
|
143
|
+
children: 'Tap to Pay'
|
|
144
|
+
}) : null,
|
|
145
|
+
pay.counter ? /*#__PURE__*/ _jsx(Button, {
|
|
146
|
+
variant: pay.reader || pay.tap ? 'outlined' : 'contained',
|
|
147
|
+
size: "large",
|
|
148
|
+
disabled: busy,
|
|
149
|
+
onClick: onCounter,
|
|
150
|
+
sx: posDisplayTouchSx,
|
|
151
|
+
children: 'Pay at counter'
|
|
152
|
+
}) : null,
|
|
153
|
+
/*#__PURE__*/ _jsx(Button, {
|
|
154
|
+
size: "large",
|
|
155
|
+
disabled: busy,
|
|
156
|
+
onClick: onBack,
|
|
157
|
+
sx: (theme)=>({
|
|
158
|
+
minHeight: theme.spacing(7)
|
|
159
|
+
}),
|
|
160
|
+
children: 'Back to menu'
|
|
161
|
+
})
|
|
162
|
+
]
|
|
163
|
+
})
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
/** Waiting on the card: the reader's prompt, or the device's Tap to Pay. */ export function KioskPaying({ chargeCents, currency, method, failure, testMode, busy, onCancel, onRetry, onCounter, onSimulate }) {
|
|
167
|
+
return /*#__PURE__*/ _jsx(Container, {
|
|
168
|
+
maxWidth: "sm",
|
|
169
|
+
sx: {
|
|
170
|
+
py: 6
|
|
171
|
+
},
|
|
172
|
+
children: /*#__PURE__*/ _jsxs(Stack, {
|
|
173
|
+
spacing: 4,
|
|
174
|
+
sx: {
|
|
175
|
+
alignItems: 'stretch',
|
|
176
|
+
textAlign: 'center'
|
|
177
|
+
},
|
|
178
|
+
children: [
|
|
179
|
+
/*#__PURE__*/ _jsx(Typography, {
|
|
180
|
+
variant: "h3",
|
|
181
|
+
component: "h1",
|
|
182
|
+
children: failure ? 'The card did not go through' : method === 'reader' ? 'Tap, insert or swipe your card on the reader' : 'Hold your card near the device'
|
|
183
|
+
}),
|
|
184
|
+
/*#__PURE__*/ _jsx(Typography, {
|
|
185
|
+
variant: "h5",
|
|
186
|
+
component: "p",
|
|
187
|
+
color: "text.secondary",
|
|
188
|
+
children: `Total ${displayMoney(chargeCents, currency)}`
|
|
189
|
+
}),
|
|
190
|
+
failure ? /*#__PURE__*/ _jsx(Alert, {
|
|
191
|
+
severity: "error",
|
|
192
|
+
children: failure
|
|
193
|
+
}) : null,
|
|
194
|
+
failure ? /*#__PURE__*/ _jsx(Button, {
|
|
195
|
+
variant: "contained",
|
|
196
|
+
size: "large",
|
|
197
|
+
disabled: busy,
|
|
198
|
+
onClick: onRetry,
|
|
199
|
+
sx: posDisplayTouchSx,
|
|
200
|
+
children: 'Try again'
|
|
201
|
+
}) : null,
|
|
202
|
+
failure && onCounter ? /*#__PURE__*/ _jsx(Button, {
|
|
203
|
+
variant: "outlined",
|
|
204
|
+
size: "large",
|
|
205
|
+
disabled: busy,
|
|
206
|
+
onClick: onCounter,
|
|
207
|
+
sx: posDisplayTouchSx,
|
|
208
|
+
children: 'Pay at counter'
|
|
209
|
+
}) : null,
|
|
210
|
+
!failure && testMode && onSimulate ? /*#__PURE__*/ _jsx(Button, {
|
|
211
|
+
variant: "outlined",
|
|
212
|
+
disabled: busy,
|
|
213
|
+
onClick: onSimulate,
|
|
214
|
+
children: 'Test mode: tap a test card'
|
|
215
|
+
}) : null,
|
|
216
|
+
/*#__PURE__*/ _jsx(Button, {
|
|
217
|
+
size: "large",
|
|
218
|
+
disabled: busy,
|
|
219
|
+
onClick: onCancel,
|
|
220
|
+
sx: (theme)=>({
|
|
221
|
+
minHeight: theme.spacing(7)
|
|
222
|
+
}),
|
|
223
|
+
children: failure ? 'Back to my order' : 'Cancel'
|
|
224
|
+
})
|
|
225
|
+
]
|
|
226
|
+
})
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
/** The order number the customer is called by, paid or to pay at the counter. */ export function KioskDone({ sale, currency, onDone }) {
|
|
230
|
+
const queued = sale.status === 'queued';
|
|
231
|
+
return /*#__PURE__*/ _jsxs(Stack, {
|
|
232
|
+
spacing: 4,
|
|
233
|
+
sx: {
|
|
234
|
+
minHeight: '100dvh',
|
|
235
|
+
alignItems: 'center',
|
|
236
|
+
justifyContent: 'center',
|
|
237
|
+
textAlign: 'center',
|
|
238
|
+
px: 2
|
|
239
|
+
},
|
|
240
|
+
children: [
|
|
241
|
+
/*#__PURE__*/ _jsx(Typography, {
|
|
242
|
+
variant: "h5",
|
|
243
|
+
component: "p",
|
|
244
|
+
color: "text.secondary",
|
|
245
|
+
children: 'Your order number'
|
|
246
|
+
}),
|
|
247
|
+
/*#__PURE__*/ _jsx(Typography, {
|
|
248
|
+
variant: "h1",
|
|
249
|
+
component: "p",
|
|
250
|
+
"aria-label": "Order number",
|
|
251
|
+
children: sale.number
|
|
252
|
+
}),
|
|
253
|
+
/*#__PURE__*/ _jsx(Typography, {
|
|
254
|
+
variant: "h4",
|
|
255
|
+
component: "h1",
|
|
256
|
+
children: queued ? 'Please pay at the counter' : 'Thank you!'
|
|
257
|
+
}),
|
|
258
|
+
/*#__PURE__*/ _jsx(Typography, {
|
|
259
|
+
variant: "h6",
|
|
260
|
+
component: "p",
|
|
261
|
+
color: "text.secondary",
|
|
262
|
+
children: queued ? `Show this number at the counter. Total ${displayMoney(sale.totalCents, currency)}.` : 'We’ll call your number when your order is ready.'
|
|
263
|
+
}),
|
|
264
|
+
/*#__PURE__*/ _jsx(Button, {
|
|
265
|
+
variant: "contained",
|
|
266
|
+
size: "large",
|
|
267
|
+
onClick: onDone,
|
|
268
|
+
sx: posDisplayTouchSx,
|
|
269
|
+
children: 'Done'
|
|
270
|
+
})
|
|
271
|
+
]
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
//# sourceMappingURL=kiosk-checkout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../../../libs/plugins/commerce/src/lib/components/console/pos-kiosk/kiosk-checkout.tsx"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n'use client'\n\nimport Alert from '@mui/material/Alert'\nimport Box from '@mui/material/Box'\nimport Button from '@mui/material/Button'\nimport Container from '@mui/material/Container'\nimport Divider from '@mui/material/Divider'\nimport Stack from '@mui/material/Stack'\nimport Typography from '@mui/material/Typography'\nimport type * as CommerceModel from '../../../model'\nimport { displayMoney } from '../pos-display/pos-display-api'\nimport { posDisplayTouchSx } from '../pos-display/tip-screen'\n\n/** How the customer can pay, from the kiosk's context and the device. */\nexport interface KioskPayOptions {\n reader: boolean\n tap: boolean\n counter: boolean\n}\n\nfunction Row({ label, value, strong }: { label: string; value: string; strong?: boolean }) {\n return (\n <Stack direction=\"row\" sx={{ justifyContent: 'space-between' }}>\n <Typography variant={strong ? 'h5' : 'body1'} component=\"span\">\n {label}\n </Typography>\n <Typography variant={strong ? 'h5' : 'body1'} component=\"span\">\n {value}\n </Typography>\n </Stack>\n )\n}\n\n/**\n * The priced order (AGL-3623): every line, the server's subtotal, discount,\n * tax and total, and the ways to pay. Nothing here was computed on the kiosk.\n */\nexport function KioskReview({\n sale,\n currency,\n pay,\n busy,\n notice,\n onPay,\n onCounter,\n onBack,\n}: {\n sale: CommerceModel.PosKioskSale\n currency: string\n pay: KioskPayOptions\n busy: boolean\n notice: string | null\n onPay: (method: 'reader' | 'tap') => void\n onCounter: () => void\n onBack: () => void\n}) {\n const money = (cents: number) => displayMoney(cents, currency)\n const none = !pay.reader && !pay.tap && !pay.counter\n return (\n <Container maxWidth=\"sm\" sx={{ py: 4 }}>\n <Stack spacing={3}>\n <Typography variant=\"h4\" component=\"h1\">\n {'Review your order'}\n </Typography>\n <Stack spacing={1} divider={<Divider flexItem />}>\n {sale.lines.map((line, index) => (\n <Stack key={index} direction=\"row\" spacing={2} sx={{ justifyContent: 'space-between' }}>\n <Box>\n <Typography variant=\"subtitle1\">{`${line.quantity} × ${line.name}`}</Typography>\n {line.variantLabel ? (\n <Typography variant=\"body2\" color=\"text.secondary\">\n {line.variantLabel}\n </Typography>\n ) : null}\n </Box>\n <Typography variant=\"subtitle1\">{money(line.amountCents)}</Typography>\n </Stack>\n ))}\n </Stack>\n <Divider />\n <Stack spacing={1}>\n <Row label=\"Subtotal\" value={money(sale.itemsCents)} />\n {sale.discountCents > 0 ? <Row label=\"Discount\" value={`−${money(sale.discountCents)}`} /> : null}\n <Row label=\"Tax\" value={money(sale.taxCents)} />\n <Row label=\"Total\" value={money(sale.totalCents)} strong />\n </Stack>\n {notice ? <Alert severity=\"warning\">{notice}</Alert> : null}\n {none ? (\n <Alert severity=\"info\">{'Payment is not set up on this kiosk yet. Please order at the counter.'}</Alert>\n ) : null}\n {pay.reader ? (\n <Button variant=\"contained\" size=\"large\" disabled={busy} onClick={() => onPay('reader')} sx={posDisplayTouchSx}>\n {'Pay with card'}\n </Button>\n ) : null}\n {pay.tap ? (\n <Button\n variant={pay.reader ? 'outlined' : 'contained'}\n size=\"large\"\n disabled={busy}\n onClick={() => onPay('tap')}\n sx={posDisplayTouchSx}\n >\n {'Tap to Pay'}\n </Button>\n ) : null}\n {pay.counter ? (\n <Button\n variant={pay.reader || pay.tap ? 'outlined' : 'contained'}\n size=\"large\"\n disabled={busy}\n onClick={onCounter}\n sx={posDisplayTouchSx}\n >\n {'Pay at counter'}\n </Button>\n ) : null}\n <Button size=\"large\" disabled={busy} onClick={onBack} sx={(theme) => ({ minHeight: theme.spacing(7) })}>\n {'Back to menu'}\n </Button>\n </Stack>\n </Container>\n )\n}\n\n/** Waiting on the card: the reader's prompt, or the device's Tap to Pay. */\nexport function KioskPaying({\n chargeCents,\n currency,\n method,\n failure,\n testMode,\n busy,\n onCancel,\n onRetry,\n onCounter,\n onSimulate,\n}: {\n /** What the card is charged: the order's balance and the tip chosen. */\n chargeCents: number\n currency: string\n method: 'reader' | 'tap'\n failure: string | null\n testMode: boolean\n busy: boolean\n onCancel: () => void\n onRetry: () => void\n onCounter: (() => void) | null\n onSimulate: (() => void) | null\n}) {\n return (\n <Container maxWidth=\"sm\" sx={{ py: 6 }}>\n <Stack spacing={4} sx={{ alignItems: 'stretch', textAlign: 'center' }}>\n <Typography variant=\"h3\" component=\"h1\">\n {failure\n ? 'The card did not go through'\n : method === 'reader'\n ? 'Tap, insert or swipe your card on the reader'\n : 'Hold your card near the device'}\n </Typography>\n <Typography variant=\"h5\" component=\"p\" color=\"text.secondary\">\n {`Total ${displayMoney(chargeCents, currency)}`}\n </Typography>\n {failure ? <Alert severity=\"error\">{failure}</Alert> : null}\n {failure ? (\n <Button variant=\"contained\" size=\"large\" disabled={busy} onClick={onRetry} sx={posDisplayTouchSx}>\n {'Try again'}\n </Button>\n ) : null}\n {failure && onCounter ? (\n <Button variant=\"outlined\" size=\"large\" disabled={busy} onClick={onCounter} sx={posDisplayTouchSx}>\n {'Pay at counter'}\n </Button>\n ) : null}\n {!failure && testMode && onSimulate ? (\n <Button variant=\"outlined\" disabled={busy} onClick={onSimulate}>\n {'Test mode: tap a test card'}\n </Button>\n ) : null}\n <Button size=\"large\" disabled={busy} onClick={onCancel} sx={(theme) => ({ minHeight: theme.spacing(7) })}>\n {failure ? 'Back to my order' : 'Cancel'}\n </Button>\n </Stack>\n </Container>\n )\n}\n\n/** The order number the customer is called by, paid or to pay at the counter. */\nexport function KioskDone({\n sale,\n currency,\n onDone,\n}: {\n sale: CommerceModel.PosKioskSale\n currency: string\n onDone: () => void\n}) {\n const queued = sale.status === 'queued'\n return (\n <Stack\n spacing={4}\n sx={{ minHeight: '100dvh', alignItems: 'center', justifyContent: 'center', textAlign: 'center', px: 2 }}\n >\n <Typography variant=\"h5\" component=\"p\" color=\"text.secondary\">\n {'Your order number'}\n </Typography>\n <Typography variant=\"h1\" component=\"p\" aria-label=\"Order number\">\n {sale.number}\n </Typography>\n <Typography variant=\"h4\" component=\"h1\">\n {queued ? 'Please pay at the counter' : 'Thank you!'}\n </Typography>\n <Typography variant=\"h6\" component=\"p\" color=\"text.secondary\">\n {queued\n ? `Show this number at the counter. Total ${displayMoney(sale.totalCents, currency)}.`\n : 'We’ll call your number when your order is ready.'}\n </Typography>\n <Button variant=\"contained\" size=\"large\" onClick={onDone} sx={posDisplayTouchSx}>\n {'Done'}\n </Button>\n </Stack>\n )\n}\n"],"names":["Alert","Box","Button","Container","Divider","Stack","Typography","displayMoney","posDisplayTouchSx","Row","label","value","strong","direction","sx","justifyContent","variant","component","KioskReview","sale","currency","pay","busy","notice","onPay","onCounter","onBack","money","cents","none","reader","tap","counter","maxWidth","py","spacing","divider","flexItem","lines","map","line","index","quantity","name","variantLabel","color","amountCents","itemsCents","discountCents","taxCents","totalCents","severity","size","disabled","onClick","theme","minHeight","KioskPaying","chargeCents","method","failure","testMode","onCancel","onRetry","onSimulate","alignItems","textAlign","KioskDone","onDone","queued","status","px","aria-label","number"],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import * as CommerceModel from '../../../model';
|
|
2
|
+
/** A cart line on the kiosk: what is sent, plus what the screen shows. */
|
|
3
|
+
export interface KioskCartLine extends CommerceModel.PosKioskLine {
|
|
4
|
+
/** Merges the same item with the same choices. */
|
|
5
|
+
key: string;
|
|
6
|
+
name: string;
|
|
7
|
+
label?: string;
|
|
8
|
+
/** The catalog's price per unit, modifiers included: an estimate until checkout. */
|
|
9
|
+
unitCents: number;
|
|
10
|
+
}
|
|
11
|
+
/** The lowest price a product sells at, for its tile. */
|
|
12
|
+
export declare function kioskFromCents(product: CommerceModel.PosKioskProduct): number;
|
|
13
|
+
export declare function kioskProductSoldOut(product: CommerceModel.PosKioskProduct): boolean;
|
|
14
|
+
/**
|
|
15
|
+
* The menu (AGL-3623): category chips, the product tiles, and the cart bar.
|
|
16
|
+
* A category chip asks the server for that category; nothing is filtered
|
|
17
|
+
* out of a list already loaded.
|
|
18
|
+
*/
|
|
19
|
+
export declare function KioskMenu({ catalog, loading, categoryId, onCategory, onProduct, lines, currency, onReview, onQuantity, cartOpen, onCartOpen, busy, }: {
|
|
20
|
+
catalog: CommerceModel.PosKioskCatalog | null;
|
|
21
|
+
loading: boolean;
|
|
22
|
+
categoryId: string | null;
|
|
23
|
+
onCategory: (categoryId: string | null) => void;
|
|
24
|
+
onProduct: (product: CommerceModel.PosKioskProduct) => void;
|
|
25
|
+
lines: KioskCartLine[];
|
|
26
|
+
currency: string;
|
|
27
|
+
onReview: () => void;
|
|
28
|
+
onQuantity: (key: string, quantity: number) => void;
|
|
29
|
+
cartOpen: boolean;
|
|
30
|
+
onCartOpen: (open: boolean) => void;
|
|
31
|
+
busy: boolean;
|
|
32
|
+
}): import("react").JSX.Element;
|