@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.
Files changed (59) hide show
  1. package/cjs/dist/react/FulfillmentDetails.d.ts +139 -15
  2. package/cjs/dist/react/FulfillmentDetails.js +128 -24
  3. package/cjs/dist/react/ItemDetails.d.ts +4 -4
  4. package/cjs/dist/react/ItemDetails.js +5 -6
  5. package/cjs/dist/react/Settings.d.ts +8 -0
  6. package/cjs/dist/react/Settings.js +18 -25
  7. package/cjs/dist/react/core/FulfillmentDetails.d.ts +73 -7
  8. package/cjs/dist/react/core/FulfillmentDetails.js +133 -86
  9. package/cjs/dist/react/core/ItemDetails.d.ts +1 -1
  10. package/cjs/dist/react/core/ItemDetails.js +5 -16
  11. package/cjs/dist/react/core/Settings.d.ts +19 -4
  12. package/cjs/dist/react/core/Settings.js +29 -20
  13. package/cjs/dist/services/fulfillment-details-service.d.ts +127 -0
  14. package/cjs/dist/services/fulfillment-details-service.js +351 -0
  15. package/cjs/dist/services/fulfillments-service.js +67 -43
  16. package/cjs/dist/services/index.d.ts +2 -0
  17. package/cjs/dist/services/index.js +1 -0
  18. package/cjs/dist/services/item-details-service.d.ts +1 -1
  19. package/cjs/dist/services/item-details-service.js +10 -16
  20. package/cjs/dist/services/olo-settings-service.d.ts +0 -1
  21. package/cjs/dist/services/olo-settings-service.js +1 -3
  22. package/cjs/dist/services/utils.d.ts +4 -0
  23. package/cjs/dist/services/utils.js +12 -0
  24. package/cjs/dist/types/fulfillments-types.d.ts +18 -1
  25. package/cjs/dist/types/fulfillments-types.js +9 -0
  26. package/cjs/dist/utils/date-utils.d.ts +164 -0
  27. package/cjs/dist/utils/date-utils.js +297 -0
  28. package/cjs/dist/utils/fulfillments-utils.d.ts +3 -2
  29. package/cjs/dist/utils/fulfillments-utils.js +13 -57
  30. package/dist/react/FulfillmentDetails.d.ts +139 -15
  31. package/dist/react/FulfillmentDetails.js +128 -24
  32. package/dist/react/ItemDetails.d.ts +4 -4
  33. package/dist/react/ItemDetails.js +5 -6
  34. package/dist/react/Settings.d.ts +8 -0
  35. package/dist/react/Settings.js +18 -25
  36. package/dist/react/core/FulfillmentDetails.d.ts +73 -7
  37. package/dist/react/core/FulfillmentDetails.js +133 -86
  38. package/dist/react/core/ItemDetails.d.ts +1 -1
  39. package/dist/react/core/ItemDetails.js +5 -16
  40. package/dist/react/core/Settings.d.ts +19 -4
  41. package/dist/react/core/Settings.js +29 -20
  42. package/dist/services/fulfillment-details-service.d.ts +127 -0
  43. package/dist/services/fulfillment-details-service.js +351 -0
  44. package/dist/services/fulfillments-service.js +67 -43
  45. package/dist/services/index.d.ts +2 -0
  46. package/dist/services/index.js +1 -0
  47. package/dist/services/item-details-service.d.ts +1 -1
  48. package/dist/services/item-details-service.js +10 -16
  49. package/dist/services/olo-settings-service.d.ts +0 -1
  50. package/dist/services/olo-settings-service.js +1 -3
  51. package/dist/services/utils.d.ts +4 -0
  52. package/dist/services/utils.js +12 -0
  53. package/dist/types/fulfillments-types.d.ts +18 -1
  54. package/dist/types/fulfillments-types.js +9 -0
  55. package/dist/utils/date-utils.d.ts +164 -0
  56. package/dist/utils/date-utils.js +297 -0
  57. package/dist/utils/fulfillments-utils.d.ts +3 -2
  58. package/dist/utils/fulfillments-utils.js +13 -57
  59. package/package.json +3 -2
@@ -1,11 +1,14 @@
1
1
  import React from 'react';
2
- import { DispatchType } from '../../types/fulfillments-types.js';
2
+ import { type FulfillmentDetailsServiceConfig } from '../../services/fulfillment-details-service.js';
3
+ import { DispatchType, FulfillmentTypeEnum } from '../../types/fulfillments-types.js';
3
4
  export interface RootProps {
4
5
  children: React.ReactNode;
6
+ fulfillmentDetailsServiceConfig?: FulfillmentDetailsServiceConfig;
5
7
  }
