@aglyn/plugins-commerce 1.0.0-beta.278 → 1.0.0-beta.283
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 +17 -14
- package/src/lib/components/commerce-console-page.js +33 -1
- package/src/lib/components/commerce-console-page.js.map +1 -1
- package/src/lib/components/console/payments-settings-card.component.js +1 -1
- package/src/lib/components/console/payments-settings-card.component.js.map +1 -1
- package/src/lib/components/console/pos/pos-hardware-api.d.ts +122 -0
- package/src/lib/components/console/pos/pos-hardware-api.js +90 -0
- package/src/lib/components/console/pos/pos-hardware-api.js.map +1 -0
- package/src/lib/components/console/pos/pos-reader-splash-api.d.ts +58 -0
- package/src/lib/components/console/pos/pos-reader-splash-api.js +101 -0
- package/src/lib/components/console/pos/pos-reader-splash-api.js.map +1 -0
- package/src/lib/components/console/pos-devices-card.component.js +5 -0
- package/src/lib/components/console/pos-devices-card.component.js.map +1 -1
- package/src/lib/components/console/pos-hardware-card.component.d.ts +26 -0
- package/src/lib/components/console/pos-hardware-card.component.js +456 -0
- package/src/lib/components/console/pos-hardware-card.component.js.map +1 -0
- package/src/lib/components/console/pos-hardware-orders-staff-page.component.d.ts +14 -0
- package/src/lib/components/console/pos-hardware-orders-staff-page.component.js +519 -0
- package/src/lib/components/console/pos-hardware-orders-staff-page.component.js.map +1 -0
- package/src/lib/components/console/pos-ops/pos-check-in-dialog.component.d.ts +27 -0
- package/src/lib/components/console/pos-ops/pos-check-in-dialog.component.js +444 -0
- package/src/lib/components/console/pos-ops/pos-check-in-dialog.component.js.map +1 -0
- package/src/lib/components/console/pos-ops/pos-check-in-zone.component.d.ts +9 -0
- package/src/lib/components/console/pos-ops/pos-check-in-zone.component.js +37 -0
- package/src/lib/components/console/pos-ops/pos-check-in-zone.component.js.map +1 -0
- package/src/lib/components/console/pos-ops/pos-check-ins-card.component.d.ts +24 -0
- package/src/lib/components/console/pos-ops/pos-check-ins-card.component.js +346 -0
- package/src/lib/components/console/pos-ops/pos-check-ins-card.component.js.map +1 -0
- package/src/lib/components/console/pos-ops/pos-customer-lookup.component.d.ts +5 -1
- package/src/lib/components/console/pos-ops/pos-customer-lookup.component.js +83 -4
- package/src/lib/components/console/pos-ops/pos-customer-lookup.component.js.map +1 -1
- package/src/lib/components/console/pos-ops/pos-day-totals-card.component.d.ts +35 -0
- package/src/lib/components/console/pos-ops/pos-day-totals-card.component.js +546 -0
- package/src/lib/components/console/pos-ops/pos-day-totals-card.component.js.map +1 -0
- package/src/lib/components/console/pos-ops/pos-operations-bar.component.d.ts +2 -1
- package/src/lib/components/console/pos-ops/pos-operations-bar.component.js +20 -1
- package/src/lib/components/console/pos-ops/pos-operations-bar.component.js.map +1 -1
- package/src/lib/components/console/pos-ops/pos-ops-api.d.ts +1 -1
- package/src/lib/components/console/pos-ops/pos-ops-api.js.map +1 -1
- package/src/lib/components/console/pos-page.component.js +6 -3
- package/src/lib/components/console/pos-page.component.js.map +1 -1
- package/src/lib/components/console/pos-reader-splash-setting.component.d.ts +22 -0
- package/src/lib/components/console/pos-reader-splash-setting.component.js +275 -0
- package/src/lib/components/console/pos-reader-splash-setting.component.js.map +1 -0
- package/src/lib/components/console/pos-reader-splash-staff-page.component.d.ts +14 -0
- package/src/lib/components/console/pos-reader-splash-staff-page.component.js +301 -0
- package/src/lib/components/console/pos-reader-splash-staff-page.component.js.map +1 -0
- package/src/lib/components/console/pos-zones.d.ts +37 -3
- package/src/lib/components/console/pos-zones.js +11 -1
- package/src/lib/components/console/pos-zones.js.map +1 -1
- package/src/lib/components/console/product-check-in-fields.component.d.ts +20 -0
- package/src/lib/components/console/product-check-in-fields.component.js +172 -0
- package/src/lib/components/console/product-check-in-fields.component.js.map +1 -0
- package/src/lib/components/console/product-editor-dialog.component.js +48 -9
- package/src/lib/components/console/product-editor-dialog.component.js.map +1 -1
- package/src/lib/components/console/product-register-fields.component.d.ts +12 -0
- package/src/lib/components/console/product-register-fields.component.js +39 -1
- package/src/lib/components/console/product-register-fields.component.js.map +1 -1
- package/src/lib/components/console/products-hub-card.component.js +21 -6
- package/src/lib/components/console/products-hub-card.component.js.map +1 -1
- package/src/lib/components/console/reservations-card.component.js +239 -70
- package/src/lib/components/console/reservations-card.component.js.map +1 -1
- package/src/lib/components/reservation-widget.js +16 -0
- package/src/lib/components/reservation-widget.js.map +1 -1
- package/src/lib/constants/operator-alerts.d.ts +6 -0
- package/src/lib/constants/operator-alerts.js +20 -1
- package/src/lib/constants/operator-alerts.js.map +1 -1
- package/src/lib/declarations.console-server.js +7 -0
- package/src/lib/declarations.console-server.js.map +1 -1
- package/src/lib/declarations.d.ts +26 -0
- package/src/lib/declarations.js +34 -0
- package/src/lib/declarations.js.map +1 -0
- package/src/lib/model/commerce-check-in-product.d.ts +37 -0
- package/src/lib/model/commerce-check-in-product.js +49 -0
- package/src/lib/model/commerce-check-in-product.js.map +1 -0
- package/src/lib/model/commerce-check-in.d.ts +187 -0
- package/src/lib/model/commerce-check-in.js +468 -0
- package/src/lib/model/commerce-check-in.js.map +1 -0
- package/src/lib/model/commerce-pos-day-report.d.ts +209 -0
- package/src/lib/model/commerce-pos-day-report.js +572 -0
- package/src/lib/model/commerce-pos-day-report.js.map +1 -0
- package/src/lib/model/commerce-pos-offline.d.ts +65 -3
- package/src/lib/model/commerce-pos-offline.js +104 -7
- package/src/lib/model/commerce-pos-offline.js.map +1 -1
- package/src/lib/model/commerce-pos-ops.d.ts +3 -0
- package/src/lib/model/commerce-pos-ops.js +1 -0
- package/src/lib/model/commerce-pos-ops.js.map +1 -1
- package/src/lib/model/commerce-pos.d.ts +43 -3
- package/src/lib/model/commerce-pos.js +73 -5
- package/src/lib/model/commerce-pos.js.map +1 -1
- package/src/lib/model/commerce-reservations.d.ts +73 -7
- package/src/lib/model/commerce-reservations.js +90 -10
- package/src/lib/model/commerce-reservations.js.map +1 -1
- package/src/lib/model/commerce.d.ts +40 -0
- package/src/lib/model/commerce.js +22 -4
- package/src/lib/model/commerce.js.map +1 -1
- package/src/lib/model/index.d.ts +1 -0
- package/src/lib/model/index.js +1 -0
- package/src/lib/model/index.js.map +1 -1
- package/src/lib/model/plugin-permissions.d.ts +1 -1
- package/src/lib/model/plugin-permissions.js +2 -1
- package/src/lib/model/plugin-permissions.js.map +1 -1
- package/src/lib/model/pos-hardware.d.ts +288 -0
- package/src/lib/model/pos-hardware.js +499 -0
- package/src/lib/model/pos-hardware.js.map +1 -0
- package/src/lib/model/pos-offline-card-limits.d.ts +20 -0
- package/src/lib/model/pos-offline-card-limits.js +28 -0
- package/src/lib/model/pos-offline-card-limits.js.map +1 -0
- package/src/lib/model/pos-reader-splash.d.ts +114 -0
- package/src/lib/model/pos-reader-splash.js +141 -0
- package/src/lib/model/pos-reader-splash.js.map +1 -0
- package/src/lib/model/product-write.d.ts +6 -0
- package/src/lib/plugin-config.d.ts +10 -0
- package/src/lib/plugin-config.js +40 -0
- package/src/lib/plugin-config.js.map +1 -1
- package/src/lib/plugin.js +28 -0
- package/src/lib/plugin.js.map +1 -1
- package/src/lib/server/cart-checkout.js +3 -1
- package/src/lib/server/cart-checkout.js.map +1 -1
- package/src/lib/server/cart.js +12 -1
- package/src/lib/server/cart.js.map +1 -1
- package/src/lib/server/catalog.js +49 -12
- package/src/lib/server/catalog.js.map +1 -1
- package/src/lib/server/checkout-extras.js +1 -1
- package/src/lib/server/checkout-extras.js.map +1 -1
- package/src/lib/server/checkout.js +7 -0
- package/src/lib/server/checkout.js.map +1 -1
- package/src/lib/server/person-eraser.d.ts +8 -1
- package/src/lib/server/person-eraser.js +23 -1
- package/src/lib/server/person-eraser.js.map +1 -1
- package/src/lib/server/pos-check-in.d.ts +49 -0
- package/src/lib/server/pos-check-in.js +652 -0
- package/src/lib/server/pos-check-in.js.map +1 -0
- package/src/lib/server/pos-day-report.d.ts +46 -0
- package/src/lib/server/pos-day-report.js +299 -0
- package/src/lib/server/pos-day-report.js.map +1 -0
- package/src/lib/server/pos-hardware-admin.d.ts +50 -0
- package/src/lib/server/pos-hardware-admin.js +366 -0
- package/src/lib/server/pos-hardware-admin.js.map +1 -0
- package/src/lib/server/pos-hardware-notify.d.ts +27 -0
- package/src/lib/server/pos-hardware-notify.js +142 -0
- package/src/lib/server/pos-hardware-notify.js.map +1 -0
- package/src/lib/server/pos-hardware-user-eraser.d.ts +26 -0
- package/src/lib/server/pos-hardware-user-eraser.js +67 -0
- package/src/lib/server/pos-hardware-user-eraser.js.map +1 -0
- package/src/lib/server/pos-hardware-webhook.d.ts +31 -0
- package/src/lib/server/pos-hardware-webhook.js +176 -0
- package/src/lib/server/pos-hardware-webhook.js.map +1 -0
- package/src/lib/server/pos-hardware.d.ts +58 -0
- package/src/lib/server/pos-hardware.js +234 -0
- package/src/lib/server/pos-hardware.js.map +1 -0
- package/src/lib/server/pos-offline-card-reconcile.d.ts +38 -0
- package/src/lib/server/pos-offline-card-reconcile.js +58 -0
- package/src/lib/server/pos-offline-card-reconcile.js.map +1 -0
- package/src/lib/server/pos-offline-sync.d.ts +32 -0
- package/src/lib/server/pos-offline-sync.js +191 -15
- package/src/lib/server/pos-offline-sync.js.map +1 -1
- package/src/lib/server/pos-ops-routes.d.ts +4 -2
- package/src/lib/server/pos-ops-routes.js +14 -2
- package/src/lib/server/pos-ops-routes.js.map +1 -1
- package/src/lib/server/pos-order.js +39 -51
- package/src/lib/server/pos-order.js.map +1 -1
- package/src/lib/server/pos-payment.js +8 -4
- package/src/lib/server/pos-payment.js.map +1 -1
- package/src/lib/server/pos-reader-splash-admin.d.ts +36 -0
- package/src/lib/server/pos-reader-splash-admin.js +295 -0
- package/src/lib/server/pos-reader-splash-admin.js.map +1 -0
- package/src/lib/server/pos-reader-splash-render.d.ts +40 -0
- package/src/lib/server/pos-reader-splash-render.js +138 -0
- package/src/lib/server/pos-reader-splash-render.js.map +1 -0
- package/src/lib/server/pos-reader-splash-server.d.ts +32 -0
- package/src/lib/server/pos-reader-splash-server.js +32 -0
- package/src/lib/server/pos-reader-splash-server.js.map +1 -0
- package/src/lib/server/pos-reader-splash.d.ts +105 -0
- package/src/lib/server/pos-reader-splash.js +548 -0
- package/src/lib/server/pos-reader-splash.js.map +1 -0
- package/src/lib/server/pos-sale.d.ts +2 -1
- package/src/lib/server/pos-sale.js +3 -1
- package/src/lib/server/pos-sale.js.map +1 -1
- package/src/lib/server/pos-terminal.d.ts +67 -4
- package/src/lib/server/pos-terminal.js +239 -32
- package/src/lib/server/pos-terminal.js.map +1 -1
- package/src/lib/server/process-restock.js +4 -0
- package/src/lib/server/process-restock.js.map +1 -1
- package/src/lib/server/product-card.js +2 -2
- package/src/lib/server/product-card.js.map +1 -1
- package/src/lib/server/product-catalog.d.ts +2 -0
- package/src/lib/server/product-catalog.js +11 -4
- package/src/lib/server/product-catalog.js.map +1 -1
- package/src/lib/server/product.js +3 -1
- package/src/lib/server/product.js.map +1 -1
- package/src/lib/server/related.js +8 -1
- package/src/lib/server/related.js.map +1 -1
- package/src/lib/server/reservation-availability-query.d.ts +35 -0
- package/src/lib/server/reservation-availability-query.js +34 -0
- package/src/lib/server/reservation-availability-query.js.map +1 -0
- package/src/lib/server/reservation-availability.d.ts +21 -0
- package/src/lib/server/reservation-availability.js +64 -10
- package/src/lib/server/reservation-availability.js.map +1 -1
- package/src/lib/server/reservation-walk-in.d.ts +28 -0
- package/src/lib/server/reservation-walk-in.js +166 -0
- package/src/lib/server/reservation-walk-in.js.map +1 -0
- package/src/lib/server/reserve.js +13 -10
- package/src/lib/server/reserve.js.map +1 -1
- package/src/lib/server/reviews.js +3 -1
- package/src/lib/server/reviews.js.map +1 -1
- package/src/lib/server/site-page-resolver.js +5 -2
- package/src/lib/server/site-page-resolver.js.map +1 -1
- package/src/lib/server.js +26 -0
- package/src/lib/server.js.map +1 -1
- package/src/lib/testing/fake-firestore.js +72 -0
- package/src/lib/testing/fake-firestore.js.map +1 -1
|
@@ -0,0 +1,456 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Aglyn LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/ 'use client';
|
|
17
|
+
import { _ as _extends } from "@swc/helpers/_/_extends";
|
|
18
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
19
|
+
import { pluginDocsHelp } from "@aglyn/aglyn";
|
|
20
|
+
import { CardDisplay } from "@aglyn/shared-ui-jsx";
|
|
21
|
+
import { ListTable } from "@aglyn/shared-ui-jsx/components/list-table.component";
|
|
22
|
+
import { useSnackbar } from "@aglyn/shared-ui-snackstack";
|
|
23
|
+
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 { useCallback, useEffect, useMemo, useState } from "react";
|
|
26
|
+
import { formatPosHardwareCents, POS_HARDWARE_ANCHOR, POS_HARDWARE_MAX_PER_LINE, POS_HARDWARE_STATUS_LABELS } from "../../model/pos-hardware.js";
|
|
27
|
+
import { newAttemptKey } from "./pos/pos-api.js";
|
|
28
|
+
import { openPosHardwareCheckout, posHardwareCatalog, posHardwareCheckout, posHardwareOrders, PosHardwareRequestError } from "./pos/pos-hardware-api.js";
|
|
29
|
+
export const POS_HARDWARE_STATUS_COLOR = {
|
|
30
|
+
paid: 'info',
|
|
31
|
+
ordered: 'info',
|
|
32
|
+
shipped: 'primary',
|
|
33
|
+
delivered: 'success',
|
|
34
|
+
registered: 'success',
|
|
35
|
+
canceled: 'default',
|
|
36
|
+
refunded: 'default'
|
|
37
|
+
};
|
|
38
|
+
const QUANTITIES = Array.from({
|
|
39
|
+
length: POS_HARDWARE_MAX_PER_LINE + 1
|
|
40
|
+
}, (_, index)=>index);
|
|
41
|
+
const placedOn = (ms)=>ms ? new Date(ms).toLocaleDateString([], {
|
|
42
|
+
month: 'short',
|
|
43
|
+
day: 'numeric',
|
|
44
|
+
year: 'numeric'
|
|
45
|
+
}) : '—';
|
|
46
|
+
/**
|
|
47
|
+
* The Hardware card (AGL-4038): Stripe card readers and accessories sold by
|
|
48
|
+
* the platform and shipped by Stripe straight to the store, with the store's
|
|
49
|
+
* orders and their tracking underneath.
|
|
50
|
+
*
|
|
51
|
+
* HIDDEN, NOT DISABLED, while the deployment has not opened the shop: it is a
|
|
52
|
+
* gate only the platform can lift, so naming it would point at a step nobody
|
|
53
|
+
* on the workspace can take. The route answers `available: false` until
|
|
54
|
+
* every price, the markup and the shipping figures are configured.
|
|
55
|
+
*/ export function PosHardwareCard({ hostId, canManagePos = false }) {
|
|
56
|
+
var _ref, _ref1;
|
|
57
|
+
const { data: user } = useUser();
|
|
58
|
+
const { enqueueSnackbar } = useSnackbar();
|
|
59
|
+
const [catalog, setCatalog] = useState(null);
|
|
60
|
+
const [orders, setOrders] = useState(null);
|
|
61
|
+
const [quantities, setQuantities] = useState({});
|
|
62
|
+
const [shippingMethod, setShippingMethod] = useState('');
|
|
63
|
+
const [busy, setBusy] = useState(false);
|
|
64
|
+
const [returned, setReturned] = useState(null);
|
|
65
|
+
const uid = (_ref = user == null ? void 0 : user.uid) != null ? _ref : '';
|
|
66
|
+
useEffect(()=>{
|
|
67
|
+
if (!user || !canManagePos) return;
|
|
68
|
+
let active = true;
|
|
69
|
+
void posHardwareCatalog(user, hostId).then((answer)=>{
|
|
70
|
+
if (active) setCatalog(answer);
|
|
71
|
+
}).catch(()=>{
|
|
72
|
+
if (active) setCatalog({
|
|
73
|
+
available: false
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
return ()=>{
|
|
77
|
+
active = false;
|
|
78
|
+
};
|
|
79
|
+
// Keyed on the person, not the session object.
|
|
80
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
81
|
+
}, [
|
|
82
|
+
uid,
|
|
83
|
+
hostId,
|
|
84
|
+
canManagePos
|
|
85
|
+
]);
|
|
86
|
+
const available = (catalog == null ? void 0 : catalog.available) === true;
|
|
87
|
+
const loadOrders = useCallback(async ()=>{
|
|
88
|
+
if (!user) return;
|
|
89
|
+
try {
|
|
90
|
+
setOrders((await posHardwareOrders(user, hostId)).orders);
|
|
91
|
+
} catch (unused) {
|
|
92
|
+
setOrders([]);
|
|
93
|
+
}
|
|
94
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
95
|
+
}, [
|
|
96
|
+
uid,
|
|
97
|
+
hostId
|
|
98
|
+
]);
|
|
99
|
+
useEffect(()=>{
|
|
100
|
+
if (available) void loadOrders();
|
|
101
|
+
}, [
|
|
102
|
+
available,
|
|
103
|
+
loadOrders
|
|
104
|
+
]);
|
|
105
|
+
// The first shipping speed is the default once the catalog answers.
|
|
106
|
+
useEffect(()=>{
|
|
107
|
+
if ((catalog == null ? void 0 : catalog.available) && !shippingMethod && catalog.shipping.length) {
|
|
108
|
+
setShippingMethod(catalog.shipping[0].method);
|
|
109
|
+
}
|
|
110
|
+
}, [
|
|
111
|
+
catalog,
|
|
112
|
+
shippingMethod
|
|
113
|
+
]);
|
|
114
|
+
// Back from Checkout: say what happened, then drop the marker from the URL.
|
|
115
|
+
useEffect(()=>{
|
|
116
|
+
if (typeof window === 'undefined') return;
|
|
117
|
+
const url = new URL(window.location.href);
|
|
118
|
+
const outcome = url.searchParams.get('hardwareOrder');
|
|
119
|
+
if (outcome === 'placed' || outcome === 'canceled') {
|
|
120
|
+
setReturned(outcome);
|
|
121
|
+
url.searchParams.delete('hardwareOrder');
|
|
122
|
+
window.history.replaceState(window.history.state, '', url.toString());
|
|
123
|
+
}
|
|
124
|
+
}, []);
|
|
125
|
+
// Arrived by an email's link or Checkout's return: bring the card into view.
|
|
126
|
+
useEffect(()=>{
|
|
127
|
+
var _document_getElementById_scrollIntoView, _document_getElementById;
|
|
128
|
+
if (!available || typeof window === 'undefined') return;
|
|
129
|
+
if (window.location.hash !== `#${POS_HARDWARE_ANCHOR}`) return;
|
|
130
|
+
(_document_getElementById = document.getElementById(POS_HARDWARE_ANCHOR)) == null ? void 0 : (_document_getElementById_scrollIntoView = _document_getElementById.scrollIntoView) == null ? void 0 : _document_getElementById_scrollIntoView.call(_document_getElementById, {
|
|
131
|
+
block: 'start'
|
|
132
|
+
});
|
|
133
|
+
}, [
|
|
134
|
+
available
|
|
135
|
+
]);
|
|
136
|
+
const lines = useMemo(()=>Object.entries(quantities).filter(([, quantity])=>quantity > 0).map(([sku, quantity])=>({
|
|
137
|
+
sku,
|
|
138
|
+
quantity
|
|
139
|
+
})), [
|
|
140
|
+
quantities
|
|
141
|
+
]);
|
|
142
|
+
const shipping = (catalog == null ? void 0 : catalog.available) ? catalog.shipping.find((option)=>option.method === shippingMethod) : undefined;
|
|
143
|
+
const subtotalCents = (catalog == null ? void 0 : catalog.available) ? lines.reduce((sum, line)=>{
|
|
144
|
+
var _ref;
|
|
145
|
+
var _catalog_offers_find;
|
|
146
|
+
return sum + ((_ref = (_catalog_offers_find = catalog.offers.find((offer)=>offer.sku === line.sku)) == null ? void 0 : _catalog_offers_find.unitCents) != null ? _ref : 0) * line.quantity;
|
|
147
|
+
}, 0) : 0;
|
|
148
|
+
// One attempt per basket: a second press of the same basket reaches the
|
|
149
|
+
// same Checkout Session, and a changed basket is a new one.
|
|
150
|
+
const basketKey = JSON.stringify([
|
|
151
|
+
lines,
|
|
152
|
+
shippingMethod
|
|
153
|
+
]);
|
|
154
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
155
|
+
const attemptKey = useMemo(()=>newAttemptKey(), [
|
|
156
|
+
basketKey
|
|
157
|
+
]);
|
|
158
|
+
const checkout = async ()=>{
|
|
159
|
+
if (!user || !shippingMethod || !lines.length) return;
|
|
160
|
+
setBusy(true);
|
|
161
|
+
try {
|
|
162
|
+
const { url } = await posHardwareCheckout(user, attemptKey, {
|
|
163
|
+
hostId,
|
|
164
|
+
lines,
|
|
165
|
+
shippingMethod
|
|
166
|
+
});
|
|
167
|
+
openPosHardwareCheckout(url);
|
|
168
|
+
} catch (error) {
|
|
169
|
+
enqueueSnackbar(error instanceof PosHardwareRequestError ? error.message : 'Checkout could not be started', {
|
|
170
|
+
variant: 'warning',
|
|
171
|
+
persist: false
|
|
172
|
+
});
|
|
173
|
+
setBusy(false);
|
|
174
|
+
}
|
|
175
|
+
};
|
|
176
|
+
const columns = useMemo(()=>[
|
|
177
|
+
{
|
|
178
|
+
field: 'number',
|
|
179
|
+
headerName: 'Order',
|
|
180
|
+
minWidth: 110
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
field: 'createdAtMs',
|
|
184
|
+
headerName: 'Placed',
|
|
185
|
+
type: 'number',
|
|
186
|
+
minWidth: 120,
|
|
187
|
+
align: 'left',
|
|
188
|
+
headerAlign: 'left',
|
|
189
|
+
valueFormatter: (value)=>placedOn(value)
|
|
190
|
+
},
|
|
191
|
+
{
|
|
192
|
+
field: 'items',
|
|
193
|
+
headerName: 'Items',
|
|
194
|
+
flex: 1,
|
|
195
|
+
minWidth: 200,
|
|
196
|
+
valueGetter: (_value, row)=>row.lines.map((line)=>`${line.name} × ${line.quantity}`).join(', ')
|
|
197
|
+
},
|
|
198
|
+
{
|
|
199
|
+
field: 'totalCents',
|
|
200
|
+
headerName: 'Total',
|
|
201
|
+
type: 'number',
|
|
202
|
+
minWidth: 100,
|
|
203
|
+
valueFormatter: (value)=>formatPosHardwareCents(value)
|
|
204
|
+
},
|
|
205
|
+
{
|
|
206
|
+
field: 'status',
|
|
207
|
+
headerName: 'Status',
|
|
208
|
+
minWidth: 130,
|
|
209
|
+
valueGetter: (_value, row)=>POS_HARDWARE_STATUS_LABELS[row.status],
|
|
210
|
+
renderCell: ({ row })=>/*#__PURE__*/ _jsx(Chip, {
|
|
211
|
+
size: "small",
|
|
212
|
+
color: POS_HARDWARE_STATUS_COLOR[row.status],
|
|
213
|
+
label: POS_HARDWARE_STATUS_LABELS[row.status]
|
|
214
|
+
})
|
|
215
|
+
},
|
|
216
|
+
{
|
|
217
|
+
field: 'tracking',
|
|
218
|
+
headerName: 'Tracking',
|
|
219
|
+
minWidth: 160,
|
|
220
|
+
valueGetter: (_value, row)=>{
|
|
221
|
+
var _ref;
|
|
222
|
+
var _row_tracking;
|
|
223
|
+
return (_ref = (_row_tracking = row.tracking) == null ? void 0 : _row_tracking.number) != null ? _ref : '';
|
|
224
|
+
},
|
|
225
|
+
renderCell: ({ row })=>{
|
|
226
|
+
var _ref;
|
|
227
|
+
var _row_tracking, _row_tracking1;
|
|
228
|
+
return ((_row_tracking = row.tracking) == null ? void 0 : _row_tracking.url) ? /*#__PURE__*/ _jsx(Link, {
|
|
229
|
+
href: row.tracking.url,
|
|
230
|
+
target: "_blank",
|
|
231
|
+
rel: "noopener noreferrer",
|
|
232
|
+
children: row.tracking.number
|
|
233
|
+
}) : (_ref = (_row_tracking1 = row.tracking) == null ? void 0 : _row_tracking1.number) != null ? _ref : '—';
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
], []);
|
|
237
|
+
if (!available || !(catalog == null ? void 0 : catalog.available)) return null;
|
|
238
|
+
return /*#__PURE__*/ _jsx(CardDisplay, {
|
|
239
|
+
id: POS_HARDWARE_ANCHOR,
|
|
240
|
+
header: 'Hardware',
|
|
241
|
+
subheader: 'Card readers from Stripe, shipped straight to you',
|
|
242
|
+
help: pluginDocsHelp('posHardware', {
|
|
243
|
+
anchor: '#buy-a-reader-from-aglyn'
|
|
244
|
+
}),
|
|
245
|
+
HeaderProps: {
|
|
246
|
+
action: /*#__PURE__*/ _jsx(Button, {
|
|
247
|
+
size: "small",
|
|
248
|
+
variant: "contained",
|
|
249
|
+
disabled: busy || !lines.length || !shipping,
|
|
250
|
+
onClick: ()=>void checkout(),
|
|
251
|
+
children: 'Check out'
|
|
252
|
+
})
|
|
253
|
+
},
|
|
254
|
+
contentGutterX: true,
|
|
255
|
+
contentGutterY: true,
|
|
256
|
+
children: /*#__PURE__*/ _jsxs(Stack, {
|
|
257
|
+
spacing: 3,
|
|
258
|
+
children: [
|
|
259
|
+
returned === 'placed' ? /*#__PURE__*/ _jsx(Alert, {
|
|
260
|
+
severity: "success",
|
|
261
|
+
onClose: ()=>setReturned(null),
|
|
262
|
+
children: 'Thanks, your order is in. It shows under Your orders within a minute, and we email you as it ships.'
|
|
263
|
+
}) : returned === 'canceled' ? /*#__PURE__*/ _jsx(Alert, {
|
|
264
|
+
severity: "info",
|
|
265
|
+
onClose: ()=>setReturned(null),
|
|
266
|
+
children: 'Checkout was canceled. Nothing was charged.'
|
|
267
|
+
}) : null,
|
|
268
|
+
/*#__PURE__*/ _jsx(Typography, {
|
|
269
|
+
variant: "body2",
|
|
270
|
+
color: "text.secondary",
|
|
271
|
+
children: '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.'
|
|
272
|
+
}),
|
|
273
|
+
/*#__PURE__*/ _jsx(Box, {
|
|
274
|
+
sx: {
|
|
275
|
+
display: 'grid',
|
|
276
|
+
gap: 2,
|
|
277
|
+
gridTemplateColumns: {
|
|
278
|
+
xs: '1fr',
|
|
279
|
+
sm: 'repeat(2, 1fr)',
|
|
280
|
+
md: 'repeat(3, 1fr)'
|
|
281
|
+
}
|
|
282
|
+
},
|
|
283
|
+
children: catalog.offers.map((offer)=>{
|
|
284
|
+
var _quantities_offer_sku;
|
|
285
|
+
return /*#__PURE__*/ _jsx(Card, {
|
|
286
|
+
variant: "outlined",
|
|
287
|
+
children: /*#__PURE__*/ _jsx(CardContent, {
|
|
288
|
+
children: /*#__PURE__*/ _jsxs(Stack, {
|
|
289
|
+
spacing: 1,
|
|
290
|
+
sx: {
|
|
291
|
+
height: '100%'
|
|
292
|
+
},
|
|
293
|
+
children: [
|
|
294
|
+
/*#__PURE__*/ _jsx(Typography, {
|
|
295
|
+
variant: "subtitle2",
|
|
296
|
+
children: offer.name
|
|
297
|
+
}),
|
|
298
|
+
/*#__PURE__*/ _jsx(Typography, {
|
|
299
|
+
variant: "body2",
|
|
300
|
+
color: "text.secondary",
|
|
301
|
+
sx: {
|
|
302
|
+
flex: 1
|
|
303
|
+
},
|
|
304
|
+
children: offer.use
|
|
305
|
+
}),
|
|
306
|
+
/*#__PURE__*/ _jsxs(Stack, {
|
|
307
|
+
direction: "row",
|
|
308
|
+
spacing: 1,
|
|
309
|
+
sx: {
|
|
310
|
+
alignItems: 'center',
|
|
311
|
+
justifyContent: 'space-between'
|
|
312
|
+
},
|
|
313
|
+
children: [
|
|
314
|
+
/*#__PURE__*/ _jsx(Typography, {
|
|
315
|
+
variant: "body1",
|
|
316
|
+
children: formatPosHardwareCents(offer.unitCents)
|
|
317
|
+
}),
|
|
318
|
+
/*#__PURE__*/ _jsx(TextField, {
|
|
319
|
+
select: true,
|
|
320
|
+
size: "small",
|
|
321
|
+
label: "Quantity",
|
|
322
|
+
value: (_quantities_offer_sku = quantities[offer.sku]) != null ? _quantities_offer_sku : 0,
|
|
323
|
+
onChange: (event)=>setQuantities((prev)=>_extends({}, prev, {
|
|
324
|
+
[offer.sku]: Number(event.target.value)
|
|
325
|
+
})),
|
|
326
|
+
slotProps: {
|
|
327
|
+
htmlInput: {
|
|
328
|
+
'aria-label': `Quantity of ${offer.name}`
|
|
329
|
+
}
|
|
330
|
+
},
|
|
331
|
+
children: QUANTITIES.map((quantity)=>/*#__PURE__*/ _jsx(MenuItem, {
|
|
332
|
+
value: quantity,
|
|
333
|
+
children: quantity
|
|
334
|
+
}, quantity))
|
|
335
|
+
})
|
|
336
|
+
]
|
|
337
|
+
})
|
|
338
|
+
]
|
|
339
|
+
})
|
|
340
|
+
})
|
|
341
|
+
}, offer.sku);
|
|
342
|
+
})
|
|
343
|
+
}),
|
|
344
|
+
/*#__PURE__*/ _jsxs(Stack, {
|
|
345
|
+
direction: {
|
|
346
|
+
xs: 'column',
|
|
347
|
+
sm: 'row'
|
|
348
|
+
},
|
|
349
|
+
spacing: 2,
|
|
350
|
+
sx: {
|
|
351
|
+
alignItems: {
|
|
352
|
+
sm: 'flex-start'
|
|
353
|
+
}
|
|
354
|
+
},
|
|
355
|
+
children: [
|
|
356
|
+
/*#__PURE__*/ _jsx(TextField, {
|
|
357
|
+
select: true,
|
|
358
|
+
size: "small",
|
|
359
|
+
label: "Shipping",
|
|
360
|
+
value: shippingMethod,
|
|
361
|
+
onChange: (event)=>setShippingMethod(event.target.value),
|
|
362
|
+
sx: {
|
|
363
|
+
minWidth: {
|
|
364
|
+
sm: '40%'
|
|
365
|
+
}
|
|
366
|
+
},
|
|
367
|
+
children: catalog.shipping.map((option)=>/*#__PURE__*/ _jsx(MenuItem, {
|
|
368
|
+
value: option.method,
|
|
369
|
+
children: `${option.label} · ${formatPosHardwareCents(option.cents)}`
|
|
370
|
+
}, option.method))
|
|
371
|
+
}),
|
|
372
|
+
/*#__PURE__*/ _jsxs(Stack, {
|
|
373
|
+
spacing: 0.5,
|
|
374
|
+
sx: {
|
|
375
|
+
flex: 1
|
|
376
|
+
},
|
|
377
|
+
"aria-label": "Order summary",
|
|
378
|
+
children: [
|
|
379
|
+
/*#__PURE__*/ _jsx(SummaryRow, {
|
|
380
|
+
label: "Items",
|
|
381
|
+
value: formatPosHardwareCents(subtotalCents)
|
|
382
|
+
}),
|
|
383
|
+
/*#__PURE__*/ _jsx(SummaryRow, {
|
|
384
|
+
label: "Shipping",
|
|
385
|
+
value: shipping ? formatPosHardwareCents(shipping.cents) : '—'
|
|
386
|
+
}),
|
|
387
|
+
catalog.automaticTax ? /*#__PURE__*/ _jsx(SummaryRow, {
|
|
388
|
+
label: "Tax",
|
|
389
|
+
value: "Calculated at checkout"
|
|
390
|
+
}) : null,
|
|
391
|
+
/*#__PURE__*/ _jsx(SummaryRow, {
|
|
392
|
+
label: catalog.automaticTax ? 'Total before tax' : 'Total',
|
|
393
|
+
value: formatPosHardwareCents(subtotalCents + ((_ref1 = shipping == null ? void 0 : shipping.cents) != null ? _ref1 : 0)),
|
|
394
|
+
strong: true
|
|
395
|
+
})
|
|
396
|
+
]
|
|
397
|
+
})
|
|
398
|
+
]
|
|
399
|
+
}),
|
|
400
|
+
/*#__PURE__*/ _jsx(Typography, {
|
|
401
|
+
variant: "caption",
|
|
402
|
+
color: "text.secondary",
|
|
403
|
+
children: 'Ships to street addresses in the United States. P.O. boxes and military addresses are not accepted.'
|
|
404
|
+
}),
|
|
405
|
+
/*#__PURE__*/ _jsxs(Stack, {
|
|
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
|
+
})
|
|
427
|
+
]
|
|
428
|
+
})
|
|
429
|
+
});
|
|
430
|
+
}
|
|
431
|
+
PosHardwareCard.displayName = 'PosHardwareCard';
|
|
432
|
+
function SummaryRow(props) {
|
|
433
|
+
return /*#__PURE__*/ _jsxs(Stack, {
|
|
434
|
+
direction: "row",
|
|
435
|
+
sx: {
|
|
436
|
+
justifyContent: 'space-between'
|
|
437
|
+
},
|
|
438
|
+
children: [
|
|
439
|
+
/*#__PURE__*/ _jsx(Typography, {
|
|
440
|
+
variant: "body2",
|
|
441
|
+
color: props.strong ? 'text.primary' : 'text.secondary',
|
|
442
|
+
children: props.label
|
|
443
|
+
}),
|
|
444
|
+
/*#__PURE__*/ _jsx(Typography, {
|
|
445
|
+
variant: "body2",
|
|
446
|
+
sx: props.strong ? {
|
|
447
|
+
fontWeight: 'fontWeightMedium'
|
|
448
|
+
} : undefined,
|
|
449
|
+
children: props.value
|
|
450
|
+
})
|
|
451
|
+
]
|
|
452
|
+
});
|
|
453
|
+
}
|
|
454
|
+
export default PosHardwareCard;
|
|
455
|
+
|
|
456
|
+
//# sourceMappingURL=pos-hardware-card.component.js.map
|
|
@@ -0,0 +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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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { ConsoleStaffPageProps } from '@aglyn/aglyn';
|
|
2
|
+
/**
|
|
3
|
+
* Staff → Hardware orders (AGL-4038): every workspace's orders from the POS
|
|
4
|
+
* hardware shop, newest first. In phase 1 a person places each one in the
|
|
5
|
+
* Stripe Dashboard's Terminal hardware shop, then records Stripe's order id
|
|
6
|
+
* and the tracking here and moves the order along; the merchant is emailed
|
|
7
|
+
* as it ships and is delivered. Canceling or refunding returns the whole
|
|
8
|
+
* payment and is offered only before the order ships.
|
|
9
|
+
*/
|
|
10
|
+
export declare function PosHardwareOrdersStaffPage(props: ConsoleStaffPageProps): import("react").JSX.Element;
|
|
11
|
+
export declare namespace PosHardwareOrdersStaffPage {
|
|
12
|
+
var displayName: string;
|
|
13
|
+
}
|
|
14
|
+
export default PosHardwareOrdersStaffPage;
|