@aglyn/plugins-commerce 1.0.0-beta.232 → 1.0.0-beta.234

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 (228) hide show
  1. package/package.json +13 -13
  2. package/src/lib/components/cart-extras.d.ts +6 -0
  3. package/src/lib/components/cart-extras.js +4 -1
  4. package/src/lib/components/cart-extras.js.map +1 -1
  5. package/src/lib/components/cart-fulfillment.d.ts +117 -0
  6. package/src/lib/components/cart-fulfillment.js +367 -0
  7. package/src/lib/components/cart-fulfillment.js.map +1 -0
  8. package/src/lib/components/cart.js +52 -10
  9. package/src/lib/components/cart.js.map +1 -1
  10. package/src/lib/components/commerce-console-page.js +42 -1
  11. package/src/lib/components/commerce-console-page.js.map +1 -1
  12. package/src/lib/components/console/host-orders-card.component.js +38 -10
  13. package/src/lib/components/console/host-orders-card.component.js.map +1 -1
  14. package/src/lib/components/console/local-delivery-settings-card.component.d.ts +37 -0
  15. package/src/lib/components/console/local-delivery-settings-card.component.js +542 -0
  16. package/src/lib/components/console/local-delivery-settings-card.component.js.map +1 -0
  17. package/src/lib/components/console/locations-card.component.js +177 -3
  18. package/src/lib/components/console/locations-card.component.js.map +1 -1
  19. package/src/lib/components/console/order-detail-dialog.component.js +10 -0
  20. package/src/lib/components/console/order-detail-dialog.component.js.map +1 -1
  21. package/src/lib/components/console/order-local-fulfillment-panel.component.d.ts +44 -0
  22. package/src/lib/components/console/order-local-fulfillment-panel.component.js +265 -0
  23. package/src/lib/components/console/order-local-fulfillment-panel.component.js.map +1 -0
  24. package/src/lib/components/console/order-offline-notice.component.d.ts +12 -0
  25. package/src/lib/components/console/order-offline-notice.component.js +53 -0
  26. package/src/lib/components/console/order-offline-notice.component.js.map +1 -0
  27. package/src/lib/components/console/pickup-delivery-queue-card.component.d.ts +35 -0
  28. package/src/lib/components/console/pickup-delivery-queue-card.component.js +222 -0
  29. package/src/lib/components/console/pickup-delivery-queue-card.component.js.map +1 -0
  30. package/src/lib/components/console/pos/pos-api.d.ts +24 -1
  31. package/src/lib/components/console/pos/pos-api.js +13 -0
  32. package/src/lib/components/console/pos/pos-api.js.map +1 -1
  33. package/src/lib/components/console/pos/pos-item-dialog.component.d.ts +12 -0
  34. package/src/lib/components/console/pos/pos-item-dialog.component.js +10 -8
  35. package/src/lib/components/console/pos/pos-item-dialog.component.js.map +1 -1
  36. package/src/lib/components/console/pos/pos-kiosk-queue.component.d.ts +22 -0
  37. package/src/lib/components/console/pos/pos-kiosk-queue.component.js +168 -0
  38. package/src/lib/components/console/pos/pos-kiosk-queue.component.js.map +1 -0
  39. package/src/lib/components/console/pos/pos-tender-dialogs.component.d.ts +18 -0
  40. package/src/lib/components/console/pos/pos-tender-dialogs.component.js +116 -1
  41. package/src/lib/components/console/pos/pos-tender-dialogs.component.js.map +1 -1
  42. package/src/lib/components/console/pos/pos-tender-panel.component.d.ts +8 -0
  43. package/src/lib/components/console/pos/pos-tender-panel.component.js +77 -18
  44. package/src/lib/components/console/pos/pos-tender-panel.component.js.map +1 -1
  45. package/src/lib/components/console/pos/use-pos-display.d.ts +5 -2
  46. package/src/lib/components/console/pos/use-pos-display.js +3 -2
  47. package/src/lib/components/console/pos/use-pos-display.js.map +1 -1
  48. package/src/lib/components/console/pos-devices-card.component.js +2 -2
  49. package/src/lib/components/console/pos-devices-card.component.js.map +1 -1
  50. package/src/lib/components/console/pos-display/pairing-screen.d.ts +5 -2
  51. package/src/lib/components/console/pos-display/pairing-screen.js +7 -5
  52. package/src/lib/components/console/pos-display/pairing-screen.js.map +1 -1
  53. package/src/lib/components/console/pos-display/pos-display-api.d.ts +7 -1
  54. package/src/lib/components/console/pos-display/pos-display-api.js +7 -2
  55. package/src/lib/components/console/pos-display/pos-display-api.js.map +1 -1
  56. package/src/lib/components/console/pos-kiosk/kiosk-checkout.d.ts +41 -0
  57. package/src/lib/components/console/pos-kiosk/kiosk-checkout.js +275 -0
  58. package/src/lib/components/console/pos-kiosk/kiosk-checkout.js.map +1 -0
  59. package/src/lib/components/console/pos-kiosk/kiosk-menu.d.ts +32 -0
  60. package/src/lib/components/console/pos-kiosk/kiosk-menu.js +344 -0
  61. package/src/lib/components/console/pos-kiosk/kiosk-menu.js.map +1 -0
  62. package/src/lib/components/console/pos-kiosk/kiosk-staff.d.ts +12 -0
  63. package/src/lib/components/console/pos-kiosk/kiosk-staff.js +257 -0
  64. package/src/lib/components/console/pos-kiosk/kiosk-staff.js.map +1 -0
  65. package/src/lib/components/console/pos-kiosk/pos-kiosk-api.d.ts +114 -0
  66. package/src/lib/components/console/pos-kiosk/pos-kiosk-api.js +189 -0
  67. package/src/lib/components/console/pos-kiosk/pos-kiosk-api.js.map +1 -0
  68. package/src/lib/components/console/pos-kiosk/use-kiosk-idle.d.ts +16 -0
  69. package/src/lib/components/console/pos-kiosk/use-kiosk-idle.js +80 -0
  70. package/src/lib/components/console/pos-kiosk/use-kiosk-idle.js.map +1 -0
  71. package/src/lib/components/console/pos-kiosk-page.component.d.ts +28 -0
  72. package/src/lib/components/console/pos-kiosk-page.component.js +791 -0
  73. package/src/lib/components/console/pos-kiosk-page.component.js.map +1 -0
  74. package/src/lib/components/console/pos-offline/pos-offline-api.d.ts +44 -0
  75. package/src/lib/components/console/pos-offline/pos-offline-api.js +69 -0
  76. package/src/lib/components/console/pos-offline/pos-offline-api.js.map +1 -0
  77. package/src/lib/components/console/pos-offline/pos-offline-banner.component.d.ts +7 -0
  78. package/src/lib/components/console/pos-offline/pos-offline-banner.component.js +135 -0
  79. package/src/lib/components/console/pos-offline/pos-offline-banner.component.js.map +1 -0
  80. package/src/lib/components/console/pos-offline/pos-offline-checkout.component.d.ts +32 -0
  81. package/src/lib/components/console/pos-offline/pos-offline-checkout.component.js +287 -0
  82. package/src/lib/components/console/pos-offline/pos-offline-checkout.component.js.map +1 -0
  83. package/src/lib/components/console/pos-offline/pos-offline-store.d.ts +63 -0
  84. package/src/lib/components/console/pos-offline/pos-offline-store.js +145 -0
  85. package/src/lib/components/console/pos-offline/pos-offline-store.js.map +1 -0
  86. package/src/lib/components/console/pos-offline/register-offline.d.ts +24 -0
  87. package/src/lib/components/console/pos-offline/register-offline.js +24 -0
  88. package/src/lib/components/console/pos-offline/register-offline.js.map +1 -0
  89. package/src/lib/components/console/pos-offline/use-pos-offline.d.ts +85 -0
  90. package/src/lib/components/console/pos-offline/use-pos-offline.js +542 -0
  91. package/src/lib/components/console/pos-offline/use-pos-offline.js.map +1 -0
  92. package/src/lib/components/console/pos-ops/pos-shift-history-card.component.js +72 -17
  93. package/src/lib/components/console/pos-ops/pos-shift-history-card.component.js.map +1 -1
  94. package/src/lib/components/console/pos-page.component.js +174 -27
  95. package/src/lib/components/console/pos-page.component.js.map +1 -1
  96. package/src/lib/components/console/products-hub-card.component.js +35 -10
  97. package/src/lib/components/console/products-hub-card.component.js.map +1 -1
  98. package/src/lib/components/console/shipping-settings-card.component.js +1 -1
  99. package/src/lib/components/console/shipping-settings-card.component.js.map +1 -1
  100. package/src/lib/components/console/stock-movements-card.component.js +48 -16
  101. package/src/lib/components/console/stock-movements-card.component.js.map +1 -1
  102. package/src/lib/components/console/store-zones.d.ts +8 -1
  103. package/src/lib/components/console/store-zones.js +11 -1
  104. package/src/lib/components/console/store-zones.js.map +1 -1
  105. package/src/lib/components/order-status.js +66 -0
  106. package/src/lib/components/order-status.js.map +1 -1
  107. package/src/lib/components/product-detail.js +42 -15
  108. package/src/lib/components/product-detail.js.map +1 -1
  109. package/src/lib/constants/local-fulfillment-list-query.d.ts +48 -0
  110. package/src/lib/constants/local-fulfillment-list-query.js +84 -0
  111. package/src/lib/constants/local-fulfillment-list-query.js.map +1 -0
  112. package/src/lib/constants/orders-list-query.d.ts +7 -2
  113. package/src/lib/constants/orders-list-query.js +89 -8
  114. package/src/lib/constants/orders-list-query.js.map +1 -1
  115. package/src/lib/constants/pos-shift-list-query.d.ts +22 -0
  116. package/src/lib/constants/pos-shift-list-query.js +115 -0
  117. package/src/lib/constants/pos-shift-list-query.js.map +1 -0
  118. package/src/lib/constants/product-list-query.d.ts +6 -1
  119. package/src/lib/constants/product-list-query.js +77 -8
  120. package/src/lib/constants/product-list-query.js.map +1 -1
  121. package/src/lib/constants/stock-movement-query.d.ts +3 -2
  122. package/src/lib/constants/stock-movement-query.js +52 -8
  123. package/src/lib/constants/stock-movement-query.js.map +1 -1
  124. package/src/lib/model/buyer-notifications.d.ts +5 -3
  125. package/src/lib/model/buyer-notifications.js +25 -4
  126. package/src/lib/model/buyer-notifications.js.map +1 -1
  127. package/src/lib/model/commerce-orders.d.ts +59 -0
  128. package/src/lib/model/commerce-orders.js.map +1 -1
  129. package/src/lib/model/commerce-pos-kiosk.d.ts +175 -0
  130. package/src/lib/model/commerce-pos-kiosk.js +147 -0
  131. package/src/lib/model/commerce-pos-kiosk.js.map +1 -0
  132. package/src/lib/model/commerce-pos-offline.d.ts +234 -0
  133. package/src/lib/model/commerce-pos-offline.js +301 -0
  134. package/src/lib/model/commerce-pos-offline.js.map +1 -0
  135. package/src/lib/model/commerce-pos-ops.d.ts +16 -6
  136. package/src/lib/model/commerce-pos-ops.js +12 -4
  137. package/src/lib/model/commerce-pos-ops.js.map +1 -1
  138. package/src/lib/model/commerce-pos.d.ts +13 -1
  139. package/src/lib/model/commerce-pos.js +5 -4
  140. package/src/lib/model/commerce-pos.js.map +1 -1
  141. package/src/lib/model/commerce-stock-holds.d.ts +24 -3
  142. package/src/lib/model/commerce-stock-holds.js +26 -8
  143. package/src/lib/model/commerce-stock-holds.js.map +1 -1
  144. package/src/lib/model/commerce.d.ts +3 -0
  145. package/src/lib/model/commerce.js.map +1 -1
  146. package/src/lib/model/index.d.ts +4 -0
  147. package/src/lib/model/index.js +4 -0
  148. package/src/lib/model/index.js.map +1 -1
  149. package/src/lib/model/local-fulfillment-settings.d.ts +178 -0
  150. package/src/lib/model/local-fulfillment-settings.js +361 -0
  151. package/src/lib/model/local-fulfillment-settings.js.map +1 -0
  152. package/src/lib/model/order-list-fields.d.ts +10 -1
  153. package/src/lib/model/order-list-fields.js +1 -0
  154. package/src/lib/model/order-list-fields.js.map +1 -1
  155. package/src/lib/model/order-local-fulfillment.d.ts +131 -0
  156. package/src/lib/model/order-local-fulfillment.js +125 -0
  157. package/src/lib/model/order-local-fulfillment.js.map +1 -0
  158. package/src/lib/model/order-shipping-export.js +4 -0
  159. package/src/lib/model/order-shipping-export.js.map +1 -1
  160. package/src/lib/model/order-status-view.d.ts +20 -1
  161. package/src/lib/model/order-status-view.js +60 -6
  162. package/src/lib/model/order-status-view.js.map +1 -1
  163. package/src/lib/plugin-config.js +6 -2
  164. package/src/lib/plugin-config.js.map +1 -1
  165. package/src/lib/plugin.js +8 -0
  166. package/src/lib/plugin.js.map +1 -1
  167. package/src/lib/pos-kiosk-config.d.ts +26 -0
  168. package/src/lib/pos-kiosk-config.js +59 -0
  169. package/src/lib/pos-kiosk-config.js.map +1 -0
  170. package/src/lib/server/api-v1/openapi.js +8 -0
  171. package/src/lib/server/api-v1/openapi.js.map +1 -1
  172. package/src/lib/server/api-v1/order-view.d.ts +19 -0
  173. package/src/lib/server/api-v1/order-view.js +35 -0
  174. package/src/lib/server/api-v1/order-view.js.map +1 -1
  175. package/src/lib/server/billing-webhook.js +238 -87
  176. package/src/lib/server/billing-webhook.js.map +1 -1
  177. package/src/lib/server/cart-checkout.d.ts +2 -0
  178. package/src/lib/server/cart-checkout.js +173 -13
  179. package/src/lib/server/cart-checkout.js.map +1 -1
  180. package/src/lib/server/checkout-extras.js +18 -4
  181. package/src/lib/server/checkout-extras.js.map +1 -1
  182. package/src/lib/server/checkout.js +71 -14
  183. package/src/lib/server/checkout.js.map +1 -1
  184. package/src/lib/server/local-fulfillment-status.d.ts +86 -0
  185. package/src/lib/server/local-fulfillment-status.js +379 -0
  186. package/src/lib/server/local-fulfillment-status.js.map +1 -0
  187. package/src/lib/server/local-fulfillment.d.ts +190 -0
  188. package/src/lib/server/local-fulfillment.js +580 -0
  189. package/src/lib/server/local-fulfillment.js.map +1 -0
  190. package/src/lib/server/membership-register.js +3 -1
  191. package/src/lib/server/membership-register.js.map +1 -1
  192. package/src/lib/server/order-notifications.js +61 -0
  193. package/src/lib/server/order-notifications.js.map +1 -1
  194. package/src/lib/server/pos-display.d.ts +27 -1
  195. package/src/lib/server/pos-display.js +50 -9
  196. package/src/lib/server/pos-display.js.map +1 -1
  197. package/src/lib/server/pos-kiosk-principal.d.ts +29 -0
  198. package/src/lib/server/pos-kiosk-principal.js +42 -0
  199. package/src/lib/server/pos-kiosk-principal.js.map +1 -0
  200. package/src/lib/server/pos-kiosk.d.ts +54 -0
  201. package/src/lib/server/pos-kiosk.js +972 -0
  202. package/src/lib/server/pos-kiosk.js.map +1 -0
  203. package/src/lib/server/pos-offline-sync.d.ts +85 -0
  204. package/src/lib/server/pos-offline-sync.js +765 -0
  205. package/src/lib/server/pos-offline-sync.js.map +1 -0
  206. package/src/lib/server/pos-order.js +22 -4
  207. package/src/lib/server/pos-order.js.map +1 -1
  208. package/src/lib/server/pos-payment.d.ts +6 -0
  209. package/src/lib/server/pos-payment.js +225 -6
  210. package/src/lib/server/pos-payment.js.map +1 -1
  211. package/src/lib/server/pos-print.js +5 -0
  212. package/src/lib/server/pos-print.js.map +1 -1
  213. package/src/lib/server/pos-return.js +27 -0
  214. package/src/lib/server/pos-return.js.map +1 -1
  215. package/src/lib/server/pos-sale.d.ts +6 -0
  216. package/src/lib/server/pos-sale.js +2 -0
  217. package/src/lib/server/pos-sale.js.map +1 -1
  218. package/src/lib/server/pos-shift.js +8 -1
  219. package/src/lib/server/pos-shift.js.map +1 -1
  220. package/src/lib/server/refund.js +3 -0
  221. package/src/lib/server/refund.js.map +1 -1
  222. package/src/lib/server/stock-hold.d.ts +9 -1
  223. package/src/lib/server/stock-hold.js +15 -7
  224. package/src/lib/server/stock-hold.js.map +1 -1
  225. package/src/lib/server.js +16 -0
  226. package/src/lib/server.js.map +1 -1
  227. package/src/lib/tenant-emails.js +161 -0
  228. package/src/lib/tenant-emails.js.map +1 -1