6
8
  /**
7
9
  * Root component for FulfillmentDetails
8
10
  * Provides context for all fulfillment detail sub-components
11
+ * Adds FulfillmentDetailsService to the services map after FulfillmentsService is loaded
9
12
  */
10
13
  export declare const Root: React.FC<RootProps>;
11
14
  export interface AddressNameProps {
@@ -56,18 +59,18 @@ export interface AvailableTimeSlotsProps {
56
59
  * Shows time ranges when the order can be fulfilled
57
60
  */
58
61
  export declare const AvailableTimeSlots: React.FC<AvailableTimeSlotsProps>;
59
- export declare enum FulfillmentTypeEnum {
60
- ASAP = "ASAP",
61
- PREORDER = "PREORDER",
62
- ASAP_AND_FUTURE = "ASAP_AND_FUTURE"
63
- }
64
62
  export interface FulfillmentTypeProps {
65
63
  children: (props: {
66
- selectedType: FulfillmentTypeEnum;
64
+ selectedType: FulfillmentTypeEnum | undefined;
67
65
  onTypeChange: (type: FulfillmentTypeEnum) => void;
68
66
  hasAsapOption: boolean;
69
67
  hasPreorderOption: boolean;
70
68
  hasAsapAndFutureOption: boolean;
69
+ asapTime: number | undefined;
70
+ asapTimeRange: {
71
+ minDuration?: number;
72
+ maxDuration?: number;
73
+ } | undefined;
71
74
  }) => React.ReactNode;
72
75
  }
73
76
  /**
@@ -76,3 +79,66 @@ export interface FulfillmentTypeProps {
76
79
  * Pre-order: Order will be fulfilled at a scheduled time
77
80
  */
78
81
  export declare const FulfillmentType: React.FC<FulfillmentTypeProps>;
82
+ /**
83
+ * Address fields that can be updated
84
+ */
85
+ export interface DeliveryAddressFields {
86
+ /** Street address line 1 */
87
+ addressLine?: string;
88
+ /** Street address line 2 (apartment, suite, etc.) */
89
+ addressLine2?: string;
90
+ /** City */
91
+ city?: string;
92
+ /** State/Province/Subdivision */
93
+ subdivision?: string;
94
+ /** Postal/ZIP code */
95
+ postalCode?: string;
96
+ /** Country */
97
+ country?: string;
98
+ /** Formatted full address string */
99
+ formattedAddress?: string;
100
+ }
101
+ export interface DeliveryAddressProps {
102
+ children: (props: {
103
+ /** Current address fields */
104
+ address: DeliveryAddressFields | null;
105
+ /** Whether there is a current address */
106
+ hasAddress: boolean;
107
+ /** Current dispatch type */
108
+ dispatchType: DispatchType | null;
109
+ /** Whether delivery is selected */
110
+ isDelivery: boolean;
111
+ /** Update the delivery address */
112
+ onAddressChange: (address: DeliveryAddressFields) => void;
113
+ /** Clear the delivery address */
114
+ onAddressClear: () => void;
115
+ }) => React.ReactNode;
116
+ }
117
+ /**
118
+ * Component that provides delivery address editing functionality
119
+ * Only renders content when dispatch type is DELIVERY
120
+ *
121
+ * @example
122
+ * ```tsx
123
+ * <CoreFulfillmentDetails.DeliveryAddress>
124
+ * {({ address, hasAddress, isDelivery, onAddressChange, onAddressClear }) => (
125
+ * isDelivery && (
126
+ * <div>
127
+ * <input
128
+ * value={address?.addressLine || ''}
129
+ * onChange={(e) => onAddressChange({ ...address, addressLine: e.target.value })}
130
+ * placeholder="Street Address"
131
+ * />
132
+ * <input
133
+ * value={address?.city || ''}
134
+ * onChange={(e) => onAddressChange({ ...address, city: e.target.value })}
135
+ * placeholder="City"
136
+ * />
137
+ * <button onClick={onAddressClear}>Clear</button>
138
+ * </div>
139
+ * )
140
+ * )}
141
+ * </CoreFulfillmentDetails.DeliveryAddress>
142
+ * ```
143
+ */
144
+ export declare const DeliveryAddress: React.FC<DeliveryAddressProps>;
@@ -1,13 +1,36 @@
1
- import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
2
- import { useState } from 'react';
3
- import { useService } from '@wix/services-manager-react';
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useState, useEffect } from 'react';
3
+ import { WixServices, useService } from '@wix/services-manager-react';
4
4
  import { FulfillmentsServiceDefinition } from '../../services/fulfillments-service.js';
5
+ import { FulfillmentDetailsService, FulfillmentDetailsServiceDefinition, loadFulfillmentDetailsServiceConfig, } from '../../services/fulfillment-details-service.js';
6
+ import { OLOSettingsServiceDefinition } from '../../services/olo-settings-service.js';
7
+ import { DispatchType, FulfillmentTypeEnum, } from '../../types/fulfillments-types.js';
8
+ import { createServicesMap } from '@wix/services-manager';
9
+ import { formatTimeRange, getToday, getFutureDate, } from '../../utils/date-utils.js';
5
10
  /**
6
11
  * Root component for FulfillmentDetails
7
12
  * Provides context for all fulfillment detail sub-components
13
+ * Adds FulfillmentDetailsService to the services map after FulfillmentsService is loaded
8
14
  */
9
- export const Root = ({ children }) => {
10
- return _jsx(_Fragment, { children: children });
15
+ export const Root = ({ children, fulfillmentDetailsServiceConfig, }) => {
16
+ const oloSettingsService = useService(OLOSettingsServiceDefinition);
17
+ const fulfillmentsService = useService(FulfillmentsServiceDefinition);
18
+ const [config, setConfig] = useState(fulfillmentDetailsServiceConfig);
19
+ const isFulfillmentsLoading = fulfillmentsService.isLoading?.get() ?? true;
20
+ useEffect(() => {
21
+ if (!fulfillmentDetailsServiceConfig &&
22
+ oloSettingsService.operation?.get()) {
23
+ const operation = oloSettingsService.operation.get();
24
+ if (operation) {
25
+ const loadedConfig = loadFulfillmentDetailsServiceConfig(operation);
26
+ setConfig(loadedConfig);
27
+ }
28
+ }
29
+ }, [fulfillmentDetailsServiceConfig, oloSettingsService.operation]);
30
+ if (!config || isFulfillmentsLoading) {
31
+ return null;
32
+ }
33
+ return (_jsx(WixServices, { servicesMap: createServicesMap().addService(FulfillmentDetailsServiceDefinition, FulfillmentDetailsService, config), children: children }));
11
34
  };
12
35
  /**
13
36
  * Component that provides the address name for the selected fulfillment
@@ -15,12 +38,11 @@ export const Root = ({ children }) => {
15
38
  * For delivery: shows the delivery address
16
39
  */
17
40
  export const AddressName = ({ children }) => {
18
- const fulfillmentsService = useService(FulfillmentsServiceDefinition);
19
- const selectedDispatchInfo = fulfillmentsService.selectedDispatchInfoSignal?.get();
20
- const selectedAddress = selectedDispatchInfo?.address ?? null;
21
- const selectedTimeSlot = fulfillmentsService.selectedTimeSlot?.get();
22
- const dispatchType = selectedTimeSlot?.dispatchType ?? null;
23
- const addressName = selectedAddress?.formatted ?? null;
41
+ const fulfillmentDetailsService = useService(FulfillmentDetailsServiceDefinition);
42
+ const selectedAddress = fulfillmentDetailsService?.address?.get();
43
+ console.log('selectedAddress', selectedAddress);
44
+ const dispatchType = fulfillmentDetailsService.dispatchType?.get();
45
+ const addressName = selectedAddress?.formatted;
24
46
  const fullAddress = selectedAddress
25
47
  ? [
26
48
  // @ts-expect-error - selectedAddress is not typed
@@ -49,30 +71,23 @@ export const AddressName = ({ children }) => {
49
71
  */
50
72
  export const FulfillmentDate = ({ children, }) => {
51
73
  const fulfillmentsService = useService(FulfillmentsServiceDefinition);
52
- const selectedTimeSlot = fulfillmentsService.selectedTimeSlot?.get();
53
- const [selectedDate, setSelectedDate] = useState(selectedTimeSlot?.startTime ?? null);
54
- const onDateChange = (date) => {
55
- setSelectedDate(date);
56
- // Find time slots for the selected date and update if needed
57
- const timeSlots = fulfillmentsService.firstAvailableTimeSlots?.get() ?? [];
58
- const slotsForDate = timeSlots.filter((slot) => {
59
- const slotDate = new Date(slot.startTime);
60
- return (slotDate.getFullYear() === date.getFullYear() &&
61
- slotDate.getMonth() === date.getMonth() &&
62
- slotDate.getDate() === date.getDate());
63
- });
64
- // If there are slots for this date, select the first one
65
- if (slotsForDate.length > 0) {
66
- fulfillmentsService.setSelectedTimeSlot(slotsForDate[0]);
67
- }
74
+ const hasAsapOption = fulfillmentsService.hasAsapOption?.get();
75
+ const hasAsapAndFutureOption = fulfillmentsService.hasAsapAndFutureOption?.get();
76
+ if (hasAsapOption && !hasAsapAndFutureOption) {
77
+ return null;
78
+ }
79
+ const fulfillmentDetailsService = useService(FulfillmentDetailsServiceDefinition);
80
+ if (fulfillmentDetailsService?.schedulingType.get() === FulfillmentTypeEnum.ASAP) {
81
+ return null;
82
+ }
83
+ const selectedDate = fulfillmentDetailsService.date?.get();
84
+ const availableDates = fulfillmentDetailsService.availableDates?.get() ?? [];
85
+ const onDateChange = async (date) => {
86
+ await fulfillmentDetailsService.setDate(date);
68
87
  };
69
- // Set min date to today
70
- const minDate = new Date();
71
- minDate.setHours(0, 0, 0, 0);
72
- // Set max date to 30 days from now (reasonable booking window)
73
- const maxDate = new Date();
74
- maxDate.setDate(maxDate.getDate() + 30);
75
- maxDate.setHours(23, 59, 59, 999);
88
+ // Calculate min/max dates from available dates if available, otherwise use defaults
89
+ const minDate = availableDates[0]?.date ?? getToday();
90
+ const maxDate = availableDates[availableDates.length - 1]?.date ?? getFutureDate(30);
76
91
  return children({
77
92
  selectedDate,
78
93
  onDateChange,
@@ -86,24 +101,20 @@ export const FulfillmentDate = ({ children, }) => {
86
101
  */
87
102
  export const AvailableTimeSlots = ({ children, }) => {
88
103
  const fulfillmentsService = useService(FulfillmentsServiceDefinition);
89
- const timeSlots = fulfillmentsService.firstAvailableTimeSlots?.get() ?? [];
90
- console.log('timeSlots', timeSlots);
91
- const selectedTimeSlot = fulfillmentsService.selectedTimeSlot?.get();
92
- const formatTimeRange = (startTime, endTime) => {
93
- const options = {
94
- hour: 'numeric',
95
- minute: 'numeric',
96
- hour12: true,
97
- };
98
- const start = startTime.toLocaleString('en-US', options);
99
- const end = endTime.toLocaleString('en-US', options);
100
- return `${start} - ${end}`;
101
- };
104
+ const hasAsapOption = fulfillmentsService.hasAsapOption?.get();
105
+ const hasAsapAndFutureOption = fulfillmentsService.hasAsapAndFutureOption?.get();
106
+ if (hasAsapOption && !hasAsapAndFutureOption) {
107
+ return null;
108
+ }
109
+ const fulfillmentDetailsService = useService(FulfillmentDetailsServiceDefinition);
110
+ if (fulfillmentDetailsService?.schedulingType.get() === FulfillmentTypeEnum.ASAP) {
111
+ return null;
112
+ }
113
+ const timeSlots = fulfillmentDetailsService.availableTimeSlots?.get() ?? [];
114
+ const selectedTimeSlot = fulfillmentDetailsService.timeslot?.get();
102
115
  const timeSlotOptions = timeSlots.map((slot) => ({
103
116
  id: slot.id,
104
- label: slot.startsNow
105
- ? 'ASAP'
106
- : formatTimeRange(slot.startTime, slot.endTime),
117
+ label: formatTimeRange(slot.startTime, slot.endTime),
107
118
  startTime: slot.startTime,
108
119
  endTime: slot.endTime,
109
120
  dispatchType: slot.dispatchType,
@@ -112,7 +123,7 @@ export const AvailableTimeSlots = ({ children, }) => {
112
123
  const onTimeSlotChange = (timeSlotId) => {
113
124
  const timeSlot = timeSlots.find((slot) => slot.id === timeSlotId);
114
125
  if (timeSlot) {
115
- fulfillmentsService.setSelectedTimeSlot(timeSlot);
126
+ fulfillmentDetailsService.setTimeslot(timeSlot);
116
127
  }
117
128
  };
118
129
  const hasTimeSlots = timeSlotOptions.length > 0;
@@ -124,15 +135,6 @@ export const AvailableTimeSlots = ({ children, }) => {
124
135
  hasTimeSlots,
125
136
  });
126
137
  };
127
- // ========================================
128
- // FULFILLMENT TYPE COMPONENT
129
- // ========================================
130
- export var FulfillmentTypeEnum;
131
- (function (FulfillmentTypeEnum) {
132
- FulfillmentTypeEnum["ASAP"] = "ASAP";
133
- FulfillmentTypeEnum["PREORDER"] = "PREORDER";
134
- FulfillmentTypeEnum["ASAP_AND_FUTURE"] = "ASAP_AND_FUTURE";
135
- })(FulfillmentTypeEnum || (FulfillmentTypeEnum = {}));
136
138
  /**
137
139
  * Component that provides fulfillment type selection (ASAP or Pre-order)
138
140
  * ASAP: Order will be fulfilled as soon as possible
@@ -140,38 +142,83 @@ export var FulfillmentTypeEnum;
140
142
  */
141
143
  export const FulfillmentType = ({ children, }) => {
142
144
  const fulfillmentsService = useService(FulfillmentsServiceDefinition);
143
- const timeSlots = fulfillmentsService.firstAvailableTimeSlots?.get() ?? [];
144
- const selectedTimeSlot = fulfillmentsService.selectedTimeSlot?.get();
145
- const hasAsapOption = timeSlots.some((slot) => slot.startsNow);
146
- const hasPreorderOption = timeSlots.some((slot) => !slot.startsNow);
147
- const currentType = selectedTimeSlot?.startsNow
148
- ? FulfillmentTypeEnum.ASAP
149
- : FulfillmentTypeEnum.PREORDER;
150
- const [selectedType, setSelectedType] = useState(currentType);
145
+ const fulfillmentDetailsService = useService(FulfillmentDetailsServiceDefinition);
146
+ // Get fulfillment type options from service
147
+ const hasAsapOption = fulfillmentsService.hasAsapOption?.get();
148
+ const hasPreorderOption = fulfillmentsService.hasPreorderOption?.get();
149
+ const hasAsapAndFutureOption = fulfillmentsService.hasAsapAndFutureOption?.get();
150
+ const asapTime = fulfillmentsService.asapTimeSignal?.get();
151
+ const asapTimeRange = fulfillmentsService.asapTimeRangeSignal?.get();
152
+ const selectedType = fulfillmentDetailsService.schedulingType?.get();
151
153
  const onTypeChange = (type) => {
152
- console.log('onTypeChange', type);
153
- setSelectedType(type);
154
- // Find appropriate time slot based on type
155
- const targetSlot = timeSlots.find((slot) => {
156
- if (type === FulfillmentTypeEnum.ASAP) {
157
- return slot.startsNow;
158
- }
159
- else {
160
- return !slot.startsNow;
161
- }
162
- });
163
- if (targetSlot) {
164
- fulfillmentsService.setSelectedTimeSlot(targetSlot);
165
- }
154
+ fulfillmentDetailsService.setSchedulingType(type);
166
155
  };
167
- console.log('selectedType', selectedType);
168
- console.log('hasAsapOption', hasAsapOption);
169
- console.log('hasPreorderOption', hasPreorderOption);
170
156
  return children({
171
157
  selectedType,
172
158
  onTypeChange,
173
159
  hasAsapOption,
174
160
  hasPreorderOption,
175
- hasAsapAndFutureOption: false,
161
+ hasAsapAndFutureOption,
162
+ asapTime,
163
+ asapTimeRange,
164
+ });
165
+ };
166
+ /**
167
+ * Component that provides delivery address editing functionality
168
+ * Only renders content when dispatch type is DELIVERY
169
+ *
170
+ * @example
171
+ * ```tsx
172
+ * <CoreFulfillmentDetails.DeliveryAddress>
173
+ * {({ address, hasAddress, isDelivery, onAddressChange, onAddressClear }) => (
174
+ * isDelivery && (
175
+ * <div>
176
+ * <input
177
+ * value={address?.addressLine || ''}
178
+ * onChange={(e) => onAddressChange({ ...address, addressLine: e.target.value })}
179
+ * placeholder="Street Address"
180
+ * />
181
+ * <input
182
+ * value={address?.city || ''}
183
+ * onChange={(e) => onAddressChange({ ...address, city: e.target.value })}
184
+ * placeholder="City"
185
+ * />
186
+ * <button onClick={onAddressClear}>Clear</button>
187
+ * </div>
188
+ * )
189
+ * )}
190
+ * </CoreFulfillmentDetails.DeliveryAddress>
191
+ * ```
192
+ */
193
+ export const DeliveryAddress = ({ children, }) => {
194
+ const fulfillmentDetailsService = useService(FulfillmentDetailsServiceDefinition);
195
+ const currentAddress = fulfillmentDetailsService?.address?.get();
196
+ const dispatchType = fulfillmentDetailsService.dispatchType?.get();
197
+ const isDelivery = dispatchType === DispatchType.DELIVERY;
198
+ const address = currentAddress
199
+ ? {
200
+ addressLine: currentAddress.addressLine,
201
+ addressLine2: currentAddress.addressLine2,
202
+ city: currentAddress.city,
203
+ subdivision: currentAddress.subdivision,
204
+ postalCode: currentAddress.postalCode,
205
+ country: currentAddress.country,
206
+ formattedAddress: currentAddress.formattedAddress,
207
+ }
208
+ : null;
209
+ const hasAddress = Boolean(currentAddress);
210
+ const onAddressChange = (newAddress) => {
211
+ fulfillmentDetailsService.setAddress(newAddress);
212
+ };
213
+ const onAddressClear = () => {
214
+ fulfillmentDetailsService.setAddress(null);
215
+ };
216
+ return children({
217
+ address,
218
+ hasAddress,
219
+ dispatchType,
220
+ isDelivery,
221
+ onAddressChange,
222
+ onAddressClear,
176
223
  });
177
224
  };
@@ -21,12 +21,12 @@ interface ItemDetailsLineItemProps {
21
21
  addToCartLabelMap: Record<AddToCartButtonState, string>;
22
22
  children: (props: {
23
23
  loadingState: string | React.ReactNode;
24
+ onHandleAddToCart: (onClick: (lineItem: LineItem) => void) => void;
24
25
  lineItem: LineItem;
25
26
  buttonState: AddToCartButtonState;
26
27
  addToCartButtonDisabled: boolean;
27
28
  labelText: string;
28
29
  formattedPrice: string;
29
- modifierGroupHasError: boolean;
30
30
  }) => React.ReactNode;
31
31
  }
32
32
  export declare const LineItemComponent: React.FC<ItemDetailsLineItemProps>;
@@ -2,24 +2,13 @@ import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { useState } from 'react';
3
3
  import { useService, WixServices } from '@wix/services-manager-react';
4
4
  import { createServicesMap } from '@wix/services-manager';
5
- import { ItemService, ItemServiceDefinition, loadItemServiceConfig, } from '../../services/item-details-service.js';
5
+ import { ItemService, ItemServiceDefinition, } from '../../services/item-details-service.js';
6
6
  import { OLOSettingsServiceDefinition } from '../../services/olo-settings-service.js';
7
7
  import { useItemContext } from '@wix/headless-restaurants-menus/react';
8
8
  import { AvailabilityStatus, AddToCartButtonState, } from '../../services/common-types.js';
9
9
  import { getAvailabilityText } from '../../services/utils.js';
10
10
  export const Root = ({ children, itemDetailsServiceConfig, }) => {
11
- const service = useService(OLOSettingsServiceDefinition);
12
- const selectedItem = service.selectedItem?.get();
13
- const config = itemDetailsServiceConfig ??
14
- loadItemServiceConfig({
15
- item: selectedItem,
16
- // @ts-expect-error - operation is not typed
17
- operationId: service.operation?.get()?.id ?? '',
18
- });
19
- if (config.item) {
20
- service.selectedItem?.set(config.item);
21
- }
22
- return (_jsx(WixServices, { servicesMap: createServicesMap().addService(ItemServiceDefinition, ItemService, config), children: children({ item: itemDetailsServiceConfig?.item ?? selectedItem }) }));
11
+ return (_jsx(WixServices, { servicesMap: createServicesMap().addService(ItemServiceDefinition, ItemService, itemDetailsServiceConfig), children: children({ item: itemDetailsServiceConfig?.item }) }));
23
12
  };
24
13
  export const SpecialRequest = ({ children, }) => {
25
14
  const service = useService(ItemServiceDefinition);
@@ -42,6 +31,7 @@ export const LineItemComponent = ({ addToCartLabelMap, children, }) => {
42
31
  const service = useService(ItemServiceDefinition);
43
32
  const oloSettingsService = useService(OLOSettingsServiceDefinition);
44
33
  const lineItem = service.lineItem?.get?.() ?? {};
34
+ const onHandleAddToCart = service.onHandleAddToCart;
45
35
  const loadingState = service.isLoading?.get?.() ?? false;
46
36
  const buttonState = service.buttonState?.get?.() ?? AddToCartButtonState.VALID_TO_CONTINUE;
47
37
  const addToCartButtonDisabled = service.addToCartButtonDisabled?.get?.() ?? false;
@@ -49,15 +39,14 @@ export const LineItemComponent = ({ addToCartLabelMap, children, }) => {
49
39
  const formatCurrency = oloSettingsService.formatCurrency;
50
40
  const formattedPrice = formatCurrency(price);
51
41
  const labelText = addToCartLabelMap[buttonState];
52
- const modifierGroupHasError = service.doesModifierGroupHaveError?.get?.() ?? false;
53
42
  return children({
54
43
  loadingState,
55
- lineItem,
44
+ onHandleAddToCart,
56
45
  buttonState,
57
46
  addToCartButtonDisabled,
58
47
  labelText,
59
48
  formattedPrice,
60
- modifierGroupHasError,
49
+ lineItem,
61
50
  });
62
51
  };
63
52
  export const QuantityComponent = ({ children, }) => {
@@ -12,15 +12,30 @@ export interface RootProps {
12
12
  * Core Settings Root component that provides service context
13
13
  * Wraps children with both OLOSettingsService and FulfillmentsService providers
14
14
  *
15
+ * Note: Use loadFulfillmentsServiceConfig from '@wix/headless-restaurants-olo/services'
16
+ * to load the config before rendering this component.
17
+ *
15
18
  * @example
16
19
  * ```tsx
17
- * <CoreSettings.Root fulfillmentsServiceConfig={config}>
18
- * <CoreSettings.CurrentTimeSlot>
20
+ * import { loadFulfillmentsServiceConfig, OLOSettingsServiceDefinition } from '@wix/headless-restaurants-olo/services';
21
+ *
22
+ * // In your component:
23
+ * const service = useService(OLOSettingsServiceDefinition);
24
+ * const [config, setConfig] = useState(null);
25
+ *
26
+ * useEffect(() => {
27
+ * loadFulfillmentsServiceConfig(service.operation?.get()).then(setConfig);
28
+ * }, []);
29
+ *
30
+ * if (!config) return <div>Loading...</div>;
31
+ *
32
+ * <Settings.Root fulfillmentsServiceConfig={config}>
33
+ * <Settings.CurrentTimeSlot>
19
34
  * {({ timeSlot, hasDetails }) => (
20
35
  * <div>{timeSlot?.dispatchType}</div>
21
36
  * )}
22
- * </CoreSettings.CurrentTimeSlot>
23
- * </CoreSettings.Root>
37
+ * </Settings.CurrentTimeSlot>
38
+ * </Settings.Root>
24
39
  * ```
25
40
  */
26
41
  export declare const Root: React.FC<RootProps>;
@@ -1,39 +1,43 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
- import { useEffect, useState } from 'react';
3
2
  import { WixServices, useService } from '@wix/services-manager-react';
4
3
  import { OLOSettingsServiceDefinition } from '../../services/olo-settings-service.js';
5
- import { FulfillmentsService, FulfillmentsServiceDefinition, loadFulfillmentsServiceConfig, } from '../../services/fulfillments-service.js';
4
+ import { FulfillmentsService, FulfillmentsServiceDefinition, } from '../../services/fulfillments-service.js';
6
5
  import { createServicesMap } from '@wix/services-manager';
7
6
  /**
8
7
  * Core Settings Root component that provides service context
9
8
  * Wraps children with both OLOSettingsService and FulfillmentsService providers
10
9
  *
10
+ * Note: Use loadFulfillmentsServiceConfig from '@wix/headless-restaurants-olo/services'
11
+ * to load the config before rendering this component.
12
+ *
11
13
  * @example
12
14
  * ```tsx
13
- * <CoreSettings.Root fulfillmentsServiceConfig={config}>
14
- * <CoreSettings.CurrentTimeSlot>
15
+ * import { loadFulfillmentsServiceConfig, OLOSettingsServiceDefinition } from '@wix/headless-restaurants-olo/services';
16
+ *
17
+ * // In your component:
18
+ * const service = useService(OLOSettingsServiceDefinition);
19
+ * const [config, setConfig] = useState(null);
20
+ *
21
+ * useEffect(() => {
22
+ * loadFulfillmentsServiceConfig(service.operation?.get()).then(setConfig);
23
+ * }, []);
24
+ *
25
+ * if (!config) return <div>Loading...</div>;
26
+ *
27
+ * <Settings.Root fulfillmentsServiceConfig={config}>
28
+ * <Settings.CurrentTimeSlot>
15
29
  * {({ timeSlot, hasDetails }) => (
16
30
  * <div>{timeSlot?.dispatchType}</div>
17
31
  * )}
18
- * </CoreSettings.CurrentTimeSlot>
19
- * </CoreSettings.Root>
32
+ * </Settings.CurrentTimeSlot>
33
+ * </Settings.Root>
20
34
  * ```
21
35
  */
22
36
  export const Root = ({ children, fulfillmentsServiceConfig, }) => {
23
- const service = useService(OLOSettingsServiceDefinition);
24
- const [config, setConfig] = useState(fulfillmentsServiceConfig);
25
- useEffect(() => {
26
- if (!fulfillmentsServiceConfig) {
27
- loadFulfillmentsServiceConfig(service.operation?.get()).then((loadedConfig) => {
28
- setConfig(loadedConfig);
29
- });
30
- }
31
- }, [fulfillmentsServiceConfig]);
32
- service.isLoading.set(!config);
33
- if (!config) {
34
- return children({ isLoading: !config });
37
+ if (!fulfillmentsServiceConfig) {
38
+ return children({ isLoading: true });
35
39
  }
36
- return (_jsx(WixServices, { servicesMap: createServicesMap().addService(FulfillmentsServiceDefinition, FulfillmentsService, config), children: children({ isLoading: !config }) }));
40
+ return (_jsx(WixServices, { servicesMap: createServicesMap().addService(FulfillmentsServiceDefinition, FulfillmentsService, fulfillmentsServiceConfig), children: children({ isLoading: false }) }));
37
41
  };
38
42
  /**
39
43
  * Component that provides access to current time slot
@@ -160,6 +164,10 @@ export const MinOrderAmount = ({ children }) => {
160
164
  export const AcceptingOrders = ({ children, }) => {
161
165
  const service = useService(OLOSettingsServiceDefinition);
162
166
  const fulfillmentsService = useService(FulfillmentsServiceDefinition);
167
+ // Check if FulfillmentsService is available (it won't be during loading)
168
+ if (!fulfillmentsService?.selectedFulfillment) {
169
+ return null;
170
+ }
163
171
  const operation = service.operation?.get();
164
172
  const selectedFulfillment = fulfillmentsService.selectedFulfillment?.get();
165
173
  const acceptingOrders = Boolean(operation?.enabled) && Boolean(selectedFulfillment);
@@ -184,7 +192,6 @@ export const AcceptingOrders = ({ children, }) => {
184
192
  export const DeliveryFee = ({ children }) => {
185
193
  const fulfillmentsService = useService(FulfillmentsServiceDefinition);
186
194
  const selectedDispatchInfo = fulfillmentsService.selectedDispatchInfoSignal?.get();
187
- console.log('selectedDispatchInfo', selectedDispatchInfo);
188
195
  const deliveryFee = selectedDispatchInfo?.deliveryFee ?? undefined;
189
196
  const hasDeliveryFee = Boolean(deliveryFee);
190
197
  return children({ deliveryFee, hasDeliveryFee });
@@ -231,6 +238,8 @@ export const FreeDeliveryThreshold = ({ children, }) => {
231
238
  export const SelectedAddress = ({ children, }) => {
232
239
  const fulfillmentsService = useService(FulfillmentsServiceDefinition);
233
240
  const selectedDispatchInfo = fulfillmentsService.selectedDispatchInfoSignal?.get();
241
+ const fulfillments = fulfillmentsService.fulfillments?.get() ?? null;
242
+ console.log('fulfillments', fulfillments);
234
243
  const selectedAddress = selectedDispatchInfo?.address ?? null;
235
244
  const hasAddress = Boolean(selectedAddress);
236
245
  const selectedTimeSlot = fulfillmentsService.selectedTimeSlot?.get();