@aglyn/plugins-commerce 1.0.0-beta.285 → 1.0.0-beta.288
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/README.md +1 -1
- package/package.json +13 -13
- package/src/lib/components/cart.js +25 -12
- package/src/lib/components/cart.js.map +1 -1
- package/src/lib/components/commerce-console-page.js +70 -13
- package/src/lib/components/commerce-console-page.js.map +1 -1
- package/src/lib/components/console/order-detail-dialog.component.js +2 -1
- package/src/lib/components/console/order-detail-dialog.component.js.map +1 -1
- package/src/lib/components/console/order-webhooks-card.component.js +1 -1
- package/src/lib/components/console/order-webhooks-card.component.js.map +1 -1
- package/src/lib/components/console/payment-methods-card.component.js +1 -1
- package/src/lib/components/console/payment-methods-card.component.js.map +1 -1
- package/src/lib/components/console/pos/pos-cart-panel.component.d.ts +5 -0
- package/src/lib/components/console/pos/pos-cart-panel.component.js +18 -12
- package/src/lib/components/console/pos/pos-cart-panel.component.js.map +1 -1
- package/src/lib/components/console/pos/pos-hardware-api.d.ts +76 -5
- package/src/lib/components/console/pos/pos-hardware-api.js +53 -11
- package/src/lib/components/console/pos/pos-hardware-api.js.map +1 -1
- package/src/lib/components/console/pos/pos-hardware-buyer.component.d.ts +18 -0
- package/src/lib/components/console/pos/pos-hardware-buyer.component.js +629 -0
- package/src/lib/components/console/pos/pos-hardware-buyer.component.js.map +1 -0
- package/src/lib/components/console/pos/pos-hardware-sale-api.d.ts +162 -0
- package/src/lib/components/console/pos/pos-hardware-sale-api.js +122 -0
- package/src/lib/components/console/pos/pos-hardware-sale-api.js.map +1 -0
- package/src/lib/components/console/pos/pos-hardware-sale-terms.component.d.ts +39 -0
- package/src/lib/components/console/pos/pos-hardware-sale-terms.component.js +251 -0
- package/src/lib/components/console/pos/pos-hardware-sale-terms.component.js.map +1 -0
- package/src/lib/components/console/pos/use-pos-display.js +50 -0
- package/src/lib/components/console/pos/use-pos-display.js.map +1 -1
- package/src/lib/components/console/pos-cellular-control.component.d.ts +41 -0
- package/src/lib/components/console/pos-cellular-control.component.js +211 -0
- package/src/lib/components/console/pos-cellular-control.component.js.map +1 -0
- package/src/lib/components/console/pos-devices-card.component.d.ts +9 -1
- package/src/lib/components/console/pos-devices-card.component.js +47 -15
- package/src/lib/components/console/pos-devices-card.component.js.map +1 -1
- package/src/lib/components/console/pos-display/pos-display-api.d.ts +6 -0
- package/src/lib/components/console/pos-display/pos-display-api.js +8 -1
- package/src/lib/components/console/pos-display/pos-display-api.js.map +1 -1
- package/src/lib/components/console/pos-display-page.component.d.ts +13 -0
- package/src/lib/components/console/pos-display-page.component.js +44 -2
- package/src/lib/components/console/pos-display-page.component.js.map +1 -1
- package/src/lib/components/console/pos-hardware-card.component.d.ts +12 -4
- package/src/lib/components/console/pos-hardware-card.component.js +157 -36
- package/src/lib/components/console/pos-hardware-card.component.js.map +1 -1
- package/src/lib/components/console/pos-hardware-orders-staff-page.component.js +360 -80
- package/src/lib/components/console/pos-hardware-orders-staff-page.component.js.map +1 -1
- package/src/lib/components/console/pos-hardware-terms-page.component.d.ts +34 -0
- package/src/lib/components/console/pos-hardware-terms-page.component.js +257 -0
- package/src/lib/components/console/pos-hardware-terms-page.component.js.map +1 -0
- package/src/lib/components/console/pos-hardware-terms-sign-page.component.d.ts +27 -0
- package/src/lib/components/console/pos-hardware-terms-sign-page.component.js +104 -0
- package/src/lib/components/console/pos-hardware-terms-sign-page.component.js.map +1 -0
- package/src/lib/components/console/pos-hardware-waiting-card.component.d.ts +24 -0
- package/src/lib/components/console/pos-hardware-waiting-card.component.js +205 -0
- package/src/lib/components/console/pos-hardware-waiting-card.component.js.map +1 -0
- package/src/lib/components/console/pos-ops/pos-check-in-dialog.component.js +297 -201
- package/src/lib/components/console/pos-ops/pos-check-in-dialog.component.js.map +1 -1
- package/src/lib/components/console/pos-ops/pos-check-ins-card.component.d.ts +3 -0
- package/src/lib/components/console/pos-ops/pos-check-ins-card.component.js +260 -92
- package/src/lib/components/console/pos-ops/pos-check-ins-card.component.js.map +1 -1
- package/src/lib/components/console/pos-ops/pos-operations-bar.component.d.ts +9 -0
- package/src/lib/components/console/pos-ops/pos-operations-bar.component.js +15 -6
- package/src/lib/components/console/pos-ops/pos-operations-bar.component.js.map +1 -1
- package/src/lib/components/console/pos-ops/pos-rain-check-dialog.component.d.ts +25 -0
- package/src/lib/components/console/pos-ops/pos-rain-check-dialog.component.js +136 -0
- package/src/lib/components/console/pos-ops/pos-rain-check-dialog.component.js.map +1 -0
- package/src/lib/components/console/pos-ops/pos-shift-panel.component.d.ts +6 -0
- package/src/lib/components/console/pos-ops/pos-shift-panel.component.js +48 -31
- package/src/lib/components/console/pos-ops/pos-shift-panel.component.js.map +1 -1
- package/src/lib/components/console/pos-page.component.d.ts +1 -1
- package/src/lib/components/console/pos-page.component.js +63 -12
- package/src/lib/components/console/pos-page.component.js.map +1 -1
- package/src/lib/components/console/pos-reader-splash-setting.component.js +1 -1
- package/src/lib/components/console/pos-reader-splash-setting.component.js.map +1 -1
- package/src/lib/components/console/product-check-in-fields.component.d.ts +4 -2
- package/src/lib/components/console/product-check-in-fields.component.js +60 -14
- package/src/lib/components/console/product-check-in-fields.component.js.map +1 -1
- package/src/lib/components/console/product-editor-dialog.component.js +44 -1
- package/src/lib/components/console/product-editor-dialog.component.js.map +1 -1
- package/src/lib/components/console/product-hardware-sku-field.component.d.ts +19 -0
- package/src/lib/components/console/product-hardware-sku-field.component.js +92 -0
- package/src/lib/components/console/product-hardware-sku-field.component.js.map +1 -0
- package/src/lib/components/console/product-kiosk-offer-field.component.d.ts +22 -0
- package/src/lib/components/console/product-kiosk-offer-field.component.js +94 -0
- package/src/lib/components/console/product-kiosk-offer-field.component.js.map +1 -0
- package/src/lib/components/console/product-register-fields.component.d.ts +4 -0
- package/src/lib/components/console/product-register-fields.component.js +31 -2
- package/src/lib/components/console/product-register-fields.component.js.map +1 -1
- package/src/lib/components/console/products-hub-card.component.js +11 -2
- package/src/lib/components/console/products-hub-card.component.js.map +1 -1
- package/src/lib/components/console/register-hardware-card.component.d.ts +11 -0
- package/src/lib/components/console/register-hardware-card.component.js +56 -27
- package/src/lib/components/console/register-hardware-card.component.js.map +1 -1
- package/src/lib/components/console/reservation-guests-dialog.component.d.ts +28 -0
- package/src/lib/components/console/reservation-guests-dialog.component.js +189 -0
- package/src/lib/components/console/reservation-guests-dialog.component.js.map +1 -0
- package/src/lib/components/console/reservations-card.component.d.ts +9 -0
- package/src/lib/components/console/reservations-card.component.js +158 -23
- package/src/lib/components/console/reservations-card.component.js.map +1 -1
- package/src/lib/components/console/shippingeasy-card.component.js +1 -1
- package/src/lib/components/console/shippingeasy-card.component.js.map +1 -1
- package/src/lib/components/console/shipstation-card.component.d.ts +1 -1
- package/src/lib/components/console/shipstation-card.component.js +3 -3
- package/src/lib/components/console/shipstation-card.component.js.map +1 -1
- package/src/lib/components/product-detail.d.ts +4 -0
- package/src/lib/components/product-detail.js +40 -5
- package/src/lib/components/product-detail.js.map +1 -1
- package/src/lib/components/product-reviews.js +28 -11
- package/src/lib/components/product-reviews.js.map +1 -1
- package/src/lib/components/reservation-widget.js +28 -5
- package/src/lib/components/reservation-widget.js.map +1 -1
- package/src/lib/components/use-day-picker.d.ts +25 -0
- package/src/lib/components/use-day-picker.js +57 -0
- package/src/lib/components/use-day-picker.js.map +1 -0
- package/src/lib/constants/operator-alerts.d.ts +55 -0
- package/src/lib/constants/operator-alerts.js +156 -1
- package/src/lib/constants/operator-alerts.js.map +1 -1
- package/src/lib/declarations.console-server.js +54 -1
- package/src/lib/declarations.console-server.js.map +1 -1
- package/src/lib/declarations.d.ts +4 -2
- package/src/lib/declarations.js +15 -4
- package/src/lib/declarations.js.map +1 -1
- package/src/lib/declarations.server.js +9 -0
- package/src/lib/declarations.server.js.map +1 -1
- package/src/lib/model/commerce-cart.d.ts +9 -1
- package/src/lib/model/commerce-cart.js +4 -3
- package/src/lib/model/commerce-cart.js.map +1 -1
- package/src/lib/model/commerce-check-in-product.d.ts +26 -0
- package/src/lib/model/commerce-check-in-product.js +64 -2
- package/src/lib/model/commerce-check-in-product.js.map +1 -1
- package/src/lib/model/commerce-check-in-record.d.ts +127 -0
- package/src/lib/model/commerce-check-in-record.js +36 -0
- package/src/lib/model/commerce-check-in-record.js.map +1 -0
- package/src/lib/model/commerce-check-in.d.ts +91 -87
- package/src/lib/model/commerce-check-in.js +186 -62
- package/src/lib/model/commerce-check-in.js.map +1 -1
- package/src/lib/model/commerce-kiosk-offer.d.ts +31 -0
- package/src/lib/model/commerce-kiosk-offer.js +35 -0
- package/src/lib/model/commerce-kiosk-offer.js.map +1 -0
- package/src/lib/model/commerce-orders.d.ts +76 -0
- package/src/lib/model/commerce-orders.js +6 -0
- package/src/lib/model/commerce-orders.js.map +1 -1
- package/src/lib/model/commerce-pos-day-report.d.ts +54 -1
- package/src/lib/model/commerce-pos-day-report.js +39 -2
- package/src/lib/model/commerce-pos-day-report.js.map +1 -1
- package/src/lib/model/commerce-pos-offline.d.ts +1 -1
- package/src/lib/model/commerce-pos-offline.js +6 -1
- package/src/lib/model/commerce-pos-offline.js.map +1 -1
- package/src/lib/model/commerce-pos-ops.js +3 -2
- package/src/lib/model/commerce-pos-ops.js.map +1 -1
- package/src/lib/model/commerce-pos.d.ts +36 -3
- package/src/lib/model/commerce-pos.js +14 -6
- package/src/lib/model/commerce-pos.js.map +1 -1
- package/src/lib/model/commerce-receipt.js +3 -2
- package/src/lib/model/commerce-receipt.js.map +1 -1
- package/src/lib/model/commerce-reservations.d.ts +69 -4
- package/src/lib/model/commerce-reservations.js +57 -5
- package/src/lib/model/commerce-reservations.js.map +1 -1
- package/src/lib/model/commerce.d.ts +66 -0
- package/src/lib/model/commerce.js +15 -0
- package/src/lib/model/commerce.js.map +1 -1
- package/src/lib/model/order-list-fields.d.ts +11 -0
- package/src/lib/model/order-list-fields.js +17 -1
- package/src/lib/model/order-list-fields.js.map +1 -1
- package/src/lib/model/own-store-tax-summary.d.ts +152 -0
- package/src/lib/model/own-store-tax-summary.js +288 -0
- package/src/lib/model/own-store-tax-summary.js.map +1 -0
- package/src/lib/model/plugin-permissions.d.ts +74 -0
- package/src/lib/model/plugin-permissions.js +224 -7
- package/src/lib/model/plugin-permissions.js.map +1 -1
- package/src/lib/model/pos-cellular.d.ts +223 -0
- package/src/lib/model/pos-cellular.js +293 -0
- package/src/lib/model/pos-cellular.js.map +1 -0
- package/src/lib/model/pos-hardware-in-person.d.ts +98 -0
- package/src/lib/model/pos-hardware-in-person.js +224 -0
- package/src/lib/model/pos-hardware-in-person.js.map +1 -0
- package/src/lib/model/pos-hardware-tax-summary.d.ts +166 -0
- package/src/lib/model/pos-hardware-tax-summary.js +225 -0
- package/src/lib/model/pos-hardware-tax-summary.js.map +1 -0
- package/src/lib/model/pos-hardware-terms.d.ts +74 -0
- package/src/lib/model/pos-hardware-terms.js +115 -0
- package/src/lib/model/pos-hardware-terms.js.map +1 -0
- package/src/lib/model/pos-hardware.d.ts +349 -7
- package/src/lib/model/pos-hardware.js +291 -20
- package/src/lib/model/pos-hardware.js.map +1 -1
- package/src/lib/model/product-write.d.ts +10 -0
- package/src/lib/model/product-write.js +4 -2
- package/src/lib/model/product-write.js.map +1 -1
- package/src/lib/model/workspace-site-permissions.d.ts +26 -0
- package/src/lib/model/workspace-site-permissions.js +81 -0
- package/src/lib/model/workspace-site-permissions.js.map +1 -0
- package/src/lib/plugin.js +16 -0
- package/src/lib/plugin.js.map +1 -1
- package/src/lib/server/billing-webhook.js +25 -1
- package/src/lib/server/billing-webhook.js.map +1 -1
- package/src/lib/server/cancel-order.js +7 -5
- package/src/lib/server/cancel-order.js.map +1 -1
- package/src/lib/server/cart-checkout.js +20 -8
- package/src/lib/server/cart-checkout.js.map +1 -1
- package/src/lib/server/cart.js +29 -0
- package/src/lib/server/cart.js.map +1 -1
- package/src/lib/server/checkout.js +42 -13
- package/src/lib/server/checkout.js.map +1 -1
- package/src/lib/server/collection-membership.d.ts +4 -0
- package/src/lib/server/collection-membership.js +5 -10
- package/src/lib/server/collection-membership.js.map +1 -1
- package/src/lib/server/commerce-site-keys.d.ts +48 -0
- package/src/lib/server/commerce-site-keys.js +61 -0
- package/src/lib/server/commerce-site-keys.js.map +1 -0
- package/src/lib/server/draft-order.js +8 -5
- package/src/lib/server/draft-order.js.map +1 -1
- package/src/lib/server/fulfill-order.js +7 -5
- package/src/lib/server/fulfill-order.js.map +1 -1
- package/src/lib/server/gift-cards.js +8 -5
- package/src/lib/server/gift-cards.js.map +1 -1
- package/src/lib/server/local-fulfillment-status.js +9 -6
- package/src/lib/server/local-fulfillment-status.js.map +1 -1
- package/src/lib/server/member-post.js +6 -5
- package/src/lib/server/member-post.js.map +1 -1
- package/src/lib/server/membership-admin-password.d.ts +4 -2
- package/src/lib/server/membership-admin-password.js +10 -8
- package/src/lib/server/membership-admin-password.js.map +1 -1
- package/src/lib/server/membership-admin-remove.d.ts +7 -5
- package/src/lib/server/membership-admin-remove.js +9 -9
- package/src/lib/server/membership-admin-remove.js.map +1 -1
- package/src/lib/server/order-notifications.js +5 -2
- package/src/lib/server/order-notifications.js.map +1 -1
- package/src/lib/server/order-print.js +7 -5
- package/src/lib/server/order-print.js.map +1 -1
- package/src/lib/server/order-receipt-send.js +8 -5
- package/src/lib/server/order-receipt-send.js.map +1 -1
- package/src/lib/server/order-webhooks.js +8 -8
- package/src/lib/server/order-webhooks.js.map +1 -1
- package/src/lib/server/orders-shipping-prepare.js +9 -6
- package/src/lib/server/orders-shipping-prepare.js.map +1 -1
- package/src/lib/server/own-store-tax-return-source.d.ts +47 -0
- package/src/lib/server/own-store-tax-return-source.js +312 -0
- package/src/lib/server/own-store-tax-return-source.js.map +1 -0
- package/src/lib/server/payment-methods.js +13 -9
- package/src/lib/server/payment-methods.js.map +1 -1
- package/src/lib/server/pos-auth.d.ts +37 -6
- package/src/lib/server/pos-auth.js +40 -15
- package/src/lib/server/pos-auth.js.map +1 -1
- package/src/lib/server/pos-cellular-billing.d.ts +81 -0
- package/src/lib/server/pos-cellular-billing.js +711 -0
- package/src/lib/server/pos-cellular-billing.js.map +1 -0
- package/src/lib/server/pos-cellular-notify.d.ts +47 -0
- package/src/lib/server/pos-cellular-notify.js +150 -0
- package/src/lib/server/pos-cellular-notify.js.map +1 -0
- package/src/lib/server/pos-cellular.d.ts +88 -0
- package/src/lib/server/pos-cellular.js +339 -0
- package/src/lib/server/pos-cellular.js.map +1 -0
- package/src/lib/server/pos-check-in.d.ts +5 -1
- package/src/lib/server/pos-check-in.js +296 -28
- package/src/lib/server/pos-check-in.js.map +1 -1
- package/src/lib/server/pos-day-report.js +29 -3
- package/src/lib/server/pos-day-report.js.map +1 -1
- package/src/lib/server/pos-display.d.ts +16 -0
- package/src/lib/server/pos-display.js +129 -2
- package/src/lib/server/pos-display.js.map +1 -1
- package/src/lib/server/pos-hardware-admin.d.ts +10 -1
- package/src/lib/server/pos-hardware-admin.js +250 -84
- package/src/lib/server/pos-hardware-admin.js.map +1 -1
- package/src/lib/server/pos-hardware-attach.d.ts +105 -0
- package/src/lib/server/pos-hardware-attach.js +443 -0
- package/src/lib/server/pos-hardware-attach.js.map +1 -0
- package/src/lib/server/pos-hardware-buyer-lookup.d.ts +58 -0
- package/src/lib/server/pos-hardware-buyer-lookup.js +180 -0
- package/src/lib/server/pos-hardware-buyer-lookup.js.map +1 -0
- package/src/lib/server/pos-hardware-buyer-record.d.ts +29 -0
- package/src/lib/server/pos-hardware-buyer-record.js +86 -0
- package/src/lib/server/pos-hardware-buyer-record.js.map +1 -0
- package/src/lib/server/pos-hardware-cancel.d.ts +58 -0
- package/src/lib/server/pos-hardware-cancel.js +147 -0
- package/src/lib/server/pos-hardware-cancel.js.map +1 -0
- package/src/lib/server/pos-hardware-closure-notices.d.ts +27 -0
- package/src/lib/server/pos-hardware-closure-notices.js +85 -0
- package/src/lib/server/pos-hardware-closure-notices.js.map +1 -0
- package/src/lib/server/pos-hardware-closure.d.ts +60 -0
- package/src/lib/server/pos-hardware-closure.js +153 -0
- package/src/lib/server/pos-hardware-closure.js.map +1 -0
- package/src/lib/server/pos-hardware-in-person.d.ts +61 -0
- package/src/lib/server/pos-hardware-in-person.js +236 -0
- package/src/lib/server/pos-hardware-in-person.js.map +1 -0
- package/src/lib/server/pos-hardware-notify.d.ts +40 -2
- package/src/lib/server/pos-hardware-notify.js +195 -14
- package/src/lib/server/pos-hardware-notify.js.map +1 -1
- package/src/lib/server/pos-hardware-readers.d.ts +115 -0
- package/src/lib/server/pos-hardware-readers.js +430 -0
- package/src/lib/server/pos-hardware-readers.js.map +1 -0
- package/src/lib/server/pos-hardware-returns.d.ts +116 -0
- package/src/lib/server/pos-hardware-returns.js +502 -0
- package/src/lib/server/pos-hardware-returns.js.map +1 -0
- package/src/lib/server/pos-hardware-sale-fields.d.ts +28 -0
- package/src/lib/server/pos-hardware-sale-fields.js +44 -0
- package/src/lib/server/pos-hardware-sale-fields.js.map +1 -0
- package/src/lib/server/pos-hardware-sale.d.ts +54 -0
- package/src/lib/server/pos-hardware-sale.js +369 -0
- package/src/lib/server/pos-hardware-sale.js.map +1 -0
- package/src/lib/server/pos-hardware-tax-return-source.d.ts +99 -0
- package/src/lib/server/pos-hardware-tax-return-source.js +462 -0
- package/src/lib/server/pos-hardware-tax-return-source.js.map +1 -0
- package/src/lib/server/pos-hardware-terms.d.ts +64 -0
- package/src/lib/server/pos-hardware-terms.js +154 -0
- package/src/lib/server/pos-hardware-terms.js.map +1 -0
- package/src/lib/server/pos-hardware-user-eraser.d.ts +3 -0
- package/src/lib/server/pos-hardware-user-eraser.js +31 -7
- package/src/lib/server/pos-hardware-user-eraser.js.map +1 -1
- package/src/lib/server/pos-hardware-webhook.d.ts +5 -0
- package/src/lib/server/pos-hardware-webhook.js +51 -6
- package/src/lib/server/pos-hardware-webhook.js.map +1 -1
- package/src/lib/server/pos-hardware.d.ts +74 -1
- package/src/lib/server/pos-hardware.js +175 -10
- package/src/lib/server/pos-hardware.js.map +1 -1
- package/src/lib/server/pos-kiosk.d.ts +2 -0
- package/src/lib/server/pos-kiosk.js +17 -12
- package/src/lib/server/pos-kiosk.js.map +1 -1
- package/src/lib/server/pos-offline-card-order.d.ts +64 -0
- package/src/lib/server/pos-offline-card-order.js +102 -0
- package/src/lib/server/pos-offline-card-order.js.map +1 -0
- package/src/lib/server/pos-offline-card-reconcile.d.ts +67 -1
- package/src/lib/server/pos-offline-card-reconcile.js +215 -18
- package/src/lib/server/pos-offline-card-reconcile.js.map +1 -1
- package/src/lib/server/pos-offline-sync.d.ts +39 -0
- package/src/lib/server/pos-offline-sync.js +190 -55
- package/src/lib/server/pos-offline-sync.js.map +1 -1
- package/src/lib/server/pos-ops-gate.d.ts +28 -9
- package/src/lib/server/pos-ops-gate.js +50 -19
- package/src/lib/server/pos-ops-gate.js.map +1 -1
- package/src/lib/server/pos-ops-routes.js +24 -0
- package/src/lib/server/pos-ops-routes.js.map +1 -1
- package/src/lib/server/pos-order-refund-ids.d.ts +28 -0
- package/src/lib/server/pos-order-refund-ids.js +31 -0
- package/src/lib/server/pos-order-refund-ids.js.map +1 -0
- package/src/lib/server/pos-order.js +52 -49
- package/src/lib/server/pos-order.js.map +1 -1
- package/src/lib/server/pos-payment.js +1 -1
- package/src/lib/server/pos-payment.js.map +1 -1
- package/src/lib/server/pos-reader-splash-admin.js +30 -32
- package/src/lib/server/pos-reader-splash-admin.js.map +1 -1
- package/src/lib/server/pos-reader-splash-images-route.d.ts +17 -0
- package/src/lib/server/pos-reader-splash-images-route.js +113 -0
- package/src/lib/server/pos-reader-splash-images-route.js.map +1 -0
- package/src/lib/server/pos-reader-splash-images.d.ts +51 -0
- package/src/lib/server/pos-reader-splash-images.js +123 -0
- package/src/lib/server/pos-reader-splash-images.js.map +1 -0
- package/src/lib/server/pos-reader-splash.d.ts +68 -1
- package/src/lib/server/pos-reader-splash.js +182 -11
- package/src/lib/server/pos-reader-splash.js.map +1 -1
- package/src/lib/server/pos-readers.d.ts +29 -0
- package/src/lib/server/pos-readers.js +134 -35
- package/src/lib/server/pos-readers.js.map +1 -1
- package/src/lib/server/pos-refund-authority.d.ts +3 -1
- package/src/lib/server/pos-refund-authority.js +3 -2
- package/src/lib/server/pos-refund-authority.js.map +1 -1
- package/src/lib/server/pos-return.d.ts +10 -0
- package/src/lib/server/pos-return.js +29 -7
- package/src/lib/server/pos-return.js.map +1 -1
- package/src/lib/server/pos-sale.js +6 -1
- package/src/lib/server/pos-sale.js.map +1 -1
- package/src/lib/server/pos-shift.js +11 -0
- package/src/lib/server/pos-shift.js.map +1 -1
- package/src/lib/server/pos-staff-pin.js +29 -24
- package/src/lib/server/pos-staff-pin.js.map +1 -1
- package/src/lib/server/pos-terminal.d.ts +14 -4
- package/src/lib/server/pos-terminal.js +34 -38
- package/src/lib/server/pos-terminal.js.map +1 -1
- package/src/lib/server/printers.d.ts +7 -3
- package/src/lib/server/printers.js +18 -12
- package/src/lib/server/printers.js.map +1 -1
- package/src/lib/server/product-drafts.d.ts +11 -1
- package/src/lib/server/product-drafts.js +12 -8
- package/src/lib/server/product-drafts.js.map +1 -1
- package/src/lib/server/product.d.ts +15 -1
- package/src/lib/server/product.js +16 -3
- package/src/lib/server/product.js.map +1 -1
- package/src/lib/server/products-write.d.ts +26 -2
- package/src/lib/server/products-write.js +19 -7
- package/src/lib/server/products-write.js.map +1 -1
- package/src/lib/server/refund.js +55 -42
- package/src/lib/server/refund.js.map +1 -1
- package/src/lib/server/reservation-availability-query.d.ts +8 -0
- package/src/lib/server/reservation-availability-query.js +11 -1
- package/src/lib/server/reservation-availability-query.js.map +1 -1
- package/src/lib/server/reservation-availability.d.ts +1 -1
- package/src/lib/server/reservation-availability.js +7 -2
- package/src/lib/server/reservation-availability.js.map +1 -1
- package/src/lib/server/reservation-guests.d.ts +32 -0
- package/src/lib/server/reservation-guests.js +285 -0
- package/src/lib/server/reservation-guests.js.map +1 -0
- package/src/lib/server/reservation-walk-in.d.ts +11 -1
- package/src/lib/server/reservation-walk-in.js +56 -12
- package/src/lib/server/reservation-walk-in.js.map +1 -1
- package/src/lib/server/reserve.js +18 -5
- package/src/lib/server/reserve.js.map +1 -1
- package/src/lib/server/returns.js +9 -6
- package/src/lib/server/returns.js.map +1 -1
- package/src/lib/server/reviews.d.ts +22 -2
- package/src/lib/server/reviews.js +88 -20
- package/src/lib/server/reviews.js.map +1 -1
- package/src/lib/server/shipping-connectors.js +10 -11
- package/src/lib/server/shipping-connectors.js.map +1 -1
- package/src/lib/server/site-page-resolver.js +20 -3
- package/src/lib/server/site-page-resolver.js.map +1 -1
- package/src/lib/server/store-day.d.ts +33 -0
- package/src/lib/server/store-day.js +46 -0
- package/src/lib/server/store-day.js.map +1 -0
- package/src/lib/server/store-setup-ai-writer.d.ts +2 -1
- package/src/lib/server/store-setup-ai-writer.js +5 -6
- package/src/lib/server/store-setup-ai-writer.js.map +1 -1
- package/src/lib/server/storefront-tax.d.ts +13 -0
- package/src/lib/server/storefront-tax.js +8 -1
- package/src/lib/server/storefront-tax.js.map +1 -1
- package/src/lib/server/tax-return-source.d.ts +32 -3
- package/src/lib/server/tax-return-source.js +99 -20
- package/src/lib/server/tax-return-source.js.map +1 -1
- package/src/lib/server.js +100 -2
- package/src/lib/server.js.map +1 -1
- package/src/lib/testing/fake-firestore.js +58 -16
- package/src/lib/testing/fake-firestore.js.map +1 -1
- package/src/lib/testing/pos-ops-memory-firestore.js +18 -4
- package/src/lib/testing/pos-ops-memory-firestore.js.map +1 -1
- package/src/lib/testing/site-register-permissions.d.ts +29 -0
- package/src/lib/testing/site-register-permissions.js +38 -0
- package/src/lib/testing/site-register-permissions.js.map +1 -0
- package/src/lib/transfer/tracking.server.js +8 -5
- package/src/lib/transfer/tracking.server.js.map +1 -1
- package/src/lib/utils/add-to-cart.d.ts +2 -0
- package/src/lib/utils/add-to-cart.js +6 -3
- package/src/lib/utils/add-to-cart.js.map +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../../../libs/plugins/commerce/src/lib/components/console/pos-display-page.component.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 type { ConsolePublicPageProps } from '@aglyn/aglyn'\nimport Alert from '@mui/material/Alert'\nimport Box from '@mui/material/Box'\nimport Button from '@mui/material/Button'\nimport CircularProgress from '@mui/material/CircularProgress'\nimport Container from '@mui/material/Container'\nimport Dialog from '@mui/material/Dialog'\nimport DialogActions from '@mui/material/DialogActions'\nimport DialogContent from '@mui/material/DialogContent'\nimport DialogContentText from '@mui/material/DialogContentText'\nimport DialogTitle from '@mui/material/DialogTitle'\nimport Stack from '@mui/material/Stack'\nimport { type ReactNode, useCallback, useEffect, useRef, useState } from 'react'\nimport * as CommerceModel from '../../model'\nimport { PosDisplayBrandMark, PosDisplayBrandScreen } from './pos-display/brand-screen'\nimport { PosDisplayCartView } from './pos-display/cart-screen'\nimport { PosDisplayPairingScreen } from './pos-display/pairing-screen'\nimport {\n displayMoney,\n forgetDisplay,\n pollDisplay,\n type PosDisplayAnswer,\n type PosDisplayBranding,\n type PosDisplayPublicState,\n readStoredToken,\n respondToDisplay,\n storeToken,\n} from './pos-display/pos-display-api'\nimport { PosDisplayReceiptScreen } from './pos-display/receipt-screen'\nimport { PosDisplayTipScreen } from './pos-display/tip-screen'\n\n/** How often the display asks for news while a sale is on screen. */\nexport const POS_DISPLAY_ACTIVE_POLL_MS = 1_000\n/** And between sales, when nothing on it is changing. */\nexport const POS_DISPLAY_IDLE_POLL_MS = 3_000\n/** The store's name and logo are re-read this often, so an edit reaches the screen. */\nconst BRANDING_REFRESH_MS = 10 * 60 * 1000\n\n/**\n * The screen a register turns toward its customer (AGL-3608), served at\n * `/kiosk/commerce/pos-display` with no staff session.\n *\n * It holds one secret, the display token from pairing, and reads one thing\n * with it: its register's display state, polled. Everything the customer\n * answers goes back through `respond`, and the server checks each answer\n * against the prompt it claims to answer, so a stale screen cannot answer\n * the next sale's question.\n */\nexport default function PosDisplayPage(_props: ConsolePublicPageProps) {\n // `undefined` while storage is being read, so the pairing screen never\n // flashes on a display that is already paired.\n const [token, setToken] = useState<string | null | undefined>(undefined)\n const [branding, setBranding] = useState<PosDisplayBranding | null>(null)\n const [state, setState] = useState<PosDisplayPublicState | null>(null)\n const [offline, setOffline] = useState(false)\n const [busy, setBusy] = useState(false)\n const [notice, setNotice] = useState<string | null>(null)\n // The prompt this screen has answered, so \"the cashier will finish up\"\n // shows the moment the answer lands rather than on the next poll.\n const [sentPromptId, setSentPromptId] = useState<string | null>(null)\n const [thanksOver, setThanksOver] = useState(false)\n\n const stateRef = useRef(state)\n stateRef.current = state\n const brandingAtRef = useRef(0)\n\n useEffect(() => {\n setToken(readStoredToken())\n }, [])\n\n const unpaired = useCallback(() => {\n storeToken(null)\n brandingAtRef.current = 0\n setToken(null)\n setState(null)\n setBranding(null)\n setSentPromptId(null)\n }, [])\n\n const paired = useCallback((next: string, nextBranding: PosDisplayBranding) => {\n storeToken(next)\n setBranding(nextBranding ?? null)\n brandingAtRef.current = Date.now()\n setToken(next)\n }, [])\n\n // The poll: every second while a sale is on screen, every three between\n // sales, and not at all while the tab is hidden.\n useEffect(() => {\n if (!token) return undefined\n let active = true\n let inFlight = false\n let timer: ReturnType<typeof setTimeout> | undefined\n\n const schedule = () => {\n if (!active) return\n if (timer) clearTimeout(timer)\n const mode = stateRef.current?.mode ?? 'idle'\n timer = setTimeout(\n () => void tick(),\n mode === 'idle' ? POS_DISPLAY_IDLE_POLL_MS : POS_DISPLAY_ACTIVE_POLL_MS,\n )\n }\n\n const tick = async () => {\n timer = undefined\n if (!active || inFlight) return\n // Hidden: stop here. Coming back into view polls at once.\n if (typeof document !== 'undefined' && document.hidden) return\n inFlight = true\n const withBranding = Date.now() - brandingAtRef.current > BRANDING_REFRESH_MS\n const result = await pollDisplay(token, withBranding)\n inFlight = false\n if (!active) return\n if (result.ok) {\n setOffline(false)\n const { state: next, branding: nextBranding } = result.value ?? {}\n if (next) {\n stateRef.current = next\n setState(next)\n }\n if (nextBranding) {\n brandingAtRef.current = Date.now()\n setBranding(nextBranding)\n }\n } else if (result.status === 401) {\n unpaired()\n return\n } else {\n setOffline(true)\n }\n schedule()\n }\n\n const onVisibility = () => {\n if (document.hidden) return\n if (timer) clearTimeout(timer)\n void tick()\n }\n\n void tick()\n document.addEventListener('visibilitychange', onVisibility)\n return () => {\n active = false\n if (timer) clearTimeout(timer)\n document.removeEventListener('visibilitychange', onVisibility)\n }\n }, [token, unpaired])\n\n // Keep the screen on while paired. Best effort: a browser without the\n // Wake Lock API, or one that refuses it, just follows its own sleep.\n useEffect(() => {\n if (!token) return undefined\n let active = true\n let lock: { release?: () => Promise<void> } | null = null\n const request = async () => {\n try {\n const wakeLock = (\n navigator as Navigator & {\n wakeLock?: { request: (type: 'screen') => Promise<{ release?: () => Promise<void> }> }\n }\n ).wakeLock\n if (!wakeLock || document.hidden) return\n const next = await wakeLock.request('screen')\n if (active) lock = next\n else await next.release?.()\n } catch {\n // Refused (battery saver, no user gesture yet): nothing to do.\n }\n }\n void request()\n // The browser drops the lock when the tab is hidden; take it back.\n const onVisibility = () => {\n if (!document.hidden) void request()\n }\n document.addEventListener('visibilitychange', onVisibility)\n return () => {\n active = false\n document.removeEventListener('visibilitychange', onVisibility)\n lock?.release?.().catch(() => undefined)\n }\n }, [token])\n\n // A new prompt or mode clears whatever this screen said about the last one.\n const promptKey = `${state?.mode ?? 'idle'}:${state?.promptId ?? ''}`\n useEffect(() => {\n setNotice(null)\n }, [promptKey])\n\n // The thank-you returns to the idle screen on its own, even if the next\n // poll is late; the server reports idle after the same interval.\n const thanksKey = state?.mode === 'thanks' ? `${state.promptId ?? ''}:${state.updatedAtMs}` : ''\n useEffect(() => {\n setThanksOver(false)\n if (!thanksKey) return undefined\n const timer = setTimeout(() => setThanksOver(true), CommerceModel.POS_DISPLAY_THANKS_MS)\n return () => clearTimeout(timer)\n }, [thanksKey])\n\n const answer = useCallback(\n async (response: PosDisplayAnswer) => {\n if (!token) return\n setBusy(true)\n setNotice(null)\n const result = await respondToDisplay(token, response)\n setBusy(false)\n if (result.ok) {\n setSentPromptId(response.promptId)\n return\n }\n if (result.status === 401) {\n unpaired()\n return\n }\n setNotice(\n result.status === 409\n ? 'That screen has moved on. Check the display.'\n : (result.error ?? 'Something went wrong. Try again.'),\n )\n },\n [token, unpaired],\n )\n\n if (token === undefined) {\n return (\n <Box sx={{ minHeight: '100dvh', display: 'grid', placeItems: 'center' }}>\n <CircularProgress aria-label=\"Loading\" />\n </Box>\n )\n }\n\n if (!token) return <PosDisplayPairingScreen onPaired={paired} />\n\n return (\n <Box sx={{ position: 'relative', minHeight: '100dvh' }}>\n {offline ? (\n <Alert severity=\"warning\" sx={{ position: 'absolute', top: 0, left: 0, right: 0 }}>\n Reconnecting…\n </Alert>\n ) : null}\n <PosDisplayBody\n key={promptKey}\n state={state}\n branding={branding}\n busy={busy}\n notice={notice}\n answered={Boolean(\n state && (state.answered || (state.promptId && state.promptId === sentPromptId)),\n )}\n thanksOver={thanksOver}\n onAnswer={answer}\n />\n <UnpairControl\n onUnpair={async () => {\n await forgetDisplay(token)\n unpaired()\n }}\n />\n </Box>\n )\n}\n\n/**\n * The screen for the current mode. Keyed by mode and prompt where it is\n * used, so moving on unmounts every input the customer typed into.\n */\nfunction PosDisplayBody({\n state,\n branding,\n busy,\n notice,\n answered,\n thanksOver,\n onAnswer,\n}: {\n state: PosDisplayPublicState | null\n branding: PosDisplayBranding | null\n busy: boolean\n notice: string | null\n answered: boolean\n thanksOver: boolean\n onAnswer: (answer: PosDisplayAnswer) => void\n}) {\n const idle = <PosDisplayBrandScreen branding={branding} message={branding?.message || 'Welcome'} />\n if (!state || state.mode === 'idle') return idle\n\n if (state.mode === 'thanks') {\n if (thanksOver) return idle\n return <PosDisplayBrandScreen branding={branding} title=\"Thank you!\" />\n }\n\n if (state.mode === 'processing') {\n const due = state.cart?.dueCents ?? state.cart?.totalCents\n return (\n <PosDisplayBrandScreen\n branding={branding}\n title={state.processing?.message || 'Tap, insert or swipe your card on the reader.'}\n message={due ? `Total ${displayMoney(due, state.currency)}` : undefined}\n busy\n />\n )\n }\n\n if ((state.mode === 'tip' || state.mode === 'receipt') && answered) {\n return <PosDisplayBrandScreen branding={branding} title=\"Thanks — the cashier will finish up\" />\n }\n\n const promptId = state.promptId ?? ''\n let body: ReactNode\n if (state.mode === 'tip' && state.tip && promptId) {\n body = (\n <PosDisplayTipScreen\n tip={state.tip}\n promptId={promptId}\n busy={busy}\n currency={state.currency}\n onAnswer={onAnswer}\n />\n )\n } else if (state.mode === 'receipt' && state.receipt && promptId) {\n body = (\n <PosDisplayReceiptScreen\n receipt={state.receipt}\n promptId={promptId}\n busy={busy}\n onAnswer={onAnswer}\n />\n )\n } else if (state.cart) {\n body = <PosDisplayCartView cart={state.cart} currency={state.currency} />\n } else {\n return idle\n }\n\n return (\n <Container maxWidth=\"md\" sx={{ py: 4 }}>\n <Stack spacing={4} sx={{ alignItems: 'center' }}>\n <PosDisplayBrandMark branding={branding} />\n {notice ? (\n <Alert severity=\"info\" sx={{ width: '100%' }}>\n {notice}\n </Alert>\n ) : null}\n {body}\n </Stack>\n </Container>\n )\n}\n\n/**\n * Unpairing, tucked into a corner behind a confirmation: the person at the\n * counter is a customer, and one stray tap must not take the screen away.\n */\nfunction UnpairControl({ onUnpair }: { onUnpair: () => Promise<void> }) {\n const [open, setOpen] = useState(false)\n const [busy, setBusy] = useState(false)\n return (\n <>\n <Button\n size=\"small\"\n color=\"inherit\"\n onClick={() => setOpen(true)}\n sx={(theme) => ({\n position: 'fixed',\n right: theme.spacing(1),\n bottom: theme.spacing(1),\n opacity: 0.4,\n })}\n >\n Unpair this display\n </Button>\n <Dialog open={open} onClose={() => (busy ? undefined : setOpen(false))}>\n <DialogTitle>Unpair this display?</DialogTitle>\n <DialogContent>\n <DialogContentText>\n It stops showing sales from the register. To use it again, enter a new code from the\n register.\n </DialogContentText>\n </DialogContent>\n <DialogActions>\n <Button onClick={() => setOpen(false)} disabled={busy}>\n Cancel\n </Button>\n <Button\n color=\"error\"\n variant=\"contained\"\n disabled={busy}\n onClick={async () => {\n setBusy(true)\n await onUnpair()\n setBusy(false)\n setOpen(false)\n }}\n >\n Unpair\n </Button>\n </DialogActions>\n </Dialog>\n </>\n )\n}\n"],"names":["Alert","Box","Button","CircularProgress","Container","Dialog","DialogActions","DialogContent","DialogContentText","DialogTitle","Stack","useCallback","useEffect","useRef","useState","CommerceModel","PosDisplayBrandMark","PosDisplayBrandScreen","PosDisplayCartView","PosDisplayPairingScreen","displayMoney","forgetDisplay","pollDisplay","readStoredToken","respondToDisplay","storeToken","PosDisplayReceiptScreen","PosDisplayTipScreen","POS_DISPLAY_ACTIVE_POLL_MS","POS_DISPLAY_IDLE_POLL_MS","BRANDING_REFRESH_MS","PosDisplayPage","_props","state","token","setToken","undefined","branding","setBranding","setState","offline","setOffline","busy","setBusy","notice","setNotice","sentPromptId","setSentPromptId","thanksOver","setThanksOver","stateRef","current","brandingAtRef","unpaired","paired","next","nextBranding","Date","now","active","inFlight","timer","schedule","clearTimeout","mode","setTimeout","tick","document","hidden","withBranding","result","ok","value","status","onVisibility","addEventListener","removeEventListener","lock","request","wakeLock","navigator","release","catch","promptKey","promptId","thanksKey","updatedAtMs","POS_DISPLAY_THANKS_MS","answer","response","error","sx","minHeight","display","placeItems","aria-label","onPaired","position","severity","top","left","right","PosDisplayBody","answered","Boolean","onAnswer","UnpairControl","onUnpair","idle","message","title","due","cart","dueCents","totalCents","processing","currency","body","tip","receipt","maxWidth","py","spacing","alignItems","width","open","setOpen","size","color","onClick","theme","bottom","opacity","onClose","disabled","variant"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GACD;;AAGA,OAAOA,WAAW,sBAAqB;AACvC,OAAOC,SAAS,oBAAmB;AACnC,OAAOC,YAAY,uBAAsB;AACzC,OAAOC,sBAAsB,iCAAgC;AAC7D,OAAOC,eAAe,0BAAyB;AAC/C,OAAOC,YAAY,uBAAsB;AACzC,OAAOC,mBAAmB,8BAA6B;AACvD,OAAOC,mBAAmB,8BAA6B;AACvD,OAAOC,uBAAuB,kCAAiC;AAC/D,OAAOC,iBAAiB,4BAA2B;AACnD,OAAOC,WAAW,sBAAqB;AACvC,SAAyBC,WAAW,EAAEC,SAAS,EAAEC,MAAM,EAAEC,QAAQ,QAAQ,QAAO;AAChF,YAAYC,mBAAmB,uBAAa;AAC5C,SAASC,mBAAmB,EAAEC,qBAAqB,QAAQ,gCAA4B;AACvF,SAASC,kBAAkB,QAAQ,+BAA2B;AAC9D,SAASC,uBAAuB,QAAQ,kCAA8B;AACtE,SACEC,YAAY,EACZC,aAAa,EACbC,WAAW,EAIXC,eAAe,EACfC,gBAAgB,EAChBC,UAAU,QACL,mCAA+B;AACtC,SAASC,uBAAuB,QAAQ,kCAA8B;AACtE,SAASC,mBAAmB,QAAQ,8BAA0B;AAE9D,mEAAmE,GACnE,OAAO,MAAMC,6BAA6B,KAAK;AAC/C,uDAAuD,GACvD,OAAO,MAAMC,2BAA2B,KAAK;AAC7C,qFAAqF,GACrF,MAAMC,sBAAsB,KAAK,KAAK;AAEtC;;;;;;;;;CASC,GACD,eAAe,SAASC,eAAeC,MAA8B;qBA+InBC;IA9IhD,uEAAuE;IACvE,+CAA+C;IAC/C,MAAM,CAACC,OAAOC,SAAS,GAAGrB,SAAoCsB;IAC9D,MAAM,CAACC,UAAUC,YAAY,GAAGxB,SAAoC;IACpE,MAAM,CAACmB,OAAOM,SAAS,GAAGzB,SAAuC;IACjE,MAAM,CAAC0B,SAASC,WAAW,GAAG3B,SAAS;IACvC,MAAM,CAAC4B,MAAMC,QAAQ,GAAG7B,SAAS;IACjC,MAAM,CAAC8B,QAAQC,UAAU,GAAG/B,SAAwB;IACpD,uEAAuE;IACvE,kEAAkE;IAClE,MAAM,CAACgC,cAAcC,gBAAgB,GAAGjC,SAAwB;IAChE,MAAM,CAACkC,YAAYC,cAAc,GAAGnC,SAAS;IAE7C,MAAMoC,WAAWrC,OAAOoB;IACxBiB,SAASC,OAAO,GAAGlB;IACnB,MAAMmB,gBAAgBvC,OAAO;IAE7BD,UAAU;QACRuB,SAASZ;IACX,GAAG,EAAE;IAEL,MAAM8B,WAAW1C,YAAY;QAC3Bc,WAAW;QACX2B,cAAcD,OAAO,GAAG;QACxBhB,SAAS;QACTI,SAAS;QACTD,YAAY;QACZS,gBAAgB;IAClB,GAAG,EAAE;IAEL,MAAMO,SAAS3C,YAAY,CAAC4C,MAAcC;QACxC/B,WAAW8B;QACXjB,YAAYkB,uBAAAA,eAAgB;QAC5BJ,cAAcD,OAAO,GAAGM,KAAKC,GAAG;QAChCvB,SAASoB;IACX,GAAG,EAAE;IAEL,wEAAwE;IACxE,iDAAiD;IACjD3C,UAAU;QACR,IAAI,CAACsB,OAAO,OAAOE;QACnB,IAAIuB,SAAS;QACb,IAAIC,WAAW;QACf,IAAIC;QAEJ,MAAMC,WAAW;;gBAGFZ;YAFb,IAAI,CAACS,QAAQ;YACb,IAAIE,OAAOE,aAAaF;YACxB,MAAMG,gBAAOd,oBAAAA,SAASC,OAAO,qBAAhBD,kBAAkBc,IAAI,mBAAI;YACvCH,QAAQI,WACN,IAAM,KAAKC,QACXF,SAAS,SAASnC,2BAA2BD;QAEjD;QAEA,MAAMsC,OAAO;YACXL,QAAQzB;YACR,IAAI,CAACuB,UAAUC,UAAU;YACzB,0DAA0D;YAC1D,IAAI,OAAOO,aAAa,eAAeA,SAASC,MAAM,EAAE;YACxDR,WAAW;YACX,MAAMS,eAAeZ,KAAKC,GAAG,KAAKN,cAAcD,OAAO,GAAGrB;YAC1D,MAAMwC,SAAS,MAAMhD,YAAYY,OAAOmC;YACxCT,WAAW;YACX,IAAI,CAACD,QAAQ;YACb,IAAIW,OAAOC,EAAE,EAAE;oBAEmCD;gBADhD7B,WAAW;gBACX,MAAM,EAAER,OAAOsB,IAAI,EAAElB,UAAUmB,YAAY,EAAE,IAAGc,gBAAAA,OAAOE,KAAK,YAAZF,gBAAgB,CAAC;gBACjE,IAAIf,MAAM;oBACRL,SAASC,OAAO,GAAGI;oBACnBhB,SAASgB;gBACX;gBACA,IAAIC,cAAc;oBAChBJ,cAAcD,OAAO,GAAGM,KAAKC,GAAG;oBAChCpB,YAAYkB;gBACd;YACF,OAAO,IAAIc,OAAOG,MAAM,KAAK,KAAK;gBAChCpB;gBACA;YACF,OAAO;gBACLZ,WAAW;YACb;YACAqB;QACF;QAEA,MAAMY,eAAe;YACnB,IAAIP,SAASC,MAAM,EAAE;YACrB,IAAIP,OAAOE,aAAaF;YACxB,KAAKK;QACP;QAEA,KAAKA;QACLC,SAASQ,gBAAgB,CAAC,oBAAoBD;QAC9C,OAAO;YACLf,SAAS;YACT,IAAIE,OAAOE,aAAaF;YACxBM,SAASS,mBAAmB,CAAC,oBAAoBF;QACnD;IACF,GAAG;QAACxC;QAAOmB;KAAS;IAEpB,sEAAsE;IACtE,qEAAqE;IACrEzC,UAAU;QACR,IAAI,CAACsB,OAAO,OAAOE;QACnB,IAAIuB,SAAS;QACb,IAAIkB,OAAiD;QACrD,MAAMC,UAAU;YACd,IAAI;gBACF,MAAMC,WAAW,AACfC,UAGAD,QAAQ;gBACV,IAAI,CAACA,YAAYZ,SAASC,MAAM,EAAE;gBAClC,MAAMb,OAAO,MAAMwB,SAASD,OAAO,CAAC;gBACpC,IAAInB,QAAQkB,OAAOtB;qBACd,OAAMA,KAAK0B,OAAO,oBAAZ1B,KAAK0B,OAAO,MAAZ1B;YACb,EAAE,eAAM;YACN,+DAA+D;YACjE;QACF;QACA,KAAKuB;QACL,mEAAmE;QACnE,MAAMJ,eAAe;YACnB,IAAI,CAACP,SAASC,MAAM,EAAE,KAAKU;QAC7B;QACAX,SAASQ,gBAAgB,CAAC,oBAAoBD;QAC9C,OAAO;gBAGLG;YAFAlB,SAAS;YACTQ,SAASS,mBAAmB,CAAC,oBAAoBF;YACjDG,yBAAAA,gBAAAA,KAAMI,OAAO,qBAAbJ,mBAAAA,MAAkBK,KAAK,CAAC,IAAM9C;QAChC;IACF,GAAG;QAACF;KAAM;IAEV,4EAA4E;IAC5E,MAAMiD,YAAY,WAAGlD,yBAAAA,MAAO+B,IAAI,mBAAI,OAAO,CAAC,WAAE/B,yBAAAA,MAAOmD,QAAQ,oBAAI,IAAI;IACrExE,UAAU;QACRiC,UAAU;IACZ,GAAG;QAACsC;KAAU;IAEd,wEAAwE;IACxE,iEAAiE;IACjE,MAAME,YAAYpD,CAAAA,yBAAAA,MAAO+B,IAAI,MAAK,WAAW,IAAG/B,kBAAAA,MAAMmD,QAAQ,YAAdnD,kBAAkB,GAAG,CAAC,EAAEA,MAAMqD,WAAW,EAAE,GAAG;IAC9F1E,UAAU;QACRqC,cAAc;QACd,IAAI,CAACoC,WAAW,OAAOjD;QACvB,MAAMyB,QAAQI,WAAW,IAAMhB,cAAc,OAAOlC,cAAcwE,qBAAqB;QACvF,OAAO,IAAMxB,aAAaF;IAC5B,GAAG;QAACwB;KAAU;IAEd,MAAMG,SAAS7E,YACb,OAAO8E;YAiBEnB;QAhBP,IAAI,CAACpC,OAAO;QACZS,QAAQ;QACRE,UAAU;QACV,MAAMyB,SAAS,MAAM9C,iBAAiBU,OAAOuD;QAC7C9C,QAAQ;QACR,IAAI2B,OAAOC,EAAE,EAAE;YACbxB,gBAAgB0C,SAASL,QAAQ;YACjC;QACF;QACA,IAAId,OAAOG,MAAM,KAAK,KAAK;YACzBpB;YACA;QACF;QACAR,UACEyB,OAAOG,MAAM,KAAK,MACd,kDACCH,gBAAAA,OAAOoB,KAAK,YAAZpB,gBAAgB;IAEzB,GACA;QAACpC;QAAOmB;KAAS;IAGnB,IAAInB,UAAUE,WAAW;QACvB,qBACE,KAACnC;YAAI0F,IAAI;gBAAEC,WAAW;gBAAUC,SAAS;gBAAQC,YAAY;YAAS;sBACpE,cAAA,KAAC3F;gBAAiB4F,cAAW;;;IAGnC;IAEA,IAAI,CAAC7D,OAAO,qBAAO,KAACf;QAAwB6E,UAAU1C;;IAEtD,qBACE,MAACrD;QAAI0F,IAAI;YAAEM,UAAU;YAAYL,WAAW;QAAS;;YAClDpD,wBACC,KAACxC;gBAAMkG,UAAS;gBAAUP,IAAI;oBAAEM,UAAU;oBAAYE,KAAK;oBAAGC,MAAM;oBAAGC,OAAO;gBAAE;0BAAG;iBAGjF;0BACJ,KAACC;gBAECrE,OAAOA;gBACPI,UAAUA;gBACVK,MAAMA;gBACNE,QAAQA;gBACR2D,UAAUC,QACRvE,SAAUA,CAAAA,MAAMsE,QAAQ,IAAKtE,MAAMmD,QAAQ,IAAInD,MAAMmD,QAAQ,KAAKtC,YAAY;gBAEhFE,YAAYA;gBACZyD,UAAUjB;eATLL;0BAWP,KAACuB;gBACCC,UAAU;oBACR,MAAMtF,cAAca;oBACpBmB;gBACF;;;;AAIR;AAEA;;;CAGC,GACD,SAASiD,eAAe,EACtBrE,KAAK,EACLI,QAAQ,EACRK,IAAI,EACJE,MAAM,EACN2D,QAAQ,EACRvD,UAAU,EACVyD,QAAQ,EAST;QAyBkBxE;IAxBjB,MAAM2E,qBAAO,KAAC3F;QAAsBoB,UAAUA;QAAUwE,SAASxE,CAAAA,4BAAAA,SAAUwE,OAAO,KAAI;;IACtF,IAAI,CAAC5E,SAASA,MAAM+B,IAAI,KAAK,QAAQ,OAAO4C;IAE5C,IAAI3E,MAAM+B,IAAI,KAAK,UAAU;QAC3B,IAAIhB,YAAY,OAAO4D;QACvB,qBAAO,KAAC3F;YAAsBoB,UAAUA;YAAUyE,OAAM;;IAC1D;IAEA,IAAI7E,MAAM+B,IAAI,KAAK,cAAc;;YACnB/B,aAAwBA,cAIzBA;QAJX,MAAM8E,eAAM9E,cAAAA,MAAM+E,IAAI,qBAAV/E,YAAYgF,QAAQ,oBAAIhF,eAAAA,MAAM+E,IAAI,qBAAV/E,aAAYiF,UAAU;QAC1D,qBACE,KAACjG;YACCoB,UAAUA;YACVyE,OAAO7E,EAAAA,oBAAAA,MAAMkF,UAAU,qBAAhBlF,kBAAkB4E,OAAO,KAAI;YACpCA,SAASE,MAAM,CAAC,MAAM,EAAE3F,aAAa2F,KAAK9E,MAAMmF,QAAQ,GAAG,GAAGhF;YAC9DM,IAAI;;IAGV;IAEA,IAAI,AAACT,CAAAA,MAAM+B,IAAI,KAAK,SAAS/B,MAAM+B,IAAI,KAAK,SAAQ,KAAMuC,UAAU;QAClE,qBAAO,KAACtF;YAAsBoB,UAAUA;YAAUyE,OAAM;;IAC1D;IAEA,MAAM1B,YAAWnD,kBAAAA,MAAMmD,QAAQ,YAAdnD,kBAAkB;IACnC,IAAIoF;IACJ,IAAIpF,MAAM+B,IAAI,KAAK,SAAS/B,MAAMqF,GAAG,IAAIlC,UAAU;QACjDiC,qBACE,KAAC1F;YACC2F,KAAKrF,MAAMqF,GAAG;YACdlC,UAAUA;YACV1C,MAAMA;YACN0E,UAAUnF,MAAMmF,QAAQ;YACxBX,UAAUA;;IAGhB,OAAO,IAAIxE,MAAM+B,IAAI,KAAK,aAAa/B,MAAMsF,OAAO,IAAInC,UAAU;QAChEiC,qBACE,KAAC3F;YACC6F,SAAStF,MAAMsF,OAAO;YACtBnC,UAAUA;YACV1C,MAAMA;YACN+D,UAAUA;;IAGhB,OAAO,IAAIxE,MAAM+E,IAAI,EAAE;QACrBK,qBAAO,KAACnG;YAAmB8F,MAAM/E,MAAM+E,IAAI;YAAEI,UAAUnF,MAAMmF,QAAQ;;IACvE,OAAO;QACL,OAAOR;IACT;IAEA,qBACE,KAACxG;QAAUoH,UAAS;QAAK7B,IAAI;YAAE8B,IAAI;QAAE;kBACnC,cAAA,MAAC/G;YAAMgH,SAAS;YAAG/B,IAAI;gBAAEgC,YAAY;YAAS;;8BAC5C,KAAC3G;oBAAoBqB,UAAUA;;gBAC9BO,uBACC,KAAC5C;oBAAMkG,UAAS;oBAAOP,IAAI;wBAAEiC,OAAO;oBAAO;8BACxChF;qBAED;gBACHyE;;;;AAIT;AAEA;;;CAGC,GACD,SAASX,cAAc,EAAEC,QAAQ,EAAqC;IACpE,MAAM,CAACkB,MAAMC,QAAQ,GAAGhH,SAAS;IACjC,MAAM,CAAC4B,MAAMC,QAAQ,GAAG7B,SAAS;IACjC,qBACE;;0BACE,KAACZ;gBACC6H,MAAK;gBACLC,OAAM;gBACNC,SAAS,IAAMH,QAAQ;gBACvBnC,IAAI,CAACuC,QAAW,CAAA;wBACdjC,UAAU;wBACVI,OAAO6B,MAAMR,OAAO,CAAC;wBACrBS,QAAQD,MAAMR,OAAO,CAAC;wBACtBU,SAAS;oBACX,CAAA;0BACD;;0BAGD,MAAC/H;gBAAOwH,MAAMA;gBAAMQ,SAAS,IAAO3F,OAAON,YAAY0F,QAAQ;;kCAC7D,KAACrH;kCAAY;;kCACb,KAACF;kCACC,cAAA,KAACC;sCAAkB;;;kCAKrB,MAACF;;0CACC,KAACJ;gCAAO+H,SAAS,IAAMH,QAAQ;gCAAQQ,UAAU5F;0CAAM;;0CAGvD,KAACxC;gCACC8H,OAAM;gCACNO,SAAQ;gCACRD,UAAU5F;gCACVuF,SAAS;oCACPtF,QAAQ;oCACR,MAAMgE;oCACNhE,QAAQ;oCACRmF,QAAQ;gCACV;0CACD;;;;;;;;AAOX"}
|
|
1
|
+
{"version":3,"sources":["../../../../../../../../libs/plugins/commerce/src/lib/components/console/pos-display-page.component.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 type { ConsolePublicPageProps } from '@aglyn/aglyn'\nimport {\n customerDisplayScreenHref,\n rememberCustomerDisplayCredential,\n} from '@aglyn/aglyn/plugin-manager/plugin-customer-display'\nimport Alert from '@mui/material/Alert'\nimport Box from '@mui/material/Box'\nimport Button from '@mui/material/Button'\nimport CircularProgress from '@mui/material/CircularProgress'\nimport Container from '@mui/material/Container'\nimport Dialog from '@mui/material/Dialog'\nimport DialogActions from '@mui/material/DialogActions'\nimport DialogContent from '@mui/material/DialogContent'\nimport DialogContentText from '@mui/material/DialogContentText'\nimport DialogTitle from '@mui/material/DialogTitle'\nimport Stack from '@mui/material/Stack'\nimport { type ReactNode, useCallback, useEffect, useRef, useState } from 'react'\nimport * as CommerceModel from '../../model'\nimport { PosDisplayBrandMark, PosDisplayBrandScreen } from './pos-display/brand-screen'\nimport { PosDisplayCartView } from './pos-display/cart-screen'\nimport { PosDisplayPairingScreen } from './pos-display/pairing-screen'\nimport {\n displayMoney,\n forgetDisplay,\n pollDisplay,\n type PosDisplayAnswer,\n type PosDisplayBranding,\n type PosDisplayPublicState,\n readStoredToken,\n respondToDisplay,\n storeToken,\n} from './pos-display/pos-display-api'\nimport { PosDisplayReceiptScreen } from './pos-display/receipt-screen'\nimport { PosDisplayTipScreen } from './pos-display/tip-screen'\n\n/** How often the display asks for news while a sale is on screen. */\nexport const POS_DISPLAY_ACTIVE_POLL_MS = 1_000\n/** And between sales, when nothing on it is changing. */\nexport const POS_DISPLAY_IDLE_POLL_MS = 3_000\n/** The store's name and logo are re-read this often, so an edit reaches the screen. */\nconst BRANDING_REFRESH_MS = 10 * 60 * 1000\n\n/** This page's own address, where another plugin's screen sends the display back. */\nexport const POS_DISPLAY_PAGE_PATH = '/kiosk/commerce/pos-display'\n\n/** The prompts of the plugin screens this tab already opened, so coming back opens none again. */\nconst OPENED_SCREENS_KEY = 'aglyn.posDisplayOpenedScreens'\n\n/**\n * Whether this tab may open the screen of a prompt, marking it opened. Session\n * storage, so it survives the trip to the plugin's page and back and is gone\n * with the tab. A browser that refuses storage opens no screen at all: it\n * could not remember coming back, and would open the same one again.\n */\nexport function claimDisplayScreen(promptId: string): boolean {\n try {\n const opened = JSON.parse(window.sessionStorage.getItem(OPENED_SCREENS_KEY) ?? '[]') as string[]\n if (opened.includes(promptId)) return false\n window.sessionStorage.setItem(OPENED_SCREENS_KEY, JSON.stringify([...opened, promptId].slice(-20)))\n return true\n } catch {\n return false\n }\n}\n\n/** Leaves for another plugin's screen; an object so a spec can watch it. */\nexport const posDisplayNavigation = {\n open(href: string): void {\n window.location.assign(href)\n },\n}\n\n/**\n * The screen a register turns toward its customer (AGL-3608), served at\n * `/kiosk/commerce/pos-display` with no staff session.\n *\n * It holds one secret, the display token from pairing, and reads one thing\n * with it: its register's display state, polled. Everything the customer\n * answers goes back through `respond`, and the server checks each answer\n * against the prompt it claims to answer, so a stale screen cannot answer\n * the next sale's question.\n */\nexport default function PosDisplayPage(_props: ConsolePublicPageProps) {\n // `undefined` while storage is being read, so the pairing screen never\n // flashes on a display that is already paired.\n const [token, setToken] = useState<string | null | undefined>(undefined)\n const [branding, setBranding] = useState<PosDisplayBranding | null>(null)\n const [state, setState] = useState<PosDisplayPublicState | null>(null)\n const [offline, setOffline] = useState(false)\n const [busy, setBusy] = useState(false)\n const [notice, setNotice] = useState<string | null>(null)\n // The prompt this screen has answered, so \"the cashier will finish up\"\n // shows the moment the answer lands rather than on the next poll.\n const [sentPromptId, setSentPromptId] = useState<string | null>(null)\n const [thanksOver, setThanksOver] = useState(false)\n\n const stateRef = useRef(state)\n stateRef.current = state\n const brandingAtRef = useRef(0)\n\n useEffect(() => {\n const stored = readStoredToken()\n // A display paired before core kept the credential (AGL-4042) hands it\n // over here, so another plugin's screen on it works without pairing again.\n rememberCustomerDisplayCredential(stored)\n setToken(stored)\n }, [])\n\n const unpaired = useCallback(() => {\n storeToken(null)\n brandingAtRef.current = 0\n setToken(null)\n setState(null)\n setBranding(null)\n setSentPromptId(null)\n }, [])\n\n const paired = useCallback((next: string, nextBranding: PosDisplayBranding) => {\n storeToken(next)\n setBranding(nextBranding ?? null)\n brandingAtRef.current = Date.now()\n setToken(next)\n }, [])\n\n // The poll: every second while a sale is on screen, every three between\n // sales, and not at all while the tab is hidden.\n useEffect(() => {\n if (!token) return undefined\n let active = true\n let inFlight = false\n let timer: ReturnType<typeof setTimeout> | undefined\n\n const schedule = () => {\n if (!active) return\n if (timer) clearTimeout(timer)\n const mode = stateRef.current?.mode ?? 'idle'\n timer = setTimeout(\n () => void tick(),\n mode === 'idle' ? POS_DISPLAY_IDLE_POLL_MS : POS_DISPLAY_ACTIVE_POLL_MS,\n )\n }\n\n const tick = async () => {\n timer = undefined\n if (!active || inFlight) return\n // Hidden: stop here. Coming back into view polls at once.\n if (typeof document !== 'undefined' && document.hidden) return\n inFlight = true\n const withBranding = Date.now() - brandingAtRef.current > BRANDING_REFRESH_MS\n const result = await pollDisplay(token, withBranding)\n inFlight = false\n if (!active) return\n if (result.ok) {\n setOffline(false)\n const { state: next, branding: nextBranding } = result.value ?? {}\n if (next) {\n stateRef.current = next\n setState(next)\n }\n if (nextBranding) {\n brandingAtRef.current = Date.now()\n setBranding(nextBranding)\n }\n } else if (result.status === 401) {\n unpaired()\n return\n } else {\n setOffline(true)\n }\n schedule()\n }\n\n const onVisibility = () => {\n if (document.hidden) return\n if (timer) clearTimeout(timer)\n void tick()\n }\n\n void tick()\n document.addEventListener('visibilitychange', onVisibility)\n return () => {\n active = false\n if (timer) clearTimeout(timer)\n document.removeEventListener('visibilitychange', onVisibility)\n }\n }, [token, unpaired])\n\n // Another plugin's screen (AGL-4042): opened once per prompt, at the\n // plugin's own public page, which sends the display back here when the\n // customer is done. Back here, the same prompt shows the store's screen.\n useEffect(() => {\n if (state?.mode !== 'screen' || !state.screen || !state.promptId) return\n const href = customerDisplayScreenHref(state.screen, POS_DISPLAY_PAGE_PATH)\n if (href && claimDisplayScreen(state.promptId)) posDisplayNavigation.open(href)\n }, [state])\n\n // Keep the screen on while paired. Best effort: a browser without the\n // Wake Lock API, or one that refuses it, just follows its own sleep.\n useEffect(() => {\n if (!token) return undefined\n let active = true\n let lock: { release?: () => Promise<void> } | null = null\n const request = async () => {\n try {\n const wakeLock = (\n navigator as Navigator & {\n wakeLock?: { request: (type: 'screen') => Promise<{ release?: () => Promise<void> }> }\n }\n ).wakeLock\n if (!wakeLock || document.hidden) return\n const next = await wakeLock.request('screen')\n if (active) lock = next\n else await next.release?.()\n } catch {\n // Refused (battery saver, no user gesture yet): nothing to do.\n }\n }\n void request()\n // The browser drops the lock when the tab is hidden; take it back.\n const onVisibility = () => {\n if (!document.hidden) void request()\n }\n document.addEventListener('visibilitychange', onVisibility)\n return () => {\n active = false\n document.removeEventListener('visibilitychange', onVisibility)\n lock?.release?.().catch(() => undefined)\n }\n }, [token])\n\n // A new prompt or mode clears whatever this screen said about the last one.\n const promptKey = `${state?.mode ?? 'idle'}:${state?.promptId ?? ''}`\n useEffect(() => {\n setNotice(null)\n }, [promptKey])\n\n // The thank-you returns to the idle screen on its own, even if the next\n // poll is late; the server reports idle after the same interval.\n const thanksKey = state?.mode === 'thanks' ? `${state.promptId ?? ''}:${state.updatedAtMs}` : ''\n useEffect(() => {\n setThanksOver(false)\n if (!thanksKey) return undefined\n const timer = setTimeout(() => setThanksOver(true), CommerceModel.POS_DISPLAY_THANKS_MS)\n return () => clearTimeout(timer)\n }, [thanksKey])\n\n const answer = useCallback(\n async (response: PosDisplayAnswer) => {\n if (!token) return\n setBusy(true)\n setNotice(null)\n const result = await respondToDisplay(token, response)\n setBusy(false)\n if (result.ok) {\n setSentPromptId(response.promptId)\n return\n }\n if (result.status === 401) {\n unpaired()\n return\n }\n setNotice(\n result.status === 409\n ? 'That screen has moved on. Check the display.'\n : (result.error ?? 'Something went wrong. Try again.'),\n )\n },\n [token, unpaired],\n )\n\n if (token === undefined) {\n return (\n <Box sx={{ minHeight: '100dvh', display: 'grid', placeItems: 'center' }}>\n <CircularProgress aria-label=\"Loading\" />\n </Box>\n )\n }\n\n if (!token) return <PosDisplayPairingScreen onPaired={paired} />\n\n return (\n <Box sx={{ position: 'relative', minHeight: '100dvh' }}>\n {offline ? (\n <Alert severity=\"warning\" sx={{ position: 'absolute', top: 0, left: 0, right: 0 }}>\n Reconnecting…\n </Alert>\n ) : null}\n <PosDisplayBody\n key={promptKey}\n state={state}\n branding={branding}\n busy={busy}\n notice={notice}\n answered={Boolean(\n state && (state.answered || (state.promptId && state.promptId === sentPromptId)),\n )}\n thanksOver={thanksOver}\n onAnswer={answer}\n />\n <UnpairControl\n onUnpair={async () => {\n await forgetDisplay(token)\n unpaired()\n }}\n />\n </Box>\n )\n}\n\n/**\n * The screen for the current mode. Keyed by mode and prompt where it is\n * used, so moving on unmounts every input the customer typed into.\n */\nfunction PosDisplayBody({\n state,\n branding,\n busy,\n notice,\n answered,\n thanksOver,\n onAnswer,\n}: {\n state: PosDisplayPublicState | null\n branding: PosDisplayBranding | null\n busy: boolean\n notice: string | null\n answered: boolean\n thanksOver: boolean\n onAnswer: (answer: PosDisplayAnswer) => void\n}) {\n const idle = <PosDisplayBrandScreen branding={branding} message={branding?.message || 'Welcome'} />\n // A plugin's screen opens its own page; back here, the store's screen shows.\n if (!state || state.mode === 'idle' || state.mode === 'screen') return idle\n\n if (state.mode === 'thanks') {\n if (thanksOver) return idle\n return <PosDisplayBrandScreen branding={branding} title=\"Thank you!\" />\n }\n\n if (state.mode === 'processing') {\n const due = state.cart?.dueCents ?? state.cart?.totalCents\n return (\n <PosDisplayBrandScreen\n branding={branding}\n title={state.processing?.message || 'Tap, insert or swipe your card on the reader.'}\n message={due ? `Total ${displayMoney(due, state.currency)}` : undefined}\n busy\n />\n )\n }\n\n if ((state.mode === 'tip' || state.mode === 'receipt') && answered) {\n return <PosDisplayBrandScreen branding={branding} title=\"Thanks — the cashier will finish up\" />\n }\n\n const promptId = state.promptId ?? ''\n let body: ReactNode\n if (state.mode === 'tip' && state.tip && promptId) {\n body = (\n <PosDisplayTipScreen\n tip={state.tip}\n promptId={promptId}\n busy={busy}\n currency={state.currency}\n onAnswer={onAnswer}\n />\n )\n } else if (state.mode === 'receipt' && state.receipt && promptId) {\n body = (\n <PosDisplayReceiptScreen\n receipt={state.receipt}\n promptId={promptId}\n busy={busy}\n onAnswer={onAnswer}\n />\n )\n } else if (state.cart) {\n body = <PosDisplayCartView cart={state.cart} currency={state.currency} />\n } else {\n return idle\n }\n\n return (\n <Container maxWidth=\"md\" sx={{ py: 4 }}>\n <Stack spacing={4} sx={{ alignItems: 'center' }}>\n <PosDisplayBrandMark branding={branding} />\n {notice ? (\n <Alert severity=\"info\" sx={{ width: '100%' }}>\n {notice}\n </Alert>\n ) : null}\n {body}\n </Stack>\n </Container>\n )\n}\n\n/**\n * Unpairing, tucked into a corner behind a confirmation: the person at the\n * counter is a customer, and one stray tap must not take the screen away.\n */\nfunction UnpairControl({ onUnpair }: { onUnpair: () => Promise<void> }) {\n const [open, setOpen] = useState(false)\n const [busy, setBusy] = useState(false)\n return (\n <>\n <Button\n size=\"small\"\n color=\"inherit\"\n onClick={() => setOpen(true)}\n sx={(theme) => ({\n position: 'fixed',\n right: theme.spacing(1),\n bottom: theme.spacing(1),\n opacity: 0.4,\n })}\n >\n Unpair this display\n </Button>\n <Dialog open={open} onClose={() => (busy ? undefined : setOpen(false))}>\n <DialogTitle>Unpair this display?</DialogTitle>\n <DialogContent>\n <DialogContentText>\n It stops showing sales from the register. To use it again, enter a new code from the\n register.\n </DialogContentText>\n </DialogContent>\n <DialogActions>\n <Button onClick={() => setOpen(false)} disabled={busy}>\n Cancel\n </Button>\n <Button\n color=\"error\"\n variant=\"contained\"\n disabled={busy}\n onClick={async () => {\n setBusy(true)\n await onUnpair()\n setBusy(false)\n setOpen(false)\n }}\n >\n Unpair\n </Button>\n </DialogActions>\n </Dialog>\n </>\n )\n}\n"],"names":["customerDisplayScreenHref","rememberCustomerDisplayCredential","Alert","Box","Button","CircularProgress","Container","Dialog","DialogActions","DialogContent","DialogContentText","DialogTitle","Stack","useCallback","useEffect","useRef","useState","CommerceModel","PosDisplayBrandMark","PosDisplayBrandScreen","PosDisplayCartView","PosDisplayPairingScreen","displayMoney","forgetDisplay","pollDisplay","readStoredToken","respondToDisplay","storeToken","PosDisplayReceiptScreen","PosDisplayTipScreen","POS_DISPLAY_ACTIVE_POLL_MS","POS_DISPLAY_IDLE_POLL_MS","BRANDING_REFRESH_MS","POS_DISPLAY_PAGE_PATH","OPENED_SCREENS_KEY","claimDisplayScreen","promptId","window","opened","JSON","parse","sessionStorage","getItem","includes","setItem","stringify","slice","posDisplayNavigation","open","href","location","assign","PosDisplayPage","_props","state","token","setToken","undefined","branding","setBranding","setState","offline","setOffline","busy","setBusy","notice","setNotice","sentPromptId","setSentPromptId","thanksOver","setThanksOver","stateRef","current","brandingAtRef","stored","unpaired","paired","next","nextBranding","Date","now","active","inFlight","timer","schedule","clearTimeout","mode","setTimeout","tick","document","hidden","withBranding","result","ok","value","status","onVisibility","addEventListener","removeEventListener","screen","lock","request","wakeLock","navigator","release","catch","promptKey","thanksKey","updatedAtMs","POS_DISPLAY_THANKS_MS","answer","response","error","sx","minHeight","display","placeItems","aria-label","onPaired","position","severity","top","left","right","PosDisplayBody","answered","Boolean","onAnswer","UnpairControl","onUnpair","idle","message","title","due","cart","dueCents","totalCents","processing","currency","body","tip","receipt","maxWidth","py","spacing","alignItems","width","setOpen","size","color","onClick","theme","bottom","opacity","onClose","disabled","variant"],"mappings":"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"}
|
|
@@ -3,11 +3,19 @@ export declare const POS_HARDWARE_STATUS_COLOR: Record<PosHardwareOrderStatus, '
|
|
|
3
3
|
export interface PosHardwareCardProps {
|
|
4
4
|
hostId: string;
|
|
5
5
|
/**
|
|
6
|
-
* Whether the viewer may work this site's register
|
|
7
|
-
*
|
|
8
|
-
* the register's hardware, so a viewer who may not run it is not shown it.
|
|
6
|
+
* Whether the viewer may work this site's register (`managePos`). The shop
|
|
7
|
+
* is the register's hardware, so whoever works it is shown the shop.
|
|
9
8
|
*/
|
|
10
9
|
canManagePos?: boolean;
|
|
10
|
+
/**
|
|
11
|
+
* Whether the viewer may start a checkout (AGL-4047): the "Buy point of
|
|
12
|
+
* sale hardware" key the route asks of a checkout. It stands on its own,
|
|
13
|
+
* so a member who holds it without the register is shown the shop and
|
|
14
|
+
* their orders too. Someone who works the register without it sees the
|
|
15
|
+
* shop with Check out disabled and the reason. Absent follows
|
|
16
|
+
* `canManagePos`.
|
|
17
|
+
*/
|
|
18
|
+
canBuyHardware?: boolean;
|
|
11
19
|
}
|
|
12
20
|
/**
|
|
13
21
|
* The Hardware card (AGL-4038): Stripe card readers and accessories sold by
|
|
@@ -19,7 +27,7 @@ export interface PosHardwareCardProps {
|
|
|
19
27
|
* on the workspace can take. The route answers `available: false` until
|
|
20
28
|
* every price, the markup and the shipping figures are configured.
|
|
21
29
|
*/
|
|
22
|
-
export declare function PosHardwareCard({ hostId, canManagePos }: PosHardwareCardProps): import("react").JSX.Element;
|
|
30
|
+
export declare function PosHardwareCard({ hostId, canManagePos, canBuyHardware, }: PosHardwareCardProps): import("react").JSX.Element;
|
|
23
31
|
export declare namespace PosHardwareCard {
|
|
24
32
|
var displayName: string;
|
|
25
33
|
}
|
|
@@ -18,14 +18,15 @@ import { _ as _extends } from "@swc/helpers/_/_extends";
|
|
|
18
18
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
19
19
|
import { pluginDocsHelp } from "@aglyn/aglyn";
|
|
20
20
|
import { CardDisplay } from "@aglyn/shared-ui-jsx";
|
|
21
|
+
import { BlockedControl } from "@aglyn/shared-ui-jsx/components/blocked-control.component";
|
|
21
22
|
import { ListTable } from "@aglyn/shared-ui-jsx/components/list-table.component";
|
|
22
23
|
import { useSnackbar } from "@aglyn/shared-ui-snackstack";
|
|
23
24
|
import { useUser } from "@aglyn/tenant-feature-instance";
|
|
24
|
-
import { Alert, Box, Button, Card, CardContent, Chip, Link, MenuItem, Stack, TextField, Typography } from "@mui/material";
|
|
25
|
+
import { Alert, Box, Button, Card, CardContent, Chip, Dialog, DialogActions, DialogContent, DialogTitle, Link, MenuItem, Stack, TextField, Typography } from "@mui/material";
|
|
25
26
|
import { useCallback, useEffect, useMemo, useState } from "react";
|
|
26
27
|
import { formatPosHardwareCents, POS_HARDWARE_ANCHOR, POS_HARDWARE_MAX_PER_LINE, POS_HARDWARE_STATUS_LABELS } from "../../model/pos-hardware.js";
|
|
27
28
|
import { newAttemptKey } from "./pos/pos-api.js";
|
|
28
|
-
import { openPosHardwareCheckout, posHardwareCatalog, posHardwareCheckout, posHardwareOrders, PosHardwareRequestError } from "./pos/pos-hardware-api.js";
|
|
29
|
+
import { openPosHardwareCheckout, posHardwareCatalog, posHardwareCheckout, posHardwareOrders, posHardwareRequestReturn, PosHardwareRequestError } from "./pos/pos-hardware-api.js";
|
|
29
30
|
export const POS_HARDWARE_STATUS_COLOR = {
|
|
30
31
|
paid: 'info',
|
|
31
32
|
ordered: 'info',
|
|
@@ -35,6 +36,11 @@ export const POS_HARDWARE_STATUS_COLOR = {
|
|
|
35
36
|
canceled: 'default',
|
|
36
37
|
refunded: 'default'
|
|
37
38
|
};
|
|
39
|
+
/** What the buyer reads of their return request. */ const RETURN_LABELS = {
|
|
40
|
+
requested: 'Return requested',
|
|
41
|
+
declined: 'Return declined',
|
|
42
|
+
refunded: 'Returned'
|
|
43
|
+
};
|
|
38
44
|
const QUANTITIES = Array.from({
|
|
39
45
|
length: POS_HARDWARE_MAX_PER_LINE + 1
|
|
40
46
|
}, (_, index)=>index);
|
|
@@ -43,6 +49,7 @@ const placedOn = (ms)=>ms ? new Date(ms).toLocaleDateString([], {
|
|
|
43
49
|
day: 'numeric',
|
|
44
50
|
year: 'numeric'
|
|
45
51
|
}) : '—';
|
|
52
|
+
/** Why Check out is not offered to someone who works the register. */ const BUY_KEY_REASON = 'Only a member with the "Buy point of sale hardware" permission can place an order. Ask an organization admin.';
|
|
46
53
|
/**
|
|
47
54
|
* The Hardware card (AGL-4038): Stripe card readers and accessories sold by
|
|
48
55
|
* the platform and shipped by Stripe straight to the store, with the store's
|
|
@@ -52,7 +59,7 @@ const placedOn = (ms)=>ms ? new Date(ms).toLocaleDateString([], {
|
|
|
52
59
|
* gate only the platform can lift, so naming it would point at a step nobody
|
|
53
60
|
* on the workspace can take. The route answers `available: false` until
|
|
54
61
|
* every price, the markup and the shipping figures are configured.
|
|
55
|
-
*/ export function PosHardwareCard({ hostId, canManagePos = false }) {
|
|
62
|
+
*/ export function PosHardwareCard({ hostId, canManagePos = false, canBuyHardware = canManagePos }) {
|
|
56
63
|
var _ref, _ref1;
|
|
57
64
|
const { data: user } = useUser();
|
|
58
65
|
const { enqueueSnackbar } = useSnackbar();
|
|
@@ -63,8 +70,10 @@ const placedOn = (ms)=>ms ? new Date(ms).toLocaleDateString([], {
|
|
|
63
70
|
const [busy, setBusy] = useState(false);
|
|
64
71
|
const [returned, setReturned] = useState(null);
|
|
65
72
|
const uid = (_ref = user == null ? void 0 : user.uid) != null ? _ref : '';
|
|
73
|
+
// The route's own door (AGL-4047): the register, or the key to buy.
|
|
74
|
+
const mayVisit = canManagePos || canBuyHardware;
|
|
66
75
|
useEffect(()=>{
|
|
67
|
-
if (!user || !
|
|
76
|
+
if (!user || !mayVisit) return;
|
|
68
77
|
let active = true;
|
|
69
78
|
void posHardwareCatalog(user, hostId).then((answer)=>{
|
|
70
79
|
if (active) setCatalog(answer);
|
|
@@ -81,7 +90,7 @@ const placedOn = (ms)=>ms ? new Date(ms).toLocaleDateString([], {
|
|
|
81
90
|
}, [
|
|
82
91
|
uid,
|
|
83
92
|
hostId,
|
|
84
|
-
|
|
93
|
+
mayVisit
|
|
85
94
|
]);
|
|
86
95
|
const available = (catalog == null ? void 0 : catalog.available) === true;
|
|
87
96
|
const loadOrders = useCallback(async ()=>{
|
|
@@ -96,12 +105,37 @@ const placedOn = (ms)=>ms ? new Date(ms).toLocaleDateString([], {
|
|
|
96
105
|
uid,
|
|
97
106
|
hostId
|
|
98
107
|
]);
|
|
108
|
+
// The orders load whether or not the shop is open: a reader bought in
|
|
109
|
+
// person (AGL-4038) is the workspace's purchase history too.
|
|
99
110
|
useEffect(()=>{
|
|
100
|
-
if (
|
|
111
|
+
if (mayVisit) void loadOrders();
|
|
101
112
|
}, [
|
|
102
|
-
|
|
113
|
+
mayVisit,
|
|
103
114
|
loadOrders
|
|
104
115
|
]);
|
|
116
|
+
/** The order whose return is being asked for, and why (AGL-4038). */ const [returning, setReturning] = useState(null);
|
|
117
|
+
const [returnReason, setReturnReason] = useState('');
|
|
118
|
+
const requestReturn = async ()=>{
|
|
119
|
+
if (!user || !returning) return;
|
|
120
|
+
setBusy(true);
|
|
121
|
+
try {
|
|
122
|
+
await posHardwareRequestReturn(user, hostId, returning.id, returnReason.trim());
|
|
123
|
+
enqueueSnackbar('Return requested. Our team arranges it with you.', {
|
|
124
|
+
variant: 'success',
|
|
125
|
+
persist: false
|
|
126
|
+
});
|
|
127
|
+
setReturning(null);
|
|
128
|
+
setReturnReason('');
|
|
129
|
+
await loadOrders();
|
|
130
|
+
} catch (error) {
|
|
131
|
+
enqueueSnackbar(error instanceof PosHardwareRequestError ? error.message : 'The request did not go through', {
|
|
132
|
+
variant: 'warning',
|
|
133
|
+
persist: false
|
|
134
|
+
});
|
|
135
|
+
} finally{
|
|
136
|
+
setBusy(false);
|
|
137
|
+
}
|
|
138
|
+
};
|
|
105
139
|
// The first shipping speed is the default once the catalog answers.
|
|
106
140
|
useEffect(()=>{
|
|
107
141
|
if ((catalog == null ? void 0 : catalog.available) && !shippingMethod && catalog.shipping.length) {
|
|
@@ -213,6 +247,26 @@ const placedOn = (ms)=>ms ? new Date(ms).toLocaleDateString([], {
|
|
|
213
247
|
label: POS_HARDWARE_STATUS_LABELS[row.status]
|
|
214
248
|
})
|
|
215
249
|
},
|
|
250
|
+
{
|
|
251
|
+
// A reader bought in person, or an order shipped to you once it has
|
|
252
|
+
// shipped (AGL-4038), can be asked back from here.
|
|
253
|
+
field: 'returnRequest',
|
|
254
|
+
headerName: 'Return',
|
|
255
|
+
minWidth: 170,
|
|
256
|
+
valueGetter: (_value, row)=>{
|
|
257
|
+
var _RETURN_LABELS_, _ref;
|
|
258
|
+
var _row_returnRequest;
|
|
259
|
+
return (_RETURN_LABELS_ = RETURN_LABELS[(_ref = (_row_returnRequest = row.returnRequest) == null ? void 0 : _row_returnRequest.state) != null ? _ref : '']) != null ? _RETURN_LABELS_ : '';
|
|
260
|
+
},
|
|
261
|
+
renderCell: ({ row })=>row.returnRequest ? RETURN_LABELS[row.returnRequest.state] : row.status === 'delivered' || row.status === 'registered' || row.source !== 'in_person' && row.status === 'shipped' ? /*#__PURE__*/ _jsx(Button, {
|
|
262
|
+
size: "small",
|
|
263
|
+
onClick: (event)=>{
|
|
264
|
+
event.stopPropagation();
|
|
265
|
+
setReturning(row);
|
|
266
|
+
},
|
|
267
|
+
children: 'Request a return'
|
|
268
|
+
}) : '—'
|
|
269
|
+
},
|
|
216
270
|
{
|
|
217
271
|
field: 'tracking',
|
|
218
272
|
headerName: 'Tracking',
|
|
@@ -234,7 +288,91 @@ const placedOn = (ms)=>ms ? new Date(ms).toLocaleDateString([], {
|
|
|
234
288
|
}
|
|
235
289
|
}
|
|
236
290
|
], []);
|
|
237
|
-
|
|
291
|
+
const ordersSection = /*#__PURE__*/ _jsxs(Stack, {
|
|
292
|
+
spacing: 1,
|
|
293
|
+
children: [
|
|
294
|
+
/*#__PURE__*/ _jsx(Typography, {
|
|
295
|
+
variant: "subtitle2",
|
|
296
|
+
children: 'Your orders'
|
|
297
|
+
}),
|
|
298
|
+
orders && orders.length === 0 ? /*#__PURE__*/ _jsx(Typography, {
|
|
299
|
+
variant: "body2",
|
|
300
|
+
color: "text.secondary",
|
|
301
|
+
children: 'No hardware orders yet.'
|
|
302
|
+
}) : /*#__PURE__*/ _jsx(ListTable, {
|
|
303
|
+
rows: (orders != null ? orders : []).map((order)=>_extends({}, order, {
|
|
304
|
+
$id: order.id
|
|
305
|
+
})),
|
|
306
|
+
columns: columns,
|
|
307
|
+
loading: orders === null,
|
|
308
|
+
hideFooter: true,
|
|
309
|
+
quickFilter: false
|
|
310
|
+
}),
|
|
311
|
+
/*#__PURE__*/ _jsxs(Dialog, {
|
|
312
|
+
open: Boolean(returning),
|
|
313
|
+
onClose: ()=>setReturning(null),
|
|
314
|
+
maxWidth: "sm",
|
|
315
|
+
fullWidth: true,
|
|
316
|
+
children: [
|
|
317
|
+
/*#__PURE__*/ _jsx(DialogTitle, {
|
|
318
|
+
children: returning ? `Return ${returning.number}?` : ''
|
|
319
|
+
}),
|
|
320
|
+
/*#__PURE__*/ _jsxs(DialogContent, {
|
|
321
|
+
sx: {
|
|
322
|
+
display: 'flex',
|
|
323
|
+
flexDirection: 'column',
|
|
324
|
+
gap: 2
|
|
325
|
+
},
|
|
326
|
+
children: [
|
|
327
|
+
/*#__PURE__*/ _jsx(Typography, {
|
|
328
|
+
variant: "body2",
|
|
329
|
+
color: "text.secondary",
|
|
330
|
+
children: 'Tell us why. Our team gets your request and arranges the return with you. Returns follow the hardware terms of sale: the return shipping is yours to pay, the original shipping is not refunded, and any restocking fee charged for the return comes off the refund.'
|
|
331
|
+
}),
|
|
332
|
+
/*#__PURE__*/ _jsx(TextField, {
|
|
333
|
+
label: "Why are you returning it?",
|
|
334
|
+
value: returnReason,
|
|
335
|
+
onChange: (event)=>setReturnReason(event.target.value),
|
|
336
|
+
multiline: true,
|
|
337
|
+
minRows: 2,
|
|
338
|
+
fullWidth: true
|
|
339
|
+
})
|
|
340
|
+
]
|
|
341
|
+
}),
|
|
342
|
+
/*#__PURE__*/ _jsxs(DialogActions, {
|
|
343
|
+
children: [
|
|
344
|
+
/*#__PURE__*/ _jsx(Button, {
|
|
345
|
+
onClick: ()=>setReturning(null),
|
|
346
|
+
children: 'Cancel'
|
|
347
|
+
}),
|
|
348
|
+
/*#__PURE__*/ _jsx(Button, {
|
|
349
|
+
variant: "contained",
|
|
350
|
+
disabled: busy || returnReason.trim().length < 3,
|
|
351
|
+
onClick: ()=>void requestReturn(),
|
|
352
|
+
children: 'Request return'
|
|
353
|
+
})
|
|
354
|
+
]
|
|
355
|
+
})
|
|
356
|
+
]
|
|
357
|
+
})
|
|
358
|
+
]
|
|
359
|
+
});
|
|
360
|
+
// With the shop closed, the card is the purchase history alone, and only
|
|
361
|
+
// when there is one (AGL-4038): a reader bought in person.
|
|
362
|
+
if (!available || !(catalog == null ? void 0 : catalog.available)) {
|
|
363
|
+
if (!(orders == null ? void 0 : orders.length)) return null;
|
|
364
|
+
return /*#__PURE__*/ _jsx(CardDisplay, {
|
|
365
|
+
id: POS_HARDWARE_ANCHOR,
|
|
366
|
+
header: 'Hardware',
|
|
367
|
+
subheader: 'Your card reader orders',
|
|
368
|
+
help: pluginDocsHelp('posHardware', {
|
|
369
|
+
anchor: '#bought-from-us-in-person'
|
|
370
|
+
}),
|
|
371
|
+
contentGutterX: true,
|
|
372
|
+
contentGutterY: true,
|
|
373
|
+
children: ordersSection
|
|
374
|
+
});
|
|
375
|
+
}
|
|
238
376
|
return /*#__PURE__*/ _jsx(CardDisplay, {
|
|
239
377
|
id: POS_HARDWARE_ANCHOR,
|
|
240
378
|
header: 'Hardware',
|
|
@@ -243,12 +381,16 @@ const placedOn = (ms)=>ms ? new Date(ms).toLocaleDateString([], {
|
|
|
243
381
|
anchor: '#buy-a-reader-from-aglyn'
|
|
244
382
|
}),
|
|
245
383
|
HeaderProps: {
|
|
246
|
-
action: /*#__PURE__*/ _jsx(
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
384
|
+
action: /*#__PURE__*/ _jsx(BlockedControl, {
|
|
385
|
+
blocked: !canBuyHardware,
|
|
386
|
+
reason: BUY_KEY_REASON,
|
|
387
|
+
children: /*#__PURE__*/ _jsx(Button, {
|
|
388
|
+
size: "small",
|
|
389
|
+
variant: "contained",
|
|
390
|
+
disabled: busy || !lines.length || !shipping,
|
|
391
|
+
onClick: ()=>void checkout(),
|
|
392
|
+
children: 'Check out'
|
|
393
|
+
})
|
|
252
394
|
})
|
|
253
395
|
},
|
|
254
396
|
contentGutterX: true,
|
|
@@ -402,28 +544,7 @@ const placedOn = (ms)=>ms ? new Date(ms).toLocaleDateString([], {
|
|
|
402
544
|
color: "text.secondary",
|
|
403
545
|
children: 'Ships to street addresses in the United States. P.O. boxes and military addresses are not accepted.'
|
|
404
546
|
}),
|
|
405
|
-
|
|
406
|
-
spacing: 1,
|
|
407
|
-
children: [
|
|
408
|
-
/*#__PURE__*/ _jsx(Typography, {
|
|
409
|
-
variant: "subtitle2",
|
|
410
|
-
children: 'Your orders'
|
|
411
|
-
}),
|
|
412
|
-
orders && orders.length === 0 ? /*#__PURE__*/ _jsx(Typography, {
|
|
413
|
-
variant: "body2",
|
|
414
|
-
color: "text.secondary",
|
|
415
|
-
children: 'No hardware orders yet.'
|
|
416
|
-
}) : /*#__PURE__*/ _jsx(ListTable, {
|
|
417
|
-
rows: (orders != null ? orders : []).map((order)=>_extends({}, order, {
|
|
418
|
-
$id: order.id
|
|
419
|
-
})),
|
|
420
|
-
columns: columns,
|
|
421
|
-
loading: orders === null,
|
|
422
|
-
hideFooter: true,
|
|
423
|
-
quickFilter: false
|
|
424
|
-
})
|
|
425
|
-
]
|
|
426
|
-
})
|
|
547
|
+
ordersSection
|
|
427
548
|
]
|
|
428
549
|
})
|
|
429
550
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../../../libs/plugins/commerce/src/lib/components/console/pos-hardware-card.component.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 { pluginDocsHelp } from '@aglyn/aglyn'\nimport { CardDisplay } from '@aglyn/shared-ui-jsx'\nimport { ListTable } from '@aglyn/shared-ui-jsx/components/list-table.component'\nimport { useSnackbar } from '@aglyn/shared-ui-snackstack'\nimport { useUser } from '@aglyn/tenant-feature-instance'\nimport {\n Alert,\n Box,\n Button,\n Card,\n CardContent,\n Chip,\n Link,\n MenuItem,\n Stack,\n TextField,\n Typography,\n} from '@mui/material'\nimport type { GridColDef } from '@mui/x-data-grid'\nimport { useCallback, useEffect, useMemo, useState } from 'react'\nimport {\n formatPosHardwareCents,\n POS_HARDWARE_ANCHOR,\n POS_HARDWARE_MAX_PER_LINE,\n POS_HARDWARE_STATUS_LABELS,\n type PosHardwareOrderStatus,\n type PosHardwareShippingMethod,\n} from '../../model/pos-hardware'\nimport { newAttemptKey } from './pos/pos-api'\nimport {\n openPosHardwareCheckout,\n posHardwareCatalog,\n posHardwareCheckout,\n posHardwareOrders,\n PosHardwareRequestError,\n type PosHardwareCatalog,\n type PosHardwareOrderRow,\n} from './pos/pos-hardware-api'\n\n\nexport const POS_HARDWARE_STATUS_COLOR: Record<\n PosHardwareOrderStatus,\n 'default' | 'info' | 'primary' | 'success'\n> = {\n paid: 'info',\n ordered: 'info',\n shipped: 'primary',\n delivered: 'success',\n registered: 'success',\n canceled: 'default',\n refunded: 'default',\n}\n\nconst QUANTITIES = Array.from({ length: POS_HARDWARE_MAX_PER_LINE + 1 }, (_, index) => index)\n\nconst placedOn = (ms: number) =>\n ms ? new Date(ms).toLocaleDateString([], { month: 'short', day: 'numeric', year: 'numeric' }) : '—'\n\nexport interface PosHardwareCardProps {\n hostId: string\n /**\n * Whether the viewer may work this site's register — the same gate the\n * shop's route asks (`managePos` on an admin or editor role). The shop is\n * the register's hardware, so a viewer who may not run it is not shown it.\n */\n canManagePos?: boolean\n}\n\n/**\n * The Hardware card (AGL-4038): Stripe card readers and accessories sold by\n * the platform and shipped by Stripe straight to the store, with the store's\n * orders and their tracking underneath.\n *\n * HIDDEN, NOT DISABLED, while the deployment has not opened the shop: it is a\n * gate only the platform can lift, so naming it would point at a step nobody\n * on the workspace can take. The route answers `available: false` until\n * every price, the markup and the shipping figures are configured.\n */\nexport function PosHardwareCard({ hostId, canManagePos = false }: PosHardwareCardProps) {\n const { data: user } = useUser()\n const { enqueueSnackbar } = useSnackbar()\n const [catalog, setCatalog] = useState<PosHardwareCatalog | null>(null)\n const [orders, setOrders] = useState<PosHardwareOrderRow[] | null>(null)\n const [quantities, setQuantities] = useState<Record<string, number>>({})\n const [shippingMethod, setShippingMethod] = useState<PosHardwareShippingMethod | ''>('')\n const [busy, setBusy] = useState(false)\n const [returned, setReturned] = useState<'placed' | 'canceled' | null>(null)\n const uid = user?.uid ?? ''\n\n useEffect(() => {\n if (!user || !canManagePos) return\n let active = true\n void posHardwareCatalog(user, hostId)\n .then((answer) => {\n if (active) setCatalog(answer)\n })\n .catch(() => {\n if (active) setCatalog({ available: false })\n })\n return () => {\n active = false\n }\n // Keyed on the person, not the session object.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [uid, hostId, canManagePos])\n\n const available = catalog?.available === true\n\n const loadOrders = useCallback(async () => {\n if (!user) return\n try {\n setOrders((await posHardwareOrders(user, hostId)).orders)\n } catch {\n setOrders([])\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [uid, hostId])\n\n useEffect(() => {\n if (available) void loadOrders()\n }, [available, loadOrders])\n\n // The first shipping speed is the default once the catalog answers.\n useEffect(() => {\n if (catalog?.available && !shippingMethod && catalog.shipping.length) {\n setShippingMethod(catalog.shipping[0].method)\n }\n }, [catalog, shippingMethod])\n\n // Back from Checkout: say what happened, then drop the marker from the URL.\n useEffect(() => {\n if (typeof window === 'undefined') return\n const url = new URL(window.location.href)\n const outcome = url.searchParams.get('hardwareOrder')\n if (outcome === 'placed' || outcome === 'canceled') {\n setReturned(outcome)\n url.searchParams.delete('hardwareOrder')\n window.history.replaceState(window.history.state, '', url.toString())\n }\n }, [])\n\n // Arrived by an email's link or Checkout's return: bring the card into view.\n useEffect(() => {\n if (!available || typeof window === 'undefined') return\n if (window.location.hash !== `#${POS_HARDWARE_ANCHOR}`) return\n document.getElementById(POS_HARDWARE_ANCHOR)?.scrollIntoView?.({ block: 'start' })\n }, [available])\n\n const lines = useMemo(\n () =>\n Object.entries(quantities)\n .filter(([, quantity]) => quantity > 0)\n .map(([sku, quantity]) => ({ sku, quantity })),\n [quantities],\n )\n const shipping = catalog?.available ? catalog.shipping.find((option) => option.method === shippingMethod) : undefined\n const subtotalCents = catalog?.available\n ? lines.reduce(\n (sum, line) => sum + (catalog.offers.find((offer) => offer.sku === line.sku)?.unitCents ?? 0) * line.quantity,\n 0,\n )\n : 0\n\n // One attempt per basket: a second press of the same basket reaches the\n // same Checkout Session, and a changed basket is a new one.\n const basketKey = JSON.stringify([lines, shippingMethod])\n // eslint-disable-next-line react-hooks/exhaustive-deps\n const attemptKey = useMemo(() => newAttemptKey(), [basketKey])\n\n const checkout = async () => {\n if (!user || !shippingMethod || !lines.length) return\n setBusy(true)\n try {\n const { url } = await posHardwareCheckout(user, attemptKey, { hostId, lines, shippingMethod })\n openPosHardwareCheckout(url)\n } catch (error) {\n enqueueSnackbar(\n error instanceof PosHardwareRequestError ? error.message : 'Checkout could not be started',\n { variant: 'warning', persist: false },\n )\n setBusy(false)\n }\n }\n\n const columns = useMemo<GridColDef[]>(\n () => [\n { field: 'number', headerName: 'Order', minWidth: 110 },\n {\n field: 'createdAtMs',\n headerName: 'Placed',\n type: 'number',\n minWidth: 120,\n align: 'left',\n headerAlign: 'left',\n valueFormatter: (value: number) => placedOn(value),\n },\n {\n field: 'items',\n headerName: 'Items',\n flex: 1,\n minWidth: 200,\n valueGetter: (_value: unknown, row: PosHardwareOrderRow) =>\n row.lines.map((line) => `${line.name} × ${line.quantity}`).join(', '),\n },\n {\n field: 'totalCents',\n headerName: 'Total',\n type: 'number',\n minWidth: 100,\n valueFormatter: (value: number) => formatPosHardwareCents(value),\n },\n {\n field: 'status',\n headerName: 'Status',\n minWidth: 130,\n valueGetter: (_value: unknown, row: PosHardwareOrderRow) => POS_HARDWARE_STATUS_LABELS[row.status],\n renderCell: ({ row }: { row: PosHardwareOrderRow }) => (\n <Chip size=\"small\" color={POS_HARDWARE_STATUS_COLOR[row.status]} label={POS_HARDWARE_STATUS_LABELS[row.status]} />\n ),\n },\n {\n field: 'tracking',\n headerName: 'Tracking',\n minWidth: 160,\n valueGetter: (_value: unknown, row: PosHardwareOrderRow) => row.tracking?.number ?? '',\n renderCell: ({ row }: { row: PosHardwareOrderRow }) =>\n row.tracking?.url ? (\n <Link href={row.tracking.url} target=\"_blank\" rel=\"noopener noreferrer\">\n {row.tracking.number}\n </Link>\n ) : (\n row.tracking?.number ?? '—'\n ),\n },\n ],\n [],\n )\n\n if (!available || !catalog?.available) return null\n\n return (\n <CardDisplay\n id={POS_HARDWARE_ANCHOR}\n header={'Hardware'}\n subheader={'Card readers from Stripe, shipped straight to you'}\n help={pluginDocsHelp('posHardware', { anchor: '#buy-a-reader-from-aglyn' })}\n HeaderProps={{\n action: (\n <Button\n size=\"small\"\n variant=\"contained\"\n disabled={busy || !lines.length || !shipping}\n onClick={() => void checkout()}\n >\n {'Check out'}\n </Button>\n ),\n }}\n contentGutterX\n contentGutterY\n >\n <Stack spacing={3}>\n {returned === 'placed' ? (\n <Alert severity=\"success\" onClose={() => setReturned(null)}>\n {'Thanks, your order is in. It shows under Your orders within a minute, and we email you as it ships.'}\n </Alert>\n ) : returned === 'canceled' ? (\n <Alert severity=\"info\" onClose={() => setReturned(null)}>\n {'Checkout was canceled. Nothing was charged.'}\n </Alert>\n ) : null}\n <Typography variant=\"body2\" color=\"text.secondary\">\n {'Choose the readers and accessories you need. Stripe ships them to the address you enter at checkout, and you add each reader to a register on the POS devices card when it arrives.'}\n </Typography>\n <Box\n sx={{\n display: 'grid',\n gap: 2,\n gridTemplateColumns: { xs: '1fr', sm: 'repeat(2, 1fr)', md: 'repeat(3, 1fr)' },\n }}\n >\n {catalog.offers.map((offer) => (\n <Card key={offer.sku} variant=\"outlined\">\n <CardContent>\n <Stack spacing={1} sx={{ height: '100%' }}>\n <Typography variant=\"subtitle2\">{offer.name}</Typography>\n <Typography variant=\"body2\" color=\"text.secondary\" sx={{ flex: 1 }}>\n {offer.use}\n </Typography>\n <Stack direction=\"row\" spacing={1} sx={{ alignItems: 'center', justifyContent: 'space-between' }}>\n <Typography variant=\"body1\">{formatPosHardwareCents(offer.unitCents)}</Typography>\n <TextField\n select\n size=\"small\"\n label=\"Quantity\"\n value={quantities[offer.sku] ?? 0}\n onChange={(event) =>\n setQuantities((prev) => ({ ...prev, [offer.sku]: Number(event.target.value) }))\n }\n slotProps={{ htmlInput: { 'aria-label': `Quantity of ${offer.name}` } }}\n >\n {QUANTITIES.map((quantity) => (\n <MenuItem key={quantity} value={quantity}>\n {quantity}\n </MenuItem>\n ))}\n </TextField>\n </Stack>\n </Stack>\n </CardContent>\n </Card>\n ))}\n </Box>\n <Stack direction={{ xs: 'column', sm: 'row' }} spacing={2} sx={{ alignItems: { sm: 'flex-start' } }}>\n <TextField\n select\n size=\"small\"\n label=\"Shipping\"\n value={shippingMethod}\n onChange={(event) => setShippingMethod(event.target.value as PosHardwareShippingMethod)}\n sx={{ minWidth: { sm: '40%' } }}\n >\n {catalog.shipping.map((option) => (\n <MenuItem key={option.method} value={option.method}>\n {`${option.label} · ${formatPosHardwareCents(option.cents)}`}\n </MenuItem>\n ))}\n </TextField>\n <Stack spacing={0.5} sx={{ flex: 1 }} aria-label=\"Order summary\">\n <SummaryRow label=\"Items\" value={formatPosHardwareCents(subtotalCents)} />\n <SummaryRow label=\"Shipping\" value={shipping ? formatPosHardwareCents(shipping.cents) : '—'} />\n {catalog.automaticTax ? <SummaryRow label=\"Tax\" value=\"Calculated at checkout\" /> : null}\n <SummaryRow\n label={catalog.automaticTax ? 'Total before tax' : 'Total'}\n value={formatPosHardwareCents(subtotalCents + (shipping?.cents ?? 0))}\n strong\n />\n </Stack>\n </Stack>\n <Typography variant=\"caption\" color=\"text.secondary\">\n {'Ships to street addresses in the United States. P.O. boxes and military addresses are not accepted.'}\n </Typography>\n <Stack spacing={1}>\n <Typography variant=\"subtitle2\">{'Your orders'}</Typography>\n {orders && orders.length === 0 ? (\n <Typography variant=\"body2\" color=\"text.secondary\">\n {'No hardware orders yet.'}\n </Typography>\n ) : (\n <ListTable\n rows={(orders ?? []).map((order) => ({ ...order, $id: order.id }))}\n columns={columns}\n loading={orders === null}\n hideFooter\n quickFilter={false}\n />\n )}\n </Stack>\n </Stack>\n </CardDisplay>\n )\n}\nPosHardwareCard.displayName = 'PosHardwareCard'\n\nfunction SummaryRow(props: { label: string; value: string; strong?: boolean }) {\n return (\n <Stack direction=\"row\" sx={{ justifyContent: 'space-between' }}>\n <Typography variant=\"body2\" color={props.strong ? 'text.primary' : 'text.secondary'}>\n {props.label}\n </Typography>\n <Typography variant=\"body2\" sx={props.strong ? { fontWeight: 'fontWeightMedium' } : undefined}>\n {props.value}\n </Typography>\n </Stack>\n )\n}\n\nexport default PosHardwareCard\n"],"names":["pluginDocsHelp","CardDisplay","ListTable","useSnackbar","useUser","Alert","Box","Button","Card","CardContent","Chip","Link","MenuItem","Stack","TextField","Typography","useCallback","useEffect","useMemo","useState","formatPosHardwareCents","POS_HARDWARE_ANCHOR","POS_HARDWARE_MAX_PER_LINE","POS_HARDWARE_STATUS_LABELS","newAttemptKey","openPosHardwareCheckout","posHardwareCatalog","posHardwareCheckout","posHardwareOrders","PosHardwareRequestError","POS_HARDWARE_STATUS_COLOR","paid","ordered","shipped","delivered","registered","canceled","refunded","QUANTITIES","Array","from","length","_","index","placedOn","ms","Date","toLocaleDateString","month","day","year","PosHardwareCard","hostId","canManagePos","data","user","enqueueSnackbar","catalog","setCatalog","orders","setOrders","quantities","setQuantities","shippingMethod","setShippingMethod","busy","setBusy","returned","setReturned","uid","active","then","answer","catch","available","loadOrders","shipping","method","window","url","URL","location","href","outcome","searchParams","get","delete","history","replaceState","state","toString","document","hash","getElementById","scrollIntoView","block","lines","Object","entries","filter","quantity","map","sku","find","option","undefined","subtotalCents","reduce","sum","line","offers","offer","unitCents","basketKey","JSON","stringify","attemptKey","checkout","error","message","variant","persist","columns","field","headerName","minWidth","type","align","headerAlign","valueFormatter","value","flex","valueGetter","_value","row","name","join","status","renderCell","size","color","label","tracking","number","target","rel","id","header","subheader","help","anchor","HeaderProps","action","disabled","onClick","contentGutterX","contentGutterY","spacing","severity","onClose","sx","display","gap","gridTemplateColumns","xs","sm","md","height","use","direction","alignItems","justifyContent","select","onChange","event","prev","Number","slotProps","htmlInput","cents","aria-label","SummaryRow","automaticTax","strong","rows","order","$id","loading","hideFooter","quickFilter","displayName","props","fontWeight"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../../../../libs/plugins/commerce/src/lib/components/console/pos-hardware-card.component.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 { pluginDocsHelp } from '@aglyn/aglyn'\nimport { CardDisplay } from '@aglyn/shared-ui-jsx'\nimport { BlockedControl } from '@aglyn/shared-ui-jsx/components/blocked-control.component'\nimport { ListTable } from '@aglyn/shared-ui-jsx/components/list-table.component'\nimport { useSnackbar } from '@aglyn/shared-ui-snackstack'\nimport { useUser } from '@aglyn/tenant-feature-instance'\nimport {\n Alert,\n Box,\n Button,\n Card,\n CardContent,\n Chip,\n Dialog,\n DialogActions,\n DialogContent,\n DialogTitle,\n Link,\n MenuItem,\n Stack,\n TextField,\n Typography,\n} from '@mui/material'\nimport type { GridColDef } from '@mui/x-data-grid'\nimport { useCallback, useEffect, useMemo, useState } from 'react'\nimport {\n formatPosHardwareCents,\n POS_HARDWARE_ANCHOR,\n POS_HARDWARE_MAX_PER_LINE,\n POS_HARDWARE_STATUS_LABELS,\n type PosHardwareOrderStatus,\n type PosHardwareShippingMethod,\n} from '../../model/pos-hardware'\nimport { newAttemptKey } from './pos/pos-api'\nimport {\n openPosHardwareCheckout,\n posHardwareCatalog,\n posHardwareCheckout,\n posHardwareOrders,\n posHardwareRequestReturn,\n PosHardwareRequestError,\n type PosHardwareCatalog,\n type PosHardwareOrderRow,\n} from './pos/pos-hardware-api'\n\n\nexport const POS_HARDWARE_STATUS_COLOR: Record<\n PosHardwareOrderStatus,\n 'default' | 'info' | 'primary' | 'success'\n> = {\n paid: 'info',\n ordered: 'info',\n shipped: 'primary',\n delivered: 'success',\n registered: 'success',\n canceled: 'default',\n refunded: 'default',\n}\n\n/** What the buyer reads of their return request. */\nconst RETURN_LABELS: Record<string, string> = {\n requested: 'Return requested',\n declined: 'Return declined',\n refunded: 'Returned',\n}\n\nconst QUANTITIES = Array.from({ length: POS_HARDWARE_MAX_PER_LINE + 1 }, (_, index) => index)\n\nconst placedOn = (ms: number) =>\n ms ? new Date(ms).toLocaleDateString([], { month: 'short', day: 'numeric', year: 'numeric' }) : '—'\n\nexport interface PosHardwareCardProps {\n hostId: string\n /**\n * Whether the viewer may work this site's register (`managePos`). The shop\n * is the register's hardware, so whoever works it is shown the shop.\n */\n canManagePos?: boolean\n /**\n * Whether the viewer may start a checkout (AGL-4047): the \"Buy point of\n * sale hardware\" key the route asks of a checkout. It stands on its own,\n * so a member who holds it without the register is shown the shop and\n * their orders too. Someone who works the register without it sees the\n * shop with Check out disabled and the reason. Absent follows\n * `canManagePos`.\n */\n canBuyHardware?: boolean\n}\n\n/** Why Check out is not offered to someone who works the register. */\nconst BUY_KEY_REASON =\n 'Only a member with the \"Buy point of sale hardware\" permission can place an order. Ask an organization admin.'\n\n/**\n * The Hardware card (AGL-4038): Stripe card readers and accessories sold by\n * the platform and shipped by Stripe straight to the store, with the store's\n * orders and their tracking underneath.\n *\n * HIDDEN, NOT DISABLED, while the deployment has not opened the shop: it is a\n * gate only the platform can lift, so naming it would point at a step nobody\n * on the workspace can take. The route answers `available: false` until\n * every price, the markup and the shipping figures are configured.\n */\nexport function PosHardwareCard({\n hostId,\n canManagePos = false,\n canBuyHardware = canManagePos,\n}: PosHardwareCardProps) {\n const { data: user } = useUser()\n const { enqueueSnackbar } = useSnackbar()\n const [catalog, setCatalog] = useState<PosHardwareCatalog | null>(null)\n const [orders, setOrders] = useState<PosHardwareOrderRow[] | null>(null)\n const [quantities, setQuantities] = useState<Record<string, number>>({})\n const [shippingMethod, setShippingMethod] = useState<PosHardwareShippingMethod | ''>('')\n const [busy, setBusy] = useState(false)\n const [returned, setReturned] = useState<'placed' | 'canceled' | null>(null)\n const uid = user?.uid ?? ''\n // The route's own door (AGL-4047): the register, or the key to buy.\n const mayVisit = canManagePos || canBuyHardware\n\n useEffect(() => {\n if (!user || !mayVisit) return\n let active = true\n void posHardwareCatalog(user, hostId)\n .then((answer) => {\n if (active) setCatalog(answer)\n })\n .catch(() => {\n if (active) setCatalog({ available: false })\n })\n return () => {\n active = false\n }\n // Keyed on the person, not the session object.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [uid, hostId, mayVisit])\n\n const available = catalog?.available === true\n\n const loadOrders = useCallback(async () => {\n if (!user) return\n try {\n setOrders((await posHardwareOrders(user, hostId)).orders)\n } catch {\n setOrders([])\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [uid, hostId])\n\n // The orders load whether or not the shop is open: a reader bought in\n // person (AGL-4038) is the workspace's purchase history too.\n useEffect(() => {\n if (mayVisit) void loadOrders()\n }, [mayVisit, loadOrders])\n\n /** The order whose return is being asked for, and why (AGL-4038). */\n const [returning, setReturning] = useState<PosHardwareOrderRow | null>(null)\n const [returnReason, setReturnReason] = useState('')\n const requestReturn = async () => {\n if (!user || !returning) return\n setBusy(true)\n try {\n await posHardwareRequestReturn(user, hostId, returning.id, returnReason.trim())\n enqueueSnackbar('Return requested. Our team arranges it with you.', { variant: 'success', persist: false })\n setReturning(null)\n setReturnReason('')\n await loadOrders()\n } catch (error) {\n enqueueSnackbar(error instanceof PosHardwareRequestError ? error.message : 'The request did not go through', {\n variant: 'warning',\n persist: false,\n })\n } finally {\n setBusy(false)\n }\n }\n\n // The first shipping speed is the default once the catalog answers.\n useEffect(() => {\n if (catalog?.available && !shippingMethod && catalog.shipping.length) {\n setShippingMethod(catalog.shipping[0].method)\n }\n }, [catalog, shippingMethod])\n\n // Back from Checkout: say what happened, then drop the marker from the URL.\n useEffect(() => {\n if (typeof window === 'undefined') return\n const url = new URL(window.location.href)\n const outcome = url.searchParams.get('hardwareOrder')\n if (outcome === 'placed' || outcome === 'canceled') {\n setReturned(outcome)\n url.searchParams.delete('hardwareOrder')\n window.history.replaceState(window.history.state, '', url.toString())\n }\n }, [])\n\n // Arrived by an email's link or Checkout's return: bring the card into view.\n useEffect(() => {\n if (!available || typeof window === 'undefined') return\n if (window.location.hash !== `#${POS_HARDWARE_ANCHOR}`) return\n document.getElementById(POS_HARDWARE_ANCHOR)?.scrollIntoView?.({ block: 'start' })\n }, [available])\n\n const lines = useMemo(\n () =>\n Object.entries(quantities)\n .filter(([, quantity]) => quantity > 0)\n .map(([sku, quantity]) => ({ sku, quantity })),\n [quantities],\n )\n const shipping = catalog?.available ? catalog.shipping.find((option) => option.method === shippingMethod) : undefined\n const subtotalCents = catalog?.available\n ? lines.reduce(\n (sum, line) => sum + (catalog.offers.find((offer) => offer.sku === line.sku)?.unitCents ?? 0) * line.quantity,\n 0,\n )\n : 0\n\n // One attempt per basket: a second press of the same basket reaches the\n // same Checkout Session, and a changed basket is a new one.\n const basketKey = JSON.stringify([lines, shippingMethod])\n // eslint-disable-next-line react-hooks/exhaustive-deps\n const attemptKey = useMemo(() => newAttemptKey(), [basketKey])\n\n const checkout = async () => {\n if (!user || !shippingMethod || !lines.length) return\n setBusy(true)\n try {\n const { url } = await posHardwareCheckout(user, attemptKey, { hostId, lines, shippingMethod })\n openPosHardwareCheckout(url)\n } catch (error) {\n enqueueSnackbar(\n error instanceof PosHardwareRequestError ? error.message : 'Checkout could not be started',\n { variant: 'warning', persist: false },\n )\n setBusy(false)\n }\n }\n\n const columns = useMemo<GridColDef[]>(\n () => [\n { field: 'number', headerName: 'Order', minWidth: 110 },\n {\n field: 'createdAtMs',\n headerName: 'Placed',\n type: 'number',\n minWidth: 120,\n align: 'left',\n headerAlign: 'left',\n valueFormatter: (value: number) => placedOn(value),\n },\n {\n field: 'items',\n headerName: 'Items',\n flex: 1,\n minWidth: 200,\n valueGetter: (_value: unknown, row: PosHardwareOrderRow) =>\n row.lines.map((line) => `${line.name} × ${line.quantity}`).join(', '),\n },\n {\n field: 'totalCents',\n headerName: 'Total',\n type: 'number',\n minWidth: 100,\n valueFormatter: (value: number) => formatPosHardwareCents(value),\n },\n {\n field: 'status',\n headerName: 'Status',\n minWidth: 130,\n valueGetter: (_value: unknown, row: PosHardwareOrderRow) => POS_HARDWARE_STATUS_LABELS[row.status],\n renderCell: ({ row }: { row: PosHardwareOrderRow }) => (\n <Chip size=\"small\" color={POS_HARDWARE_STATUS_COLOR[row.status]} label={POS_HARDWARE_STATUS_LABELS[row.status]} />\n ),\n },\n {\n // A reader bought in person, or an order shipped to you once it has\n // shipped (AGL-4038), can be asked back from here.\n field: 'returnRequest',\n headerName: 'Return',\n minWidth: 170,\n valueGetter: (_value: unknown, row: PosHardwareOrderRow) => RETURN_LABELS[row.returnRequest?.state ?? ''] ?? '',\n renderCell: ({ row }: { row: PosHardwareOrderRow }) =>\n row.returnRequest ? (\n RETURN_LABELS[row.returnRequest.state]\n ) : (row.status === 'delivered' || row.status === 'registered' || (row.source !== 'in_person' && row.status === 'shipped')) ? (\n <Button\n size=\"small\"\n onClick={(event) => {\n event.stopPropagation()\n setReturning(row)\n }}\n >\n {'Request a return'}\n </Button>\n ) : (\n '—'\n ),\n },\n {\n field: 'tracking',\n headerName: 'Tracking',\n minWidth: 160,\n valueGetter: (_value: unknown, row: PosHardwareOrderRow) => row.tracking?.number ?? '',\n renderCell: ({ row }: { row: PosHardwareOrderRow }) =>\n row.tracking?.url ? (\n <Link href={row.tracking.url} target=\"_blank\" rel=\"noopener noreferrer\">\n {row.tracking.number}\n </Link>\n ) : (\n row.tracking?.number ?? '—'\n ),\n },\n ],\n [],\n )\n\n const ordersSection = (\n <Stack spacing={1}>\n <Typography variant=\"subtitle2\">{'Your orders'}</Typography>\n {orders && orders.length === 0 ? (\n <Typography variant=\"body2\" color=\"text.secondary\">\n {'No hardware orders yet.'}\n </Typography>\n ) : (\n <ListTable\n rows={(orders ?? []).map((order) => ({ ...order, $id: order.id }))}\n columns={columns}\n loading={orders === null}\n hideFooter\n quickFilter={false}\n />\n )}\n <Dialog open={Boolean(returning)} onClose={() => setReturning(null)} maxWidth=\"sm\" fullWidth>\n <DialogTitle>{returning ? `Return ${returning.number}?` : ''}</DialogTitle>\n <DialogContent sx={{ display: 'flex', flexDirection: 'column', gap: 2 }}>\n <Typography variant=\"body2\" color=\"text.secondary\">\n {'Tell us why. Our team gets your request and arranges the return with you. Returns follow the hardware terms of sale: the return shipping is yours to pay, the original shipping is not refunded, and any restocking fee charged for the return comes off the refund.'}\n </Typography>\n <TextField\n label=\"Why are you returning it?\"\n value={returnReason}\n onChange={(event) => setReturnReason(event.target.value)}\n multiline\n minRows={2}\n fullWidth\n />\n </DialogContent>\n <DialogActions>\n <Button onClick={() => setReturning(null)}>{'Cancel'}</Button>\n <Button variant=\"contained\" disabled={busy || returnReason.trim().length < 3} onClick={() => void requestReturn()}>\n {'Request return'}\n </Button>\n </DialogActions>\n </Dialog>\n </Stack>\n )\n\n // With the shop closed, the card is the purchase history alone, and only\n // when there is one (AGL-4038): a reader bought in person.\n if (!available || !catalog?.available) {\n if (!orders?.length) return null\n return (\n <CardDisplay\n id={POS_HARDWARE_ANCHOR}\n header={'Hardware'}\n subheader={'Your card reader orders'}\n help={pluginDocsHelp('posHardware', { anchor: '#bought-from-us-in-person' })}\n contentGutterX\n contentGutterY\n >\n {ordersSection}\n </CardDisplay>\n )\n }\n\n return (\n <CardDisplay\n id={POS_HARDWARE_ANCHOR}\n header={'Hardware'}\n subheader={'Card readers from Stripe, shipped straight to you'}\n help={pluginDocsHelp('posHardware', { anchor: '#buy-a-reader-from-aglyn' })}\n HeaderProps={{\n action: (\n <BlockedControl blocked={!canBuyHardware} reason={BUY_KEY_REASON}>\n <Button\n size=\"small\"\n variant=\"contained\"\n disabled={busy || !lines.length || !shipping}\n onClick={() => void checkout()}\n >\n {'Check out'}\n </Button>\n </BlockedControl>\n ),\n }}\n contentGutterX\n contentGutterY\n >\n <Stack spacing={3}>\n {returned === 'placed' ? (\n <Alert severity=\"success\" onClose={() => setReturned(null)}>\n {'Thanks, your order is in. It shows under Your orders within a minute, and we email you as it ships.'}\n </Alert>\n ) : returned === 'canceled' ? (\n <Alert severity=\"info\" onClose={() => setReturned(null)}>\n {'Checkout was canceled. Nothing was charged.'}\n </Alert>\n ) : null}\n <Typography variant=\"body2\" color=\"text.secondary\">\n {'Choose the readers and accessories you need. Stripe ships them to the address you enter at checkout, and you add each reader to a register on the POS devices card when it arrives.'}\n </Typography>\n <Box\n sx={{\n display: 'grid',\n gap: 2,\n gridTemplateColumns: { xs: '1fr', sm: 'repeat(2, 1fr)', md: 'repeat(3, 1fr)' },\n }}\n >\n {catalog.offers.map((offer) => (\n <Card key={offer.sku} variant=\"outlined\">\n <CardContent>\n <Stack spacing={1} sx={{ height: '100%' }}>\n <Typography variant=\"subtitle2\">{offer.name}</Typography>\n <Typography variant=\"body2\" color=\"text.secondary\" sx={{ flex: 1 }}>\n {offer.use}\n </Typography>\n <Stack direction=\"row\" spacing={1} sx={{ alignItems: 'center', justifyContent: 'space-between' }}>\n <Typography variant=\"body1\">{formatPosHardwareCents(offer.unitCents)}</Typography>\n <TextField\n select\n size=\"small\"\n label=\"Quantity\"\n value={quantities[offer.sku] ?? 0}\n onChange={(event) =>\n setQuantities((prev) => ({ ...prev, [offer.sku]: Number(event.target.value) }))\n }\n slotProps={{ htmlInput: { 'aria-label': `Quantity of ${offer.name}` } }}\n >\n {QUANTITIES.map((quantity) => (\n <MenuItem key={quantity} value={quantity}>\n {quantity}\n </MenuItem>\n ))}\n </TextField>\n </Stack>\n </Stack>\n </CardContent>\n </Card>\n ))}\n </Box>\n <Stack direction={{ xs: 'column', sm: 'row' }} spacing={2} sx={{ alignItems: { sm: 'flex-start' } }}>\n <TextField\n select\n size=\"small\"\n label=\"Shipping\"\n value={shippingMethod}\n onChange={(event) => setShippingMethod(event.target.value as PosHardwareShippingMethod)}\n sx={{ minWidth: { sm: '40%' } }}\n >\n {catalog.shipping.map((option) => (\n <MenuItem key={option.method} value={option.method}>\n {`${option.label} · ${formatPosHardwareCents(option.cents)}`}\n </MenuItem>\n ))}\n </TextField>\n <Stack spacing={0.5} sx={{ flex: 1 }} aria-label=\"Order summary\">\n <SummaryRow label=\"Items\" value={formatPosHardwareCents(subtotalCents)} />\n <SummaryRow label=\"Shipping\" value={shipping ? formatPosHardwareCents(shipping.cents) : '—'} />\n {catalog.automaticTax ? <SummaryRow label=\"Tax\" value=\"Calculated at checkout\" /> : null}\n <SummaryRow\n label={catalog.automaticTax ? 'Total before tax' : 'Total'}\n value={formatPosHardwareCents(subtotalCents + (shipping?.cents ?? 0))}\n strong\n />\n </Stack>\n </Stack>\n <Typography variant=\"caption\" color=\"text.secondary\">\n {'Ships to street addresses in the United States. P.O. boxes and military addresses are not accepted.'}\n </Typography>\n {ordersSection}\n </Stack>\n </CardDisplay>\n )\n}\nPosHardwareCard.displayName = 'PosHardwareCard'\n\nfunction SummaryRow(props: { label: string; value: string; strong?: boolean }) {\n return (\n <Stack direction=\"row\" sx={{ justifyContent: 'space-between' }}>\n <Typography variant=\"body2\" color={props.strong ? 'text.primary' : 'text.secondary'}>\n {props.label}\n </Typography>\n <Typography variant=\"body2\" sx={props.strong ? { fontWeight: 'fontWeightMedium' } : undefined}>\n {props.value}\n </Typography>\n </Stack>\n )\n}\n\nexport default PosHardwareCard\n"],"names":["pluginDocsHelp","CardDisplay","BlockedControl","ListTable","useSnackbar","useUser","Alert","Box","Button","Card","CardContent","Chip","Dialog","DialogActions","DialogContent","DialogTitle","Link","MenuItem","Stack","TextField","Typography","useCallback","useEffect","useMemo","useState","formatPosHardwareCents","POS_HARDWARE_ANCHOR","POS_HARDWARE_MAX_PER_LINE","POS_HARDWARE_STATUS_LABELS","newAttemptKey","openPosHardwareCheckout","posHardwareCatalog","posHardwareCheckout","posHardwareOrders","posHardwareRequestReturn","PosHardwareRequestError","POS_HARDWARE_STATUS_COLOR","paid","ordered","shipped","delivered","registered","canceled","refunded","RETURN_LABELS","requested","declined","QUANTITIES","Array","from","length","_","index","placedOn","ms","Date","toLocaleDateString","month","day","year","BUY_KEY_REASON","PosHardwareCard","hostId","canManagePos","canBuyHardware","data","user","enqueueSnackbar","catalog","setCatalog","orders","setOrders","quantities","setQuantities","shippingMethod","setShippingMethod","busy","setBusy","returned","setReturned","uid","mayVisit","active","then","answer","catch","available","loadOrders","returning","setReturning","returnReason","setReturnReason","requestReturn","id","trim","variant","persist","error","message","shipping","method","window","url","URL","location","href","outcome","searchParams","get","delete","history","replaceState","state","toString","document","hash","getElementById","scrollIntoView","block","lines","Object","entries","filter","quantity","map","sku","find","option","undefined","subtotalCents","reduce","sum","line","offers","offer","unitCents","basketKey","JSON","stringify","attemptKey","checkout","columns","field","headerName","minWidth","type","align","headerAlign","valueFormatter","value","flex","valueGetter","_value","row","name","join","status","renderCell","size","color","label","returnRequest","source","onClick","event","stopPropagation","tracking","number","target","rel","ordersSection","spacing","rows","order","$id","loading","hideFooter","quickFilter","open","Boolean","onClose","maxWidth","fullWidth","sx","display","flexDirection","gap","onChange","multiline","minRows","disabled","header","subheader","help","anchor","contentGutterX","contentGutterY","HeaderProps","action","blocked","reason","severity","gridTemplateColumns","xs","sm","md","height","use","direction","alignItems","justifyContent","select","prev","Number","slotProps","htmlInput","cents","aria-label","SummaryRow","automaticTax","strong","displayName","props","fontWeight"],"mappings":"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"}
|