@wix/headless-restaurants-olo 0.0.33 → 0.0.35
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/cjs/dist/react/FulfillmentDetails.d.ts +139 -15
- package/cjs/dist/react/FulfillmentDetails.js +128 -24
- package/cjs/dist/react/ItemDetails.d.ts +4 -4
- package/cjs/dist/react/ItemDetails.js +5 -6
- package/cjs/dist/react/Settings.d.ts +8 -0
- package/cjs/dist/react/Settings.js +18 -25
- package/cjs/dist/react/core/FulfillmentDetails.d.ts +73 -7
- package/cjs/dist/react/core/FulfillmentDetails.js +133 -86
- package/cjs/dist/react/core/ItemDetails.d.ts +1 -1
- package/cjs/dist/react/core/ItemDetails.js +5 -16
- package/cjs/dist/react/core/Settings.d.ts +19 -4
- package/cjs/dist/react/core/Settings.js +29 -20
- package/cjs/dist/services/fulfillment-details-service.d.ts +127 -0
- package/cjs/dist/services/fulfillment-details-service.js +351 -0
- package/cjs/dist/services/fulfillments-service.js +67 -43
- package/cjs/dist/services/index.d.ts +2 -0
- package/cjs/dist/services/index.js +1 -0
- package/cjs/dist/services/item-details-service.d.ts +1 -1
- package/cjs/dist/services/item-details-service.js +10 -16
- package/cjs/dist/services/olo-settings-service.d.ts +0 -1
- package/cjs/dist/services/olo-settings-service.js +1 -3
- package/cjs/dist/services/utils.d.ts +4 -0
- package/cjs/dist/services/utils.js +12 -0
- package/cjs/dist/types/fulfillments-types.d.ts +18 -1
- package/cjs/dist/types/fulfillments-types.js +9 -0
- package/cjs/dist/utils/date-utils.d.ts +164 -0
- package/cjs/dist/utils/date-utils.js +297 -0
- package/cjs/dist/utils/fulfillments-utils.d.ts +3 -2
- package/cjs/dist/utils/fulfillments-utils.js +13 -57
- package/dist/react/FulfillmentDetails.d.ts +139 -15
- package/dist/react/FulfillmentDetails.js +128 -24
- package/dist/react/ItemDetails.d.ts +4 -4
- package/dist/react/ItemDetails.js +5 -6
- package/dist/react/Settings.d.ts +8 -0
- package/dist/react/Settings.js +18 -25
- package/dist/react/core/FulfillmentDetails.d.ts +73 -7
- package/dist/react/core/FulfillmentDetails.js +133 -86
- package/dist/react/core/ItemDetails.d.ts +1 -1
- package/dist/react/core/ItemDetails.js +5 -16
- package/dist/react/core/Settings.d.ts +19 -4
- package/dist/react/core/Settings.js +29 -20
- package/dist/services/fulfillment-details-service.d.ts +127 -0
- package/dist/services/fulfillment-details-service.js +351 -0
- package/dist/services/fulfillments-service.js +67 -43
- package/dist/services/index.d.ts +2 -0
- package/dist/services/index.js +1 -0
- package/dist/services/item-details-service.d.ts +1 -1
- package/dist/services/item-details-service.js +10 -16
- package/dist/services/olo-settings-service.d.ts +0 -1
- package/dist/services/olo-settings-service.js +1 -3
- package/dist/services/utils.d.ts +4 -0
- package/dist/services/utils.js +12 -0
- package/dist/types/fulfillments-types.d.ts +18 -1
- package/dist/types/fulfillments-types.js +9 -0
- package/dist/utils/date-utils.d.ts +164 -0
- package/dist/utils/date-utils.js +297 -0
- package/dist/utils/fulfillments-utils.d.ts +3 -2
- package/dist/utils/fulfillments-utils.js +13 -57
- package/package.json +3 -2
|
@@ -2,8 +2,8 @@ import { defineService, implementService } from '@wix/services-definitions';
|
|
|
2
2
|
import { SignalsServiceDefinition } from '@wix/services-definitions/core-services/signals';
|
|
3
3
|
import * as operationsSDK from '@wix/auto_sdk_restaurants_operations';
|
|
4
4
|
import * as fulfillemtMethodsSDK from '@wix/auto_sdk_restaurants_fulfillment-methods';
|
|
5
|
-
import { processFulfillments, processFulfillmentTimeSlotByOperationList, } from '../utils/fulfillments-utils.js';
|
|
6
|
-
import { DispatchType, } from '../types/fulfillments-types.js';
|
|
5
|
+
import { convertDateToTimezone, getLocale, getTimezone, processFulfillments, processFulfillmentTimeSlotByOperationList, } from '../utils/fulfillments-utils.js';
|
|
6
|
+
import { DispatchType, FulfillmentTypeEnum, } from '../types/fulfillments-types.js';
|
|
7
7
|
export const FulfillmentsServiceDefinition = defineService('fulfillments');
|
|
8
8
|
export const FulfillmentsService = implementService.withConfig()(FulfillmentsServiceDefinition, ({ getService, config }) => {
|
|
9
9
|
if (!config.operation) {
|
|
@@ -12,42 +12,80 @@ export const FulfillmentsService = implementService.withConfig()(FulfillmentsSer
|
|
|
12
12
|
const signalsService = getService(SignalsServiceDefinition);
|
|
13
13
|
const firstAvailableTimeSlotsByOperationList = new Map(config.firstAvailableTimeSlots?.map(processFulfillmentTimeSlotByOperationList) ?? []);
|
|
14
14
|
const fulfillments = signalsService.signal(config.fulfillments ?? []);
|
|
15
|
-
const firstAvailableTimeSlots = signalsService.signal(firstAvailableTimeSlotsByOperationList.get(
|
|
16
|
-
// @ts-expect-error - operation is not typed
|
|
17
|
-
config.operation?.id ?? '') ?? []);
|
|
15
|
+
const firstAvailableTimeSlots = signalsService.signal(firstAvailableTimeSlotsByOperationList.get(config.operation?.id ?? '') ?? []);
|
|
18
16
|
const isLoading = signalsService.signal(false);
|
|
19
17
|
const error = signalsService.signal(null);
|
|
20
18
|
const dispatchesInfoSignal = signalsService.signal({});
|
|
21
19
|
const selectedDispatchInfoSignal = signalsService.signal(null);
|
|
22
20
|
const asapTimeSignal = signalsService.signal(undefined);
|
|
23
21
|
const asapTimeRangeSignal = signalsService.signal(undefined);
|
|
24
|
-
|
|
25
|
-
const { dispatchesInfo } = result ?? {};
|
|
26
|
-
dispatchesInfoSignal.set(dispatchesInfo ?? {});
|
|
27
|
-
const selectedDispatchInfo = dispatchesInfoSignal.get()[selectedFulfillment.get()?.type];
|
|
28
|
-
selectedDispatchInfoSignal.set(selectedDispatchInfo ?? null);
|
|
29
|
-
const { maxTimeOptions, durationRangeOptions } = selectedDispatchInfo ?? {};
|
|
30
|
-
// const isDelivery = !!address;
|
|
31
|
-
const isAsap = !!selectedTimeSlot.get()?.startsNow;
|
|
32
|
-
// if (isDelivery && isAsap) {
|
|
33
|
-
const { fulfillmentDetails } = selectedTimeSlot.get() ?? {};
|
|
34
|
-
if (isAsap) {
|
|
35
|
-
asapTimeSignal.set(fulfillmentDetails?.maxTimeOptions ?? maxTimeOptions);
|
|
36
|
-
asapTimeRangeSignal.set(fulfillmentDetails?.durationRangeOptions ?? durationRangeOptions);
|
|
37
|
-
}
|
|
38
|
-
});
|
|
22
|
+
const selectedFulfillment = signalsService.signal(null);
|
|
39
23
|
const pickupTimeSlot = firstAvailableTimeSlots
|
|
40
24
|
.get()
|
|
41
25
|
?.find((t) => t.dispatchType === DispatchType.PICKUP) ?? null;
|
|
42
26
|
const initialSelected = pickupTimeSlot ?? firstAvailableTimeSlots.get()?.[0] ?? null;
|
|
43
27
|
const selectedTimeSlot = signalsService.signal(initialSelected);
|
|
44
|
-
const
|
|
28
|
+
const { dispatchesInfo } = processFulfillments(fulfillments.get() ?? [], firstAvailableTimeSlots.get() ?? [], config.operation ?? undefined) ?? {};
|
|
29
|
+
// Initialize selected fulfillment for initial time slot
|
|
30
|
+
if (initialSelected && fulfillments.get()?.length > 0) {
|
|
31
|
+
const timezone = getTimezone();
|
|
32
|
+
const locale = getLocale();
|
|
33
|
+
initialSelected.startTime = convertDateToTimezone(initialSelected.startTime, timezone, locale);
|
|
34
|
+
initialSelected.endTime = convertDateToTimezone(initialSelected.endTime, timezone, locale);
|
|
35
|
+
const fulfillmentList = fulfillments.get();
|
|
36
|
+
const matchingFulfillment = fulfillmentList.find((f) => f.type === initialSelected.dispatchType) ?? null;
|
|
37
|
+
selectedFulfillment.set(matchingFulfillment);
|
|
38
|
+
}
|
|
39
|
+
dispatchesInfoSignal.set(dispatchesInfo ?? {});
|
|
40
|
+
const selectedDispatchInfo = dispatchesInfoSignal.get()[selectedFulfillment.get()?.type];
|
|
41
|
+
selectedDispatchInfoSignal.set(selectedDispatchInfo ?? null);
|
|
42
|
+
const { maxTimeOptions, durationRangeOptions } = selectedDispatchInfo ?? {};
|
|
43
|
+
// const isDelivery = !!address;
|
|
44
|
+
const isAsap = !!selectedTimeSlot.get()?.startsNow;
|
|
45
|
+
// if (isDelivery && isAsap) {
|
|
46
|
+
const { fulfillmentDetails } = selectedTimeSlot.get() ?? {};
|
|
47
|
+
if (isAsap) {
|
|
48
|
+
asapTimeSignal.set(fulfillmentDetails?.maxTimeOptions ?? maxTimeOptions);
|
|
49
|
+
asapTimeRangeSignal.set(fulfillmentDetails?.durationRangeOptions ?? durationRangeOptions);
|
|
50
|
+
}
|
|
51
|
+
// });
|
|
45
52
|
const availableTypes = signalsService.signal([]);
|
|
53
|
+
const getSchedulingType = (timeSlot) => {
|
|
54
|
+
if (!timeSlot)
|
|
55
|
+
return undefined;
|
|
56
|
+
if (config.operation?.operationType === operationsSDK.SchedulingType.ASAP) {
|
|
57
|
+
return timeSlot.startsNow
|
|
58
|
+
? FulfillmentTypeEnum.ASAP
|
|
59
|
+
: FulfillmentTypeEnum.ASAP_AND_FUTURE;
|
|
60
|
+
}
|
|
61
|
+
return FulfillmentTypeEnum.PREORDER;
|
|
62
|
+
};
|
|
63
|
+
const schedulingType = signalsService.signal(getSchedulingType(initialSelected));
|
|
64
|
+
// Compute initial fulfillment type options based on time slots
|
|
65
|
+
const computeFulfillmentTypeOptions = (timeSlots) => {
|
|
66
|
+
const hasAsap = timeSlots
|
|
67
|
+
.filter((slot) => slot.dispatchType === selectedFulfillment.get()?.type)
|
|
68
|
+
.some((slot) => slot.startsNow);
|
|
69
|
+
const hasFuture = !!config.operation?.allowAsapFutureHandling;
|
|
70
|
+
return {
|
|
71
|
+
hasAsapOption: hasAsap,
|
|
72
|
+
hasPreorderOption: !hasAsap && hasFuture,
|
|
73
|
+
hasAsapAndFutureOption: hasAsap && hasFuture,
|
|
74
|
+
};
|
|
75
|
+
};
|
|
76
|
+
const initialOptions = computeFulfillmentTypeOptions(firstAvailableTimeSlots.get() ?? []);
|
|
77
|
+
const hasAsapOption = signalsService.signal(initialOptions.hasAsapOption);
|
|
78
|
+
const hasPreorderOption = signalsService.signal(initialOptions.hasPreorderOption);
|
|
79
|
+
const hasAsapAndFutureOption = signalsService.signal(initialOptions.hasAsapAndFutureOption);
|
|
46
80
|
selectedTimeSlot.set(initialSelected);
|
|
47
81
|
const selectFulfillmentType = (type) => {
|
|
48
82
|
const timeSlot = firstAvailableTimeSlots.get()?.find((t) => t.dispatchType === type) ??
|
|
49
83
|
null;
|
|
50
84
|
if (timeSlot) {
|
|
85
|
+
const timezone = getTimezone();
|
|
86
|
+
const locale = getLocale();
|
|
87
|
+
timeSlot.startTime = convertDateToTimezone(timeSlot.startTime, timezone, locale);
|
|
88
|
+
timeSlot.endTime = convertDateToTimezone(timeSlot.endTime, timezone, locale);
|
|
51
89
|
setSelectedTimeSlot(timeSlot);
|
|
52
90
|
}
|
|
53
91
|
};
|
|
@@ -56,39 +94,21 @@ export const FulfillmentsService = implementService.withConfig()(FulfillmentsSer
|
|
|
56
94
|
* This action updates:
|
|
57
95
|
* - selectedTimeSlot signal
|
|
58
96
|
* - selectedFulfillment signal (based on dispatch type)
|
|
97
|
+
* - schedulingType signal (based on order scheduling type)
|
|
59
98
|
* - minOrderPrice signal (based on fulfillment method)
|
|
60
99
|
*/
|
|
61
100
|
const setSelectedTimeSlot = (timeSlot) => {
|
|
101
|
+
console.log('setSelectedTimeSlot', timeSlot);
|
|
62
102
|
// Update the selected time slot
|
|
63
103
|
selectedTimeSlot.set(timeSlot);
|
|
104
|
+
// Update scheduling type based on order scheduling configuration
|
|
105
|
+
schedulingType.set(getSchedulingType(timeSlot));
|
|
64
106
|
// Update selected fulfillment based on dispatch type
|
|
65
107
|
const matchingFulfillment = fulfillments.get().find((f) => f.type === timeSlot.dispatchType) ??
|
|
66
108
|
null;
|
|
67
109
|
selectedFulfillment.set(matchingFulfillment);
|
|
68
110
|
selectedDispatchInfoSignal.set(dispatchesInfoSignal.get()[matchingFulfillment?.type] ?? null);
|
|
69
111
|
};
|
|
70
|
-
// Initialize selected fulfillment for initial time slot
|
|
71
|
-
if (initialSelected && fulfillments.get()?.length > 0) {
|
|
72
|
-
const fulfillmentList = fulfillments.get();
|
|
73
|
-
const matchingFulfillment = fulfillmentList.find((f) => f.type === initialSelected.dispatchType) ?? null;
|
|
74
|
-
selectedFulfillment.set(matchingFulfillment);
|
|
75
|
-
}
|
|
76
|
-
// Load time slots and fulfillments if not provided
|
|
77
|
-
if (!config.firstAvailableTimeSlots && config.operation) {
|
|
78
|
-
loadFulfillmentsServiceConfig(config.operation).then((loadedConfig) => {
|
|
79
|
-
const timeSlotsMap = new Map(loadedConfig.firstAvailableTimeSlots?.map(processFulfillmentTimeSlotByOperationList) ?? []);
|
|
80
|
-
const newTimeSlots =
|
|
81
|
-
// @ts-expect-error - operation is not typed
|
|
82
|
-
timeSlotsMap.get(loadedConfig.operation?.id ?? '') ?? [];
|
|
83
|
-
firstAvailableTimeSlots.set(newTimeSlots);
|
|
84
|
-
fulfillments.set(loadedConfig.fulfillments ?? []);
|
|
85
|
-
// Set initial time slot using the action to ensure all related signals are updated
|
|
86
|
-
const newInitialSelected = newTimeSlots[0];
|
|
87
|
-
if (newInitialSelected) {
|
|
88
|
-
setSelectedTimeSlot(newInitialSelected);
|
|
89
|
-
}
|
|
90
|
-
});
|
|
91
|
-
}
|
|
92
112
|
availableTypes.set(Array.from(new Set(firstAvailableTimeSlots.get()?.map((t) => t.dispatchType) ?? [])).sort((a, _) => (a === DispatchType.PICKUP ? -1 : 1)));
|
|
93
113
|
return {
|
|
94
114
|
firstAvailableTimeSlots,
|
|
@@ -100,6 +120,10 @@ export const FulfillmentsService = implementService.withConfig()(FulfillmentsSer
|
|
|
100
120
|
asapTimeRangeSignal,
|
|
101
121
|
selectedTimeSlot,
|
|
102
122
|
availableTypes,
|
|
123
|
+
schedulingType,
|
|
124
|
+
hasAsapOption,
|
|
125
|
+
hasPreorderOption,
|
|
126
|
+
hasAsapAndFutureOption,
|
|
103
127
|
isLoading,
|
|
104
128
|
error,
|
|
105
129
|
setSelectedTimeSlot,
|
package/dist/services/index.d.ts
CHANGED
|
@@ -2,3 +2,5 @@ export { ItemService, ItemServiceDefinition, loadItemServiceConfig, ItemServiceC
|
|
|
2
2
|
export { OLOSettingsService, OLOSettingsServiceDefinition, loadOLOSettingsServiceConfig, type OLOSettingsServiceConfig, type OLOSettingsServiceAPI, } from './olo-settings-service.js';
|
|
3
3
|
export { AvailabilityStatus, AvailabilityStatusMap, RuleType, RuleTypeMap, AddToCartButtonState, AddToCartButtonLabelMap, } from './common-types.js';
|
|
4
4
|
export { FulfillmentsService, FulfillmentsServiceDefinition, loadFulfillmentsServiceConfig, } from './fulfillments-service.js';
|
|
5
|
+
export { type FulfillmentsServiceConfig } from '../types/fulfillments-types.js';
|
|
6
|
+
export { FulfillmentDetailsService, FulfillmentDetailsServiceDefinition, loadFulfillmentDetailsServiceConfig, type FulfillmentDetailsServiceAPI, type FulfillmentDetailsServiceConfig, type AvailableDate, } from './fulfillment-details-service.js';
|
package/dist/services/index.js
CHANGED
|
@@ -2,3 +2,4 @@ export { ItemService, ItemServiceDefinition, loadItemServiceConfig, } from './it
|
|
|
2
2
|
export { OLOSettingsService, OLOSettingsServiceDefinition, loadOLOSettingsServiceConfig, } from './olo-settings-service.js';
|
|
3
3
|
export { AvailabilityStatus, RuleType, AddToCartButtonState, } from './common-types.js';
|
|
4
4
|
export { FulfillmentsService, FulfillmentsServiceDefinition, loadFulfillmentsServiceConfig, } from './fulfillments-service.js';
|
|
5
|
+
export { FulfillmentDetailsService, FulfillmentDetailsServiceDefinition, loadFulfillmentDetailsServiceConfig, } from './fulfillment-details-service.js';
|
|
@@ -16,6 +16,7 @@ export interface ItemServiceAPI {
|
|
|
16
16
|
quantity: Signal<number>;
|
|
17
17
|
specialRequest: Signal<string>;
|
|
18
18
|
lineItem: ReadOnlySignal<LineItem>;
|
|
19
|
+
onHandleAddToCart: (onClick: (lineItem: LineItem) => void) => void;
|
|
19
20
|
buttonState: ReadOnlySignal<AddToCartButtonState | undefined>;
|
|
20
21
|
addToCartButtonDisabled: Signal<boolean>;
|
|
21
22
|
price: ReadOnlySignal<number>;
|
|
@@ -43,7 +44,6 @@ export interface ItemServiceAPI {
|
|
|
43
44
|
endDate?: Date;
|
|
44
45
|
weeklyAvailabilitySummary?: WeeklyAvailability;
|
|
45
46
|
};
|
|
46
|
-
doesModifierGroupHaveError: ReadOnlySignal<boolean>;
|
|
47
47
|
}
|
|
48
48
|
/**
|
|
49
49
|
* Service definition for the Item service.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { defineService, implementService } from '@wix/services-definitions';
|
|
2
2
|
import { SignalsServiceDefinition, } from '@wix/services-definitions/core-services/signals';
|
|
3
3
|
import { AddToCartButtonState, AvailabilityStatus, } from './common-types.js';
|
|
4
|
-
import { getAreNotEnoughModifiersOfMandatoryModifierGroupInStock, getModifiersInitState, getLineItemModifiers, getPriceVariantOptions, getSelectedModifierPrices, getSelectedVariantPrice, calculateItemPrice,
|
|
4
|
+
import { getAreNotEnoughModifiersOfMandatoryModifierGroupInStock, getModifiersInitState, getLineItemModifiers, getPriceVariantOptions, getSelectedModifierPrices, getSelectedVariantPrice, calculateItemPrice, getModifierGroupErrors, } from './utils.js';
|
|
5
5
|
import { OLOSettingsServiceDefinition } from './olo-settings-service.js';
|
|
6
6
|
/**
|
|
7
7
|
* Service definition for the Item service.
|
|
@@ -131,6 +131,14 @@ export const ItemService = implementService.withConfig()(ItemServiceDefinition,
|
|
|
131
131
|
},
|
|
132
132
|
};
|
|
133
133
|
});
|
|
134
|
+
const onHandleAddToCart = (onClick) => {
|
|
135
|
+
const currentSelectedModifiers = selectedModifiers.get();
|
|
136
|
+
const { errors, hasError } = getModifierGroupErrors(currentSelectedModifiers, modifierGroups);
|
|
137
|
+
modifierGroupError.set(errors);
|
|
138
|
+
if (hasError)
|
|
139
|
+
return;
|
|
140
|
+
onClick(lineItem.get());
|
|
141
|
+
};
|
|
134
142
|
const updateQuantity = (_quantity) => {
|
|
135
143
|
quantity.set(_quantity);
|
|
136
144
|
};
|
|
@@ -164,20 +172,6 @@ export const ItemService = implementService.withConfig()(ItemServiceDefinition,
|
|
|
164
172
|
}
|
|
165
173
|
}
|
|
166
174
|
};
|
|
167
|
-
const doesModifierGroupHaveError = signalsService.computed(() => {
|
|
168
|
-
const currentSelectedModifiers = selectedModifiers.get();
|
|
169
|
-
const errors = {};
|
|
170
|
-
modifierGroups.forEach((group) => {
|
|
171
|
-
if (group._id) {
|
|
172
|
-
const selectedCount = (currentSelectedModifiers[group._id] || [])
|
|
173
|
-
.length;
|
|
174
|
-
const isValid = checkModifiersValidation(group.rule, selectedCount);
|
|
175
|
-
errors[group._id] = !isValid;
|
|
176
|
-
}
|
|
177
|
-
});
|
|
178
|
-
modifierGroupError.set(errors);
|
|
179
|
-
return Object.values(errors).some((error) => error);
|
|
180
|
-
});
|
|
181
175
|
const toggleModifier = (modifierGroupId, modifierId, singleSelect = false) => {
|
|
182
176
|
const currentSelectedModifiers = selectedModifiers.get();
|
|
183
177
|
const modifierIds = getModifierIds(modifierGroupId, modifierId, singleSelect);
|
|
@@ -206,6 +200,7 @@ export const ItemService = implementService.withConfig()(ItemServiceDefinition,
|
|
|
206
200
|
error,
|
|
207
201
|
specialRequest,
|
|
208
202
|
lineItem,
|
|
203
|
+
onHandleAddToCart,
|
|
209
204
|
selectedVariant,
|
|
210
205
|
selectedModifiers,
|
|
211
206
|
availabilityStatus,
|
|
@@ -215,7 +210,6 @@ export const ItemService = implementService.withConfig()(ItemServiceDefinition,
|
|
|
215
210
|
addToCartButtonDisabled,
|
|
216
211
|
price,
|
|
217
212
|
futureAvailability,
|
|
218
|
-
doesModifierGroupHaveError,
|
|
219
213
|
};
|
|
220
214
|
});
|
|
221
215
|
/**
|
|
@@ -4,7 +4,6 @@ import { MenusServiceConfig } from '@wix/restaurants/services';
|
|
|
4
4
|
export interface OLOSettingsServiceAPI {
|
|
5
5
|
operationGroup: Signal<operationGroupsSDK.OperationGroup | undefined>;
|
|
6
6
|
operation: Signal<operationsSDK.Operation | undefined>;
|
|
7
|
-
selectedItem?: Signal<unknown>;
|
|
8
7
|
isLoading: Signal<boolean>;
|
|
9
8
|
error: Signal<string | null>;
|
|
10
9
|
availabilityDispatchAction?: Signal<(() => void) | undefined>;
|
|
@@ -10,8 +10,7 @@ export const OLOSettingsService = implementService.withConfig()(OLOSettingsServi
|
|
|
10
10
|
const operation = signalsService.signal(config.operation);
|
|
11
11
|
const formatCurrency = config.formattedPrice ??
|
|
12
12
|
((price) => price?.toFixed(2)?.toString() ?? '');
|
|
13
|
-
const
|
|
14
|
-
const isLoading = signalsService.signal(false);
|
|
13
|
+
const isLoading = signalsService.signal(true);
|
|
15
14
|
const error = signalsService.signal(null);
|
|
16
15
|
const currentFulfillment = signalsService.signal('Pickup');
|
|
17
16
|
const currentTimeSlot = signalsService.signal('10-14');
|
|
@@ -24,7 +23,6 @@ export const OLOSettingsService = implementService.withConfig()(OLOSettingsServi
|
|
|
24
23
|
operation,
|
|
25
24
|
isLoading,
|
|
26
25
|
error,
|
|
27
|
-
selectedItem,
|
|
28
26
|
availabilityDispatchAction,
|
|
29
27
|
currentFulfillment,
|
|
30
28
|
currentTimeSlot,
|
package/dist/services/utils.d.ts
CHANGED
|
@@ -35,6 +35,10 @@ export declare const chooseUpToX: ({ required, minSelections, maxSelections, }:
|
|
|
35
35
|
export declare const hasToChooseBetweenXAndY: ({ required, minSelections, maxSelections, }: ruleUtilsArgs) => boolean;
|
|
36
36
|
export declare const getRuleTypeMapValue: (ruleTypeMap: RuleTypeMap, ruleType: RuleType, rule: EnhancedModifierGroup["rule"]) => string | undefined;
|
|
37
37
|
export declare const checkModifiersValidation: (rule: EnhancedModifierGroup["rule"], selectedCount: number) => boolean;
|
|
38
|
+
export declare const getModifierGroupErrors: (selectedModifiers: Record<string, Array<string>>, modifierGroups: EnhancedModifierGroup[]) => {
|
|
39
|
+
errors: Record<string, boolean>;
|
|
40
|
+
hasError: boolean;
|
|
41
|
+
};
|
|
38
42
|
export declare const getAreNotEnoughModifiersOfMandatoryModifierGroupInStock: (modifierGroups: EnhancedModifierGroup[]) => boolean;
|
|
39
43
|
export declare const getLineItemModifiers: (selectedModifiers: Record<string, Array<string>>, modifierGroups: EnhancedModifierGroup[], formatCurrency: (price?: number) => string) => {
|
|
40
44
|
id: string;
|
package/dist/services/utils.js
CHANGED
|
@@ -158,6 +158,18 @@ export const checkModifiersValidation = (rule, selectedCount) => {
|
|
|
158
158
|
}
|
|
159
159
|
return true;
|
|
160
160
|
};
|
|
161
|
+
export const getModifierGroupErrors = (selectedModifiers, modifierGroups) => {
|
|
162
|
+
const errors = {};
|
|
163
|
+
modifierGroups.forEach((group) => {
|
|
164
|
+
if (group._id) {
|
|
165
|
+
const selectedCount = (selectedModifiers[group._id] || []).length;
|
|
166
|
+
const isValid = checkModifiersValidation(group.rule, selectedCount);
|
|
167
|
+
errors[group._id] = !isValid;
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
const hasError = Object.values(errors).some((error) => error);
|
|
171
|
+
return { errors, hasError };
|
|
172
|
+
};
|
|
161
173
|
export const getAreNotEnoughModifiersOfMandatoryModifierGroupInStock = (modifierGroups) => modifierGroups.some((modifierGroup) => {
|
|
162
174
|
const isModifierGroupMandatory = modifierGroup.rule?.required;
|
|
163
175
|
const minimumRequiredModifiers = modifierGroup.rule?.minSelections ?? 0;
|
|
@@ -2,12 +2,21 @@ import * as operationsSDK from '@wix/auto_sdk_restaurants_operations';
|
|
|
2
2
|
import { Signal } from '@wix/services-definitions/core-services/signals';
|
|
3
3
|
import * as fulfillemtMethodsSDK from '@wix/auto_sdk_restaurants_fulfillment-methods';
|
|
4
4
|
import { Address, DurationRange } from '@wix/auto_sdk_restaurants_operations';
|
|
5
|
+
import { Operation } from './operation.js';
|
|
5
6
|
export declare enum DispatchType {
|
|
6
7
|
/** Pickup fulfillment */
|
|
7
8
|
PICKUP = "PICKUP",
|
|
8
9
|
/** Delivery fulfillment */
|
|
9
10
|
DELIVERY = "DELIVERY"
|
|
10
11
|
}
|
|
12
|
+
export declare enum FulfillmentTypeEnum {
|
|
13
|
+
/** ASAP - Order will be fulfilled as soon as possible */
|
|
14
|
+
ASAP = "ASAP",
|
|
15
|
+
/** PREORDER - Order will be fulfilled at a scheduled time */
|
|
16
|
+
PREORDER = "PREORDER",
|
|
17
|
+
/** ASAP_AND_FUTURE - Both ASAP and future scheduling available */
|
|
18
|
+
ASAP_AND_FUTURE = "ASAP_AND_FUTURE"
|
|
19
|
+
}
|
|
11
20
|
export type TimeSlot = {
|
|
12
21
|
id: string;
|
|
13
22
|
startTime: Date;
|
|
@@ -52,6 +61,14 @@ export interface FulfillmentsServiceAPI {
|
|
|
52
61
|
error: Signal<string | null>;
|
|
53
62
|
/** Available dispatch types */
|
|
54
63
|
availableTypes: Signal<DispatchType[]>;
|
|
64
|
+
/** Current scheduling type (ASAP or PREORDER) based on selected time slot */
|
|
65
|
+
schedulingType: Signal<FulfillmentTypeEnum | undefined>;
|
|
66
|
+
/** Whether ASAP option is available */
|
|
67
|
+
hasAsapOption: Signal<boolean>;
|
|
68
|
+
/** Whether preorder (schedule for later) option is available */
|
|
69
|
+
hasPreorderOption: Signal<boolean>;
|
|
70
|
+
/** Whether both ASAP and future scheduling options are available */
|
|
71
|
+
hasAsapAndFutureOption: Signal<boolean>;
|
|
55
72
|
/**
|
|
56
73
|
* Dispatches info by dispatch type
|
|
57
74
|
*/
|
|
@@ -78,6 +95,6 @@ export interface FulfillmentsServiceAPI {
|
|
|
78
95
|
}
|
|
79
96
|
export interface FulfillmentsServiceConfig {
|
|
80
97
|
firstAvailableTimeSlots?: operationsSDK.TimeSlotForOperation[];
|
|
81
|
-
operation?:
|
|
98
|
+
operation?: Operation;
|
|
82
99
|
fulfillments?: fulfillemtMethodsSDK.FulfillmentMethod[];
|
|
83
100
|
}
|
|
@@ -5,3 +5,12 @@ export var DispatchType;
|
|
|
5
5
|
/** Delivery fulfillment */
|
|
6
6
|
DispatchType["DELIVERY"] = "DELIVERY";
|
|
7
7
|
})(DispatchType || (DispatchType = {}));
|
|
8
|
+
export var FulfillmentTypeEnum;
|
|
9
|
+
(function (FulfillmentTypeEnum) {
|
|
10
|
+
/** ASAP - Order will be fulfilled as soon as possible */
|
|
11
|
+
FulfillmentTypeEnum["ASAP"] = "ASAP";
|
|
12
|
+
/** PREORDER - Order will be fulfilled at a scheduled time */
|
|
13
|
+
FulfillmentTypeEnum["PREORDER"] = "PREORDER";
|
|
14
|
+
/** ASAP_AND_FUTURE - Both ASAP and future scheduling available */
|
|
15
|
+
FulfillmentTypeEnum["ASAP_AND_FUTURE"] = "ASAP_AND_FUTURE";
|
|
16
|
+
})(FulfillmentTypeEnum || (FulfillmentTypeEnum = {}));
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import { TimeOfDay, TimeOfDayRange, EntitiesDayOfWeek as DayOfWeek } from '@wix/auto_sdk_restaurants_fulfillment-methods';
|
|
2
|
+
export { TimeOfDay, TimeOfDayRange, DayOfWeek };
|
|
3
|
+
/**
|
|
4
|
+
* Get the current locale
|
|
5
|
+
* Uses the configured locale, falls back to i18n.getLocale()
|
|
6
|
+
*
|
|
7
|
+
* @returns The current locale string
|
|
8
|
+
*/
|
|
9
|
+
export declare const getLocale: () => string;
|
|
10
|
+
/**
|
|
11
|
+
* Get the current timezone
|
|
12
|
+
* Uses the configured timezone, falls back to undefined (browser default)
|
|
13
|
+
*
|
|
14
|
+
* @returns The current timezone string or undefined
|
|
15
|
+
*/
|
|
16
|
+
export declare const getTimezone: () => string | undefined;
|
|
17
|
+
/**
|
|
18
|
+
* Mapping of day of week enum to numeric value (1-7, Monday-Sunday)
|
|
19
|
+
*/
|
|
20
|
+
export declare const DAY_OF_WEEK: {
|
|
21
|
+
MON: number;
|
|
22
|
+
TUE: number;
|
|
23
|
+
WED: number;
|
|
24
|
+
THU: number;
|
|
25
|
+
FRI: number;
|
|
26
|
+
SAT: number;
|
|
27
|
+
SUN: number;
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* Extract date/time parts from a Date in a specific timezone
|
|
31
|
+
* @param date - The source Date object
|
|
32
|
+
* @param timezone - The target timezone (e.g., 'America/New_York'). Defaults to configured timezone.
|
|
33
|
+
* @param locale - The locale for formatting (e.g., 'en-US'). Defaults to configured locale.
|
|
34
|
+
* @param includeTime - Whether to include time parts (hour, minute, second)
|
|
35
|
+
* @returns Object containing the extracted date/time parts
|
|
36
|
+
*/
|
|
37
|
+
export declare const getDatePartsInTimezone: (date: Date, timezone?: string, locale?: string, includeTime?: boolean) => {
|
|
38
|
+
year: string;
|
|
39
|
+
month: string;
|
|
40
|
+
day: string;
|
|
41
|
+
hour?: string;
|
|
42
|
+
minute?: string;
|
|
43
|
+
second?: string;
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* Build a Date from date/time parts
|
|
47
|
+
* @param year - Year string
|
|
48
|
+
* @param month - Month string (2-digit)
|
|
49
|
+
* @param day - Day string (2-digit)
|
|
50
|
+
* @param hour - Hour string (2-digit, optional)
|
|
51
|
+
* @param minute - Minute string (2-digit, optional)
|
|
52
|
+
* @param second - Second string (2-digit, optional)
|
|
53
|
+
* @returns A new Date object
|
|
54
|
+
*/
|
|
55
|
+
export declare const buildDateFromParts: (year: string, month: string, day: string, hour?: string, minute?: string, second?: string) => Date;
|
|
56
|
+
/**
|
|
57
|
+
* Convert a TimeOfDay object to a Date object
|
|
58
|
+
* Creates a Date for today with the specified time in the target timezone.
|
|
59
|
+
* Equivalent to: DateTime.fromObject({ hour, minute }).setZone(timezone, { keepLocalTime: true })
|
|
60
|
+
*
|
|
61
|
+
* @param time - TimeOfDay object with hours and minutes
|
|
62
|
+
* @param timezone - The target timezone (e.g., 'America/New_York'). Defaults to configured timezone.
|
|
63
|
+
* @returns A Date object representing the time in the specified timezone
|
|
64
|
+
*/
|
|
65
|
+
export declare const convertTimeOfDayToDateTime: (time: TimeOfDay, timezone?: string) => Date;
|
|
66
|
+
/**
|
|
67
|
+
* Convert a Date to a Date adjusted for a specific timezone
|
|
68
|
+
* This is useful when you need to display or compare dates in a specific timezone
|
|
69
|
+
*
|
|
70
|
+
* @param date - The source Date object
|
|
71
|
+
* @param timezone - The target timezone (e.g., 'America/New_York'). Defaults to configured timezone.
|
|
72
|
+
* @param locale - The locale for formatting (e.g., 'en-US'). Defaults to configured locale.
|
|
73
|
+
* @returns A new Date object adjusted to represent the same moment in the target timezone
|
|
74
|
+
*/
|
|
75
|
+
export declare const convertDateToTimezone: (date: Date, timezone?: string, locale?: string) => Date;
|
|
76
|
+
/**
|
|
77
|
+
* Format a Date as a localized string for a specific timezone and locale
|
|
78
|
+
*
|
|
79
|
+
* @param date - The source Date object
|
|
80
|
+
* @param timezone - The target timezone (e.g., 'America/New_York'). Defaults to configured timezone.
|
|
81
|
+
* @param locale - The locale for formatting (e.g., 'en-US'). Defaults to configured locale.
|
|
82
|
+
* @param options - Additional Intl.DateTimeFormatOptions
|
|
83
|
+
* @returns A formatted date string
|
|
84
|
+
*/
|
|
85
|
+
export declare const formatDateInTimezone: (date: Date, timezone?: string, locale?: string, options?: Intl.DateTimeFormatOptions) => string;
|
|
86
|
+
/**
|
|
87
|
+
* Check if a time falls within a time range
|
|
88
|
+
*
|
|
89
|
+
* @param time - The time to check
|
|
90
|
+
* @param range - The time range to check against
|
|
91
|
+
* @param timeZone - The timezone for conversion. Defaults to configured timezone.
|
|
92
|
+
* @param locale - The locale for formatting. Defaults to configured locale.
|
|
93
|
+
* @returns True if the time is within the range
|
|
94
|
+
*/
|
|
95
|
+
export declare const isInTimeRange: (time: Date, range: TimeOfDayRange, timeZone?: string) => boolean;
|
|
96
|
+
/**
|
|
97
|
+
* Get the current day of week as a number (1-7, Monday-Sunday)
|
|
98
|
+
* JavaScript's getDay() returns 0 (Sunday) to 6 (Saturday),
|
|
99
|
+
* this function converts to 1 (Monday) to 7 (Sunday)
|
|
100
|
+
*
|
|
101
|
+
* @param date - The date to get the day of week from
|
|
102
|
+
* @returns The day of week as a number (1-7)
|
|
103
|
+
*/
|
|
104
|
+
export declare const getDayOfWeekNumber: (date: Date) => number;
|
|
105
|
+
/**
|
|
106
|
+
* Format a date as time only (e.g., "10:30 AM")
|
|
107
|
+
* Uses configured locale and timezone
|
|
108
|
+
*
|
|
109
|
+
* @param date - The date to format
|
|
110
|
+
* @param options - Additional Intl.DateTimeFormatOptions (defaults to hour:numeric, minute:numeric)
|
|
111
|
+
* @returns A formatted time string, or empty string if date is undefined
|
|
112
|
+
*/
|
|
113
|
+
export declare const formatTime: (date?: Date, options?: Intl.DateTimeFormatOptions) => string;
|
|
114
|
+
/**
|
|
115
|
+
* Format a time range as a localized string
|
|
116
|
+
* If start and end times are the same, returns just the time
|
|
117
|
+
* Otherwise returns "start - end" format
|
|
118
|
+
*
|
|
119
|
+
* @param startTime - The start time
|
|
120
|
+
* @param endTime - The end time
|
|
121
|
+
* @param options - Additional Intl.DateTimeFormatOptions (defaults to hour:numeric, minute:numeric, hour12:true)
|
|
122
|
+
* @returns A formatted time range string
|
|
123
|
+
*/
|
|
124
|
+
export declare const formatTimeRange: (startTime: Date, endTime: Date, options?: Intl.DateTimeFormatOptions) => string;
|
|
125
|
+
/**
|
|
126
|
+
* Check if two dates are on the same calendar day
|
|
127
|
+
* Compares year, month, and day components
|
|
128
|
+
*
|
|
129
|
+
* @param date1 - The first date to compare
|
|
130
|
+
* @param date2 - The second date to compare
|
|
131
|
+
* @returns True if both dates are on the same calendar day
|
|
132
|
+
*/
|
|
133
|
+
export declare const isSameDay: (date1: Date, date2: Date) => boolean;
|
|
134
|
+
/**
|
|
135
|
+
* Get today's date with time set to midnight (00:00:00.000)
|
|
136
|
+
*
|
|
137
|
+
* @returns A Date object representing the start of today
|
|
138
|
+
*/
|
|
139
|
+
export declare const getToday: () => Date;
|
|
140
|
+
/**
|
|
141
|
+
* Get a future date with time set to 23:59:59.999
|
|
142
|
+
*
|
|
143
|
+
* @param days - The number of days to add to the current date
|
|
144
|
+
* @returns A Date object representing the end of the future date
|
|
145
|
+
*/
|
|
146
|
+
export declare const getFutureDate: (days: number) => Date;
|
|
147
|
+
/**
|
|
148
|
+
* Create a Date object from year, month, and day numbers
|
|
149
|
+
* Adjusts for timezone offset to ensure the date represents the correct local date
|
|
150
|
+
*
|
|
151
|
+
* @param year - The year (e.g., 2024)
|
|
152
|
+
* @param month - The month (1-12, where 1 is January)
|
|
153
|
+
* @param day - The day of the month (1-31)
|
|
154
|
+
* @returns A Date object representing midnight on the specified date in local time
|
|
155
|
+
*/
|
|
156
|
+
export declare const createDateFromYMD: (year: number, month: number, day: number) => Date;
|
|
157
|
+
/**
|
|
158
|
+
* Format a Date as an ISO date string (YYYY-MM-DD)
|
|
159
|
+
* Useful for HTML date input values and attributes
|
|
160
|
+
*
|
|
161
|
+
* @param date - The date to format
|
|
162
|
+
* @returns A string in YYYY-MM-DD format
|
|
163
|
+
*/
|
|
164
|
+
export declare const toISODateString: (date: Date) => string;
|