@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.
Files changed (212) hide show
  1. package/package.json +17 -14
  2. package/src/lib/components/commerce-console-page.js +33 -1
  3. package/src/lib/components/commerce-console-page.js.map +1 -1
  4. package/src/lib/components/console/payments-settings-card.component.js +1 -1
  5. package/src/lib/components/console/payments-settings-card.component.js.map +1 -1
  6. package/src/lib/components/console/pos/pos-hardware-api.d.ts +122 -0
  7. package/src/lib/components/console/pos/pos-hardware-api.js +90 -0
  8. package/src/lib/components/console/pos/pos-hardware-api.js.map +1 -0
  9. package/src/lib/components/console/pos/pos-reader-splash-api.d.ts +58 -0
  10. package/src/lib/components/console/pos/pos-reader-splash-api.js +101 -0
  11. package/src/lib/components/console/pos/pos-reader-splash-api.js.map +1 -0
  12. package/src/lib/components/console/pos-devices-card.component.js +5 -0
  13. package/src/lib/components/console/pos-devices-card.component.js.map +1 -1
  14. package/src/lib/components/console/pos-hardware-card.component.d.ts +26 -0
  15. package/src/lib/components/console/pos-hardware-card.component.js +456 -0
  16. package/src/lib/components/console/pos-hardware-card.component.js.map +1 -0
  17. package/src/lib/components/console/pos-hardware-orders-staff-page.component.d.ts +14 -0
  18. package/src/lib/components/console/pos-hardware-orders-staff-page.component.js +519 -0
  19. package/src/lib/components/console/pos-hardware-orders-staff-page.component.js.map +1 -0
  20. package/src/lib/components/console/pos-ops/pos-check-in-dialog.component.d.ts +27 -0
  21. package/src/lib/components/console/pos-ops/pos-check-in-dialog.component.js +444 -0
  22. package/src/lib/components/console/pos-ops/pos-check-in-dialog.component.js.map +1 -0
  23. package/src/lib/components/console/pos-ops/pos-check-in-zone.component.d.ts +9 -0
  24. package/src/lib/components/console/pos-ops/pos-check-in-zone.component.js +37 -0
  25. package/src/lib/components/console/pos-ops/pos-check-in-zone.component.js.map +1 -0
  26. package/src/lib/components/console/pos-ops/pos-check-ins-card.component.d.ts +24 -0
  27. package/src/lib/components/console/pos-ops/pos-check-ins-card.component.js +346 -0
  28. package/src/lib/components/console/pos-ops/pos-check-ins-card.component.js.map +1 -0
  29. package/src/lib/components/console/pos-ops/pos-customer-lookup.component.d.ts +5 -1
  30. package/src/lib/components/console/pos-ops/pos-customer-lookup.component.js +83 -4
  31. package/src/lib/components/console/pos-ops/pos-customer-lookup.component.js.map +1 -1
  32. package/src/lib/components/console/pos-ops/pos-day-totals-card.component.d.ts +35 -0
  33. package/src/lib/components/console/pos-ops/pos-day-totals-card.component.js +546 -0
  34. package/src/lib/components/console/pos-ops/pos-day-totals-card.component.js.map +1 -0
  35. package/src/lib/components/console/pos-ops/pos-operations-bar.component.d.ts +2 -1
  36. package/src/lib/components/console/pos-ops/pos-operations-bar.component.js +20 -1
  37. package/src/lib/components/console/pos-ops/pos-operations-bar.component.js.map +1 -1
  38. package/src/lib/components/console/pos-ops/pos-ops-api.d.ts +1 -1
  39. package/src/lib/components/console/pos-ops/pos-ops-api.js.map +1 -1
  40. package/src/lib/components/console/pos-page.component.js +6 -3
  41. package/src/lib/components/console/pos-page.component.js.map +1 -1
  42. package/src/lib/components/console/pos-reader-splash-setting.component.d.ts +22 -0
  43. package/src/lib/components/console/pos-reader-splash-setting.component.js +275 -0
  44. package/src/lib/components/console/pos-reader-splash-setting.component.js.map +1 -0
  45. package/src/lib/components/console/pos-reader-splash-staff-page.component.d.ts +14 -0
  46. package/src/lib/components/console/pos-reader-splash-staff-page.component.js +301 -0
  47. package/src/lib/components/console/pos-reader-splash-staff-page.component.js.map +1 -0
  48. package/src/lib/components/console/pos-zones.d.ts +37 -3
  49. package/src/lib/components/console/pos-zones.js +11 -1
  50. package/src/lib/components/console/pos-zones.js.map +1 -1
  51. package/src/lib/components/console/product-check-in-fields.component.d.ts +20 -0
  52. package/src/lib/components/console/product-check-in-fields.component.js +172 -0
  53. package/src/lib/components/console/product-check-in-fields.component.js.map +1 -0
  54. package/src/lib/components/console/product-editor-dialog.component.js +48 -9
  55. package/src/lib/components/console/product-editor-dialog.component.js.map +1 -1
  56. package/src/lib/components/console/product-register-fields.component.d.ts +12 -0
  57. package/src/lib/components/console/product-register-fields.component.js +39 -1
  58. package/src/lib/components/console/product-register-fields.component.js.map +1 -1
  59. package/src/lib/components/console/products-hub-card.component.js +21 -6
  60. package/src/lib/components/console/products-hub-card.component.js.map +1 -1
  61. package/src/lib/components/console/reservations-card.component.js +239 -70
  62. package/src/lib/components/console/reservations-card.component.js.map +1 -1
  63. package/src/lib/components/reservation-widget.js +16 -0
  64. package/src/lib/components/reservation-widget.js.map +1 -1
  65. package/src/lib/constants/operator-alerts.d.ts +6 -0
  66. package/src/lib/constants/operator-alerts.js +20 -1
  67. package/src/lib/constants/operator-alerts.js.map +1 -1
  68. package/src/lib/declarations.console-server.js +7 -0
  69. package/src/lib/declarations.console-server.js.map +1 -1
  70. package/src/lib/declarations.d.ts +26 -0
  71. package/src/lib/declarations.js +34 -0
  72. package/src/lib/declarations.js.map +1 -0
  73. package/src/lib/model/commerce-check-in-product.d.ts +37 -0
  74. package/src/lib/model/commerce-check-in-product.js +49 -0
  75. package/src/lib/model/commerce-check-in-product.js.map +1 -0
  76. package/src/lib/model/commerce-check-in.d.ts +187 -0
  77. package/src/lib/model/commerce-check-in.js +468 -0
  78. package/src/lib/model/commerce-check-in.js.map +1 -0
  79. package/src/lib/model/commerce-pos-day-report.d.ts +209 -0
  80. package/src/lib/model/commerce-pos-day-report.js +572 -0
  81. package/src/lib/model/commerce-pos-day-report.js.map +1 -0
  82. package/src/lib/model/commerce-pos-offline.d.ts +65 -3
  83. package/src/lib/model/commerce-pos-offline.js +104 -7
  84. package/src/lib/model/commerce-pos-offline.js.map +1 -1
  85. package/src/lib/model/commerce-pos-ops.d.ts +3 -0
  86. package/src/lib/model/commerce-pos-ops.js +1 -0
  87. package/src/lib/model/commerce-pos-ops.js.map +1 -1
  88. package/src/lib/model/commerce-pos.d.ts +43 -3
  89. package/src/lib/model/commerce-pos.js +73 -5
  90. package/src/lib/model/commerce-pos.js.map +1 -1
  91. package/src/lib/model/commerce-reservations.d.ts +73 -7
  92. package/src/lib/model/commerce-reservations.js +90 -10
  93. package/src/lib/model/commerce-reservations.js.map +1 -1
  94. package/src/lib/model/commerce.d.ts +40 -0
  95. package/src/lib/model/commerce.js +22 -4
  96. package/src/lib/model/commerce.js.map +1 -1
  97. package/src/lib/model/index.d.ts +1 -0
  98. package/src/lib/model/index.js +1 -0
  99. package/src/lib/model/index.js.map +1 -1
  100. package/src/lib/model/plugin-permissions.d.ts +1 -1
  101. package/src/lib/model/plugin-permissions.js +2 -1
  102. package/src/lib/model/plugin-permissions.js.map +1 -1
  103. package/src/lib/model/pos-hardware.d.ts +288 -0
  104. package/src/lib/model/pos-hardware.js +499 -0
  105. package/src/lib/model/pos-hardware.js.map +1 -0
  106. package/src/lib/model/pos-offline-card-limits.d.ts +20 -0
  107. package/src/lib/model/pos-offline-card-limits.js +28 -0
  108. package/src/lib/model/pos-offline-card-limits.js.map +1 -0
  109. package/src/lib/model/pos-reader-splash.d.ts +114 -0
  110. package/src/lib/model/pos-reader-splash.js +141 -0
  111. package/src/lib/model/pos-reader-splash.js.map +1 -0
  112. package/src/lib/model/product-write.d.ts +6 -0
  113. package/src/lib/plugin-config.d.ts +10 -0
  114. package/src/lib/plugin-config.js +40 -0
  115. package/src/lib/plugin-config.js.map +1 -1
  116. package/src/lib/plugin.js +28 -0
  117. package/src/lib/plugin.js.map +1 -1
  118. package/src/lib/server/cart-checkout.js +3 -1
  119. package/src/lib/server/cart-checkout.js.map +1 -1
  120. package/src/lib/server/cart.js +12 -1
  121. package/src/lib/server/cart.js.map +1 -1
  122. package/src/lib/server/catalog.js +49 -12
  123. package/src/lib/server/catalog.js.map +1 -1
  124. package/src/lib/server/checkout-extras.js +1 -1
  125. package/src/lib/server/checkout-extras.js.map +1 -1
  126. package/src/lib/server/checkout.js +7 -0
  127. package/src/lib/server/checkout.js.map +1 -1
  128. package/src/lib/server/person-eraser.d.ts +8 -1
  129. package/src/lib/server/person-eraser.js +23 -1
  130. package/src/lib/server/person-eraser.js.map +1 -1
  131. package/src/lib/server/pos-check-in.d.ts +49 -0
  132. package/src/lib/server/pos-check-in.js +652 -0
  133. package/src/lib/server/pos-check-in.js.map +1 -0
  134. package/src/lib/server/pos-day-report.d.ts +46 -0
  135. package/src/lib/server/pos-day-report.js +299 -0
  136. package/src/lib/server/pos-day-report.js.map +1 -0
  137. package/src/lib/server/pos-hardware-admin.d.ts +50 -0
  138. package/src/lib/server/pos-hardware-admin.js +366 -0
  139. package/src/lib/server/pos-hardware-admin.js.map +1 -0
  140. package/src/lib/server/pos-hardware-notify.d.ts +27 -0
  141. package/src/lib/server/pos-hardware-notify.js +142 -0
  142. package/src/lib/server/pos-hardware-notify.js.map +1 -0
  143. package/src/lib/server/pos-hardware-user-eraser.d.ts +26 -0
  144. package/src/lib/server/pos-hardware-user-eraser.js +67 -0
  145. package/src/lib/server/pos-hardware-user-eraser.js.map +1 -0
  146. package/src/lib/server/pos-hardware-webhook.d.ts +31 -0
  147. package/src/lib/server/pos-hardware-webhook.js +176 -0
  148. package/src/lib/server/pos-hardware-webhook.js.map +1 -0
  149. package/src/lib/server/pos-hardware.d.ts +58 -0
  150. package/src/lib/server/pos-hardware.js +234 -0
  151. package/src/lib/server/pos-hardware.js.map +1 -0
  152. package/src/lib/server/pos-offline-card-reconcile.d.ts +38 -0
  153. package/src/lib/server/pos-offline-card-reconcile.js +58 -0
  154. package/src/lib/server/pos-offline-card-reconcile.js.map +1 -0
  155. package/src/lib/server/pos-offline-sync.d.ts +32 -0
  156. package/src/lib/server/pos-offline-sync.js +191 -15
  157. package/src/lib/server/pos-offline-sync.js.map +1 -1
  158. package/src/lib/server/pos-ops-routes.d.ts +4 -2
  159. package/src/lib/server/pos-ops-routes.js +14 -2
  160. package/src/lib/server/pos-ops-routes.js.map +1 -1
  161. package/src/lib/server/pos-order.js +39 -51
  162. package/src/lib/server/pos-order.js.map +1 -1
  163. package/src/lib/server/pos-payment.js +8 -4
  164. package/src/lib/server/pos-payment.js.map +1 -1
  165. package/src/lib/server/pos-reader-splash-admin.d.ts +36 -0
  166. package/src/lib/server/pos-reader-splash-admin.js +295 -0
  167. package/src/lib/server/pos-reader-splash-admin.js.map +1 -0
  168. package/src/lib/server/pos-reader-splash-render.d.ts +40 -0
  169. package/src/lib/server/pos-reader-splash-render.js +138 -0
  170. package/src/lib/server/pos-reader-splash-render.js.map +1 -0
  171. package/src/lib/server/pos-reader-splash-server.d.ts +32 -0
  172. package/src/lib/server/pos-reader-splash-server.js +32 -0
  173. package/src/lib/server/pos-reader-splash-server.js.map +1 -0
  174. package/src/lib/server/pos-reader-splash.d.ts +105 -0
  175. package/src/lib/server/pos-reader-splash.js +548 -0
  176. package/src/lib/server/pos-reader-splash.js.map +1 -0
  177. package/src/lib/server/pos-sale.d.ts +2 -1
  178. package/src/lib/server/pos-sale.js +3 -1
  179. package/src/lib/server/pos-sale.js.map +1 -1
  180. package/src/lib/server/pos-terminal.d.ts +67 -4
  181. package/src/lib/server/pos-terminal.js +239 -32
  182. package/src/lib/server/pos-terminal.js.map +1 -1
  183. package/src/lib/server/process-restock.js +4 -0
  184. package/src/lib/server/process-restock.js.map +1 -1
  185. package/src/lib/server/product-card.js +2 -2
  186. package/src/lib/server/product-card.js.map +1 -1
  187. package/src/lib/server/product-catalog.d.ts +2 -0
  188. package/src/lib/server/product-catalog.js +11 -4
  189. package/src/lib/server/product-catalog.js.map +1 -1
  190. package/src/lib/server/product.js +3 -1
  191. package/src/lib/server/product.js.map +1 -1
  192. package/src/lib/server/related.js +8 -1
  193. package/src/lib/server/related.js.map +1 -1
  194. package/src/lib/server/reservation-availability-query.d.ts +35 -0
  195. package/src/lib/server/reservation-availability-query.js +34 -0
  196. package/src/lib/server/reservation-availability-query.js.map +1 -0
  197. package/src/lib/server/reservation-availability.d.ts +21 -0
  198. package/src/lib/server/reservation-availability.js +64 -10
  199. package/src/lib/server/reservation-availability.js.map +1 -1
  200. package/src/lib/server/reservation-walk-in.d.ts +28 -0
  201. package/src/lib/server/reservation-walk-in.js +166 -0
  202. package/src/lib/server/reservation-walk-in.js.map +1 -0
  203. package/src/lib/server/reserve.js +13 -10
  204. package/src/lib/server/reserve.js.map +1 -1
  205. package/src/lib/server/reviews.js +3 -1
  206. package/src/lib/server/reviews.js.map +1 -1
  207. package/src/lib/server/site-page-resolver.js +5 -2
  208. package/src/lib/server/site-page-resolver.js.map +1 -1
  209. package/src/lib/server.js +26 -0
  210. package/src/lib/server.js.map +1 -1
  211. package/src/lib/testing/fake-firestore.js +72 -0
  212. 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;