@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.
- package/package.json +13 -13
- package/src/lib/components/cart-extras.d.ts +6 -0
- package/src/lib/components/cart-extras.js +4 -1
- package/src/lib/components/cart-extras.js.map +1 -1
- package/src/lib/components/cart-fulfillment.d.ts +117 -0
- package/src/lib/components/cart-fulfillment.js +367 -0
- package/src/lib/components/cart-fulfillment.js.map +1 -0
- package/src/lib/components/cart.js +52 -10
- package/src/lib/components/cart.js.map +1 -1
- package/src/lib/components/commerce-console-page.js +42 -1
- package/src/lib/components/commerce-console-page.js.map +1 -1
- package/src/lib/components/console/host-orders-card.component.js +38 -10
- package/src/lib/components/console/host-orders-card.component.js.map +1 -1
- package/src/lib/components/console/local-delivery-settings-card.component.d.ts +37 -0
- package/src/lib/components/console/local-delivery-settings-card.component.js +542 -0
- package/src/lib/components/console/local-delivery-settings-card.component.js.map +1 -0
- package/src/lib/components/console/locations-card.component.js +177 -3
- package/src/lib/components/console/locations-card.component.js.map +1 -1
- package/src/lib/components/console/order-detail-dialog.component.js +10 -0
- package/src/lib/components/console/order-detail-dialog.component.js.map +1 -1
- package/src/lib/components/console/order-local-fulfillment-panel.component.d.ts +44 -0
- package/src/lib/components/console/order-local-fulfillment-panel.component.js +265 -0
- package/src/lib/components/console/order-local-fulfillment-panel.component.js.map +1 -0
- package/src/lib/components/console/order-offline-notice.component.d.ts +12 -0
- package/src/lib/components/console/order-offline-notice.component.js +53 -0
- package/src/lib/components/console/order-offline-notice.component.js.map +1 -0
- package/src/lib/components/console/pickup-delivery-queue-card.component.d.ts +35 -0
- package/src/lib/components/console/pickup-delivery-queue-card.component.js +222 -0
- package/src/lib/components/console/pickup-delivery-queue-card.component.js.map +1 -0
- package/src/lib/components/console/pos/pos-api.d.ts +24 -1
- package/src/lib/components/console/pos/pos-api.js +13 -0
- package/src/lib/components/console/pos/pos-api.js.map +1 -1
- package/src/lib/components/console/pos/pos-item-dialog.component.d.ts +12 -0
- package/src/lib/components/console/pos/pos-item-dialog.component.js +10 -8
- package/src/lib/components/console/pos/pos-item-dialog.component.js.map +1 -1
- package/src/lib/components/console/pos/pos-kiosk-queue.component.d.ts +22 -0
- package/src/lib/components/console/pos/pos-kiosk-queue.component.js +168 -0
- package/src/lib/components/console/pos/pos-kiosk-queue.component.js.map +1 -0
- package/src/lib/components/console/pos/pos-tender-dialogs.component.d.ts +18 -0
- package/src/lib/components/console/pos/pos-tender-dialogs.component.js +116 -1
- package/src/lib/components/console/pos/pos-tender-dialogs.component.js.map +1 -1
- package/src/lib/components/console/pos/pos-tender-panel.component.d.ts +8 -0
- package/src/lib/components/console/pos/pos-tender-panel.component.js +77 -18
- package/src/lib/components/console/pos/pos-tender-panel.component.js.map +1 -1
- package/src/lib/components/console/pos/use-pos-display.d.ts +5 -2
- package/src/lib/components/console/pos/use-pos-display.js +3 -2
- package/src/lib/components/console/pos/use-pos-display.js.map +1 -1
- package/src/lib/components/console/pos-devices-card.component.js +2 -2
- package/src/lib/components/console/pos-devices-card.component.js.map +1 -1
- package/src/lib/components/console/pos-display/pairing-screen.d.ts +5 -2
- package/src/lib/components/console/pos-display/pairing-screen.js +7 -5
- package/src/lib/components/console/pos-display/pairing-screen.js.map +1 -1
- package/src/lib/components/console/pos-display/pos-display-api.d.ts +7 -1
- package/src/lib/components/console/pos-display/pos-display-api.js +7 -2
- package/src/lib/components/console/pos-display/pos-display-api.js.map +1 -1
- package/src/lib/components/console/pos-kiosk/kiosk-checkout.d.ts +41 -0
- package/src/lib/components/console/pos-kiosk/kiosk-checkout.js +275 -0
- package/src/lib/components/console/pos-kiosk/kiosk-checkout.js.map +1 -0
- package/src/lib/components/console/pos-kiosk/kiosk-menu.d.ts +32 -0
- package/src/lib/components/console/pos-kiosk/kiosk-menu.js +344 -0
- package/src/lib/components/console/pos-kiosk/kiosk-menu.js.map +1 -0
- package/src/lib/components/console/pos-kiosk/kiosk-staff.d.ts +12 -0
- package/src/lib/components/console/pos-kiosk/kiosk-staff.js +257 -0
- package/src/lib/components/console/pos-kiosk/kiosk-staff.js.map +1 -0
- package/src/lib/components/console/pos-kiosk/pos-kiosk-api.d.ts +114 -0
- package/src/lib/components/console/pos-kiosk/pos-kiosk-api.js +189 -0
- package/src/lib/components/console/pos-kiosk/pos-kiosk-api.js.map +1 -0
- package/src/lib/components/console/pos-kiosk/use-kiosk-idle.d.ts +16 -0
- package/src/lib/components/console/pos-kiosk/use-kiosk-idle.js +80 -0
- package/src/lib/components/console/pos-kiosk/use-kiosk-idle.js.map +1 -0
- package/src/lib/components/console/pos-kiosk-page.component.d.ts +28 -0
- package/src/lib/components/console/pos-kiosk-page.component.js +791 -0
- package/src/lib/components/console/pos-kiosk-page.component.js.map +1 -0
- package/src/lib/components/console/pos-offline/pos-offline-api.d.ts +44 -0
- package/src/lib/components/console/pos-offline/pos-offline-api.js +69 -0
- package/src/lib/components/console/pos-offline/pos-offline-api.js.map +1 -0
- package/src/lib/components/console/pos-offline/pos-offline-banner.component.d.ts +7 -0
- package/src/lib/components/console/pos-offline/pos-offline-banner.component.js +135 -0
- package/src/lib/components/console/pos-offline/pos-offline-banner.component.js.map +1 -0
- package/src/lib/components/console/pos-offline/pos-offline-checkout.component.d.ts +32 -0
- package/src/lib/components/console/pos-offline/pos-offline-checkout.component.js +287 -0
- package/src/lib/components/console/pos-offline/pos-offline-checkout.component.js.map +1 -0
- package/src/lib/components/console/pos-offline/pos-offline-store.d.ts +63 -0
- package/src/lib/components/console/pos-offline/pos-offline-store.js +145 -0
- package/src/lib/components/console/pos-offline/pos-offline-store.js.map +1 -0
- package/src/lib/components/console/pos-offline/register-offline.d.ts +24 -0
- package/src/lib/components/console/pos-offline/register-offline.js +24 -0
- package/src/lib/components/console/pos-offline/register-offline.js.map +1 -0
- package/src/lib/components/console/pos-offline/use-pos-offline.d.ts +85 -0
- package/src/lib/components/console/pos-offline/use-pos-offline.js +542 -0
- package/src/lib/components/console/pos-offline/use-pos-offline.js.map +1 -0
- package/src/lib/components/console/pos-ops/pos-shift-history-card.component.js +72 -17
- package/src/lib/components/console/pos-ops/pos-shift-history-card.component.js.map +1 -1
- package/src/lib/components/console/pos-page.component.js +174 -27
- package/src/lib/components/console/pos-page.component.js.map +1 -1
- package/src/lib/components/console/products-hub-card.component.js +35 -10
- package/src/lib/components/console/products-hub-card.component.js.map +1 -1
- package/src/lib/components/console/shipping-settings-card.component.js +1 -1
- package/src/lib/components/console/shipping-settings-card.component.js.map +1 -1
- package/src/lib/components/console/stock-movements-card.component.js +48 -16
- package/src/lib/components/console/stock-movements-card.component.js.map +1 -1
- package/src/lib/components/console/store-zones.d.ts +8 -1
- package/src/lib/components/console/store-zones.js +11 -1
- package/src/lib/components/console/store-zones.js.map +1 -1
- package/src/lib/components/order-status.js +66 -0
- package/src/lib/components/order-status.js.map +1 -1
- package/src/lib/components/product-detail.js +42 -15
- package/src/lib/components/product-detail.js.map +1 -1
- package/src/lib/constants/local-fulfillment-list-query.d.ts +48 -0
- package/src/lib/constants/local-fulfillment-list-query.js +84 -0
- package/src/lib/constants/local-fulfillment-list-query.js.map +1 -0
- package/src/lib/constants/orders-list-query.d.ts +7 -2
- package/src/lib/constants/orders-list-query.js +89 -8
- package/src/lib/constants/orders-list-query.js.map +1 -1
- package/src/lib/constants/pos-shift-list-query.d.ts +22 -0
- package/src/lib/constants/pos-shift-list-query.js +115 -0
- package/src/lib/constants/pos-shift-list-query.js.map +1 -0
- package/src/lib/constants/product-list-query.d.ts +6 -1
- package/src/lib/constants/product-list-query.js +77 -8
- package/src/lib/constants/product-list-query.js.map +1 -1
- package/src/lib/constants/stock-movement-query.d.ts +3 -2
- package/src/lib/constants/stock-movement-query.js +52 -8
- package/src/lib/constants/stock-movement-query.js.map +1 -1
- package/src/lib/model/buyer-notifications.d.ts +5 -3
- package/src/lib/model/buyer-notifications.js +25 -4
- package/src/lib/model/buyer-notifications.js.map +1 -1
- package/src/lib/model/commerce-orders.d.ts +59 -0
- package/src/lib/model/commerce-orders.js.map +1 -1
- package/src/lib/model/commerce-pos-kiosk.d.ts +175 -0
- package/src/lib/model/commerce-pos-kiosk.js +147 -0
- package/src/lib/model/commerce-pos-kiosk.js.map +1 -0
- package/src/lib/model/commerce-pos-offline.d.ts +234 -0
- package/src/lib/model/commerce-pos-offline.js +301 -0
- package/src/lib/model/commerce-pos-offline.js.map +1 -0
- package/src/lib/model/commerce-pos-ops.d.ts +16 -6
- package/src/lib/model/commerce-pos-ops.js +12 -4
- package/src/lib/model/commerce-pos-ops.js.map +1 -1
- package/src/lib/model/commerce-pos.d.ts +13 -1
- package/src/lib/model/commerce-pos.js +5 -4
- package/src/lib/model/commerce-pos.js.map +1 -1
- package/src/lib/model/commerce-stock-holds.d.ts +24 -3
- package/src/lib/model/commerce-stock-holds.js +26 -8
- package/src/lib/model/commerce-stock-holds.js.map +1 -1
- package/src/lib/model/commerce.d.ts +3 -0
- package/src/lib/model/commerce.js.map +1 -1
- package/src/lib/model/index.d.ts +4 -0
- package/src/lib/model/index.js +4 -0
- package/src/lib/model/index.js.map +1 -1
- package/src/lib/model/local-fulfillment-settings.d.ts +178 -0
- package/src/lib/model/local-fulfillment-settings.js +361 -0
- package/src/lib/model/local-fulfillment-settings.js.map +1 -0
- package/src/lib/model/order-list-fields.d.ts +10 -1
- package/src/lib/model/order-list-fields.js +1 -0
- package/src/lib/model/order-list-fields.js.map +1 -1
- package/src/lib/model/order-local-fulfillment.d.ts +131 -0
- package/src/lib/model/order-local-fulfillment.js +125 -0
- package/src/lib/model/order-local-fulfillment.js.map +1 -0
- package/src/lib/model/order-shipping-export.js +4 -0
- package/src/lib/model/order-shipping-export.js.map +1 -1
- package/src/lib/model/order-status-view.d.ts +20 -1
- package/src/lib/model/order-status-view.js +60 -6
- package/src/lib/model/order-status-view.js.map +1 -1
- package/src/lib/plugin-config.js +6 -2
- package/src/lib/plugin-config.js.map +1 -1
- package/src/lib/plugin.js +8 -0
- package/src/lib/plugin.js.map +1 -1
- package/src/lib/pos-kiosk-config.d.ts +26 -0
- package/src/lib/pos-kiosk-config.js +59 -0
- package/src/lib/pos-kiosk-config.js.map +1 -0
- package/src/lib/server/api-v1/openapi.js +8 -0
- package/src/lib/server/api-v1/openapi.js.map +1 -1
- package/src/lib/server/api-v1/order-view.d.ts +19 -0
- package/src/lib/server/api-v1/order-view.js +35 -0
- package/src/lib/server/api-v1/order-view.js.map +1 -1
- package/src/lib/server/billing-webhook.js +238 -87
- package/src/lib/server/billing-webhook.js.map +1 -1
- package/src/lib/server/cart-checkout.d.ts +2 -0
- package/src/lib/server/cart-checkout.js +173 -13
- package/src/lib/server/cart-checkout.js.map +1 -1
- package/src/lib/server/checkout-extras.js +18 -4
- package/src/lib/server/checkout-extras.js.map +1 -1
- package/src/lib/server/checkout.js +71 -14
- package/src/lib/server/checkout.js.map +1 -1
- package/src/lib/server/local-fulfillment-status.d.ts +86 -0
- package/src/lib/server/local-fulfillment-status.js +379 -0
- package/src/lib/server/local-fulfillment-status.js.map +1 -0
- package/src/lib/server/local-fulfillment.d.ts +190 -0
- package/src/lib/server/local-fulfillment.js +580 -0
- package/src/lib/server/local-fulfillment.js.map +1 -0
- package/src/lib/server/membership-register.js +3 -1
- package/src/lib/server/membership-register.js.map +1 -1
- package/src/lib/server/order-notifications.js +61 -0
- package/src/lib/server/order-notifications.js.map +1 -1
- package/src/lib/server/pos-display.d.ts +27 -1
- package/src/lib/server/pos-display.js +50 -9
- package/src/lib/server/pos-display.js.map +1 -1
- package/src/lib/server/pos-kiosk-principal.d.ts +29 -0
- package/src/lib/server/pos-kiosk-principal.js +42 -0
- package/src/lib/server/pos-kiosk-principal.js.map +1 -0
- package/src/lib/server/pos-kiosk.d.ts +54 -0
- package/src/lib/server/pos-kiosk.js +972 -0
- package/src/lib/server/pos-kiosk.js.map +1 -0
- package/src/lib/server/pos-offline-sync.d.ts +85 -0
- package/src/lib/server/pos-offline-sync.js +765 -0
- package/src/lib/server/pos-offline-sync.js.map +1 -0
- package/src/lib/server/pos-order.js +22 -4
- package/src/lib/server/pos-order.js.map +1 -1
- package/src/lib/server/pos-payment.d.ts +6 -0
- package/src/lib/server/pos-payment.js +225 -6
- package/src/lib/server/pos-payment.js.map +1 -1
- package/src/lib/server/pos-print.js +5 -0
- package/src/lib/server/pos-print.js.map +1 -1
- package/src/lib/server/pos-return.js +27 -0
- package/src/lib/server/pos-return.js.map +1 -1
- package/src/lib/server/pos-sale.d.ts +6 -0
- package/src/lib/server/pos-sale.js +2 -0
- package/src/lib/server/pos-sale.js.map +1 -1
- package/src/lib/server/pos-shift.js +8 -1
- package/src/lib/server/pos-shift.js.map +1 -1
- package/src/lib/server/refund.js +3 -0
- package/src/lib/server/refund.js.map +1 -1
- package/src/lib/server/stock-hold.d.ts +9 -1
- package/src/lib/server/stock-hold.js +15 -7
- package/src/lib/server/stock-hold.js.map +1 -1
- package/src/lib/server.js +16 -0
- package/src/lib/server.js.map +1 -1
- package/src/lib/tenant-emails.js +161 -0
- package/src/lib/tenant-emails.js.map +1 -1
|
@@ -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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"}
|