@@ -0,0 +1,542 @@
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 * as Aglyn from "@aglyn/aglyn";
20
+ import { invalidOpeningHoursLines } from "@aglyn/aglyn/app-utils/local-business";
21
+ import * as CommerceModel from "../../model/index.js";
22
+ import { CardDisplay } from "@aglyn/shared-ui-jsx";
23
+ import { useSnackbar } from "@aglyn/shared-ui-snackstack";
24
+ import { Alert, Button, Divider, FormControlLabel, MenuItem, Stack, Switch, TextField, Typography } from "@mui/material";
25
+ import { authorizedFetch } from "@aglyn/shared-util-http/authorized-token";
26
+ import { collection, doc, limit, query, setDoc } from "firebase/firestore";
27
+ import { useCallback, useEffect, useState } from "react";
28
+ import { useFirestore, useFirestoreCollection, useFirestoreDoc, useUser, writeGuardedBySeed } from "@aglyn/tenant-feature-instance";
29
+ import { pluginDocsHelp } from "@aglyn/aglyn";
30
+ const LEAD_TIMES = [
31
+ [
32
+ 0,
33
+ 'No notice'
34
+ ],
35
+ [
36
+ 60,
37
+ '1 hour'
38
+ ],
39
+ [
40
+ 120,
41
+ '2 hours'
42
+ ],
43
+ [
44
+ 240,
45
+ '4 hours'
46
+ ],
47
+ [
48
+ 1440,
49
+ '1 day'
50
+ ],
51
+ [
52
+ 2880,
53
+ '2 days'
54
+ ]
55
+ ];
56
+ /**
57
+ * Local delivery (AGL-3624): the store's OWN delivery — zones by postal code
58
+ * or by distance, each with a fee, a minimum order and a free-over
59
+ * threshold, and the delivery windows a buyer books at the cart. Stored on
60
+ * `settings/store.localDelivery`, written whole so a cleared field is
61
+ * cleared. Marketplace couriers (DoorDash and the rest) are the Delivery apps
62
+ * plugin's, and nothing here touches them.
63
+ *
64
+ * DISTANCE ZONES are offered only where the store's shipping address check
65
+ * can place an address on a map (`GET /api/commerce/local-fulfillment`), and
66
+ * need the store placed first ("Place on map"). Postal-code zones need
67
+ * nothing.
68
+ */ export function LocalDeliverySettingsCard(props) {
69
+ var _ref, _current_zones, _current_windows, _current_country, _current_locationId, _current_windows1, _current_leadTimeMinutes, _current_daysAhead, _current_instructions;
70
+ const { hostId } = props;
71
+ const firestore = useFirestore();
72
+ const { data: user } = useUser();
73
+ const { enqueueSnackbar } = useSnackbar();
74
+ const { data: store, status: storeStatus, fromCache } = useFirestoreDoc(()=>doc(firestore, 'hosts', hostId, 'settings', 'store'), [
75
+ firestore,
76
+ hostId
77
+ ]);
78
+ const { data: locationDocs } = useFirestoreCollection(()=>query(collection(firestore, 'hosts', hostId, 'locations'), limit(25)), [
79
+ firestore,
80
+ hostId
81
+ ], {
82
+ idField: '$id'
83
+ });
84
+ const [draft, setDraft] = useState(null);
85
+ const current = (_ref = draft != null ? draft : store == null ? void 0 : store.localDelivery) != null ? _ref : {};
86
+ const update = (patch)=>setDraft(_extends({}, current, patch));
87
+ const [radiusAvailable, setRadiusAvailable] = useState(false);
88
+ useEffect(()=>{
89
+ let live = true;
90
+ authorizedFetch(user, `/api/commerce/local-fulfillment?hostId=${encodeURIComponent(hostId)}`).then((response)=>response.ok ? response.json() : null).then((answer)=>{
91
+ if (live) setRadiusAvailable(Boolean(answer == null ? void 0 : answer.radius));
92
+ }).catch(()=>undefined);
93
+ return ()=>{
94
+ live = false;
95
+ };
96
+ }, [
97
+ hostId,
98
+ user
99
+ ]);
100
+ const zones = (_current_zones = current.zones) != null ? _current_zones : [];
101
+ const updateZone = (index, patch)=>{
102
+ const next = [
103
+ ...zones
104
+ ];
105
+ if (patch === null) next.splice(index, 1);
106
+ else next[index] = _extends({}, next[index], patch);
107
+ update({
108
+ zones: next
109
+ });
110
+ };
111
+ const addZone = ()=>update({
112
+ zones: [
113
+ ...zones,
114
+ {
115
+ id: Aglyn.createResourceUid(),
116
+ name: 'Local delivery',
117
+ kind: 'postcode',
118
+ postcodes: [],
119
+ feeCents: 0
120
+ }
121
+ ]
122
+ });
123
+ const [locating, setLocating] = useState(false);
124
+ const handleLocate = useCallback(async ()=>{
125
+ if (!current.locationId) {
126
+ return void enqueueSnackbar('Choose the location deliveries leave from first', {
127
+ variant: 'info',
128
+ persist: false
129
+ });
130
+ }
131
+ setLocating(true);
132
+ try {
133
+ const response = await authorizedFetch(user, '/api/commerce/local-fulfillment', {
134
+ method: 'POST',
135
+ headers: {
136
+ 'Content-Type': 'application/json'
137
+ },
138
+ body: JSON.stringify({
139
+ hostId,
140
+ action: 'locate',
141
+ locationId: current.locationId
142
+ })
143
+ });
144
+ const payload = await response.json().catch(()=>({}));
145
+ if (!response.ok || !(payload == null ? void 0 : payload.origin)) {
146
+ var _ref;
147
+ enqueueSnackbar((_ref = payload == null ? void 0 : payload.error) != null ? _ref : 'Could not place the store on a map', {
148
+ variant: 'warning',
149
+ persist: false
150
+ });
151
+ return;
152
+ }
153
+ setDraft(_extends({}, current, {
154
+ origin: payload.origin
155
+ }));
156
+ } finally{
157
+ setLocating(false);
158
+ }
159
+ }, [
160
+ current,
161
+ enqueueSnackbar,
162
+ hostId,
163
+ user
164
+ ]);
165
+ const badWindowLines = invalidOpeningHoursLines((_current_windows = current.windows) != null ? _current_windows : '');
166
+ const problems = CommerceModel.localDeliveryProblems(CommerceModel.normalizeLocalDeliverySettings(current));
167
+ const handleSave = useCallback(async ()=>{
168
+ const value = CommerceModel.normalizeLocalDeliverySettings(current);
169
+ const verdict = await writeGuardedBySeed({
170
+ subject: 'local delivery settings',
171
+ unreadable: storeStatus === 'error',
172
+ fromCache
173
+ }, async ()=>{
174
+ // `mergeFields` replaces `localDelivery` whole and leaves every other
175
+ // map on the settings document alone.
176
+ await setDoc(doc(firestore, 'hosts', hostId, 'settings', 'store'), {
177
+ localDelivery: value
178
+ }, {
179
+ mergeFields: [
180
+ 'localDelivery'
181
+ ]
182
+ });
183
+ });
184
+ if (!verdict.ok) {
185
+ return void enqueueSnackbar(verdict.message, {
186
+ variant: 'warning',
187
+ persist: false
188
+ });
189
+ }
190
+ setDraft(null);
191
+ enqueueSnackbar('Local delivery saved', {
192
+ variant: 'success',
193
+ persist: false
194
+ });
195
+ }, [
196
+ current,
197
+ enqueueSnackbar,
198
+ firestore,
199
+ fromCache,
200
+ hostId,
201
+ storeStatus
202
+ ]);
203
+ const dollars = (cents)=>cents ? String(cents / 100) : '';
204
+ const cents = (raw)=>raw.trim() === '' ? 0 : Math.max(0, Math.round(Number(raw) * 100) || 0);
205
+ const locations = [
206
+ ...locationDocs != null ? locationDocs : []
207
+ ].sort((a, b)=>{
208
+ var _a_name, _b_name;
209
+ return String((_a_name = a.name) != null ? _a_name : '').localeCompare(String((_b_name = b.name) != null ? _b_name : ''));
210
+ });
211
+ return /*#__PURE__*/ _jsx(CardDisplay, {
212
+ header: 'Local delivery',
213
+ help: pluginDocsHelp('commerce', {
214
+ anchor: '#pickup-and-local-delivery'
215
+ }),
216
+ HeaderProps: {
217
+ action: /*#__PURE__*/ _jsx(Button, {
218
+ variant: "contained",
219
+ size: "small",
220
+ disabled: !draft || badWindowLines.length > 0,
221
+ onClick: handleSave,
222
+ children: 'Save'
223
+ })
224
+ },
225
+ contentGutterX: true,
226
+ contentGutterY: true,
227
+ children: /*#__PURE__*/ _jsxs(Stack, {
228
+ spacing: 1.5,
229
+ children: [
230
+ /*#__PURE__*/ _jsx(FormControlLabel, {
231
+ control: /*#__PURE__*/ _jsx(Switch, {
232
+ size: "small",
233
+ checked: Boolean(current.enabled),
234
+ onChange: (event)=>update({
235
+ enabled: event.target.checked
236
+ })
237
+ }),
238
+ label: "Deliver orders yourself"
239
+ }),
240
+ /*#__PURE__*/ _jsx(Typography, {
241
+ variant: "caption",
242
+ color: "text.secondary",
243
+ children: 'Buyers choose local delivery at the cart, enter their postal code and book a delivery time. ' + 'You mark each order out for delivery and delivered, and the buyer is told at each step.'
244
+ }),
245
+ problems.length ? /*#__PURE__*/ _jsx(Alert, {
246
+ severity: "warning",
247
+ children: `Checkout won’t offer delivery yet: ${problems.join(' ')}`
248
+ }) : null,
249
+ /*#__PURE__*/ _jsxs(Stack, {
250
+ direction: {
251
+ xs: 'column',
252
+ sm: 'row'
253
+ },
254
+ spacing: 1,
255
+ children: [
256
+ /*#__PURE__*/ _jsx(TextField, {
257
+ label: "Country",
258
+ value: (_current_country = current.country) != null ? _current_country : '',
259
+ onChange: (event)=>update({
260
+ country: event.target.value.toUpperCase().slice(0, 2)
261
+ }),
262
+ size: "small",
263
+ placeholder: "US",
264
+ helperText: "Two letters",
265
+ sx: {
266
+ width: {
267
+ sm: 120
268
+ }
269
+ }
270
+ }),
271
+ /*#__PURE__*/ _jsxs(TextField, {
272
+ select: true,
273
+ label: "Leaves from",
274
+ value: (_current_locationId = current.locationId) != null ? _current_locationId : '',
275
+ onChange: (event)=>update({
276
+ locationId: event.target.value || undefined
277
+ }),
278
+ size: "small",
279
+ sx: {
280
+ flex: 1
281
+ },
282
+ helperText: "Its stock is reserved and sold for delivery orders",
283
+ children: [
284
+ /*#__PURE__*/ _jsx(MenuItem, {
285
+ value: "",
286
+ children: 'No particular location'
287
+ }),
288
+ locations.map((location)=>/*#__PURE__*/ _jsx(MenuItem, {
289
+ value: location.$id,
290
+ children: location.name
291
+ }, location.$id))
292
+ ]
293
+ })
294
+ ]
295
+ }),
296
+ /*#__PURE__*/ _jsx(Divider, {}),
297
+ /*#__PURE__*/ _jsx(Typography, {
298
+ variant: "subtitle2",
299
+ children: 'Zones'
300
+ }),
301
+ zones.map((zone, index)=>{
302
+ var _zone_radiusKm, _zone_postcodes;
303
+ return /*#__PURE__*/ _jsxs(Stack, {
304
+ spacing: 1,
305
+ children: [
306
+ /*#__PURE__*/ _jsxs(Stack, {
307
+ direction: {
308
+ xs: 'column',
309
+ sm: 'row'
310
+ },
311
+ spacing: 1,
312
+ children: [
313
+ /*#__PURE__*/ _jsx(TextField, {
314
+ label: "Zone name",
315
+ value: zone.name,
316
+ onChange: (event)=>updateZone(index, {
317
+ name: event.target.value
318
+ }),
319
+ size: "small",
320
+ sx: {
321
+ flex: 1
322
+ }
323
+ }),
324
+ radiusAvailable || zone.kind === 'radius' ? /*#__PURE__*/ _jsxs(TextField, {
325
+ select: true,
326
+ label: "Matched by",
327
+ value: zone.kind,
328
+ onChange: (event)=>updateZone(index, {
329
+ kind: event.target.value
330
+ }),
331
+ size: "small",
332
+ sx: {
333
+ width: {
334
+ sm: 160
335
+ }
336
+ },
337
+ children: [
338
+ /*#__PURE__*/ _jsx(MenuItem, {
339
+ value: "postcode",
340
+ children: 'Postal codes'
341
+ }),
342
+ /*#__PURE__*/ _jsx(MenuItem, {
343
+ value: "radius",
344
+ children: 'Distance'
345
+ })
346
+ ]
347
+ }) : null,
348
+ /*#__PURE__*/ _jsx(Button, {
349
+ size: "small",
350
+ color: "error",
351
+ onClick: ()=>updateZone(index, null),
352
+ children: 'Remove'
353
+ })
354
+ ]
355
+ }),
356
+ zone.kind === 'radius' ? /*#__PURE__*/ _jsx(TextField, {
357
+ label: "Within (km)",
358
+ type: "number",
359
+ value: (_zone_radiusKm = zone.radiusKm) != null ? _zone_radiusKm : '',
360
+ onChange: (event)=>updateZone(index, {
361
+ radiusKm: Number(event.target.value) || 0
362
+ }),
363
+ size: "small",
364
+ sx: {
365
+ width: {
366
+ sm: 160
367
+ }
368
+ }
369
+ }) : /*#__PURE__*/ _jsx(TextField, {
370
+ label: "Postal codes",
371
+ value: ((_zone_postcodes = zone.postcodes) != null ? _zone_postcodes : []).join(', '),
372
+ onChange: (event)=>updateZone(index, {
373
+ postcodes: event.target.value.split(',').map((code)=>code.trim()).filter(Boolean)
374
+ }),
375
+ size: "small",
376
+ placeholder: "10001, 100*, 10010-10020",
377
+ helperText: "Exact codes, a prefix ending in *, or a range"
378
+ }),
379
+ /*#__PURE__*/ _jsxs(Stack, {
380
+ direction: {
381
+ xs: 'column',
382
+ sm: 'row'
383
+ },
384
+ spacing: 1,
385
+ children: [
386
+ /*#__PURE__*/ _jsx(TextField, {
387
+ label: "Fee ($)",
388
+ value: dollars(zone.feeCents),
389
+ onChange: (event)=>updateZone(index, {
390
+ feeCents: cents(event.target.value)
391
+ }),
392
+ size: "small",
393
+ slotProps: {
394
+ htmlInput: {
395
+ inputMode: 'decimal'
396
+ }
397
+ }
398
+ }),
399
+ /*#__PURE__*/ _jsx(TextField, {
400
+ label: "Minimum order ($)",
401
+ value: dollars(zone.minimumCents),
402
+ onChange: (event)=>updateZone(index, {
403
+ minimumCents: cents(event.target.value) || undefined
404
+ }),
405
+ size: "small",
406
+ slotProps: {
407
+ htmlInput: {
408
+ inputMode: 'decimal'
409
+ }
410
+ }
411
+ }),
412
+ /*#__PURE__*/ _jsx(TextField, {
413
+ label: "Free over ($)",
414
+ value: dollars(zone.freeOverCents),
415
+ onChange: (event)=>updateZone(index, {
416
+ freeOverCents: cents(event.target.value) || undefined
417
+ }),
418
+ size: "small",
419
+ slotProps: {
420
+ htmlInput: {
421
+ inputMode: 'decimal'
422
+ }
423
+ }
424
+ })
425
+ ]
426
+ }),
427
+ /*#__PURE__*/ _jsx(Divider, {
428
+ flexItem: true
429
+ })
430
+ ]
431
+ }, zone.id);
432
+ }),
433
+ /*#__PURE__*/ _jsx(Button, {
434
+ size: "small",
435
+ sx: {
436
+ alignSelf: 'flex-start'
437
+ },
438
+ onClick: addZone,
439
+ children: 'Add zone'
440
+ }),
441
+ zones.some((zone)=>zone.kind === 'radius') ? /*#__PURE__*/ _jsxs(Stack, {
442
+ direction: "row",
443
+ spacing: 1,
444
+ sx: {
445
+ alignItems: 'center'
446
+ },
447
+ children: [
448
+ /*#__PURE__*/ _jsx(Typography, {
449
+ variant: "body2",
450
+ sx: {
451
+ flex: 1
452
+ },
453
+ children: current.origin ? `Distances measure from ${current.origin.lat.toFixed(4)}, ${current.origin.lng.toFixed(4)}.` : 'Distance zones measure from the location deliveries leave from, once it is placed on a map.'
454
+ }),
455
+ /*#__PURE__*/ _jsx(Button, {
456
+ size: "small",
457
+ disabled: locating,
458
+ onClick: handleLocate,
459
+ children: current.origin ? 'Place again' : 'Place on map'
460
+ })
461
+ ]
462
+ }) : null,
463
+ /*#__PURE__*/ _jsx(Divider, {}),
464
+ /*#__PURE__*/ _jsx(Typography, {
465
+ variant: "subtitle2",
466
+ children: 'Delivery times'
467
+ }),
468
+ /*#__PURE__*/ _jsx(TextField, {
469
+ label: "Delivery windows",
470
+ value: (_current_windows1 = current.windows) != null ? _current_windows1 : '',
471
+ onChange: (event)=>update({
472
+ windows: event.target.value
473
+ }),
474
+ multiline: true,
475
+ minRows: 2,
476
+ size: "small",
477
+ placeholder: 'Mo-Fr 09:00-12:00\nMo-Fr 13:00-17:00',
478
+ error: badWindowLines.length > 0,
479
+ helperText: badWindowLines.length ? `Line ${badWindowLines.join(', ')} does not read as days and times, like Mo-Fr 09:00-12:00.` : 'One window per line. Each line is offered on each of its days.'
480
+ }),
481
+ /*#__PURE__*/ _jsxs(Stack, {
482
+ direction: {
483
+ xs: 'column',
484
+ sm: 'row'
485
+ },
486
+ spacing: 1,
487
+ children: [
488
+ /*#__PURE__*/ _jsx(TextField, {
489
+ select: true,
490
+ label: "Order at least",
491
+ value: String((_current_leadTimeMinutes = current.leadTimeMinutes) != null ? _current_leadTimeMinutes : CommerceModel.LOCAL_DELIVERY_DEFAULT_LEAD_MINUTES),
492
+ onChange: (event)=>update({
493
+ leadTimeMinutes: Number(event.target.value)
494
+ }),
495
+ size: "small",
496
+ helperText: "Before a window starts",
497
+ sx: {
498
+ flex: 1
499
+ },
500
+ children: LEAD_TIMES.map(([minutes, label])=>/*#__PURE__*/ _jsx(MenuItem, {
501
+ value: String(minutes),
502
+ children: label
503
+ }, minutes))
504
+ }),
505
+ /*#__PURE__*/ _jsx(TextField, {
506
+ label: "Book up to (days ahead)",
507
+ type: "number",
508
+ value: (_current_daysAhead = current.daysAhead) != null ? _current_daysAhead : CommerceModel.LOCAL_DELIVERY_DEFAULT_DAYS_AHEAD,
509
+ onChange: (event)=>update({
510
+ daysAhead: Math.min(CommerceModel.LOCAL_DELIVERY_MAX_DAYS_AHEAD, Math.max(1, Math.round(Number(event.target.value)) || 1))
511
+ }),
512
+ size: "small",
513
+ sx: {
514
+ flex: 1
515
+ }
516
+ })
517
+ ]
518
+ }),
519
+ /*#__PURE__*/ _jsx(TextField, {
520
+ label: "What buyers should know",
521
+ value: (_current_instructions = current.instructions) != null ? _current_instructions : '',
522
+ onChange: (event)=>update({
523
+ instructions: event.target.value
524
+ }),
525
+ multiline: true,
526
+ minRows: 2,
527
+ size: "small",
528
+ placeholder: "We text when we’re 10 minutes away.",
529
+ slotProps: {
530
+ htmlInput: {
531
+ maxLength: CommerceModel.PICKUP_INSTRUCTIONS_MAX
532
+ }
533
+ }
534
+ })
535
+ ]
536
+ })
537
+ });
538
+ }
539
+ LocalDeliverySettingsCard.displayName = 'LocalDeliverySettingsCard';
540
+ export default LocalDeliverySettingsCard;
541
+
542
+ //# sourceMappingURL=local-delivery-settings-card.component.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../../libs/plugins/commerce/src/lib/components/console/local-delivery-settings-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\n'use client'\n\nimport * as Aglyn from '@aglyn/aglyn'\nimport { invalidOpeningHoursLines } from '@aglyn/aglyn/app-utils/local-business'\nimport * as CommerceModel from '../../model'\nimport { CardDisplay } from '@aglyn/shared-ui-jsx'\nimport { useSnackbar } from '@aglyn/shared-ui-snackstack'\nimport {\n Alert,\n Button,\n Divider,\n FormControlLabel,\n MenuItem,\n Stack,\n Switch,\n TextField,\n Typography,\n} from '@mui/material'\nimport { authorizedFetch } from '@aglyn/shared-util-http/authorized-token'\nimport { collection, doc, limit, query, setDoc } from 'firebase/firestore'\nimport { useCallback, useEffect, useState } from 'react'\nimport {\n useFirestore,\n useFirestoreCollection,\n useFirestoreDoc,\n useUser,\n writeGuardedBySeed,\n} from '@aglyn/tenant-feature-instance'\nimport { pluginDocsHelp } from '@aglyn/aglyn'\n\nexport interface LocalDeliverySettingsCardProps {\n hostId: string\n}\n\nconst LEAD_TIMES: ReadonlyArray<[number, string]> = [\n [0, 'No notice'],\n [60, '1 hour'],\n [120, '2 hours'],\n [240, '4 hours'],\n [1440, '1 day'],\n [2880, '2 days'],\n]\n\n/**\n * Local delivery (AGL-3624): the store's OWN delivery — zones by postal code\n * or by distance, each with a fee, a minimum order and a free-over\n * threshold, and the delivery windows a buyer books at the cart. Stored on\n * `settings/store.localDelivery`, written whole so a cleared field is\n * cleared. Marketplace couriers (DoorDash and the rest) are the Delivery apps\n * plugin's, and nothing here touches them.\n *\n * DISTANCE ZONES are offered only where the store's shipping address check\n * can place an address on a map (`GET /api/commerce/local-fulfillment`), and\n * need the store placed first (\"Place on map\"). Postal-code zones need\n * nothing.\n */\nexport function LocalDeliverySettingsCard(props: LocalDeliverySettingsCardProps) {\n const { hostId } = props\n const firestore = useFirestore()\n const { data: user } = useUser()\n const { enqueueSnackbar } = useSnackbar()\n const { data: store, status: storeStatus, fromCache } = useFirestoreDoc<any>(\n () => doc(firestore, 'hosts', hostId, 'settings', 'store'),\n [firestore, hostId],\n )\n const { data: locationDocs } = useFirestoreCollection<any>(\n () => query(collection(firestore, 'hosts', hostId, 'locations'), limit(25)),\n [firestore, hostId],\n { idField: '$id' },\n )\n const [draft, setDraft] = useState<CommerceModel.LocalDeliverySettings | null>(null)\n const current: CommerceModel.LocalDeliverySettings = draft ?? (store?.localDelivery as CommerceModel.LocalDeliverySettings) ?? {}\n const update = (patch: Partial<CommerceModel.LocalDeliverySettings>) => setDraft({ ...current, ...patch })\n const [radiusAvailable, setRadiusAvailable] = useState(false)\n useEffect(() => {\n let live = true\n authorizedFetch(user, `/api/commerce/local-fulfillment?hostId=${encodeURIComponent(hostId)}`)\n .then((response) => (response.ok ? response.json() : null))\n .then((answer) => {\n if (live) setRadiusAvailable(Boolean(answer?.radius))\n })\n .catch(() => undefined)\n return () => {\n live = false\n }\n }, [hostId, user])\n\n const zones = current.zones ?? []\n const updateZone = (index: number, patch: Partial<CommerceModel.LocalDeliveryZone> | null) => {\n const next = [...zones]\n if (patch === null) next.splice(index, 1)\n else next[index] = { ...next[index], ...patch }\n update({ zones: next })\n }\n const addZone = () =>\n update({\n zones: [\n ...zones,\n { id: Aglyn.createResourceUid(), name: 'Local delivery', kind: 'postcode', postcodes: [], feeCents: 0 },\n ],\n })\n\n const [locating, setLocating] = useState(false)\n const handleLocate = useCallback(async () => {\n if (!current.locationId) {\n return void enqueueSnackbar('Choose the location deliveries leave from first', { variant: 'info', persist: false })\n }\n setLocating(true)\n try {\n const response = await authorizedFetch(user, '/api/commerce/local-fulfillment', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ hostId, action: 'locate', locationId: current.locationId }),\n })\n const payload: any = await response.json().catch(() => ({}))\n if (!response.ok || !payload?.origin) {\n enqueueSnackbar(payload?.error ?? 'Could not place the store on a map', { variant: 'warning', persist: false })\n return\n }\n setDraft({ ...current, origin: payload.origin })\n } finally {\n setLocating(false)\n }\n }, [current, enqueueSnackbar, hostId, user])\n\n const badWindowLines = invalidOpeningHoursLines(current.windows ?? '')\n const problems = CommerceModel.localDeliveryProblems(CommerceModel.normalizeLocalDeliverySettings(current))\n\n const handleSave = useCallback(async () => {\n const value = CommerceModel.normalizeLocalDeliverySettings(current)\n const verdict = await writeGuardedBySeed(\n { subject: 'local delivery settings', unreadable: storeStatus === 'error', fromCache },\n async () => {\n // `mergeFields` replaces `localDelivery` whole and leaves every other\n // map on the settings document alone.\n await setDoc(doc(firestore, 'hosts', hostId, 'settings', 'store'), { localDelivery: value }, {\n mergeFields: ['localDelivery'],\n })\n },\n )\n if (!verdict.ok) {\n return void enqueueSnackbar(verdict.message, { variant: 'warning', persist: false })\n }\n setDraft(null)\n enqueueSnackbar('Local delivery saved', { variant: 'success', persist: false })\n }, [current, enqueueSnackbar, firestore, fromCache, hostId, storeStatus])\n\n const dollars = (cents: number | undefined) => (cents ? String(cents / 100) : '')\n const cents = (raw: string) => (raw.trim() === '' ? 0 : Math.max(0, Math.round(Number(raw) * 100) || 0))\n const locations = [...(locationDocs ?? [])].sort((a: any, b: any) =>\n String(a.name ?? '').localeCompare(String(b.name ?? '')),\n )\n\n return (\n <CardDisplay\n header={'Local delivery'}\n help={pluginDocsHelp('commerce', { anchor: '#pickup-and-local-delivery' })}\n HeaderProps={{\n action: (\n <Button variant=\"contained\" size=\"small\" disabled={!draft || badWindowLines.length > 0} onClick={handleSave}>\n {'Save'}\n </Button>\n ),\n }}\n contentGutterX\n contentGutterY\n >\n <Stack spacing={1.5}>\n <FormControlLabel\n control={\n <Switch\n size=\"small\"\n checked={Boolean(current.enabled)}\n onChange={(event) => update({ enabled: event.target.checked })}\n />\n }\n label=\"Deliver orders yourself\"\n />\n <Typography variant=\"caption\" color=\"text.secondary\">\n {'Buyers choose local delivery at the cart, enter their postal code and book a delivery time. ' +\n 'You mark each order out for delivery and delivered, and the buyer is told at each step.'}\n </Typography>\n {problems.length ? (\n <Alert severity=\"warning\">{`Checkout won’t offer delivery yet: ${problems.join(' ')}`}</Alert>\n ) : null}\n <Stack direction={{ xs: 'column', sm: 'row' }} spacing={1}>\n <TextField\n label=\"Country\"\n value={current.country ?? ''}\n onChange={(event) => update({ country: event.target.value.toUpperCase().slice(0, 2) })}\n size=\"small\"\n placeholder=\"US\"\n helperText=\"Two letters\"\n sx={{ width: { sm: 120 } }}\n />\n <TextField\n select\n label=\"Leaves from\"\n value={current.locationId ?? ''}\n onChange={(event) => update({ locationId: event.target.value || undefined })}\n size=\"small\"\n sx={{ flex: 1 }}\n helperText=\"Its stock is reserved and sold for delivery orders\"\n >\n <MenuItem value=\"\">{'No particular location'}</MenuItem>\n {locations.map((location: any) => (\n <MenuItem key={location.$id} value={location.$id}>\n {location.name}\n </MenuItem>\n ))}\n </TextField>\n </Stack>\n\n <Divider />\n <Typography variant=\"subtitle2\">{'Zones'}</Typography>\n {zones.map((zone, index) => (\n <Stack key={zone.id} spacing={1}>\n <Stack direction={{ xs: 'column', sm: 'row' }} spacing={1}>\n <TextField\n label=\"Zone name\"\n value={zone.name}\n onChange={(event) => updateZone(index, { name: event.target.value })}\n size=\"small\"\n sx={{ flex: 1 }}\n />\n {radiusAvailable || zone.kind === 'radius' ? (\n <TextField\n select\n label=\"Matched by\"\n value={zone.kind}\n onChange={(event) =>\n updateZone(index, { kind: event.target.value as CommerceModel.LocalDeliveryZone['kind'] })\n }\n size=\"small\"\n sx={{ width: { sm: 160 } }}\n >\n <MenuItem value=\"postcode\">{'Postal codes'}</MenuItem>\n <MenuItem value=\"radius\">{'Distance'}</MenuItem>\n </TextField>\n ) : null}\n <Button size=\"small\" color=\"error\" onClick={() => updateZone(index, null)}>\n {'Remove'}\n </Button>\n </Stack>\n {zone.kind === 'radius' ? (\n <TextField\n label=\"Within (km)\"\n type=\"number\"\n value={zone.radiusKm ?? ''}\n onChange={(event) => updateZone(index, { radiusKm: Number(event.target.value) || 0 })}\n size=\"small\"\n sx={{ width: { sm: 160 } }}\n />\n ) : (\n <TextField\n label=\"Postal codes\"\n value={(zone.postcodes ?? []).join(', ')}\n onChange={(event) =>\n updateZone(index, {\n postcodes: event.target.value.split(',').map((code) => code.trim()).filter(Boolean),\n })\n }\n size=\"small\"\n placeholder=\"10001, 100*, 10010-10020\"\n helperText=\"Exact codes, a prefix ending in *, or a range\"\n />\n )}\n <Stack direction={{ xs: 'column', sm: 'row' }} spacing={1}>\n <TextField\n label=\"Fee ($)\"\n value={dollars(zone.feeCents)}\n onChange={(event) => updateZone(index, { feeCents: cents(event.target.value) })}\n size=\"small\"\n slotProps={{ htmlInput: { inputMode: 'decimal' } }}\n />\n <TextField\n label=\"Minimum order ($)\"\n value={dollars(zone.minimumCents)}\n onChange={(event) => updateZone(index, { minimumCents: cents(event.target.value) || undefined })}\n size=\"small\"\n slotProps={{ htmlInput: { inputMode: 'decimal' } }}\n />\n <TextField\n label=\"Free over ($)\"\n value={dollars(zone.freeOverCents)}\n onChange={(event) => updateZone(index, { freeOverCents: cents(event.target.value) || undefined })}\n size=\"small\"\n slotProps={{ htmlInput: { inputMode: 'decimal' } }}\n />\n </Stack>\n <Divider flexItem />\n </Stack>\n ))}\n <Button size=\"small\" sx={{ alignSelf: 'flex-start' }} onClick={addZone}>\n {'Add zone'}\n </Button>\n {zones.some((zone) => zone.kind === 'radius') ? (\n <Stack direction=\"row\" spacing={1} sx={{ alignItems: 'center' }}>\n <Typography variant=\"body2\" sx={{ flex: 1 }}>\n {current.origin\n ? `Distances measure from ${current.origin.lat.toFixed(4)}, ${current.origin.lng.toFixed(4)}.`\n : 'Distance zones measure from the location deliveries leave from, once it is placed on a map.'}\n </Typography>\n <Button size=\"small\" disabled={locating} onClick={handleLocate}>\n {current.origin ? 'Place again' : 'Place on map'}\n </Button>\n </Stack>\n ) : null}\n\n <Divider />\n <Typography variant=\"subtitle2\">{'Delivery times'}</Typography>\n <TextField\n label=\"Delivery windows\"\n value={current.windows ?? ''}\n onChange={(event) => update({ windows: event.target.value })}\n multiline\n minRows={2}\n size=\"small\"\n placeholder={'Mo-Fr 09:00-12:00\\nMo-Fr 13:00-17:00'}\n error={badWindowLines.length > 0}\n helperText={\n badWindowLines.length\n ? `Line ${badWindowLines.join(', ')} does not read as days and times, like Mo-Fr 09:00-12:00.`\n : 'One window per line. Each line is offered on each of its days.'\n }\n />\n <Stack direction={{ xs: 'column', sm: 'row' }} spacing={1}>\n <TextField\n select\n label=\"Order at least\"\n value={String(current.leadTimeMinutes ?? CommerceModel.LOCAL_DELIVERY_DEFAULT_LEAD_MINUTES)}\n onChange={(event) => update({ leadTimeMinutes: Number(event.target.value) })}\n size=\"small\"\n helperText=\"Before a window starts\"\n sx={{ flex: 1 }}\n >\n {LEAD_TIMES.map(([minutes, label]) => (\n <MenuItem key={minutes} value={String(minutes)}>\n {label}\n </MenuItem>\n ))}\n </TextField>\n <TextField\n label=\"Book up to (days ahead)\"\n type=\"number\"\n value={current.daysAhead ?? CommerceModel.LOCAL_DELIVERY_DEFAULT_DAYS_AHEAD}\n onChange={(event) =>\n update({\n daysAhead: Math.min(\n CommerceModel.LOCAL_DELIVERY_MAX_DAYS_AHEAD,\n Math.max(1, Math.round(Number(event.target.value)) || 1),\n ),\n })\n }\n size=\"small\"\n sx={{ flex: 1 }}\n />\n </Stack>\n <TextField\n label=\"What buyers should know\"\n value={current.instructions ?? ''}\n onChange={(event) => update({ instructions: event.target.value })}\n multiline\n minRows={2}\n size=\"small\"\n placeholder=\"We text when we’re 10 minutes away.\"\n slotProps={{ htmlInput: { maxLength: CommerceModel.PICKUP_INSTRUCTIONS_MAX } }}\n />\n </Stack>\n </CardDisplay>\n )\n}\nLocalDeliverySettingsCard.displayName = 'LocalDeliverySettingsCard'\n\nexport default LocalDeliverySettingsCard\n"],"names":["Aglyn","invalidOpeningHoursLines","CommerceModel","CardDisplay","useSnackbar","Alert","Button","Divider","FormControlLabel","MenuItem","Stack","Switch","TextField","Typography","authorizedFetch","collection","doc","limit","query","setDoc","useCallback","useEffect","useState","useFirestore","useFirestoreCollection","useFirestoreDoc","useUser","writeGuardedBySeed","pluginDocsHelp","LEAD_TIMES","LocalDeliverySettingsCard","props","draft","current","hostId","firestore","data","user","enqueueSnackbar","store","status","storeStatus","fromCache","locationDocs","idField","setDraft","localDelivery","update","patch","radiusAvailable","setRadiusAvailable","live","encodeURIComponent","then","response","ok","json","answer","Boolean","radius","catch","undefined","zones","updateZone","index","next","splice","addZone","id","createResourceUid","name","kind","postcodes","feeCents","locating","setLocating","handleLocate","locationId","variant","persist","method","headers","body","JSON","stringify","action","payload","origin","error","badWindowLines","windows","problems","localDeliveryProblems","normalizeLocalDeliverySettings","handleSave","value","verdict","subject","unreadable","mergeFields","message","dollars","cents","String","raw","trim","Math","max","round","Number","locations","sort","a","b","localeCompare","header","help","anchor","HeaderProps","size","disabled","length","onClick","contentGutterX","contentGutterY","spacing","control","checked","enabled","onChange","event","target","label","color","severity","join","direction","xs","sm","country","toUpperCase","slice","placeholder","helperText","sx","width","select","flex","map","location","$id","zone","type","radiusKm","split","code","filter","slotProps","htmlInput","inputMode","minimumCents","freeOverCents","flexItem","alignSelf","some","alignItems","lat","toFixed","lng","multiline","minRows","leadTimeMinutes","LOCAL_DELIVERY_DEFAULT_LEAD_MINUTES","minutes","daysAhead","LOCAL_DELIVERY_DEFAULT_DAYS_AHEAD","min","LOCAL_DELIVERY_MAX_DAYS_AHEAD","instructions","maxLength","PICKUP_INSTRUCTIONS_MAX","displayName"],"mappings":"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"}