@wix/headless-restaurants-olo 0.0.0
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/ClickableItem.d.ts +9 -0
- package/cjs/dist/react/ClickableItem.js +14 -0
- package/cjs/dist/react/ItemDetails.d.ts +279 -0
- package/cjs/dist/react/ItemDetails.js +137 -0
- package/cjs/dist/react/OLO.d.ts +179 -0
- package/cjs/dist/react/OLO.js +134 -0
- package/cjs/dist/react/core/ClickableItem.d.ts +13 -0
- package/cjs/dist/react/core/ClickableItem.js +21 -0
- package/cjs/dist/react/core/ItemDetails.d.ts +68 -0
- package/cjs/dist/react/core/ItemDetails.js +127 -0
- package/cjs/dist/react/core/OLO.d.ts +92 -0
- package/cjs/dist/react/core/OLO.js +122 -0
- package/cjs/dist/react/core/index.d.ts +3 -0
- package/cjs/dist/react/core/index.js +3 -0
- package/cjs/dist/react/index.d.ts +3 -0
- package/cjs/dist/react/index.js +3 -0
- package/cjs/dist/services/common-types.d.ts +19 -0
- package/cjs/dist/services/common-types.js +8 -0
- package/cjs/dist/services/index.d.ts +3 -0
- package/cjs/dist/services/index.js +3 -0
- package/cjs/dist/services/item-details-service.d.ts +169 -0
- package/cjs/dist/services/item-details-service.js +248 -0
- package/cjs/dist/services/olo-settings-service.d.ts +37 -0
- package/cjs/dist/services/olo-settings-service.js +45 -0
- package/cjs/dist/services/utils.d.ts +20 -0
- package/cjs/dist/services/utils.js +34 -0
- package/dist/react/ClickableItem.d.ts +9 -0
- package/dist/react/ClickableItem.js +14 -0
- package/dist/react/ItemDetails.d.ts +279 -0
- package/dist/react/ItemDetails.js +137 -0
- package/dist/react/OLO.d.ts +179 -0
- package/dist/react/OLO.js +134 -0
- package/dist/react/core/ClickableItem.d.ts +13 -0
- package/dist/react/core/ClickableItem.js +21 -0
- package/dist/react/core/ItemDetails.d.ts +68 -0
- package/dist/react/core/ItemDetails.js +127 -0
- package/dist/react/core/OLO.d.ts +92 -0
- package/dist/react/core/OLO.js +122 -0
- package/dist/react/core/index.d.ts +3 -0
- package/dist/react/core/index.js +3 -0
- package/dist/react/index.d.ts +3 -0
- package/dist/react/index.js +3 -0
- package/dist/services/common-types.d.ts +19 -0
- package/dist/services/common-types.js +8 -0
- package/dist/services/index.d.ts +3 -0
- package/dist/services/index.js +3 -0
- package/dist/services/item-details-service.d.ts +169 -0
- package/dist/services/item-details-service.js +248 -0
- package/dist/services/olo-settings-service.d.ts +37 -0
- package/dist/services/olo-settings-service.js +45 -0
- package/dist/services/utils.d.ts +20 -0
- package/dist/services/utils.js +34 -0
- package/package.json +81 -0
- package/react/package.json +4 -0
- package/services/package.json +4 -0
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import { type Signal } from '@wix/services-definitions/core-services/signals';
|
|
2
|
+
import { type LineItem } from '@wix/ecom/services';
|
|
3
|
+
import { itemVariants } from '@wix/restaurants';
|
|
4
|
+
import type { EnhancedItem } from '@wix/headless-restaurants-menus/services';
|
|
5
|
+
import { AvailabilityStatus } from './common-types.js';
|
|
6
|
+
type Variant = itemVariants.Variant;
|
|
7
|
+
/**
|
|
8
|
+
* API interface for the Item Detailsservice, providing reactive item data management.
|
|
9
|
+
* This service handles loading and managing a single item's data, loading state, and errors.
|
|
10
|
+
*
|
|
11
|
+
* @interface ItemServiceAPI
|
|
12
|
+
*/
|
|
13
|
+
export interface ItemServiceAPI {
|
|
14
|
+
/** Reactive signal containing the current item data */
|
|
15
|
+
item?: Signal<EnhancedItem | undefined>;
|
|
16
|
+
quantity: Signal<number>;
|
|
17
|
+
specialRequest: Signal<string>;
|
|
18
|
+
lineItem: Signal<LineItem>;
|
|
19
|
+
selectedVariant: Signal<Variant | undefined>;
|
|
20
|
+
selectedModifiers: Signal<Record<string, Array<string>>>;
|
|
21
|
+
availabilityStatus: Signal<AvailabilityStatus>;
|
|
22
|
+
/** Reactive signal indicating if a item is currently being loaded */
|
|
23
|
+
isLoading: Signal<boolean>;
|
|
24
|
+
/** Reactive signal containing any error message, or null if no error */
|
|
25
|
+
error: Signal<string | null>;
|
|
26
|
+
/** Function to update the quantity of the item */
|
|
27
|
+
updateQuantity: (quantity: number) => void;
|
|
28
|
+
/** Function to update the special request of the item */
|
|
29
|
+
updateSpecialRequest: (specialRequest: string) => void;
|
|
30
|
+
/** Function to update the selected variant of the item */
|
|
31
|
+
updateSelectedVariant: (variant: Variant) => void;
|
|
32
|
+
/** Function to toggle a modifier instance in a specific group */
|
|
33
|
+
toggleModifier: (modifierGroupId: string, modifierId: string, singleSelect?: boolean) => void;
|
|
34
|
+
/** Function to get the selected modifiers for a specific group */
|
|
35
|
+
getSelectedModifiers: (modifierGroupId: string) => Array<string>;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Service definition for the Item service.
|
|
39
|
+
* This defines the contract that the ItemService must implement.
|
|
40
|
+
*
|
|
41
|
+
* @constant
|
|
42
|
+
*/
|
|
43
|
+
export declare const ItemServiceDefinition: string & {
|
|
44
|
+
__api: ItemServiceAPI;
|
|
45
|
+
__config: {};
|
|
46
|
+
isServiceDefinition?: boolean;
|
|
47
|
+
} & ItemServiceAPI;
|
|
48
|
+
/**
|
|
49
|
+
* Configuration interface required to initialize the ItemService.
|
|
50
|
+
* Contains the initial item data that will be loaded into the service.
|
|
51
|
+
*
|
|
52
|
+
* @interface ItemServiceConfig
|
|
53
|
+
*/
|
|
54
|
+
export interface ItemServiceConfig {
|
|
55
|
+
/** The initial item data to configure the service with */
|
|
56
|
+
item?: EnhancedItem;
|
|
57
|
+
itemId?: string;
|
|
58
|
+
operationId?: string;
|
|
59
|
+
availabilityStatus?: AvailabilityStatus;
|
|
60
|
+
}
|
|
61
|
+
export declare const ItemService: import("@wix/services-definitions").ServiceFactory<string & {
|
|
62
|
+
__api: ItemServiceAPI;
|
|
63
|
+
__config: {};
|
|
64
|
+
isServiceDefinition?: boolean;
|
|
65
|
+
} & ItemServiceAPI, ItemServiceConfig>;
|
|
66
|
+
/**
|
|
67
|
+
* Success result interface for item service configuration loading.
|
|
68
|
+
* Returned when a item is successfully found and loaded.
|
|
69
|
+
*
|
|
70
|
+
* @interface SuccessItemServiceConfigResult
|
|
71
|
+
*/
|
|
72
|
+
export interface SuccessItemServiceConfigResult {
|
|
73
|
+
/** Type "success" means that the item was found and the config is valid */
|
|
74
|
+
type: 'success';
|
|
75
|
+
/** The item config containing the loaded item data */
|
|
76
|
+
config: ItemServiceConfig;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Not found result interface for item service configuration loading.
|
|
80
|
+
* Returned when a item with the given id cannot be found.
|
|
81
|
+
*
|
|
82
|
+
* @interface NotFoundItemServiceConfigResult
|
|
83
|
+
*/
|
|
84
|
+
export interface NotFoundItemServiceConfigResult {
|
|
85
|
+
/** Type "notFound" means that the item was not found */
|
|
86
|
+
type: 'notFound';
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Loads item service configuration from the Wix Items API for SSR initialization.
|
|
90
|
+
* This function is designed to be used during Server-Side Rendering (SSR) to preload
|
|
91
|
+
* a specific item by id that will be used to configure the ItemService.
|
|
92
|
+
*
|
|
93
|
+
* @param itemSlug The item id to load
|
|
94
|
+
* @returns Promise that resolves to ItemServiceConfigResult (success with config or notFound)
|
|
95
|
+
*
|
|
96
|
+
* @example
|
|
97
|
+
* ```astro
|
|
98
|
+
* ---
|
|
99
|
+
* // Astro page example - pages/item/[id].astro
|
|
100
|
+
* import { loadItemServiceConfig } from '@wix/stores/services';
|
|
101
|
+
* import { Item } from '@wix/stores/components';
|
|
102
|
+
*
|
|
103
|
+
* // Get item id from URL params
|
|
104
|
+
* const { id } = Astro.params;
|
|
105
|
+
*
|
|
106
|
+
* // Load item data during SSR
|
|
107
|
+
* const itemResult = await loadItemServiceConfig(id);
|
|
108
|
+
*
|
|
109
|
+
* // Handle not found case
|
|
110
|
+
* if (itemResult.type === 'notFound') {
|
|
111
|
+
* return Astro.redirect('/404');
|
|
112
|
+
* }
|
|
113
|
+
* ---
|
|
114
|
+
*
|
|
115
|
+
* <Item.Root itemConfig={itemResult.config}>
|
|
116
|
+
* <Item.Name>
|
|
117
|
+
* {({ name }) => <h1>{name}</h1>}
|
|
118
|
+
* </Item.Name>
|
|
119
|
+
* </Item.Root>
|
|
120
|
+
* ```
|
|
121
|
+
*
|
|
122
|
+
* @example
|
|
123
|
+
* ```tsx
|
|
124
|
+
* // Next.js page example - pages/item/[id].tsx
|
|
125
|
+
* import { GetServerSideProps } from 'next';
|
|
126
|
+
* import { loadItemServiceConfig } from '@wix/stores/services';
|
|
127
|
+
* import { Item } from '@wix/stores/components';
|
|
128
|
+
*
|
|
129
|
+
* interface ItemPageProps {
|
|
130
|
+
* itemConfig: Extract<Awaited<ReturnType<typeof loadItemServiceConfig>>, { type: 'success' }>['config'];
|
|
131
|
+
* }
|
|
132
|
+
*
|
|
133
|
+
* export const getServerSideProps: GetServerSideProps<ItemPageProps> = async ({ params }) => {
|
|
134
|
+
* const id = params?.id as string;
|
|
135
|
+
*
|
|
136
|
+
* // Load item data during SSR
|
|
137
|
+
* const itemResult = await loadItemServiceConfig(id);
|
|
138
|
+
*
|
|
139
|
+
* // Handle not found case
|
|
140
|
+
* if (itemResult.type === 'notFound') {
|
|
141
|
+
* return {
|
|
142
|
+
* notFound: true,
|
|
143
|
+
* };
|
|
144
|
+
* }
|
|
145
|
+
*
|
|
146
|
+
* return {
|
|
147
|
+
* props: {
|
|
148
|
+
* itemConfig: itemResult.config,
|
|
149
|
+
* },
|
|
150
|
+
* };
|
|
151
|
+
* };
|
|
152
|
+
*
|
|
153
|
+
* export default function ItemPage({ itemConfig }: ItemPageProps) {
|
|
154
|
+
* return (
|
|
155
|
+
* <Item.Root itemConfig={itemConfig}>
|
|
156
|
+
* <Item.Name>
|
|
157
|
+
* {({ name }) => <h1>{name}</h1>}
|
|
158
|
+
* </Item.Name>
|
|
159
|
+
* </Item.Root>
|
|
160
|
+
* );
|
|
161
|
+
* }
|
|
162
|
+
* ```
|
|
163
|
+
*/
|
|
164
|
+
export declare function loadItemServiceConfig({ item, operationId, availabilityStatus, }: {
|
|
165
|
+
item: EnhancedItem;
|
|
166
|
+
operationId: string;
|
|
167
|
+
availabilityStatus?: AvailabilityStatus;
|
|
168
|
+
}): ItemServiceConfig;
|
|
169
|
+
export {};
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
import { defineService, implementService } from '@wix/services-definitions';
|
|
2
|
+
import { SignalsServiceDefinition, } from '@wix/services-definitions/core-services/signals';
|
|
3
|
+
import { AvailabilityStatus } from './common-types.js';
|
|
4
|
+
import { getModifiersInitState } from './utils.js';
|
|
5
|
+
/**
|
|
6
|
+
* Service definition for the Item service.
|
|
7
|
+
* This defines the contract that the ItemService must implement.
|
|
8
|
+
*
|
|
9
|
+
* @constant
|
|
10
|
+
*/
|
|
11
|
+
export const ItemServiceDefinition = defineService('item');
|
|
12
|
+
/**
|
|
13
|
+
* Implementation of the Item service that manages reactive item data.
|
|
14
|
+
* This service provides signals for item data, loading state, and error handling,
|
|
15
|
+
* along with methods to dynamically load items.
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```tsx
|
|
19
|
+
* import { ItemService, ItemServiceDefinition } from '@wix/stores/services';
|
|
20
|
+
* import { useService } from '@wix/services-manager-react';
|
|
21
|
+
*
|
|
22
|
+
* function ItemComponent({ itemConfig }) {
|
|
23
|
+
* return (
|
|
24
|
+
* <ServiceProvider services={createServicesMap([
|
|
25
|
+
* [ItemServiceDefinition, ItemService.withConfig(itemConfig)]
|
|
26
|
+
* ])}>
|
|
27
|
+
* <ItemDisplay />
|
|
28
|
+
* </ServiceProvider>
|
|
29
|
+
* );
|
|
30
|
+
* }
|
|
31
|
+
*
|
|
32
|
+
* function ItemDisplay() {
|
|
33
|
+
* const itemService = useService(ItemServiceDefinition);
|
|
34
|
+
* const item = itemService.item.get();
|
|
35
|
+
* const isLoading = itemService.isLoading.get();
|
|
36
|
+
* const error = itemService.error.get();
|
|
37
|
+
*
|
|
38
|
+
* if (isLoading) return <div>Loading...</div>;
|
|
39
|
+
* if (error) return <div>Error: {error}</div>;
|
|
40
|
+
*
|
|
41
|
+
* return <h1>{item.name}</h1>;
|
|
42
|
+
* }
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
45
|
+
const APP_ID = '9a5d83fd-8570-482e-81ab-cfa88942ee60';
|
|
46
|
+
export const ItemService = implementService.withConfig()(ItemServiceDefinition, ({ getService, config }) => {
|
|
47
|
+
const signalsService = getService(SignalsServiceDefinition);
|
|
48
|
+
const availabilityStatus = signalsService.signal(config.availabilityStatus ?? AvailabilityStatus.AVAILABLE);
|
|
49
|
+
const item = signalsService.signal(config.item);
|
|
50
|
+
const isLoading = signalsService.signal(!!config.item);
|
|
51
|
+
const error = signalsService.signal(config.item ? null : 'Item not found');
|
|
52
|
+
const quantity = signalsService.signal(1);
|
|
53
|
+
const specialRequest = signalsService.signal('');
|
|
54
|
+
const lineItem = signalsService.signal({});
|
|
55
|
+
const priceVariants = config.item?.priceVariants || [];
|
|
56
|
+
const initialVariant = priceVariants.length > 0 ? priceVariants[0] : undefined;
|
|
57
|
+
const selectedVariant = signalsService.signal(initialVariant);
|
|
58
|
+
const modifierGroups = config.item?.modifierGroups || [];
|
|
59
|
+
const initialSelectedModifiers = getModifiersInitState(modifierGroups);
|
|
60
|
+
const selectedModifiers = signalsService.signal(initialSelectedModifiers);
|
|
61
|
+
if (config.item) {
|
|
62
|
+
console.log('config.item', config.item);
|
|
63
|
+
lineItem.set({
|
|
64
|
+
quantity: quantity.get(),
|
|
65
|
+
catalogReference: {
|
|
66
|
+
// @ts-expect-error - item is not typed
|
|
67
|
+
catalogItemId: config.item._id,
|
|
68
|
+
appId: APP_ID,
|
|
69
|
+
options: {
|
|
70
|
+
operationId: config.operationId,
|
|
71
|
+
// @ts-expect-error - item is not typed
|
|
72
|
+
menuId: config.item.menuId,
|
|
73
|
+
// @ts-expect-error - item is not typed
|
|
74
|
+
sectionId: config.item.sectionId,
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
const updateQuantity = (_quantity) => {
|
|
80
|
+
quantity.set(_quantity);
|
|
81
|
+
const _lineItem = lineItem.get();
|
|
82
|
+
lineItem.set({
|
|
83
|
+
..._lineItem,
|
|
84
|
+
quantity: _quantity,
|
|
85
|
+
});
|
|
86
|
+
};
|
|
87
|
+
const updateSpecialRequest = (_specialRequest) => {
|
|
88
|
+
specialRequest.set(_specialRequest);
|
|
89
|
+
const _lineItem = lineItem.get();
|
|
90
|
+
lineItem.set({
|
|
91
|
+
..._lineItem,
|
|
92
|
+
catalogReference: {
|
|
93
|
+
..._lineItem.catalogReference,
|
|
94
|
+
options: {
|
|
95
|
+
..._lineItem.catalogReference?.options,
|
|
96
|
+
specialRequest: _specialRequest,
|
|
97
|
+
},
|
|
98
|
+
},
|
|
99
|
+
});
|
|
100
|
+
};
|
|
101
|
+
const updateSelectedVariant = (variant) => {
|
|
102
|
+
selectedVariant.set(variant);
|
|
103
|
+
};
|
|
104
|
+
const getModifierIds = (modifierGroupId, modifierId, singleSelect = false) => {
|
|
105
|
+
const currentSelectedModifiers = selectedModifiers.get();
|
|
106
|
+
const groupModifierIds = currentSelectedModifiers[modifierGroupId] || [];
|
|
107
|
+
// Check if this modifier is already selected
|
|
108
|
+
const isModifierSelected = groupModifierIds.includes(modifierId);
|
|
109
|
+
if (singleSelect) {
|
|
110
|
+
// Single select behavior: select the modifier, replacing any existing selection
|
|
111
|
+
return [modifierId];
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
// Multi-select behavior: toggle the modifier
|
|
115
|
+
if (isModifierSelected) {
|
|
116
|
+
// Remove the modifier if it exists
|
|
117
|
+
const updatedModifierIds = groupModifierIds.filter((id) => id !== modifierId);
|
|
118
|
+
return updatedModifierIds;
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
// Add the modifier to the existing selection
|
|
122
|
+
return [...groupModifierIds, modifierId];
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
const toggleModifier = (modifierGroupId, modifierId, singleSelect = false) => {
|
|
127
|
+
const currentSelectedModifiers = selectedModifiers.get();
|
|
128
|
+
const modifierIds = getModifierIds(modifierGroupId, modifierId, singleSelect);
|
|
129
|
+
selectedModifiers.set({
|
|
130
|
+
...currentSelectedModifiers,
|
|
131
|
+
[modifierGroupId]: modifierIds,
|
|
132
|
+
});
|
|
133
|
+
};
|
|
134
|
+
const getSelectedModifiers = (modifierGroupId) => {
|
|
135
|
+
const currentSelectedModifiers = selectedModifiers.get();
|
|
136
|
+
return currentSelectedModifiers[modifierGroupId] || [];
|
|
137
|
+
};
|
|
138
|
+
return {
|
|
139
|
+
item,
|
|
140
|
+
quantity,
|
|
141
|
+
updateQuantity,
|
|
142
|
+
updateSpecialRequest,
|
|
143
|
+
updateSelectedVariant,
|
|
144
|
+
toggleModifier,
|
|
145
|
+
isLoading,
|
|
146
|
+
error,
|
|
147
|
+
specialRequest,
|
|
148
|
+
lineItem,
|
|
149
|
+
selectedVariant,
|
|
150
|
+
selectedModifiers,
|
|
151
|
+
availabilityStatus,
|
|
152
|
+
getSelectedModifiers,
|
|
153
|
+
};
|
|
154
|
+
});
|
|
155
|
+
/**
|
|
156
|
+
* Loads item service configuration from the Wix Items API for SSR initialization.
|
|
157
|
+
* This function is designed to be used during Server-Side Rendering (SSR) to preload
|
|
158
|
+
* a specific item by id that will be used to configure the ItemService.
|
|
159
|
+
*
|
|
160
|
+
* @param itemSlug The item id to load
|
|
161
|
+
* @returns Promise that resolves to ItemServiceConfigResult (success with config or notFound)
|
|
162
|
+
*
|
|
163
|
+
* @example
|
|
164
|
+
* ```astro
|
|
165
|
+
* ---
|
|
166
|
+
* // Astro page example - pages/item/[id].astro
|
|
167
|
+
* import { loadItemServiceConfig } from '@wix/stores/services';
|
|
168
|
+
* import { Item } from '@wix/stores/components';
|
|
169
|
+
*
|
|
170
|
+
* // Get item id from URL params
|
|
171
|
+
* const { id } = Astro.params;
|
|
172
|
+
*
|
|
173
|
+
* // Load item data during SSR
|
|
174
|
+
* const itemResult = await loadItemServiceConfig(id);
|
|
175
|
+
*
|
|
176
|
+
* // Handle not found case
|
|
177
|
+
* if (itemResult.type === 'notFound') {
|
|
178
|
+
* return Astro.redirect('/404');
|
|
179
|
+
* }
|
|
180
|
+
* ---
|
|
181
|
+
*
|
|
182
|
+
* <Item.Root itemConfig={itemResult.config}>
|
|
183
|
+
* <Item.Name>
|
|
184
|
+
* {({ name }) => <h1>{name}</h1>}
|
|
185
|
+
* </Item.Name>
|
|
186
|
+
* </Item.Root>
|
|
187
|
+
* ```
|
|
188
|
+
*
|
|
189
|
+
* @example
|
|
190
|
+
* ```tsx
|
|
191
|
+
* // Next.js page example - pages/item/[id].tsx
|
|
192
|
+
* import { GetServerSideProps } from 'next';
|
|
193
|
+
* import { loadItemServiceConfig } from '@wix/stores/services';
|
|
194
|
+
* import { Item } from '@wix/stores/components';
|
|
195
|
+
*
|
|
196
|
+
* interface ItemPageProps {
|
|
197
|
+
* itemConfig: Extract<Awaited<ReturnType<typeof loadItemServiceConfig>>, { type: 'success' }>['config'];
|
|
198
|
+
* }
|
|
199
|
+
*
|
|
200
|
+
* export const getServerSideProps: GetServerSideProps<ItemPageProps> = async ({ params }) => {
|
|
201
|
+
* const id = params?.id as string;
|
|
202
|
+
*
|
|
203
|
+
* // Load item data during SSR
|
|
204
|
+
* const itemResult = await loadItemServiceConfig(id);
|
|
205
|
+
*
|
|
206
|
+
* // Handle not found case
|
|
207
|
+
* if (itemResult.type === 'notFound') {
|
|
208
|
+
* return {
|
|
209
|
+
* notFound: true,
|
|
210
|
+
* };
|
|
211
|
+
* }
|
|
212
|
+
*
|
|
213
|
+
* return {
|
|
214
|
+
* props: {
|
|
215
|
+
* itemConfig: itemResult.config,
|
|
216
|
+
* },
|
|
217
|
+
* };
|
|
218
|
+
* };
|
|
219
|
+
*
|
|
220
|
+
* export default function ItemPage({ itemConfig }: ItemPageProps) {
|
|
221
|
+
* return (
|
|
222
|
+
* <Item.Root itemConfig={itemConfig}>
|
|
223
|
+
* <Item.Name>
|
|
224
|
+
* {({ name }) => <h1>{name}</h1>}
|
|
225
|
+
* </Item.Name>
|
|
226
|
+
* </Item.Root>
|
|
227
|
+
* );
|
|
228
|
+
* }
|
|
229
|
+
* ```
|
|
230
|
+
*/
|
|
231
|
+
export function loadItemServiceConfig({ item, operationId, availabilityStatus = AvailabilityStatus.AVAILABLE, }) {
|
|
232
|
+
return { item, operationId, availabilityStatus };
|
|
233
|
+
}
|
|
234
|
+
// try {
|
|
235
|
+
// if (item === null) {
|
|
236
|
+
// return { item: null };
|
|
237
|
+
// }
|
|
238
|
+
// console.log('loadItemServiceConfig', item);
|
|
239
|
+
// const itemResponse = await loadItemById(item._id);
|
|
240
|
+
// console.log('itemResponse', itemResponse);
|
|
241
|
+
// if (!itemResponse) {
|
|
242
|
+
// return { item: itemResponse, item };
|
|
243
|
+
// }
|
|
244
|
+
// return { item: itemResponse };
|
|
245
|
+
// } catch (error) {
|
|
246
|
+
// console.error(`Failed to load item "${itemId}":`, error);
|
|
247
|
+
// return { item: null, itemId };
|
|
248
|
+
// }}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import * as operationGroupsApi from '@wix/auto_sdk_restaurants_operation-groups';
|
|
2
|
+
import * as operationsApi from '@wix/auto_sdk_restaurants_operations';
|
|
3
|
+
import { type Signal } from '@wix/services-definitions/core-services/signals';
|
|
4
|
+
export interface OLOSettingsServiceAPI {
|
|
5
|
+
operationGroup: Signal<operationGroupsApi.OperationGroup | undefined>;
|
|
6
|
+
operation: Signal<operationsApi.Operation | undefined>;
|
|
7
|
+
selectedItem?: Signal<unknown>;
|
|
8
|
+
isLoading: Signal<boolean>;
|
|
9
|
+
error: Signal<string | null>;
|
|
10
|
+
availabilityDispatchAction?: Signal<(() => void) | undefined>;
|
|
11
|
+
}
|
|
12
|
+
export interface OLOSettingsServiceConfig {
|
|
13
|
+
operationGroup?: operationGroupsApi.OperationGroup;
|
|
14
|
+
operation?: operationsApi.Operation;
|
|
15
|
+
availabilityDispatchAction?: () => void;
|
|
16
|
+
}
|
|
17
|
+
export declare const OLOSettingsServiceDefinition: string & {
|
|
18
|
+
__api: OLOSettingsServiceAPI;
|
|
19
|
+
__config: {};
|
|
20
|
+
isServiceDefinition?: boolean;
|
|
21
|
+
} & OLOSettingsServiceAPI;
|
|
22
|
+
export declare const OLOSettingsService: import("@wix/services-definitions").ServiceFactory<string & {
|
|
23
|
+
__api: OLOSettingsServiceAPI;
|
|
24
|
+
__config: {};
|
|
25
|
+
isServiceDefinition?: boolean;
|
|
26
|
+
} & OLOSettingsServiceAPI, OLOSettingsServiceConfig>;
|
|
27
|
+
export declare function loadOLOSettingsServiceConfig(): Promise<{
|
|
28
|
+
operationGroup: operationGroupsApi.OperationGroup | undefined;
|
|
29
|
+
operation: operationsApi.Operation | undefined;
|
|
30
|
+
isLoading?: undefined;
|
|
31
|
+
error?: undefined;
|
|
32
|
+
} | {
|
|
33
|
+
operationGroup: undefined;
|
|
34
|
+
operation: undefined;
|
|
35
|
+
isLoading: boolean;
|
|
36
|
+
error: string;
|
|
37
|
+
}>;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { defineService, implementService } from '@wix/services-definitions';
|
|
2
|
+
import * as operationGroupsApi from '@wix/auto_sdk_restaurants_operation-groups';
|
|
3
|
+
import * as operationsApi from '@wix/auto_sdk_restaurants_operations';
|
|
4
|
+
import { SignalsServiceDefinition, } from '@wix/services-definitions/core-services/signals';
|
|
5
|
+
export const OLOSettingsServiceDefinition = defineService('oloSettings');
|
|
6
|
+
export const OLOSettingsService = implementService.withConfig()(OLOSettingsServiceDefinition, ({ getService, config }) => {
|
|
7
|
+
const signalsService = getService(SignalsServiceDefinition);
|
|
8
|
+
const availabilityDispatchAction = signalsService.signal(config.availabilityDispatchAction);
|
|
9
|
+
const operationGroup = signalsService.signal(config.operationGroup);
|
|
10
|
+
const operation = signalsService.signal(config.operation);
|
|
11
|
+
const selectedItem = signalsService.signal(null);
|
|
12
|
+
const isLoading = signalsService.signal(false);
|
|
13
|
+
const error = signalsService.signal(null);
|
|
14
|
+
return {
|
|
15
|
+
operationGroup,
|
|
16
|
+
operation,
|
|
17
|
+
isLoading,
|
|
18
|
+
error,
|
|
19
|
+
selectedItem,
|
|
20
|
+
availabilityDispatchAction,
|
|
21
|
+
};
|
|
22
|
+
});
|
|
23
|
+
export async function loadOLOSettingsServiceConfig() {
|
|
24
|
+
try {
|
|
25
|
+
// Fetch operation groups and operations in parallel
|
|
26
|
+
const [operationGroupsResponse, operationsResponse] = await Promise.all([
|
|
27
|
+
operationGroupsApi.queryOperationGroups().find(),
|
|
28
|
+
operationsApi.queryOperation().find(),
|
|
29
|
+
]);
|
|
30
|
+
return {
|
|
31
|
+
operationGroup: operationGroupsResponse.items[0] || undefined,
|
|
32
|
+
operation: operationsResponse.items[0] || undefined,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
catch (error) {
|
|
36
|
+
console.error('Failed to load OLO settings service config:', error);
|
|
37
|
+
return {
|
|
38
|
+
operationGroup: undefined,
|
|
39
|
+
operation: undefined,
|
|
40
|
+
isLoading: false,
|
|
41
|
+
error: error?.message ||
|
|
42
|
+
'Failed to load OLO settings service config',
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { EnhancedModifier, EnhancedModifierGroup } from '@wix/headless-restaurants-menus/services';
|
|
2
|
+
export declare const getModifiersInitState: (modifierGroups: EnhancedModifierGroup[]) => Record<string, string[]>;
|
|
3
|
+
export declare const isSingleSelectRule: (rule: NonNullable<EnhancedModifierGroup["rule"]>) => boolean | null | undefined;
|
|
4
|
+
export declare const getFirstPreSelectedModifier: (modifiers: EnhancedModifier[]) => string | null | undefined;
|
|
5
|
+
export declare const getPreSelectedModifiers: (modifiers: EnhancedModifier[]) => string[];
|
|
6
|
+
export declare const convertModifierToFormModifier: (modifier: EnhancedModifier, index: number) => {
|
|
7
|
+
_id: string;
|
|
8
|
+
revision?: string | null;
|
|
9
|
+
_createdDate?: Date | null;
|
|
10
|
+
_updatedDate?: Date | null;
|
|
11
|
+
name?: string | null;
|
|
12
|
+
extendedFields?: import("@wix/auto_sdk_restaurants_item-modifiers").ExtendedFields;
|
|
13
|
+
inStock?: boolean | null;
|
|
14
|
+
businessLocationIds?: string[];
|
|
15
|
+
additionalChargeInfo?: {
|
|
16
|
+
additionalCharge?: string;
|
|
17
|
+
formattedAdditionalCharge?: string;
|
|
18
|
+
};
|
|
19
|
+
preSelected?: boolean;
|
|
20
|
+
};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export const getModifiersInitState = (modifierGroups) => {
|
|
2
|
+
const initialSelectedModifiers = {};
|
|
3
|
+
modifierGroups.forEach((group) => {
|
|
4
|
+
if (group._id) {
|
|
5
|
+
const isMultiSelectItem = !isSingleSelectRule(group.rule ?? {});
|
|
6
|
+
const formModifiers = group.modifiers.map(convertModifierToFormModifier);
|
|
7
|
+
if (isMultiSelectItem) {
|
|
8
|
+
const preSelectedModifiers = getPreSelectedModifiers(formModifiers);
|
|
9
|
+
initialSelectedModifiers[group._id] = preSelectedModifiers;
|
|
10
|
+
}
|
|
11
|
+
else {
|
|
12
|
+
const preSelectedModifier = getFirstPreSelectedModifier(formModifiers);
|
|
13
|
+
initialSelectedModifiers[group._id] = preSelectedModifier
|
|
14
|
+
? [preSelectedModifier]
|
|
15
|
+
: [];
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
return initialSelectedModifiers;
|
|
20
|
+
};
|
|
21
|
+
export const isSingleSelectRule = (rule) => rule.required && rule.minSelections === 1 && rule.maxSelections === 1;
|
|
22
|
+
export const getFirstPreSelectedModifier = (modifiers) => modifiers.find(({ preSelected, inStock }) => preSelected && inStock)?._id;
|
|
23
|
+
export const getPreSelectedModifiers = (modifiers) => modifiers.reduce((acc, modifier) => {
|
|
24
|
+
if (modifier.preSelected && modifier.inStock && modifier._id) {
|
|
25
|
+
return [...acc, modifier._id];
|
|
26
|
+
}
|
|
27
|
+
return acc;
|
|
28
|
+
}, []);
|
|
29
|
+
export const convertModifierToFormModifier = (modifier, index) => {
|
|
30
|
+
return {
|
|
31
|
+
...modifier,
|
|
32
|
+
_id: `${modifier._id}~${index}`,
|
|
33
|
+
};
|
|
34
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
declare function ClickableItem({ onItemSelected, children, }: {
|
|
3
|
+
onItemSelected: (item: any) => void;
|
|
4
|
+
children: React.ReactNode;
|
|
5
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
6
|
+
export declare const Actions: {
|
|
7
|
+
Select: typeof ClickableItem;
|
|
8
|
+
};
|
|
9
|
+
export {};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { CoreClickableItem } from './core/ClickableItem.js';
|
|
3
|
+
function ClickableItem({ onItemSelected, children, }) {
|
|
4
|
+
const selectItem = (item, callback) => {
|
|
5
|
+
callback();
|
|
6
|
+
onItemSelected(item);
|
|
7
|
+
};
|
|
8
|
+
return (_jsx(CoreClickableItem, { children: ({ item, itemSelected }) => (_jsx("div", { onClick: () => {
|
|
9
|
+
selectItem(item, itemSelected);
|
|
10
|
+
}, children: children })) }));
|
|
11
|
+
}
|
|
12
|
+
export const Actions = {
|
|
13
|
+
Select: ClickableItem,
|
|
14
|
+
};
|