@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.
Files changed (55) hide show
  1. package/cjs/dist/react/ClickableItem.d.ts +9 -0
  2. package/cjs/dist/react/ClickableItem.js +14 -0
  3. package/cjs/dist/react/ItemDetails.d.ts +279 -0
  4. package/cjs/dist/react/ItemDetails.js +137 -0
  5. package/cjs/dist/react/OLO.d.ts +179 -0
  6. package/cjs/dist/react/OLO.js +134 -0
  7. package/cjs/dist/react/core/ClickableItem.d.ts +13 -0
  8. package/cjs/dist/react/core/ClickableItem.js +21 -0
  9. package/cjs/dist/react/core/ItemDetails.d.ts +68 -0
  10. package/cjs/dist/react/core/ItemDetails.js +127 -0
  11. package/cjs/dist/react/core/OLO.d.ts +92 -0
  12. package/cjs/dist/react/core/OLO.js +122 -0
  13. package/cjs/dist/react/core/index.d.ts +3 -0
  14. package/cjs/dist/react/core/index.js +3 -0
  15. package/cjs/dist/react/index.d.ts +3 -0
  16. package/cjs/dist/react/index.js +3 -0
  17. package/cjs/dist/services/common-types.d.ts +19 -0
  18. package/cjs/dist/services/common-types.js +8 -0
  19. package/cjs/dist/services/index.d.ts +3 -0
  20. package/cjs/dist/services/index.js +3 -0
  21. package/cjs/dist/services/item-details-service.d.ts +169 -0
  22. package/cjs/dist/services/item-details-service.js +248 -0
  23. package/cjs/dist/services/olo-settings-service.d.ts +37 -0
  24. package/cjs/dist/services/olo-settings-service.js +45 -0
  25. package/cjs/dist/services/utils.d.ts +20 -0
  26. package/cjs/dist/services/utils.js +34 -0
  27. package/dist/react/ClickableItem.d.ts +9 -0
  28. package/dist/react/ClickableItem.js +14 -0
  29. package/dist/react/ItemDetails.d.ts +279 -0
  30. package/dist/react/ItemDetails.js +137 -0
  31. package/dist/react/OLO.d.ts +179 -0
  32. package/dist/react/OLO.js +134 -0
  33. package/dist/react/core/ClickableItem.d.ts +13 -0
  34. package/dist/react/core/ClickableItem.js +21 -0
  35. package/dist/react/core/ItemDetails.d.ts +68 -0
  36. package/dist/react/core/ItemDetails.js +127 -0
  37. package/dist/react/core/OLO.d.ts +92 -0
  38. package/dist/react/core/OLO.js +122 -0
  39. package/dist/react/core/index.d.ts +3 -0
  40. package/dist/react/core/index.js +3 -0
  41. package/dist/react/index.d.ts +3 -0
  42. package/dist/react/index.js +3 -0
  43. package/dist/services/common-types.d.ts +19 -0
  44. package/dist/services/common-types.js +8 -0
  45. package/dist/services/index.d.ts +3 -0
  46. package/dist/services/index.js +3 -0
  47. package/dist/services/item-details-service.d.ts +169 -0
  48. package/dist/services/item-details-service.js +248 -0
  49. package/dist/services/olo-settings-service.d.ts +37 -0
  50. package/dist/services/olo-settings-service.js +45 -0
  51. package/dist/services/utils.d.ts +20 -0
  52. package/dist/services/utils.js +34 -0
  53. package/package.json +81 -0
  54. package/react/package.json +4 -0
  55. 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
+ };
package/package.json ADDED
@@ -0,0 +1,81 @@
1
+ {
2
+ "name": "@wix/headless-restaurants-olo",
3
+ "version": "0.0.0",
4
+ "license": "MIT",
5
+ "type": "module",
6
+ "scripts": {
7
+ "prebuild": "cd ../components && yarn build && cd ../ecom && yarn build",
8
+ "build": "npm run build:esm && npm run build:cjs",
9
+ "build:esm": "tsc -p tsconfig.json",
10
+ "build:cjs": "tsc -p tsconfig.cjs.json",
11
+ "test": "vitest",
12
+ "lint:fix": "prettier --write \"src/**/*.{ts,tsx,js,jsx,json,md}\"",
13
+ "lint:check": "prettier --check \"src/**/*.{ts,tsx,js,jsx,json,md}\""
14
+ },
15
+ "files": [
16
+ "dist",
17
+ "cjs",
18
+ "react",
19
+ "services",
20
+ "server-actions",
21
+ "astro"
22
+ ],
23
+ "exports": {
24
+ "./react": {
25
+ "types": "./dist/react/index.d.ts",
26
+ "import": "./dist/react/index.js",
27
+ "require": "./cjs/dist/react/index.js"
28
+ },
29
+ "./services": {
30
+ "types": "./dist/services/index.d.ts",
31
+ "import": "./dist/services/index.js",
32
+ "require": "./cjs/dist/services/index.js"
33
+ }
34
+ },
35
+ "devDependencies": {
36
+ "@testing-library/dom": "^10.4.0",
37
+ "@testing-library/jest-dom": "^6.6.3",
38
+ "@testing-library/react": "^16.3.0",
39
+ "@types/node": "^20.9.0",
40
+ "@typescript-eslint/eslint-plugin": "^6.21.0",
41
+ "@typescript-eslint/parser": "^6.21.0",
42
+ "@vitest/ui": "^3.1.4",
43
+ "eslint": "^8.57.0",
44
+ "eslint-config-prettier": "^10.1.8",
45
+ "eslint-plugin-react": "^7.34.1",
46
+ "eslint-plugin-react-hooks": "^4.6.0",
47
+ "jsdom": "^26.1.0",
48
+ "prettier": "^3.4.2",
49
+ "typescript": "^5.8.3",
50
+ "vitest": "^3.1.4"
51
+ },
52
+ "dependencies": {
53
+ "@radix-ui/react-checkbox": "^1.3.3",
54
+ "@radix-ui/react-radio-group": "^1.1.3",
55
+ "@radix-ui/react-slot": "^1.1.0",
56
+ "@wix/auto_sdk_restaurants_items": "^1.0.48",
57
+ "@wix/ecom": "^1.0.1461",
58
+ "@wix/headless-media": "0.0.0",
59
+ "@wix/headless-restaurants-menus": "0.0.0",
60
+ "@wix/headless-utils": "0.0.0",
61
+ "@wix/redirects": "^1.0.0",
62
+ "@wix/restaurants": "^1.0.396",
63
+ "@wix/sdk": "^1.15.24",
64
+ "@wix/services-definitions": "^0.1.4",
65
+ "@wix/services-manager-react": "^0.1.26"
66
+ },
67
+ "peerDependencies": {
68
+ "@wix/headless-components": "workspace:*"
69
+ },
70
+ "publishConfig": {
71
+ "registry": "https://registry.npmjs.org/",
72
+ "access": "public"
73
+ },
74
+ "wix": {
75
+ "artifact": {
76
+ "artifactId": "headless-restaurants-olo",
77
+ "groupId": "com.wixpress.headless-components"
78
+ }
79
+ },
80
+ "falconPackageHash": "554f40781c7d83a472b195ab0717a348ad238c53c9331339411f7ad8"
81
+ }
@@ -0,0 +1,4 @@
1
+ {
2
+ "main": "../cjs/dist/react/index.js",
3
+ "types": "../dist/react/index.d.ts"
4
+ }
@@ -0,0 +1,4 @@
1
+ {
2
+ "main": "../cjs/dist/services/index.js",
3
+ "types": "../dist/services/index.d.ts"
4
+ }