@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
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import {
|
|
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 {
|
|
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
|
-
|
|
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
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
const
|
|
22
|
-
const
|
|
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
|
|
53
|
-
const
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
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
|
-
//
|
|
70
|
-
const minDate =
|
|
71
|
-
|
|
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
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
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.
|
|
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
|
-
|
|
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
|
|
144
|
-
|
|
145
|
-
const hasAsapOption =
|
|
146
|
-
const hasPreorderOption =
|
|
147
|
-
const
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
const
|
|
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
|
-
|
|
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
|
|
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,
|
|
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
|
-
|
|
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
|
-
|
|
44
|
+
onHandleAddToCart,
|
|
56
45
|
buttonState,
|
|
57
46
|
addToCartButtonDisabled,
|
|
58
47
|
labelText,
|
|
59
48
|
formattedPrice,
|
|
60
|
-
|
|
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
|
-
*
|
|
18
|
-
*
|
|
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
|
-
* </
|
|
23
|
-
* </
|
|
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,
|
|
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
|
-
*
|
|
14
|
-
*
|
|
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
|
-
* </
|
|
19
|
-
* </
|
|
32
|
+
* </Settings.CurrentTimeSlot>
|
|
33
|
+
* </Settings.Root>
|
|
20
34
|
* ```
|
|
21
35
|
*/
|
|
22
36
|
export const Root = ({ children, fulfillmentsServiceConfig, }) => {
|
|
23
|
-
|
|
24
|
-
|
|
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,
|
|
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();
|