@aglyn/plugins-commerce 1.0.0-beta.231 → 1.0.0-beta.233
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +13 -13
- package/src/lib/components/cart-extras.d.ts +6 -0
- package/src/lib/components/cart-extras.js +4 -1
- package/src/lib/components/cart-extras.js.map +1 -1
- package/src/lib/components/cart-fulfillment.d.ts +117 -0
- package/src/lib/components/cart-fulfillment.js +367 -0
- package/src/lib/components/cart-fulfillment.js.map +1 -0
- package/src/lib/components/cart.js +52 -10
- package/src/lib/components/cart.js.map +1 -1
- package/src/lib/components/commerce-console-page.js +42 -1
- package/src/lib/components/commerce-console-page.js.map +1 -1
- package/src/lib/components/console/catalog-organization-card.component.js +1 -0
- package/src/lib/components/console/catalog-organization-card.component.js.map +1 -1
- package/src/lib/components/console/host-orders-card.component.js +42 -11
- package/src/lib/components/console/host-orders-card.component.js.map +1 -1
- package/src/lib/components/console/local-delivery-settings-card.component.d.ts +37 -0
- package/src/lib/components/console/local-delivery-settings-card.component.js +542 -0
- package/src/lib/components/console/local-delivery-settings-card.component.js.map +1 -0
- package/src/lib/components/console/locations-card.component.js +177 -3
- package/src/lib/components/console/locations-card.component.js.map +1 -1
- package/src/lib/components/console/order-detail-dialog.component.js +10 -0
- package/src/lib/components/console/order-detail-dialog.component.js.map +1 -1
- package/src/lib/components/console/order-local-fulfillment-panel.component.d.ts +44 -0
- package/src/lib/components/console/order-local-fulfillment-panel.component.js +265 -0
- package/src/lib/components/console/order-local-fulfillment-panel.component.js.map +1 -0
- package/src/lib/components/console/order-offline-notice.component.d.ts +12 -0
- package/src/lib/components/console/order-offline-notice.component.js +53 -0
- package/src/lib/components/console/order-offline-notice.component.js.map +1 -0
- package/src/lib/components/console/pickup-delivery-queue-card.component.d.ts +35 -0
- package/src/lib/components/console/pickup-delivery-queue-card.component.js +222 -0
- package/src/lib/components/console/pickup-delivery-queue-card.component.js.map +1 -0
- package/src/lib/components/console/pos/pos-api.d.ts +24 -1
- package/src/lib/components/console/pos/pos-api.js +13 -0
- package/src/lib/components/console/pos/pos-api.js.map +1 -1
- package/src/lib/components/console/pos/pos-item-dialog.component.d.ts +12 -0
- package/src/lib/components/console/pos/pos-item-dialog.component.js +10 -8
- package/src/lib/components/console/pos/pos-item-dialog.component.js.map +1 -1
- package/src/lib/components/console/pos/pos-kiosk-queue.component.d.ts +22 -0
- package/src/lib/components/console/pos/pos-kiosk-queue.component.js +168 -0
- package/src/lib/components/console/pos/pos-kiosk-queue.component.js.map +1 -0
- package/src/lib/components/console/pos/pos-tender-dialogs.component.d.ts +18 -0
- package/src/lib/components/console/pos/pos-tender-dialogs.component.js +116 -1
- package/src/lib/components/console/pos/pos-tender-dialogs.component.js.map +1 -1
- package/src/lib/components/console/pos/pos-tender-panel.component.d.ts +8 -0
- package/src/lib/components/console/pos/pos-tender-panel.component.js +77 -18
- package/src/lib/components/console/pos/pos-tender-panel.component.js.map +1 -1
- package/src/lib/components/console/pos/use-pos-display.d.ts +5 -2
- package/src/lib/components/console/pos/use-pos-display.js +3 -2
- package/src/lib/components/console/pos/use-pos-display.js.map +1 -1
- package/src/lib/components/console/pos-devices-card.component.js +2 -2
- package/src/lib/components/console/pos-devices-card.component.js.map +1 -1
- package/src/lib/components/console/pos-display/pairing-screen.d.ts +5 -2
- package/src/lib/components/console/pos-display/pairing-screen.js +7 -5
- package/src/lib/components/console/pos-display/pairing-screen.js.map +1 -1
- package/src/lib/components/console/pos-display/pos-display-api.d.ts +7 -1
- package/src/lib/components/console/pos-display/pos-display-api.js +7 -2
- package/src/lib/components/console/pos-display/pos-display-api.js.map +1 -1
- package/src/lib/components/console/pos-kiosk/kiosk-checkout.d.ts +41 -0
- package/src/lib/components/console/pos-kiosk/kiosk-checkout.js +275 -0
- package/src/lib/components/console/pos-kiosk/kiosk-checkout.js.map +1 -0
- package/src/lib/components/console/pos-kiosk/kiosk-menu.d.ts +32 -0
- package/src/lib/components/console/pos-kiosk/kiosk-menu.js +344 -0
- package/src/lib/components/console/pos-kiosk/kiosk-menu.js.map +1 -0
- package/src/lib/components/console/pos-kiosk/kiosk-staff.d.ts +12 -0
- package/src/lib/components/console/pos-kiosk/kiosk-staff.js +257 -0
- package/src/lib/components/console/pos-kiosk/kiosk-staff.js.map +1 -0
- package/src/lib/components/console/pos-kiosk/pos-kiosk-api.d.ts +114 -0
- package/src/lib/components/console/pos-kiosk/pos-kiosk-api.js +189 -0
- package/src/lib/components/console/pos-kiosk/pos-kiosk-api.js.map +1 -0
- package/src/lib/components/console/pos-kiosk/use-kiosk-idle.d.ts +16 -0
- package/src/lib/components/console/pos-kiosk/use-kiosk-idle.js +80 -0
- package/src/lib/components/console/pos-kiosk/use-kiosk-idle.js.map +1 -0
- package/src/lib/components/console/pos-kiosk-page.component.d.ts +28 -0
- package/src/lib/components/console/pos-kiosk-page.component.js +791 -0
- package/src/lib/components/console/pos-kiosk-page.component.js.map +1 -0
- package/src/lib/components/console/pos-offline/pos-offline-api.d.ts +44 -0
- package/src/lib/components/console/pos-offline/pos-offline-api.js +69 -0
- package/src/lib/components/console/pos-offline/pos-offline-api.js.map +1 -0
- package/src/lib/components/console/pos-offline/pos-offline-banner.component.d.ts +7 -0
- package/src/lib/components/console/pos-offline/pos-offline-banner.component.js +135 -0
- package/src/lib/components/console/pos-offline/pos-offline-banner.component.js.map +1 -0
- package/src/lib/components/console/pos-offline/pos-offline-checkout.component.d.ts +32 -0
- package/src/lib/components/console/pos-offline/pos-offline-checkout.component.js +287 -0
- package/src/lib/components/console/pos-offline/pos-offline-checkout.component.js.map +1 -0
- package/src/lib/components/console/pos-offline/pos-offline-store.d.ts +63 -0
- package/src/lib/components/console/pos-offline/pos-offline-store.js +145 -0
- package/src/lib/components/console/pos-offline/pos-offline-store.js.map +1 -0
- package/src/lib/components/console/pos-offline/register-offline.d.ts +24 -0
- package/src/lib/components/console/pos-offline/register-offline.js +24 -0
- package/src/lib/components/console/pos-offline/register-offline.js.map +1 -0
- package/src/lib/components/console/pos-offline/use-pos-offline.d.ts +85 -0
- package/src/lib/components/console/pos-offline/use-pos-offline.js +542 -0
- package/src/lib/components/console/pos-offline/use-pos-offline.js.map +1 -0
- package/src/lib/components/console/pos-ops/pos-shift-history-card.component.js +72 -17
- package/src/lib/components/console/pos-ops/pos-shift-history-card.component.js.map +1 -1
- package/src/lib/components/console/pos-page.component.js +228 -51
- package/src/lib/components/console/pos-page.component.js.map +1 -1
- package/src/lib/components/console/pos-zones.d.ts +23 -0
- package/src/lib/components/console/pos-zones.js +31 -0
- package/src/lib/components/console/pos-zones.js.map +1 -0
- package/src/lib/components/console/product-editor-dialog.component.js +10 -64
- package/src/lib/components/console/product-editor-dialog.component.js.map +1 -1
- package/src/lib/components/console/products-hub-card.component.js +46 -30
- package/src/lib/components/console/products-hub-card.component.js.map +1 -1
- package/src/lib/components/console/shipping-settings-card.component.js +1 -1
- package/src/lib/components/console/shipping-settings-card.component.js.map +1 -1
- package/src/lib/components/console/stock-movements-card.component.js +48 -16
- package/src/lib/components/console/stock-movements-card.component.js.map +1 -1
- package/src/lib/components/console/store-zones.d.ts +8 -1
- package/src/lib/components/console/store-zones.js +11 -1
- package/src/lib/components/console/store-zones.js.map +1 -1
- package/src/lib/components/console/storefront-tax-summary-card.component.js +1 -0
- package/src/lib/components/console/storefront-tax-summary-card.component.js.map +1 -1
- package/src/lib/components/order-status.js +66 -0
- package/src/lib/components/order-status.js.map +1 -1
- package/src/lib/components/product-detail.js +42 -15
- package/src/lib/components/product-detail.js.map +1 -1
- package/src/lib/constants/local-fulfillment-list-query.d.ts +48 -0
- package/src/lib/constants/local-fulfillment-list-query.js +84 -0
- package/src/lib/constants/local-fulfillment-list-query.js.map +1 -0
- package/src/lib/constants/orders-list-query.d.ts +7 -2
- package/src/lib/constants/orders-list-query.js +89 -8
- package/src/lib/constants/orders-list-query.js.map +1 -1
- package/src/lib/constants/pos-shift-list-query.d.ts +22 -0
- package/src/lib/constants/pos-shift-list-query.js +115 -0
- package/src/lib/constants/pos-shift-list-query.js.map +1 -0
- package/src/lib/constants/product-list-query.d.ts +6 -1
- package/src/lib/constants/product-list-query.js +77 -8
- package/src/lib/constants/product-list-query.js.map +1 -1
- package/src/lib/constants/stock-movement-query.d.ts +3 -2
- package/src/lib/constants/stock-movement-query.js +52 -8
- package/src/lib/constants/stock-movement-query.js.map +1 -1
- package/src/lib/declarations.server.js +21 -0
- package/src/lib/declarations.server.js.map +1 -1
- package/src/lib/model/buyer-notifications.d.ts +5 -3
- package/src/lib/model/buyer-notifications.js +25 -4
- package/src/lib/model/buyer-notifications.js.map +1 -1
- package/src/lib/model/commerce-orders.d.ts +103 -1
- package/src/lib/model/commerce-orders.js +2 -1
- package/src/lib/model/commerce-orders.js.map +1 -1
- package/src/lib/model/commerce-pos-kiosk.d.ts +175 -0
- package/src/lib/model/commerce-pos-kiosk.js +147 -0
- package/src/lib/model/commerce-pos-kiosk.js.map +1 -0
- package/src/lib/model/commerce-pos-offline.d.ts +234 -0
- package/src/lib/model/commerce-pos-offline.js +301 -0
- package/src/lib/model/commerce-pos-offline.js.map +1 -0
- package/src/lib/model/commerce-pos-ops.d.ts +16 -6
- package/src/lib/model/commerce-pos-ops.js +12 -4
- package/src/lib/model/commerce-pos-ops.js.map +1 -1
- package/src/lib/model/commerce-pos.d.ts +13 -1
- package/src/lib/model/commerce-pos.js +5 -4
- package/src/lib/model/commerce-pos.js.map +1 -1
- package/src/lib/model/commerce-stock-holds.d.ts +24 -3
- package/src/lib/model/commerce-stock-holds.js +26 -8
- package/src/lib/model/commerce-stock-holds.js.map +1 -1
- package/src/lib/model/commerce.d.ts +7 -1
- package/src/lib/model/commerce.js.map +1 -1
- package/src/lib/model/index.d.ts +5 -0
- package/src/lib/model/index.js +5 -0
- package/src/lib/model/index.js.map +1 -1
- package/src/lib/model/local-fulfillment-settings.d.ts +178 -0
- package/src/lib/model/local-fulfillment-settings.js +361 -0
- package/src/lib/model/local-fulfillment-settings.js.map +1 -0
- package/src/lib/model/order-list-fields.d.ts +10 -1
- package/src/lib/model/order-list-fields.js +1 -0
- package/src/lib/model/order-list-fields.js.map +1 -1
- package/src/lib/model/order-local-fulfillment.d.ts +131 -0
- package/src/lib/model/order-local-fulfillment.js +125 -0
- package/src/lib/model/order-local-fulfillment.js.map +1 -0
- package/src/lib/model/order-shipping-export.js +4 -0
- package/src/lib/model/order-shipping-export.js.map +1 -1
- package/src/lib/model/order-status-view.d.ts +20 -1
- package/src/lib/model/order-status-view.js +60 -6
- package/src/lib/model/order-status-view.js.map +1 -1
- package/src/lib/model/product-write.d.ts +186 -0
- package/src/lib/model/product-write.js +116 -0
- package/src/lib/model/product-write.js.map +1 -0
- package/src/lib/plugin-config.js +6 -2
- package/src/lib/plugin-config.js.map +1 -1
- package/src/lib/plugin.js +11 -0
- package/src/lib/plugin.js.map +1 -1
- package/src/lib/pos-kiosk-config.d.ts +26 -0
- package/src/lib/pos-kiosk-config.js +59 -0
- package/src/lib/pos-kiosk-config.js.map +1 -0
- package/src/lib/server/api-v1/openapi.js +8 -0
- package/src/lib/server/api-v1/openapi.js.map +1 -1
- package/src/lib/server/api-v1/order-view.d.ts +19 -0
- package/src/lib/server/api-v1/order-view.js +35 -0
- package/src/lib/server/api-v1/order-view.js.map +1 -1
- package/src/lib/server/billing-webhook.js +238 -87
- package/src/lib/server/billing-webhook.js.map +1 -1
- package/src/lib/server/cart-checkout.d.ts +2 -0
- package/src/lib/server/cart-checkout.js +173 -13
- package/src/lib/server/cart-checkout.js.map +1 -1
- package/src/lib/server/channel-order-updates.d.ts +50 -0
- package/src/lib/server/channel-order-updates.js +290 -0
- package/src/lib/server/channel-order-updates.js.map +1 -0
- package/src/lib/server/channel-orders.d.ts +85 -0
- package/src/lib/server/channel-orders.js +543 -0
- package/src/lib/server/channel-orders.js.map +1 -0
- package/src/lib/server/checkout-extras.js +18 -4
- package/src/lib/server/checkout-extras.js.map +1 -1
- package/src/lib/server/checkout.js +71 -14
- package/src/lib/server/checkout.js.map +1 -1
- package/src/lib/server/local-fulfillment-status.d.ts +86 -0
- package/src/lib/server/local-fulfillment-status.js +379 -0
- package/src/lib/server/local-fulfillment-status.js.map +1 -0
- package/src/lib/server/local-fulfillment.d.ts +190 -0
- package/src/lib/server/local-fulfillment.js +580 -0
- package/src/lib/server/local-fulfillment.js.map +1 -0
- package/src/lib/server/membership-register.js +3 -1
- package/src/lib/server/membership-register.js.map +1 -1
- package/src/lib/server/order-notifications.js +61 -0
- package/src/lib/server/order-notifications.js.map +1 -1
- package/src/lib/server/pos-display.d.ts +27 -1
- package/src/lib/server/pos-display.js +50 -9
- package/src/lib/server/pos-display.js.map +1 -1
- package/src/lib/server/pos-kiosk-principal.d.ts +29 -0
- package/src/lib/server/pos-kiosk-principal.js +42 -0
- package/src/lib/server/pos-kiosk-principal.js.map +1 -0
- package/src/lib/server/pos-kiosk.d.ts +54 -0
- package/src/lib/server/pos-kiosk.js +972 -0
- package/src/lib/server/pos-kiosk.js.map +1 -0
- package/src/lib/server/pos-offline-sync.d.ts +85 -0
- package/src/lib/server/pos-offline-sync.js +765 -0
- package/src/lib/server/pos-offline-sync.js.map +1 -0
- package/src/lib/server/pos-order.js +22 -4
- package/src/lib/server/pos-order.js.map +1 -1
- package/src/lib/server/pos-payment.d.ts +6 -0
- package/src/lib/server/pos-payment.js +225 -6
- package/src/lib/server/pos-payment.js.map +1 -1
- package/src/lib/server/pos-print.js +5 -0
- package/src/lib/server/pos-print.js.map +1 -1
- package/src/lib/server/pos-return.js +27 -0
- package/src/lib/server/pos-return.js.map +1 -1
- package/src/lib/server/pos-sale.d.ts +6 -0
- package/src/lib/server/pos-sale.js +2 -0
- package/src/lib/server/pos-sale.js.map +1 -1
- package/src/lib/server/pos-shift.js +8 -1
- package/src/lib/server/pos-shift.js.map +1 -1
- package/src/lib/server/product-catalog.js +5 -1
- package/src/lib/server/product-catalog.js.map +1 -1
- package/src/lib/server/product-drafts.d.ts +5 -1
- package/src/lib/server/product-drafts.js +3 -3
- package/src/lib/server/product-drafts.js.map +1 -1
- package/src/lib/server/product-writer.d.ts +19 -0
- package/src/lib/server/product-writer.js +261 -0
- package/src/lib/server/product-writer.js.map +1 -0
- package/src/lib/server/products-write.d.ts +61 -0
- package/src/lib/server/products-write.js +375 -0
- package/src/lib/server/products-write.js.map +1 -0
- package/src/lib/server/refund.js +3 -0
- package/src/lib/server/refund.js.map +1 -1
- package/src/lib/server/stock-hold.d.ts +9 -1
- package/src/lib/server/stock-hold.js +15 -7
- package/src/lib/server/stock-hold.js.map +1 -1
- package/src/lib/server.js +21 -0
- package/src/lib/server.js.map +1 -1
- package/src/lib/tenant-emails.js +161 -0
- package/src/lib/tenant-emails.js.map +1 -1
- package/src/lib/testing/memory-firestore.d.ts +16 -3
- package/src/lib/testing/memory-firestore.js +11 -3
- package/src/lib/testing/memory-firestore.js.map +1 -1
- package/src/lib/transfer/products.server.d.ts +5 -0
- package/src/lib/transfer/products.server.js +2 -2
- package/src/lib/transfer/products.server.js.map +1 -1
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type PosCreditAccount } from './pos-api';
|
|
1
2
|
/** Cash: what the customer handed over, with one-tap round-ups. */
|
|
2
3
|
export declare function PosCashDialog(props: {
|
|
3
4
|
open: boolean;
|
|
@@ -51,3 +52,20 @@ export declare function PosKeyedCardDialog(props: {
|
|
|
51
52
|
onClose: () => void;
|
|
52
53
|
onConfirmed: () => void;
|
|
53
54
|
}): import("react").JSX.Element;
|
|
55
|
+
/**
|
|
56
|
+
* Store credit another plugin keeps (AGL-3640) — a rewards balance, a friend's
|
|
57
|
+
* referral credit. The cashier finds the customer by email or code and takes
|
|
58
|
+
* from the account found, or applies a code the customer reads out. Which
|
|
59
|
+
* plugin answers is the provider's business; the register only shows its name
|
|
60
|
+
* and what the account can give.
|
|
61
|
+
*/
|
|
62
|
+
export declare function PosCreditDialog(props: {
|
|
63
|
+
open: boolean;
|
|
64
|
+
label: string;
|
|
65
|
+
canLookup: boolean;
|
|
66
|
+
busy: boolean;
|
|
67
|
+
onClose: () => void;
|
|
68
|
+
onLookup: (query: string) => Promise<PosCreditAccount[] | null>;
|
|
69
|
+
onApplyCode: (code: string) => void;
|
|
70
|
+
onApplyAccount: (account: PosCreditAccount) => void;
|
|
71
|
+
}): import("react").JSX.Element;
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
* limitations under the License.
|
|
16
16
|
*/ 'use client';
|
|
17
17
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
18
|
-
import { Alert, Box, Button, Dialog, DialogActions, DialogContent, DialogTitle, MenuItem, Stack, TextField, Typography } from "@mui/material";
|
|
18
|
+
import { Alert, Box, Button, Dialog, DialogActions, DialogContent, DialogTitle, List, ListItemButton, ListItemText, MenuItem, Stack, TextField, Typography } from "@mui/material";
|
|
19
19
|
import { Elements, PaymentElement, useElements, useStripe } from "@stripe/react-stripe-js";
|
|
20
20
|
// `/pure`: the Stripe script loads when a typed card is actually taken, not
|
|
21
21
|
// whenever the register mounts (the AGL-2486 reasoning).
|
|
@@ -441,5 +441,120 @@ function KeyedCardForm(props) {
|
|
|
441
441
|
]
|
|
442
442
|
});
|
|
443
443
|
}
|
|
444
|
+
/**
|
|
445
|
+
* Store credit another plugin keeps (AGL-3640) — a rewards balance, a friend's
|
|
446
|
+
* referral credit. The cashier finds the customer by email or code and takes
|
|
447
|
+
* from the account found, or applies a code the customer reads out. Which
|
|
448
|
+
* plugin answers is the provider's business; the register only shows its name
|
|
449
|
+
* and what the account can give.
|
|
450
|
+
*/ export function PosCreditDialog(props) {
|
|
451
|
+
const [query, setQuery] = useState('');
|
|
452
|
+
const [found, setFound] = useState(null);
|
|
453
|
+
const close = ()=>{
|
|
454
|
+
setQuery('');
|
|
455
|
+
setFound(null);
|
|
456
|
+
props.onClose();
|
|
457
|
+
};
|
|
458
|
+
const find = async ()=>{
|
|
459
|
+
if (!query.trim()) return;
|
|
460
|
+
setFound(await props.onLookup(query.trim()));
|
|
461
|
+
};
|
|
462
|
+
return /*#__PURE__*/ _jsxs(Dialog, {
|
|
463
|
+
open: props.open,
|
|
464
|
+
onClose: close,
|
|
465
|
+
maxWidth: "xs",
|
|
466
|
+
fullWidth: true,
|
|
467
|
+
children: [
|
|
468
|
+
/*#__PURE__*/ _jsx(DialogTitle, {
|
|
469
|
+
children: props.label
|
|
470
|
+
}),
|
|
471
|
+
/*#__PURE__*/ _jsxs(DialogContent, {
|
|
472
|
+
sx: {
|
|
473
|
+
display: 'flex',
|
|
474
|
+
flexDirection: 'column',
|
|
475
|
+
gap: 2
|
|
476
|
+
},
|
|
477
|
+
children: [
|
|
478
|
+
/*#__PURE__*/ _jsx(TextField, {
|
|
479
|
+
label: props.canLookup ? 'Code or customer email' : 'Code',
|
|
480
|
+
value: query,
|
|
481
|
+
onChange: (event)=>{
|
|
482
|
+
setQuery(event.target.value);
|
|
483
|
+
setFound(null);
|
|
484
|
+
},
|
|
485
|
+
onKeyDown: (event)=>{
|
|
486
|
+
if (event.key === 'Enter' && props.canLookup) void find();
|
|
487
|
+
},
|
|
488
|
+
autoFocus: true,
|
|
489
|
+
sx: {
|
|
490
|
+
mt: 1
|
|
491
|
+
},
|
|
492
|
+
slotProps: {
|
|
493
|
+
htmlInput: {
|
|
494
|
+
autoComplete: 'off',
|
|
495
|
+
'data-testid': 'pos-credit-query'
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
}),
|
|
499
|
+
found && !found.length ? /*#__PURE__*/ _jsx(Alert, {
|
|
500
|
+
severity: "info",
|
|
501
|
+
children: 'No account matches.'
|
|
502
|
+
}) : null,
|
|
503
|
+
(found == null ? void 0 : found.length) ? /*#__PURE__*/ _jsx(List, {
|
|
504
|
+
disablePadding: true,
|
|
505
|
+
children: found.map((account)=>/*#__PURE__*/ _jsx(ListItemButton, {
|
|
506
|
+
disabled: props.busy || account.availableCents <= 0,
|
|
507
|
+
onClick: ()=>{
|
|
508
|
+
props.onApplyAccount(account);
|
|
509
|
+
setQuery('');
|
|
510
|
+
setFound(null);
|
|
511
|
+
},
|
|
512
|
+
divider: true,
|
|
513
|
+
sx: {
|
|
514
|
+
minHeight: POS_TOUCH_PX
|
|
515
|
+
},
|
|
516
|
+
children: /*#__PURE__*/ _jsx(ListItemText, {
|
|
517
|
+
primary: `${account.label}${account.last4 ? ` •• ${account.last4}` : ''} · ${usd(account.availableCents)} available`,
|
|
518
|
+
secondary: account.detail
|
|
519
|
+
})
|
|
520
|
+
}, account.reference))
|
|
521
|
+
}) : null
|
|
522
|
+
]
|
|
523
|
+
}),
|
|
524
|
+
/*#__PURE__*/ _jsxs(DialogActions, {
|
|
525
|
+
children: [
|
|
526
|
+
/*#__PURE__*/ _jsx(Button, {
|
|
527
|
+
onClick: close,
|
|
528
|
+
sx: {
|
|
529
|
+
minHeight: POS_TOUCH_PX
|
|
530
|
+
},
|
|
531
|
+
children: 'Cancel'
|
|
532
|
+
}),
|
|
533
|
+
props.canLookup ? /*#__PURE__*/ _jsx(Button, {
|
|
534
|
+
disabled: props.busy || !query.trim(),
|
|
535
|
+
onClick: ()=>void find(),
|
|
536
|
+
sx: {
|
|
537
|
+
minHeight: POS_TOUCH_PX
|
|
538
|
+
},
|
|
539
|
+
children: 'Find'
|
|
540
|
+
}) : null,
|
|
541
|
+
/*#__PURE__*/ _jsx(Button, {
|
|
542
|
+
variant: "contained",
|
|
543
|
+
disabled: props.busy || !query.trim() || query.includes('@'),
|
|
544
|
+
onClick: ()=>{
|
|
545
|
+
props.onApplyCode(query.trim());
|
|
546
|
+
setQuery('');
|
|
547
|
+
setFound(null);
|
|
548
|
+
},
|
|
549
|
+
sx: {
|
|
550
|
+
minHeight: POS_TOUCH_PX
|
|
551
|
+
},
|
|
552
|
+
children: 'Apply code'
|
|
553
|
+
})
|
|
554
|
+
]
|
|
555
|
+
})
|
|
556
|
+
]
|
|
557
|
+
});
|
|
558
|
+
}
|
|
444
559
|
|
|
445
560
|
//# sourceMappingURL=pos-tender-dialogs.component.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../../../../libs/plugins/commerce/src/lib/components/console/pos/pos-tender-dialogs.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 {\n Alert,\n Box,\n Button,\n Dialog,\n DialogActions,\n DialogContent,\n DialogTitle,\n MenuItem,\n Stack,\n TextField,\n Typography,\n} from '@mui/material'\nimport { Elements, PaymentElement, useElements, useStripe } from '@stripe/react-stripe-js'\n// `/pure`: the Stripe script loads when a typed card is actually taken, not\n// whenever the register mounts (the AGL-2486 reasoning).\nimport { loadStripe } from '@stripe/stripe-js/pure'\nimport type { Stripe } from '@stripe/stripe-js'\nimport { QRCodeSVG } from 'qrcode.react'\nimport { useMemo, useState } from 'react'\nimport { centsFromInput, usd } from './pos-api'\nimport { POS_TOUCH_PX } from './pos-product-grid.component'\n\n/*==========================================\n * The register's tender dialogs (AGL-3607). Each collects what its tender\n * needs and hands it to the tender panel, which owns the request.\n *=========================================*/\n\n/** Cash: what the customer handed over, with one-tap round-ups. */\nexport function PosCashDialog(props: {\n open: boolean\n dueCents: number\n tipCents: number\n busy: boolean\n onClose: () => void\n onTake: (tenderedCents: number) => void\n}) {\n const [received, setReceived] = useState('')\n const owed = props.dueCents + props.tipCents\n const tendered = centsFromInput(received)\n const quick = [...new Set([owed, Math.ceil(owed / 500) * 500, Math.ceil(owed / 1000) * 1000, Math.ceil(owed / 2000) * 2000])]\n .filter((value) => value >= owed)\n .slice(0, 4)\n const close = () => {\n setReceived('')\n props.onClose()\n }\n return (\n <Dialog open={props.open} onClose={close} maxWidth=\"xs\" fullWidth>\n <DialogTitle>{`Cash — ${usd(owed)}`}</DialogTitle>\n <DialogContent sx={{ display: 'flex', flexDirection: 'column', gap: 2 }}>\n <TextField\n label=\"Cash received ($)\"\n value={received}\n onChange={(event) => setReceived(event.target.value.replace(/[^0-9.]/g, ''))}\n autoFocus\n sx={{ mt: 1 }}\n slotProps={{ htmlInput: { inputMode: 'decimal' } }}\n />\n <Stack direction=\"row\" spacing={1} sx={{ flexWrap: 'wrap' }}>\n {quick.map((cents) => (\n <Button\n key={cents}\n variant=\"outlined\"\n onClick={() => setReceived((cents / 100).toFixed(2))}\n sx={{ minHeight: POS_TOUCH_PX }}\n >\n {cents === owed ? 'Exact' : usd(cents)}\n </Button>\n ))}\n </Stack>\n {tendered > 0 && tendered >= owed ? (\n <Alert severity=\"success\">{`Change: ${usd(tendered - owed)}`}</Alert>\n ) : tendered > 0 && tendered < owed ? (\n <Alert severity=\"info\">\n {`Takes ${usd(Math.max(0, tendered - props.tipCents))} toward the sale; ${usd(owed - tendered)} left to pay.`}\n </Alert>\n ) : null}\n </DialogContent>\n <DialogActions>\n <Button onClick={close} sx={{ minHeight: POS_TOUCH_PX }}>\n {'Cancel'}\n </Button>\n <Button\n variant=\"contained\"\n disabled={props.busy || tendered <= props.tipCents}\n onClick={() => {\n props.onTake(tendered)\n setReceived('')\n }}\n sx={{ minHeight: POS_TOUCH_PX }}\n >\n {'Take cash'}\n </Button>\n </DialogActions>\n </Dialog>\n )\n}\n\n/** A gift card: type or scan the code, see the balance, apply it. */\nexport function PosGiftCardDialog(props: {\n open: boolean\n busy: boolean\n onClose: () => void\n onCheck: (code: string) => Promise<{ availableCents: number; frozen: boolean; voided: boolean } | null>\n onApply: (code: string) => void\n}) {\n const [code, setCode] = useState('')\n const [balance, setBalance] = useState<string | null>(null)\n const close = () => {\n setCode('')\n setBalance(null)\n props.onClose()\n }\n return (\n <Dialog open={props.open} onClose={close} maxWidth=\"xs\" fullWidth>\n <DialogTitle>{'Gift card'}</DialogTitle>\n <DialogContent sx={{ display: 'flex', flexDirection: 'column', gap: 2 }}>\n <TextField\n label=\"Gift card code\"\n value={code}\n onChange={(event) => {\n setCode(event.target.value.toUpperCase())\n setBalance(null)\n }}\n onKeyDown={async (event) => {\n if (event.key !== 'Enter' || !code.trim()) return\n const answer = await props.onCheck(code)\n setBalance(\n answer\n ? answer.frozen\n ? 'This card is on hold.'\n : answer.voided\n ? 'This card was voided.'\n : `Available: ${usd(answer.availableCents)}`\n : null,\n )\n }}\n autoFocus\n sx={{ mt: 1 }}\n slotProps={{ htmlInput: { autoComplete: 'off', autoCapitalize: 'characters' } }}\n />\n {balance ? <Alert severity=\"info\">{balance}</Alert> : null}\n </DialogContent>\n <DialogActions>\n <Button onClick={close} sx={{ minHeight: POS_TOUCH_PX }}>\n {'Cancel'}\n </Button>\n <Button\n disabled={!code.trim()}\n onClick={async () => {\n const answer = await props.onCheck(code)\n setBalance(\n answer\n ? answer.frozen\n ? 'This card is on hold.'\n : `Available: ${usd(answer.availableCents)}`\n : null,\n )\n }}\n sx={{ minHeight: POS_TOUCH_PX }}\n >\n {'Check balance'}\n </Button>\n <Button\n variant=\"contained\"\n disabled={props.busy || !code.trim()}\n onClick={() => {\n props.onApply(code)\n setCode('')\n setBalance(null)\n }}\n sx={{ minHeight: POS_TOUCH_PX }}\n >\n {'Apply card'}\n </Button>\n </DialogActions>\n </Dialog>\n )\n}\n\n/** Charge to a checked-in stay's folio. */\nexport function PosFolioDialog(props: {\n open: boolean\n amountCents: number\n stays: any[]\n busy: boolean\n onClose: () => void\n onCharge: (reservationId: string) => void\n}) {\n const [stay, setStay] = useState('')\n return (\n <Dialog open={props.open} onClose={props.onClose} maxWidth=\"xs\" fullWidth>\n <DialogTitle>{`Charge to room — ${usd(props.amountCents)}`}</DialogTitle>\n <DialogContent>\n <TextField\n label=\"Checked-in stay\"\n value={stay}\n onChange={(event) => setStay(event.target.value)}\n select\n fullWidth\n sx={{ mt: 1 }}\n >\n {props.stays.map((entry: any) => (\n <MenuItem key={entry.$id} value={entry.$id}>\n {entry.guestName ?? entry.guestEmail ?? entry.$id}\n </MenuItem>\n ))}\n </TextField>\n </DialogContent>\n <DialogActions>\n <Button onClick={props.onClose} sx={{ minHeight: POS_TOUCH_PX }}>\n {'Cancel'}\n </Button>\n <Button\n variant=\"contained\"\n disabled={props.busy || !stay}\n onClick={() => props.onCharge(stay)}\n sx={{ minHeight: POS_TOUCH_PX }}\n >\n {'Charge folio'}\n </Button>\n </DialogActions>\n </Dialog>\n )\n}\n\n/**\n * The QR payment page. Encoded in this browser, never fetched (AGL-1671): a\n * live payment URL in a third party's query string is a link that pays the\n * sale for whoever opens it.\n */\nexport function PosQrDialog(props: { url: string; amountCents: number; onClose: () => void }) {\n return (\n <Dialog open={Boolean(props.url)} onClose={props.onClose} maxWidth=\"xs\" fullWidth>\n <DialogTitle>{`Scan to pay ${usd(props.amountCents)}`}</DialogTitle>\n <DialogContent sx={{ display: 'flex', flexDirection: 'column', gap: 2 }}>\n <Typography variant=\"body2\" color=\"text.secondary\" sx={{ mt: 1 }}>\n {'The customer scans this and pays on their phone. The payment shows ' +\n 'here as soon as it goes through.'}\n </Typography>\n <Box sx={{ display: 'flex', justifyContent: 'center' }}>\n <QRCodeSVG value={props.url} size={256} level=\"L\" marginSize={4} title=\"Payment QR\" role=\"img\" />\n </Box>\n <Button href={props.url} target=\"_blank\" rel=\"noopener noreferrer\">\n {'Open payment page'}\n </Button>\n </DialogContent>\n <DialogActions>\n <Button onClick={props.onClose} sx={{ minHeight: POS_TOUCH_PX }}>\n {'Close'}\n </Button>\n </DialogActions>\n </Dialog>\n )\n}\n\nconst stripePromises = new Map<string, Promise<Stripe | null>>()\n\nfunction stripeFor(publishableKey: string): Promise<Stripe | null> {\n let promise = stripePromises.get(publishableKey)\n if (!promise) {\n promise = loadStripe(publishableKey)\n stripePromises.set(publishableKey, promise)\n }\n return promise\n}\n\n/**\n * A card typed in by staff (card not present). The card goes into Stripe's\n * own Payment Element and never touches the register; the server created the\n * PaymentIntent and records the payment from Stripe, never from this form's\n * say-so.\n */\nexport function PosKeyedCardDialog(props: {\n clientSecret: string\n publishableKey: string\n amountCents: number\n onClose: () => void\n onConfirmed: () => void\n}) {\n const stripe = useMemo(\n () => (props.publishableKey ? stripeFor(props.publishableKey) : null),\n [props.publishableKey],\n )\n return (\n <Dialog open={Boolean(props.clientSecret)} onClose={props.onClose} maxWidth=\"sm\" fullWidth>\n <DialogTitle>{`Type a card — ${usd(props.amountCents)}`}</DialogTitle>\n {props.clientSecret && stripe ? (\n <Elements stripe={stripe} options={{ clientSecret: props.clientSecret }}>\n <KeyedCardForm onClose={props.onClose} onConfirmed={props.onConfirmed} />\n </Elements>\n ) : null}\n </Dialog>\n )\n}\n\nfunction KeyedCardForm(props: { onClose: () => void; onConfirmed: () => void }) {\n const stripe = useStripe()\n const elements = useElements()\n const [error, setError] = useState('')\n const [busy, setBusy] = useState(false)\n return (\n <>\n <DialogContent sx={{ display: 'flex', flexDirection: 'column', gap: 2 }}>\n <PaymentElement options={{ layout: 'tabs', wallets: { applePay: 'never', googlePay: 'never' } }} />\n {error ? <Alert severity=\"error\">{error}</Alert> : null}\n </DialogContent>\n <DialogActions>\n <Button onClick={props.onClose} disabled={busy} sx={{ minHeight: POS_TOUCH_PX }}>\n {'Cancel'}\n </Button>\n <Button\n variant=\"contained\"\n disabled={busy || !stripe || !elements}\n onClick={async () => {\n if (!stripe || !elements) return\n setBusy(true)\n setError('')\n const result = await stripe.confirmPayment({\n elements,\n redirect: 'if_required',\n confirmParams: { return_url: window.location.href },\n })\n setBusy(false)\n if (result.error) {\n setError(result.error.message ?? 'The card was not accepted.')\n return\n }\n props.onConfirmed()\n }}\n sx={{ minHeight: POS_TOUCH_PX }}\n >\n {busy ? 'Charging…' : 'Charge card'}\n </Button>\n </DialogActions>\n </>\n )\n}\n"],"names":["Alert","Box","Button","Dialog","DialogActions","DialogContent","DialogTitle","MenuItem","Stack","TextField","Typography","Elements","PaymentElement","useElements","useStripe","loadStripe","QRCodeSVG","useMemo","useState","centsFromInput","usd","POS_TOUCH_PX","PosCashDialog","props","received","setReceived","owed","dueCents","tipCents","tendered","quick","Set","Math","ceil","filter","value","slice","close","onClose","open","maxWidth","fullWidth","sx","display","flexDirection","gap","label","onChange","event","target","replace","autoFocus","mt","slotProps","htmlInput","inputMode","direction","spacing","flexWrap","map","cents","variant","onClick","toFixed","minHeight","severity","max","disabled","busy","onTake","PosGiftCardDialog","code","setCode","balance","setBalance","toUpperCase","onKeyDown","key","trim","answer","onCheck","frozen","voided","availableCents","autoComplete","autoCapitalize","onApply","PosFolioDialog","stay","setStay","amountCents","select","stays","entry","$id","guestName","guestEmail","onCharge","PosQrDialog","Boolean","url","color","justifyContent","size","level","marginSize","title","role","href","rel","stripePromises","Map","stripeFor","publishableKey","promise","get","set","PosKeyedCardDialog","stripe","clientSecret","options","KeyedCardForm","onConfirmed","elements","error","setError","setBusy","layout","wallets","applePay","googlePay","result","confirmPayment","redirect","confirmParams","return_url","window","location","message"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../../../../../libs/plugins/commerce/src/lib/components/console/pos/pos-tender-dialogs.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 {\n Alert,\n Box,\n Button,\n Dialog,\n DialogActions,\n DialogContent,\n DialogTitle,\n List,\n ListItemButton,\n ListItemText,\n MenuItem,\n Stack,\n TextField,\n Typography,\n} from '@mui/material'\nimport { Elements, PaymentElement, useElements, useStripe } from '@stripe/react-stripe-js'\n// `/pure`: the Stripe script loads when a typed card is actually taken, not\n// whenever the register mounts (the AGL-2486 reasoning).\nimport { loadStripe } from '@stripe/stripe-js/pure'\nimport type { Stripe } from '@stripe/stripe-js'\nimport { QRCodeSVG } from 'qrcode.react'\nimport { useMemo, useState } from 'react'\nimport { centsFromInput, usd, type PosCreditAccount } from './pos-api'\nimport { POS_TOUCH_PX } from './pos-product-grid.component'\n\n/*==========================================\n * The register's tender dialogs (AGL-3607). Each collects what its tender\n * needs and hands it to the tender panel, which owns the request.\n *=========================================*/\n\n/** Cash: what the customer handed over, with one-tap round-ups. */\nexport function PosCashDialog(props: {\n open: boolean\n dueCents: number\n tipCents: number\n busy: boolean\n onClose: () => void\n onTake: (tenderedCents: number) => void\n}) {\n const [received, setReceived] = useState('')\n const owed = props.dueCents + props.tipCents\n const tendered = centsFromInput(received)\n const quick = [...new Set([owed, Math.ceil(owed / 500) * 500, Math.ceil(owed / 1000) * 1000, Math.ceil(owed / 2000) * 2000])]\n .filter((value) => value >= owed)\n .slice(0, 4)\n const close = () => {\n setReceived('')\n props.onClose()\n }\n return (\n <Dialog open={props.open} onClose={close} maxWidth=\"xs\" fullWidth>\n <DialogTitle>{`Cash — ${usd(owed)}`}</DialogTitle>\n <DialogContent sx={{ display: 'flex', flexDirection: 'column', gap: 2 }}>\n <TextField\n label=\"Cash received ($)\"\n value={received}\n onChange={(event) => setReceived(event.target.value.replace(/[^0-9.]/g, ''))}\n autoFocus\n sx={{ mt: 1 }}\n slotProps={{ htmlInput: { inputMode: 'decimal' } }}\n />\n <Stack direction=\"row\" spacing={1} sx={{ flexWrap: 'wrap' }}>\n {quick.map((cents) => (\n <Button\n key={cents}\n variant=\"outlined\"\n onClick={() => setReceived((cents / 100).toFixed(2))}\n sx={{ minHeight: POS_TOUCH_PX }}\n >\n {cents === owed ? 'Exact' : usd(cents)}\n </Button>\n ))}\n </Stack>\n {tendered > 0 && tendered >= owed ? (\n <Alert severity=\"success\">{`Change: ${usd(tendered - owed)}`}</Alert>\n ) : tendered > 0 && tendered < owed ? (\n <Alert severity=\"info\">\n {`Takes ${usd(Math.max(0, tendered - props.tipCents))} toward the sale; ${usd(owed - tendered)} left to pay.`}\n </Alert>\n ) : null}\n </DialogContent>\n <DialogActions>\n <Button onClick={close} sx={{ minHeight: POS_TOUCH_PX }}>\n {'Cancel'}\n </Button>\n <Button\n variant=\"contained\"\n disabled={props.busy || tendered <= props.tipCents}\n onClick={() => {\n props.onTake(tendered)\n setReceived('')\n }}\n sx={{ minHeight: POS_TOUCH_PX }}\n >\n {'Take cash'}\n </Button>\n </DialogActions>\n </Dialog>\n )\n}\n\n/** A gift card: type or scan the code, see the balance, apply it. */\nexport function PosGiftCardDialog(props: {\n open: boolean\n busy: boolean\n onClose: () => void\n onCheck: (code: string) => Promise<{ availableCents: number; frozen: boolean; voided: boolean } | null>\n onApply: (code: string) => void\n}) {\n const [code, setCode] = useState('')\n const [balance, setBalance] = useState<string | null>(null)\n const close = () => {\n setCode('')\n setBalance(null)\n props.onClose()\n }\n return (\n <Dialog open={props.open} onClose={close} maxWidth=\"xs\" fullWidth>\n <DialogTitle>{'Gift card'}</DialogTitle>\n <DialogContent sx={{ display: 'flex', flexDirection: 'column', gap: 2 }}>\n <TextField\n label=\"Gift card code\"\n value={code}\n onChange={(event) => {\n setCode(event.target.value.toUpperCase())\n setBalance(null)\n }}\n onKeyDown={async (event) => {\n if (event.key !== 'Enter' || !code.trim()) return\n const answer = await props.onCheck(code)\n setBalance(\n answer\n ? answer.frozen\n ? 'This card is on hold.'\n : answer.voided\n ? 'This card was voided.'\n : `Available: ${usd(answer.availableCents)}`\n : null,\n )\n }}\n autoFocus\n sx={{ mt: 1 }}\n slotProps={{ htmlInput: { autoComplete: 'off', autoCapitalize: 'characters' } }}\n />\n {balance ? <Alert severity=\"info\">{balance}</Alert> : null}\n </DialogContent>\n <DialogActions>\n <Button onClick={close} sx={{ minHeight: POS_TOUCH_PX }}>\n {'Cancel'}\n </Button>\n <Button\n disabled={!code.trim()}\n onClick={async () => {\n const answer = await props.onCheck(code)\n setBalance(\n answer\n ? answer.frozen\n ? 'This card is on hold.'\n : `Available: ${usd(answer.availableCents)}`\n : null,\n )\n }}\n sx={{ minHeight: POS_TOUCH_PX }}\n >\n {'Check balance'}\n </Button>\n <Button\n variant=\"contained\"\n disabled={props.busy || !code.trim()}\n onClick={() => {\n props.onApply(code)\n setCode('')\n setBalance(null)\n }}\n sx={{ minHeight: POS_TOUCH_PX }}\n >\n {'Apply card'}\n </Button>\n </DialogActions>\n </Dialog>\n )\n}\n\n/** Charge to a checked-in stay's folio. */\nexport function PosFolioDialog(props: {\n open: boolean\n amountCents: number\n stays: any[]\n busy: boolean\n onClose: () => void\n onCharge: (reservationId: string) => void\n}) {\n const [stay, setStay] = useState('')\n return (\n <Dialog open={props.open} onClose={props.onClose} maxWidth=\"xs\" fullWidth>\n <DialogTitle>{`Charge to room — ${usd(props.amountCents)}`}</DialogTitle>\n <DialogContent>\n <TextField\n label=\"Checked-in stay\"\n value={stay}\n onChange={(event) => setStay(event.target.value)}\n select\n fullWidth\n sx={{ mt: 1 }}\n >\n {props.stays.map((entry: any) => (\n <MenuItem key={entry.$id} value={entry.$id}>\n {entry.guestName ?? entry.guestEmail ?? entry.$id}\n </MenuItem>\n ))}\n </TextField>\n </DialogContent>\n <DialogActions>\n <Button onClick={props.onClose} sx={{ minHeight: POS_TOUCH_PX }}>\n {'Cancel'}\n </Button>\n <Button\n variant=\"contained\"\n disabled={props.busy || !stay}\n onClick={() => props.onCharge(stay)}\n sx={{ minHeight: POS_TOUCH_PX }}\n >\n {'Charge folio'}\n </Button>\n </DialogActions>\n </Dialog>\n )\n}\n\n/**\n * The QR payment page. Encoded in this browser, never fetched (AGL-1671): a\n * live payment URL in a third party's query string is a link that pays the\n * sale for whoever opens it.\n */\nexport function PosQrDialog(props: { url: string; amountCents: number; onClose: () => void }) {\n return (\n <Dialog open={Boolean(props.url)} onClose={props.onClose} maxWidth=\"xs\" fullWidth>\n <DialogTitle>{`Scan to pay ${usd(props.amountCents)}`}</DialogTitle>\n <DialogContent sx={{ display: 'flex', flexDirection: 'column', gap: 2 }}>\n <Typography variant=\"body2\" color=\"text.secondary\" sx={{ mt: 1 }}>\n {'The customer scans this and pays on their phone. The payment shows ' +\n 'here as soon as it goes through.'}\n </Typography>\n <Box sx={{ display: 'flex', justifyContent: 'center' }}>\n <QRCodeSVG value={props.url} size={256} level=\"L\" marginSize={4} title=\"Payment QR\" role=\"img\" />\n </Box>\n <Button href={props.url} target=\"_blank\" rel=\"noopener noreferrer\">\n {'Open payment page'}\n </Button>\n </DialogContent>\n <DialogActions>\n <Button onClick={props.onClose} sx={{ minHeight: POS_TOUCH_PX }}>\n {'Close'}\n </Button>\n </DialogActions>\n </Dialog>\n )\n}\n\nconst stripePromises = new Map<string, Promise<Stripe | null>>()\n\nfunction stripeFor(publishableKey: string): Promise<Stripe | null> {\n let promise = stripePromises.get(publishableKey)\n if (!promise) {\n promise = loadStripe(publishableKey)\n stripePromises.set(publishableKey, promise)\n }\n return promise\n}\n\n/**\n * A card typed in by staff (card not present). The card goes into Stripe's\n * own Payment Element and never touches the register; the server created the\n * PaymentIntent and records the payment from Stripe, never from this form's\n * say-so.\n */\nexport function PosKeyedCardDialog(props: {\n clientSecret: string\n publishableKey: string\n amountCents: number\n onClose: () => void\n onConfirmed: () => void\n}) {\n const stripe = useMemo(\n () => (props.publishableKey ? stripeFor(props.publishableKey) : null),\n [props.publishableKey],\n )\n return (\n <Dialog open={Boolean(props.clientSecret)} onClose={props.onClose} maxWidth=\"sm\" fullWidth>\n <DialogTitle>{`Type a card — ${usd(props.amountCents)}`}</DialogTitle>\n {props.clientSecret && stripe ? (\n <Elements stripe={stripe} options={{ clientSecret: props.clientSecret }}>\n <KeyedCardForm onClose={props.onClose} onConfirmed={props.onConfirmed} />\n </Elements>\n ) : null}\n </Dialog>\n )\n}\n\nfunction KeyedCardForm(props: { onClose: () => void; onConfirmed: () => void }) {\n const stripe = useStripe()\n const elements = useElements()\n const [error, setError] = useState('')\n const [busy, setBusy] = useState(false)\n return (\n <>\n <DialogContent sx={{ display: 'flex', flexDirection: 'column', gap: 2 }}>\n <PaymentElement options={{ layout: 'tabs', wallets: { applePay: 'never', googlePay: 'never' } }} />\n {error ? <Alert severity=\"error\">{error}</Alert> : null}\n </DialogContent>\n <DialogActions>\n <Button onClick={props.onClose} disabled={busy} sx={{ minHeight: POS_TOUCH_PX }}>\n {'Cancel'}\n </Button>\n <Button\n variant=\"contained\"\n disabled={busy || !stripe || !elements}\n onClick={async () => {\n if (!stripe || !elements) return\n setBusy(true)\n setError('')\n const result = await stripe.confirmPayment({\n elements,\n redirect: 'if_required',\n confirmParams: { return_url: window.location.href },\n })\n setBusy(false)\n if (result.error) {\n setError(result.error.message ?? 'The card was not accepted.')\n return\n }\n props.onConfirmed()\n }}\n sx={{ minHeight: POS_TOUCH_PX }}\n >\n {busy ? 'Charging…' : 'Charge card'}\n </Button>\n </DialogActions>\n </>\n )\n}\n\n/**\n * Store credit another plugin keeps (AGL-3640) — a rewards balance, a friend's\n * referral credit. The cashier finds the customer by email or code and takes\n * from the account found, or applies a code the customer reads out. Which\n * plugin answers is the provider's business; the register only shows its name\n * and what the account can give.\n */\nexport function PosCreditDialog(props: {\n open: boolean\n label: string\n canLookup: boolean\n busy: boolean\n onClose: () => void\n onLookup: (query: string) => Promise<PosCreditAccount[] | null>\n onApplyCode: (code: string) => void\n onApplyAccount: (account: PosCreditAccount) => void\n}) {\n const [query, setQuery] = useState('')\n const [found, setFound] = useState<PosCreditAccount[] | null>(null)\n const close = () => {\n setQuery('')\n setFound(null)\n props.onClose()\n }\n const find = async () => {\n if (!query.trim()) return\n setFound(await props.onLookup(query.trim()))\n }\n return (\n <Dialog open={props.open} onClose={close} maxWidth=\"xs\" fullWidth>\n <DialogTitle>{props.label}</DialogTitle>\n <DialogContent sx={{ display: 'flex', flexDirection: 'column', gap: 2 }}>\n <TextField\n label={props.canLookup ? 'Code or customer email' : 'Code'}\n value={query}\n onChange={(event) => {\n setQuery(event.target.value)\n setFound(null)\n }}\n onKeyDown={(event) => {\n if (event.key === 'Enter' && props.canLookup) void find()\n }}\n autoFocus\n sx={{ mt: 1 }}\n slotProps={{ htmlInput: { autoComplete: 'off', 'data-testid': 'pos-credit-query' } }}\n />\n {found && !found.length ? <Alert severity=\"info\">{'No account matches.'}</Alert> : null}\n {found?.length ? (\n <List disablePadding>\n {found.map((account) => (\n <ListItemButton\n key={account.reference}\n disabled={props.busy || account.availableCents <= 0}\n onClick={() => {\n props.onApplyAccount(account)\n setQuery('')\n setFound(null)\n }}\n divider\n sx={{ minHeight: POS_TOUCH_PX }}\n >\n <ListItemText\n primary={`${account.label}${account.last4 ? ` •• ${account.last4}` : ''} · ${usd(account.availableCents)} available`}\n secondary={account.detail}\n />\n </ListItemButton>\n ))}\n </List>\n ) : null}\n </DialogContent>\n <DialogActions>\n <Button onClick={close} sx={{ minHeight: POS_TOUCH_PX }}>\n {'Cancel'}\n </Button>\n {props.canLookup ? (\n <Button disabled={props.busy || !query.trim()} onClick={() => void find()} sx={{ minHeight: POS_TOUCH_PX }}>\n {'Find'}\n </Button>\n ) : null}\n <Button\n variant=\"contained\"\n disabled={props.busy || !query.trim() || query.includes('@')}\n onClick={() => {\n props.onApplyCode(query.trim())\n setQuery('')\n setFound(null)\n }}\n sx={{ minHeight: POS_TOUCH_PX }}\n >\n {'Apply code'}\n </Button>\n </DialogActions>\n </Dialog>\n )\n}\n"],"names":["Alert","Box","Button","Dialog","DialogActions","DialogContent","DialogTitle","List","ListItemButton","ListItemText","MenuItem","Stack","TextField","Typography","Elements","PaymentElement","useElements","useStripe","loadStripe","QRCodeSVG","useMemo","useState","centsFromInput","usd","POS_TOUCH_PX","PosCashDialog","props","received","setReceived","owed","dueCents","tipCents","tendered","quick","Set","Math","ceil","filter","value","slice","close","onClose","open","maxWidth","fullWidth","sx","display","flexDirection","gap","label","onChange","event","target","replace","autoFocus","mt","slotProps","htmlInput","inputMode","direction","spacing","flexWrap","map","cents","variant","onClick","toFixed","minHeight","severity","max","disabled","busy","onTake","PosGiftCardDialog","code","setCode","balance","setBalance","toUpperCase","onKeyDown","key","trim","answer","onCheck","frozen","voided","availableCents","autoComplete","autoCapitalize","onApply","PosFolioDialog","stay","setStay","amountCents","select","stays","entry","$id","guestName","guestEmail","onCharge","PosQrDialog","Boolean","url","color","justifyContent","size","level","marginSize","title","role","href","rel","stripePromises","Map","stripeFor","publishableKey","promise","get","set","PosKeyedCardDialog","stripe","clientSecret","options","KeyedCardForm","onConfirmed","elements","error","setError","setBusy","layout","wallets","applePay","googlePay","result","confirmPayment","redirect","confirmParams","return_url","window","location","message","PosCreditDialog","query","setQuery","found","setFound","find","onLookup","canLookup","length","disablePadding","account","onApplyAccount","divider","primary","last4","secondary","detail","reference","includes","onApplyCode"],"mappings":"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"}
|
|
@@ -17,6 +17,14 @@ export interface PosTenderPanelProps {
|
|
|
17
17
|
/** A PIN-switched cashier (AGL-3609) takes each payment they start. */
|
|
18
18
|
cashierAssertion?: string;
|
|
19
19
|
notify: (message: string, variant: 'success' | 'error' | 'warning' | 'info') => void;
|
|
20
|
+
/**
|
|
21
|
+
* The register is offline (AGL-3625). Every tender here is the server's —
|
|
22
|
+
* the card reader, the typed card, the QR link, the gift card, the room
|
|
23
|
+
* charge and this sale's own cash — so each is off until it returns.
|
|
24
|
+
*/
|
|
25
|
+
offline?: boolean;
|
|
26
|
+
/** Rings this basket as an offline cash sale instead; offered while nothing is paid. */
|
|
27
|
+
onSellOffline?: () => void;
|
|
20
28
|
}
|
|
21
29
|
/**
|
|
22
30
|
* Taking payment on an open sale (AGL-3607): the balance due, every payment
|
|
@@ -20,9 +20,9 @@ import { Alert, Box, Button, Chip, Divider, MenuItem, Stack, TextField, Typograp
|
|
|
20
20
|
import { useConfirmationContext } from "@aglyn/shared-ui-jsx";
|
|
21
21
|
import { useCallback, useEffect, useRef, useState } from "react";
|
|
22
22
|
import * as CommerceModel from "../../../model/index.js";
|
|
23
|
-
import { centsFromInput, newAttemptKey, posGiftCardBalance, posNativeBridge, posTender, PosRequestError, usd } from "./pos-api.js";
|
|
23
|
+
import { centsFromInput, newAttemptKey, posCreditLookup, posGiftCardBalance, posNativeBridge, posTender, PosRequestError, usd } from "./pos-api.js";
|
|
24
24
|
import { POS_TOUCH_PX } from "./pos-product-grid.component.js";
|
|
25
|
-
import { PosCashDialog, PosFolioDialog, PosGiftCardDialog, PosKeyedCardDialog, PosQrDialog } from "./pos-tender-dialogs.component.js";
|
|
25
|
+
import { PosCashDialog, PosCreditDialog, PosFolioDialog, PosGiftCardDialog, PosKeyedCardDialog, PosQrDialog } from "./pos-tender-dialogs.component.js";
|
|
26
26
|
const STATUS_LABEL = {
|
|
27
27
|
pending: 'Waiting',
|
|
28
28
|
succeeded: 'Approved',
|
|
@@ -43,7 +43,7 @@ const STATUS_COLOR = {
|
|
|
43
43
|
* payments as it needs; it is paid when the balance reaches zero, and only
|
|
44
44
|
* then does the server take the stock and complete it.
|
|
45
45
|
*/ export function PosTenderPanel(props) {
|
|
46
|
-
var _ref, _ref1, _ref2, _ref3, _ref4, _ref5, _ref6;
|
|
46
|
+
var _ref, _ref1, _ref2, _ref3, _ref4, _ref5, _ref6, _ref7, _ref8;
|
|
47
47
|
var _context_terminal, _context_terminal1;
|
|
48
48
|
const { user, hostId, sale, context, display, onSale, notify } = props;
|
|
49
49
|
const settings = context == null ? void 0 : context.settings;
|
|
@@ -51,6 +51,8 @@ const STATUS_COLOR = {
|
|
|
51
51
|
const [tipCents, setTipCents] = useState(0);
|
|
52
52
|
const [busy, setBusy] = useState(false);
|
|
53
53
|
const [dialog, setDialog] = useState(null);
|
|
54
|
+
// The store-credit provider whose dialog is open (AGL-3640).
|
|
55
|
+
const [creditProvider, setCreditProvider] = useState(null);
|
|
54
56
|
const [qr, setQr] = useState(null);
|
|
55
57
|
const [keyed, setKeyed] = useState(null);
|
|
56
58
|
const [readerId, setReaderId] = useState('');
|
|
@@ -80,6 +82,7 @@ const STATUS_COLOR = {
|
|
|
80
82
|
const typedCents = centsFromInput(amount);
|
|
81
83
|
const chargeCents = typedCents > 0 ? Math.min(typedCents, sale.tenderableCents) : sale.tenderableCents;
|
|
82
84
|
const paid = sale.status === 'paid';
|
|
85
|
+
const offline = props.offline === true;
|
|
83
86
|
const run = useCallback(async (action, body = {}, starts = false)=>{
|
|
84
87
|
if (inFlight.current) return null;
|
|
85
88
|
inFlight.current = true;
|
|
@@ -368,6 +371,16 @@ const STATUS_COLOR = {
|
|
|
368
371
|
}, payment.id);
|
|
369
372
|
})
|
|
370
373
|
}) : null,
|
|
374
|
+
offline && !paid ? /*#__PURE__*/ _jsx(Alert, {
|
|
375
|
+
severity: "warning",
|
|
376
|
+
action: props.onSellOffline && sale.payments.length === 0 ? /*#__PURE__*/ _jsx(Button, {
|
|
377
|
+
color: "inherit",
|
|
378
|
+
size: "small",
|
|
379
|
+
onClick: props.onSellOffline,
|
|
380
|
+
children: 'Sell for cash offline'
|
|
381
|
+
}) : null,
|
|
382
|
+
children: sale.payments.length === 0 ? 'Offline: card readers, typed cards, the QR link, gift cards, store credit and room charges are off. ' + 'Take this basket as an offline cash sale, or wait for the connection.' : 'Offline: this sale has a payment on it and finishes when the connection returns. ' + 'Card readers, typed cards, the QR link, gift cards, store credit and room charges are off.'
|
|
383
|
+
}) : null,
|
|
371
384
|
!paid ? /*#__PURE__*/ _jsxs(_Fragment, {
|
|
372
385
|
children: [
|
|
373
386
|
/*#__PURE__*/ _jsx(Divider, {}),
|
|
@@ -412,7 +425,7 @@ const STATUS_COLOR = {
|
|
|
412
425
|
display.connected ? /*#__PURE__*/ _jsx(Button, {
|
|
413
426
|
variant: "outlined",
|
|
414
427
|
onClick: ()=>void askTip(),
|
|
415
|
-
disabled: busy || Boolean(display.asking),
|
|
428
|
+
disabled: offline || busy || Boolean(display.asking),
|
|
416
429
|
sx: {
|
|
417
430
|
minHeight: POS_TOUCH_PX
|
|
418
431
|
},
|
|
@@ -444,7 +457,7 @@ const STATUS_COLOR = {
|
|
|
444
457
|
children: [
|
|
445
458
|
/*#__PURE__*/ _jsx(Button, {
|
|
446
459
|
variant: "contained",
|
|
447
|
-
disabled: busy || chargeCents <= 0,
|
|
460
|
+
disabled: offline || busy || chargeCents <= 0,
|
|
448
461
|
onClick: ()=>setDialog('cash'),
|
|
449
462
|
sx: {
|
|
450
463
|
minHeight: 56
|
|
@@ -453,7 +466,7 @@ const STATUS_COLOR = {
|
|
|
453
466
|
}),
|
|
454
467
|
(context == null ? void 0 : (_context_terminal = context.terminal) == null ? void 0 : _context_terminal.available) && readers.length ? /*#__PURE__*/ _jsx(Button, {
|
|
455
468
|
variant: "contained",
|
|
456
|
-
disabled: busy || chargeCents <= 0 || !readerId,
|
|
469
|
+
disabled: offline || busy || chargeCents <= 0 || !readerId,
|
|
457
470
|
onClick: ()=>void startCardPresent(),
|
|
458
471
|
sx: {
|
|
459
472
|
minHeight: 56
|
|
@@ -462,7 +475,7 @@ const STATUS_COLOR = {
|
|
|
462
475
|
}) : null,
|
|
463
476
|
posNativeBridge() ? /*#__PURE__*/ _jsx(Button, {
|
|
464
477
|
variant: "contained",
|
|
465
|
-
disabled: busy || chargeCents <= 0,
|
|
478
|
+
disabled: offline || busy || chargeCents <= 0,
|
|
466
479
|
onClick: ()=>void startBridge(),
|
|
467
480
|
sx: {
|
|
468
481
|
minHeight: 56
|
|
@@ -471,7 +484,7 @@ const STATUS_COLOR = {
|
|
|
471
484
|
}) : null,
|
|
472
485
|
(context == null ? void 0 : context.publishableKey) ? /*#__PURE__*/ _jsx(Button, {
|
|
473
486
|
variant: "outlined",
|
|
474
|
-
disabled: busy || chargeCents <= 0,
|
|
487
|
+
disabled: offline || busy || chargeCents <= 0,
|
|
475
488
|
onClick: ()=>void startKeyed(),
|
|
476
489
|
sx: {
|
|
477
490
|
minHeight: 56
|
|
@@ -480,7 +493,7 @@ const STATUS_COLOR = {
|
|
|
480
493
|
}) : null,
|
|
481
494
|
/*#__PURE__*/ _jsx(Button, {
|
|
482
495
|
variant: "outlined",
|
|
483
|
-
disabled: busy || chargeCents <= 0,
|
|
496
|
+
disabled: offline || busy || chargeCents <= 0,
|
|
484
497
|
onClick: ()=>void startLink(),
|
|
485
498
|
sx: {
|
|
486
499
|
minHeight: 56
|
|
@@ -489,16 +502,28 @@ const STATUS_COLOR = {
|
|
|
489
502
|
}),
|
|
490
503
|
/*#__PURE__*/ _jsx(Button, {
|
|
491
504
|
variant: "outlined",
|
|
492
|
-
disabled: busy || chargeCents <= 0,
|
|
505
|
+
disabled: offline || busy || chargeCents <= 0,
|
|
493
506
|
onClick: ()=>setDialog('gift'),
|
|
494
507
|
sx: {
|
|
495
508
|
minHeight: 56
|
|
496
509
|
},
|
|
497
510
|
children: 'Gift card'
|
|
498
511
|
}),
|
|
512
|
+
((_ref2 = context == null ? void 0 : context.credits) != null ? _ref2 : []).map((credit)=>/*#__PURE__*/ _jsx(Button, {
|
|
513
|
+
variant: "outlined",
|
|
514
|
+
disabled: offline || busy || chargeCents <= 0,
|
|
515
|
+
onClick: ()=>{
|
|
516
|
+
setCreditProvider(credit);
|
|
517
|
+
setDialog('credit');
|
|
518
|
+
},
|
|
519
|
+
sx: {
|
|
520
|
+
minHeight: 56
|
|
521
|
+
},
|
|
522
|
+
children: credit.label
|
|
523
|
+
}, credit.providerId)),
|
|
499
524
|
props.stays.length ? /*#__PURE__*/ _jsx(Button, {
|
|
500
525
|
variant: "outlined",
|
|
501
|
-
disabled: busy || chargeCents <= 0,
|
|
526
|
+
disabled: offline || busy || chargeCents <= 0,
|
|
502
527
|
onClick: ()=>setDialog('folio'),
|
|
503
528
|
sx: {
|
|
504
529
|
minHeight: 56
|
|
@@ -524,11 +549,11 @@ const STATUS_COLOR = {
|
|
|
524
549
|
}) : null,
|
|
525
550
|
/*#__PURE__*/ _jsx(Button, {
|
|
526
551
|
color: "error",
|
|
527
|
-
disabled: busy,
|
|
552
|
+
disabled: offline || busy,
|
|
528
553
|
onClick: async ()=>{
|
|
529
554
|
const confirmed = await confirm({
|
|
530
555
|
title: 'Void this sale?',
|
|
531
|
-
description: 'Every payment taken on it is handed back: cards are refunded, gift ' + 'cards re-credited and room charges removed. Hand back any cash.',
|
|
556
|
+
description: 'Every payment taken on it is handed back: cards are refunded, gift ' + 'cards and store credit re-credited and room charges removed. Hand back any cash.',
|
|
532
557
|
confirmationText: 'Void sale',
|
|
533
558
|
confirmationButtonProps: {
|
|
534
559
|
color: 'error'
|
|
@@ -592,6 +617,40 @@ const STATUS_COLOR = {
|
|
|
592
617
|
if (result) setDialog(null);
|
|
593
618
|
}
|
|
594
619
|
}),
|
|
620
|
+
/*#__PURE__*/ _jsx(PosCreditDialog, {
|
|
621
|
+
open: dialog === 'credit' && Boolean(creditProvider),
|
|
622
|
+
label: (_ref3 = creditProvider == null ? void 0 : creditProvider.label) != null ? _ref3 : 'Store credit',
|
|
623
|
+
canLookup: Boolean(creditProvider == null ? void 0 : creditProvider.lookup),
|
|
624
|
+
busy: busy,
|
|
625
|
+
onClose: ()=>setDialog(null),
|
|
626
|
+
onLookup: async (query)=>{
|
|
627
|
+
if (!creditProvider) return null;
|
|
628
|
+
try {
|
|
629
|
+
return (await posCreditLookup(user, hostId, creditProvider.providerId, query)).accounts;
|
|
630
|
+
} catch (error) {
|
|
631
|
+
notify(error instanceof PosRequestError ? error.message : 'Could not look that up', 'warning');
|
|
632
|
+
return null;
|
|
633
|
+
}
|
|
634
|
+
},
|
|
635
|
+
onApplyCode: async (code)=>{
|
|
636
|
+
const result = await run('credit', _extends({
|
|
637
|
+
code
|
|
638
|
+
}, typedCents > 0 ? {
|
|
639
|
+
amountCents: chargeCents
|
|
640
|
+
} : {}), true);
|
|
641
|
+
if (result) setDialog(null);
|
|
642
|
+
},
|
|
643
|
+
onApplyAccount: async (account)=>{
|
|
644
|
+
if (!creditProvider) return;
|
|
645
|
+
const result = await run('credit', _extends({
|
|
646
|
+
providerId: creditProvider.providerId,
|
|
647
|
+
reference: account.reference
|
|
648
|
+
}, typedCents > 0 ? {
|
|
649
|
+
amountCents: chargeCents
|
|
650
|
+
} : {}), true);
|
|
651
|
+
if (result) setDialog(null);
|
|
652
|
+
}
|
|
653
|
+
}),
|
|
595
654
|
/*#__PURE__*/ _jsx(PosFolioDialog, {
|
|
596
655
|
open: dialog === 'folio',
|
|
597
656
|
amountCents: chargeCents,
|
|
@@ -608,14 +667,14 @@ const STATUS_COLOR = {
|
|
|
608
667
|
}
|
|
609
668
|
}),
|
|
610
669
|
/*#__PURE__*/ _jsx(PosQrDialog, {
|
|
611
|
-
url: (
|
|
612
|
-
amountCents: (
|
|
670
|
+
url: (_ref4 = qr == null ? void 0 : qr.url) != null ? _ref4 : '',
|
|
671
|
+
amountCents: (_ref5 = qr == null ? void 0 : qr.amountCents) != null ? _ref5 : 0,
|
|
613
672
|
onClose: ()=>setQr(null)
|
|
614
673
|
}),
|
|
615
674
|
/*#__PURE__*/ _jsx(PosKeyedCardDialog, {
|
|
616
|
-
clientSecret: (
|
|
617
|
-
publishableKey: (
|
|
618
|
-
amountCents: (
|
|
675
|
+
clientSecret: (_ref6 = keyed == null ? void 0 : keyed.clientSecret) != null ? _ref6 : '',
|
|
676
|
+
publishableKey: (_ref7 = context == null ? void 0 : context.publishableKey) != null ? _ref7 : '',
|
|
677
|
+
amountCents: (_ref8 = keyed == null ? void 0 : keyed.amountCents) != null ? _ref8 : 0,
|
|
619
678
|
onClose: async ()=>{
|
|
620
679
|
const open = keyed;
|
|
621
680
|
setKeyed(null);
|