@wix/headless-restaurants-olo 0.0.1
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/ItemDetails.d.ts +119 -0
- package/cjs/dist/react/ItemDetails.js +51 -0
- package/cjs/dist/react/core/ItemDetails.d.ts +50 -0
- package/cjs/dist/react/core/ItemDetails.js +73 -0
- package/cjs/dist/react/core/index.d.ts +1 -0
- package/cjs/dist/react/core/index.js +1 -0
- package/cjs/dist/react/index.d.ts +1 -0
- package/cjs/dist/react/index.js +1 -0
- package/cjs/dist/services/common-types.d.ts +3 -0
- package/cjs/dist/services/common-types.js +1 -0
- package/cjs/dist/services/index.d.ts +2 -0
- package/cjs/dist/services/index.js +2 -0
- package/cjs/dist/services/item-details-service.d.ts +154 -0
- package/cjs/dist/services/item-details-service.js +196 -0
- package/cjs/dist/services/olo-settings-service.d.ts +35 -0
- package/cjs/dist/services/olo-settings-service.js +43 -0
- package/dist/react/ItemDetails.d.ts +119 -0
- package/dist/react/ItemDetails.js +51 -0
- package/dist/react/core/ItemDetails.d.ts +50 -0
- package/dist/react/core/ItemDetails.js +73 -0
- package/dist/react/core/index.d.ts +1 -0
- package/dist/react/core/index.js +1 -0
- package/dist/react/index.d.ts +1 -0
- package/dist/react/index.js +1 -0
- package/dist/services/common-types.d.ts +3 -0
- package/dist/services/common-types.js +1 -0
- package/dist/services/index.d.ts +2 -0
- package/dist/services/index.js +2 -0
- package/dist/services/item-details-service.d.ts +154 -0
- package/dist/services/item-details-service.js +196 -0
- package/dist/services/olo-settings-service.d.ts +35 -0
- package/dist/services/olo-settings-service.js +43 -0
- package/package.json +64 -0
- package/react/package.json +4 -0
- package/services/package.json +4 -0
|
@@ -0,0 +1,35 @@
|
|
|
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
|
+
}
|
|
11
|
+
export interface OLOSettingsServiceConfig {
|
|
12
|
+
operationGroup?: operationGroupsApi.OperationGroup;
|
|
13
|
+
operation?: operationsApi.Operation;
|
|
14
|
+
}
|
|
15
|
+
export declare const OLOSettingsServiceDefinition: string & {
|
|
16
|
+
__api: OLOSettingsServiceAPI;
|
|
17
|
+
__config: {};
|
|
18
|
+
isServiceDefinition?: boolean;
|
|
19
|
+
} & OLOSettingsServiceAPI;
|
|
20
|
+
export declare const OLOSettingsService: import("@wix/services-definitions").ServiceFactory<string & {
|
|
21
|
+
__api: OLOSettingsServiceAPI;
|
|
22
|
+
__config: {};
|
|
23
|
+
isServiceDefinition?: boolean;
|
|
24
|
+
} & OLOSettingsServiceAPI, OLOSettingsServiceConfig>;
|
|
25
|
+
export declare function loadOLOSettingsServiceConfig(): Promise<{
|
|
26
|
+
operationGroup: operationGroupsApi.OperationGroup | undefined;
|
|
27
|
+
operation: operationsApi.Operation | undefined;
|
|
28
|
+
isLoading?: undefined;
|
|
29
|
+
error?: undefined;
|
|
30
|
+
} | {
|
|
31
|
+
operationGroup: undefined;
|
|
32
|
+
operation: undefined;
|
|
33
|
+
isLoading: boolean;
|
|
34
|
+
error: string;
|
|
35
|
+
}>;
|
|
@@ -0,0 +1,43 @@
|
|
|
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 operationGroup = signalsService.signal(config.operationGroup);
|
|
9
|
+
const operation = signalsService.signal(config.operation);
|
|
10
|
+
const selectedItem = signalsService.signal(null);
|
|
11
|
+
const isLoading = signalsService.signal(false);
|
|
12
|
+
const error = signalsService.signal(null);
|
|
13
|
+
return {
|
|
14
|
+
operationGroup,
|
|
15
|
+
operation,
|
|
16
|
+
isLoading,
|
|
17
|
+
error,
|
|
18
|
+
selectedItem,
|
|
19
|
+
};
|
|
20
|
+
});
|
|
21
|
+
export async function loadOLOSettingsServiceConfig() {
|
|
22
|
+
try {
|
|
23
|
+
// Fetch operation groups and operations in parallel
|
|
24
|
+
const [operationGroupsResponse, operationsResponse] = await Promise.all([
|
|
25
|
+
operationGroupsApi.queryOperationGroups().find(),
|
|
26
|
+
operationsApi.queryOperation().find(),
|
|
27
|
+
]);
|
|
28
|
+
return {
|
|
29
|
+
operationGroup: operationGroupsResponse.items[0] || undefined,
|
|
30
|
+
operation: operationsResponse.items[0] || undefined,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
catch (error) {
|
|
34
|
+
console.error('Failed to load OLO settings service config:', error);
|
|
35
|
+
return {
|
|
36
|
+
operationGroup: undefined,
|
|
37
|
+
operation: undefined,
|
|
38
|
+
isLoading: false,
|
|
39
|
+
error: error?.message ||
|
|
40
|
+
'Failed to load OLO settings service config',
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Commerce } from '@wix/ecom/components';
|
|
3
|
+
import { type LineItem } from '@wix/ecom/services';
|
|
4
|
+
import { type AsChildChildren } from '@wix/headless-utils/react';
|
|
5
|
+
import { ItemServiceConfig } from '../services/item-details-service.js';
|
|
6
|
+
/**
|
|
7
|
+
* Root component for menu item display and interaction.
|
|
8
|
+
* Provides context for all menu item-related components like name, price, description, image, etc.
|
|
9
|
+
*
|
|
10
|
+
* @component
|
|
11
|
+
* @example
|
|
12
|
+
* ```tsx
|
|
13
|
+
* <ItemDetails>
|
|
14
|
+
* <ItemDetailsImage src="wix:image://v1/abc123.jpg" alt="Menu item" />
|
|
15
|
+
* <ItemDetailsName />
|
|
16
|
+
* <ItemDetailsPrice />
|
|
17
|
+
* <ItemDetailsDescription />
|
|
18
|
+
* </ItemDetails>
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
export interface RootProps {
|
|
22
|
+
asChild?: boolean;
|
|
23
|
+
children: React.ReactNode;
|
|
24
|
+
itemDetailsServiceConfig: ItemServiceConfig;
|
|
25
|
+
}
|
|
26
|
+
export declare const Root: ({ children, itemDetailsServiceConfig }: RootProps) => import("react/jsx-runtime").JSX.Element;
|
|
27
|
+
export interface ItemDetailsNameProps {
|
|
28
|
+
asChild?: boolean;
|
|
29
|
+
/** Custom render function when using asChild */
|
|
30
|
+
children?: AsChildChildren<{
|
|
31
|
+
name: string;
|
|
32
|
+
}>;
|
|
33
|
+
/** CSS classes to apply to the default element */
|
|
34
|
+
className?: string;
|
|
35
|
+
}
|
|
36
|
+
export interface AddToCartActionProps {
|
|
37
|
+
/** Whether to render as a child component */
|
|
38
|
+
asChild?: boolean;
|
|
39
|
+
/** Text label for the button */
|
|
40
|
+
label: string;
|
|
41
|
+
/** Custom render function when using asChild */
|
|
42
|
+
lineItems: LineItem[];
|
|
43
|
+
/** CSS classes to apply to the button */
|
|
44
|
+
className?: string;
|
|
45
|
+
/** Content to display when loading */
|
|
46
|
+
loadingState?: string | React.ReactNode;
|
|
47
|
+
children?: React.ReactNode;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Add to Cart button for the menu item.
|
|
51
|
+
* Triggers the action to add the selected item (and its modifiers/variants) to the cart.
|
|
52
|
+
*
|
|
53
|
+
* @component
|
|
54
|
+
* @example
|
|
55
|
+
* ```tsx
|
|
56
|
+
* <ItemDetails>
|
|
57
|
+
* <AddToCart
|
|
58
|
+
* label="Add to Cart"
|
|
59
|
+
* lineItems={[{ catalogReference: { ... }, quantity: 1 }]}
|
|
60
|
+
* />
|
|
61
|
+
* </ItemDetails>
|
|
62
|
+
* ```
|
|
63
|
+
*/
|
|
64
|
+
export declare const AddToCart: React.ForwardRefExoticComponent<AddToCartActionProps & React.RefAttributes<HTMLButtonElement>>;
|
|
65
|
+
/**
|
|
66
|
+
* Multi-line text input component for special requests or instructions.
|
|
67
|
+
* Provides a textarea for customers to add custom notes or modifications.
|
|
68
|
+
*
|
|
69
|
+
* @component
|
|
70
|
+
* @example
|
|
71
|
+
* ```tsx
|
|
72
|
+
* <ItemDetails>
|
|
73
|
+
* <SpecialRequest
|
|
74
|
+
* placeholder="Any special requests or dietary restrictions?"
|
|
75
|
+
* maxLength={200}
|
|
76
|
+
* className="mt-4"
|
|
77
|
+
* />
|
|
78
|
+
* </ItemDetails>
|
|
79
|
+
* ```
|
|
80
|
+
*/
|
|
81
|
+
export interface SpecialRequestProps {
|
|
82
|
+
asChild?: boolean;
|
|
83
|
+
children?: AsChildChildren<{
|
|
84
|
+
description: string;
|
|
85
|
+
}>;
|
|
86
|
+
/** Placeholder text for the textarea */
|
|
87
|
+
placeholder?: string;
|
|
88
|
+
/** Maximum number of characters allowed */
|
|
89
|
+
maxLength?: number;
|
|
90
|
+
/** Number of visible text lines */
|
|
91
|
+
rows?: number;
|
|
92
|
+
/** CSS classes to apply to the textarea */
|
|
93
|
+
className?: string;
|
|
94
|
+
labelClassName?: string;
|
|
95
|
+
/** Label text for the input */
|
|
96
|
+
label?: string;
|
|
97
|
+
/** Whether to show character count */
|
|
98
|
+
showCharCount?: boolean;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* AddToCartButton component that uses Commerce.Actions.AddToCart with AsChildSlot,
|
|
102
|
+
* and gets the lineItem from CoreItemDetails.LineItemComponent.
|
|
103
|
+
*
|
|
104
|
+
* Usage:
|
|
105
|
+
* <ItemDetails.AddToCartButton>Add to cart</ItemDetails.AddToCartButton>
|
|
106
|
+
*/
|
|
107
|
+
export interface AddToCartButtonProps extends Omit<React.ComponentPropsWithoutRef<typeof Commerce.Actions.AddToCart>, 'lineItems'> {
|
|
108
|
+
asChild?: boolean;
|
|
109
|
+
children?: React.ReactNode;
|
|
110
|
+
className?: string;
|
|
111
|
+
label?: string;
|
|
112
|
+
onClick?: () => void;
|
|
113
|
+
}
|
|
114
|
+
export interface ItemDetailsQuantityProps {
|
|
115
|
+
children: React.ReactNode;
|
|
116
|
+
}
|
|
117
|
+
export declare const AddToCartButton: React.FC<AddToCartButtonProps>;
|
|
118
|
+
export declare const Quantity: React.FC<ItemDetailsQuantityProps>;
|
|
119
|
+
export declare const SpecialRequest: React.ForwardRefExoticComponent<SpecialRequestProps & React.RefAttributes<never>>;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { Commerce } from '@wix/ecom/components';
|
|
4
|
+
import { AsChildSlot } from '@wix/headless-utils/react';
|
|
5
|
+
import { Quantity as QuantityComponent } from '@wix/headless-components/react';
|
|
6
|
+
import { Item } from '@wix/restaurants/components';
|
|
7
|
+
import * as CoreItemDetails from './core/ItemDetails.js';
|
|
8
|
+
var TestIds;
|
|
9
|
+
(function (TestIds) {
|
|
10
|
+
TestIds["itemName"] = "item-name";
|
|
11
|
+
TestIds["itemPrice"] = "item-price";
|
|
12
|
+
TestIds["itemDescription"] = "item-description";
|
|
13
|
+
TestIds["itemImage"] = "item-image";
|
|
14
|
+
TestIds["itemAddToCart"] = "item-add-to-cart";
|
|
15
|
+
TestIds["itemSpecialRequest"] = "item-special-request";
|
|
16
|
+
})(TestIds || (TestIds = {}));
|
|
17
|
+
export const Root = ({ children, itemDetailsServiceConfig }) => {
|
|
18
|
+
return (_jsx(CoreItemDetails.Root, { itemDetailsServiceConfig: itemDetailsServiceConfig, children: ({ item }) => _jsx(Item.Root, { item: item, children: children }) }));
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Add to Cart button for the menu item.
|
|
22
|
+
* Triggers the action to add the selected item (and its modifiers/variants) to the cart.
|
|
23
|
+
*
|
|
24
|
+
* @component
|
|
25
|
+
* @example
|
|
26
|
+
* ```tsx
|
|
27
|
+
* <ItemDetails>
|
|
28
|
+
* <AddToCart
|
|
29
|
+
* label="Add to Cart"
|
|
30
|
+
* lineItems={[{ catalogReference: { ... }, quantity: 1 }]}
|
|
31
|
+
* />
|
|
32
|
+
* </ItemDetails>
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
export const AddToCart = React.forwardRef(({ lineItems, className, label, ...props }, ref) => {
|
|
36
|
+
return (_jsx(Commerce.Actions.AddToCart, { ref: ref, asChild: false, label: label, className: className, lineItems: lineItems, children: props.children }));
|
|
37
|
+
});
|
|
38
|
+
AddToCart.displayName = 'AddToCart';
|
|
39
|
+
export const AddToCartButton = ({ asChild = false, children, className, onClick, label = 'Add to cart', ...props }) => {
|
|
40
|
+
return (_jsx(CoreItemDetails.LineItemComponent, { children: ({ lineItem }) => (_jsx(AsChildSlot, { asChild: asChild, className: className, customElement: children, customElementProps: {
|
|
41
|
+
onClick,
|
|
42
|
+
}, children: _jsx(Commerce.Actions.AddToCart, { asChild: false, label: label, className: className, lineItems: [lineItem], ...props, children: children }) })) }));
|
|
43
|
+
};
|
|
44
|
+
export const Quantity = ({ children }, ref) => {
|
|
45
|
+
return (_jsx(CoreItemDetails.QuantityComponent, { children: ({ quantity, onValueChange, }) => (_jsx(QuantityComponent.Root, { ref: ref, onValueChange: onValueChange, initialValue: quantity, children: children })) }));
|
|
46
|
+
};
|
|
47
|
+
Quantity.displayName = 'Quantity';
|
|
48
|
+
export const SpecialRequest = React.forwardRef(({ className, labelClassName, placeholder = 'Any special requests or dietary restrictions?', maxLength = 200, rows = 3, label = 'Special Requests', asChild, children, ...props }, ref) => {
|
|
49
|
+
return (_jsx(CoreItemDetails.SpecialRequest, { children: ({ value, onChange, }) => (_jsxs(AsChildSlot, { ref: ref, asChild: asChild, className: className, onChange: onChange, "data-testid": TestIds.itemSpecialRequest, customElement: children, customElementProps: { label, value }, content: value, ...props, children: [label && _jsx("label", { className: labelClassName, children: label }), _jsx("textarea", { value: value, onChange: (e) => onChange(e.target.value), placeholder: placeholder, maxLength: maxLength, rows: rows, className: className, children: value })] })) }));
|
|
50
|
+
});
|
|
51
|
+
SpecialRequest.displayName = 'SpecialRequest';
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { type LineItem } from '@wix/ecom/services';
|
|
3
|
+
import { ItemServiceConfig } from '../../services/item-details-service.js';
|
|
4
|
+
interface ItemDetailsRootProps {
|
|
5
|
+
children: (props: {
|
|
6
|
+
item: unknown;
|
|
7
|
+
}) => React.ReactNode;
|
|
8
|
+
itemDetailsServiceConfig: ItemServiceConfig;
|
|
9
|
+
}
|
|
10
|
+
export declare const Root: React.FC<ItemDetailsRootProps>;
|
|
11
|
+
interface ItemDetailsModifiersRepeaterProps {
|
|
12
|
+
children: (props: {
|
|
13
|
+
modifiers: [];
|
|
14
|
+
hasModifiers: boolean;
|
|
15
|
+
}) => React.ReactNode;
|
|
16
|
+
}
|
|
17
|
+
export declare const ModifiersRepeater: React.FC<ItemDetailsModifiersRepeaterProps>;
|
|
18
|
+
interface ItemDetailsVariantsRepeaterProps {
|
|
19
|
+
children: (props: {
|
|
20
|
+
variants: [];
|
|
21
|
+
hasVariants: boolean;
|
|
22
|
+
}) => React.ReactNode;
|
|
23
|
+
}
|
|
24
|
+
export declare const VariantsRepeater: React.FC<ItemDetailsVariantsRepeaterProps>;
|
|
25
|
+
interface ItemDetailsSpecialRequestProps {
|
|
26
|
+
children: (props: {
|
|
27
|
+
value: string;
|
|
28
|
+
onChange: (value: string) => void;
|
|
29
|
+
}) => React.ReactNode;
|
|
30
|
+
}
|
|
31
|
+
export declare const SpecialRequest: React.FC<ItemDetailsSpecialRequestProps>;
|
|
32
|
+
interface ItemDetailsLineItemProps {
|
|
33
|
+
children: (props: {
|
|
34
|
+
lineItem: LineItem;
|
|
35
|
+
}) => React.ReactNode;
|
|
36
|
+
}
|
|
37
|
+
export declare const LineItemComponent: React.FC<ItemDetailsLineItemProps>;
|
|
38
|
+
interface ItemDetailsQuantityProps {
|
|
39
|
+
children: (props: {
|
|
40
|
+
quantity: number;
|
|
41
|
+
increment: () => void;
|
|
42
|
+
decrement: () => void;
|
|
43
|
+
setQuantity: (quantity: number) => void;
|
|
44
|
+
canIncrement: boolean;
|
|
45
|
+
canDecrement: boolean;
|
|
46
|
+
onValueChange: (value: number) => void;
|
|
47
|
+
}) => React.ReactNode;
|
|
48
|
+
}
|
|
49
|
+
export declare const QuantityComponent: React.FC<ItemDetailsQuantityProps>;
|
|
50
|
+
export {};
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useState } from 'react';
|
|
3
|
+
import { useService, WixServices } from '@wix/services-manager-react';
|
|
4
|
+
import { createServicesMap } from '@wix/services-manager';
|
|
5
|
+
import { ItemService, ItemServiceDefinition, loadItemServiceConfig, } from '../../services/item-details-service.js';
|
|
6
|
+
import { OLOSettingsServiceDefinition } from '../../services/olo-settings-service.js';
|
|
7
|
+
export const Root = ({ children }) => {
|
|
8
|
+
const service = useService(OLOSettingsServiceDefinition);
|
|
9
|
+
const selectedItem = service.selectedItem?.get();
|
|
10
|
+
const itemDetailsServiceConfig = loadItemServiceConfig({
|
|
11
|
+
item: selectedItem,
|
|
12
|
+
operationId: service.operation?.get()?._id ?? '',
|
|
13
|
+
});
|
|
14
|
+
return (_jsx(WixServices, { servicesMap: createServicesMap().addService(ItemServiceDefinition, ItemService, itemDetailsServiceConfig), children: children({ item: selectedItem }) }));
|
|
15
|
+
};
|
|
16
|
+
export const ModifiersRepeater = ({ children, }) => {
|
|
17
|
+
const service = useService(ItemServiceDefinition);
|
|
18
|
+
const item = service.item.get();
|
|
19
|
+
// TODO: Check if modifiers exist on item type - might be in a different property
|
|
20
|
+
const modifiers = item?.modifiers || [];
|
|
21
|
+
const hasModifiers = modifiers.length > 0;
|
|
22
|
+
return children({ modifiers, hasModifiers });
|
|
23
|
+
};
|
|
24
|
+
export const VariantsRepeater = ({ children, }) => {
|
|
25
|
+
const service = useService(ItemServiceDefinition);
|
|
26
|
+
const item = service.item.get();
|
|
27
|
+
// TODO: Check if variants exist on item type - might be in a different property
|
|
28
|
+
const variants = item?.variants || [];
|
|
29
|
+
const hasVariants = variants.length > 0;
|
|
30
|
+
return children({ variants, hasVariants });
|
|
31
|
+
};
|
|
32
|
+
export const SpecialRequest = ({ children, }) => {
|
|
33
|
+
const [value, setValue] = useState('');
|
|
34
|
+
const service = useService(ItemServiceDefinition);
|
|
35
|
+
const onChange = (newValue) => {
|
|
36
|
+
setValue(newValue);
|
|
37
|
+
service.updateSpecialRequest(newValue);
|
|
38
|
+
};
|
|
39
|
+
return children({
|
|
40
|
+
value,
|
|
41
|
+
onChange,
|
|
42
|
+
// placeholder: 'Any special requests or dietary restrictions?',
|
|
43
|
+
// maxLength: 200
|
|
44
|
+
});
|
|
45
|
+
};
|
|
46
|
+
export const LineItemComponent = ({ children, }) => {
|
|
47
|
+
const service = useService(ItemServiceDefinition);
|
|
48
|
+
const lineItem = service.lineItem?.get?.() ?? {};
|
|
49
|
+
return children({ lineItem });
|
|
50
|
+
};
|
|
51
|
+
export const QuantityComponent = ({ children, }) => {
|
|
52
|
+
const service = useService(ItemServiceDefinition);
|
|
53
|
+
const quantity = service.quantity?.get?.() ?? 1;
|
|
54
|
+
const increment = () => service.quantity?.set?.(quantity + 1);
|
|
55
|
+
const decrement = () => service.quantity?.set?.(quantity - 1);
|
|
56
|
+
const setQuantity = (quantity) => {
|
|
57
|
+
service.updateQuantity?.(quantity);
|
|
58
|
+
};
|
|
59
|
+
const canIncrement = true;
|
|
60
|
+
const canDecrement = quantity > 1;
|
|
61
|
+
const onValueChange = (value) => {
|
|
62
|
+
service.updateQuantity?.(value);
|
|
63
|
+
};
|
|
64
|
+
return children({
|
|
65
|
+
quantity,
|
|
66
|
+
increment,
|
|
67
|
+
decrement,
|
|
68
|
+
setQuantity,
|
|
69
|
+
canIncrement,
|
|
70
|
+
canDecrement,
|
|
71
|
+
onValueChange,
|
|
72
|
+
});
|
|
73
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * as CoreItemDetails from './ItemDetails.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * as CoreItemDetails from './ItemDetails.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './ItemDetails.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './ItemDetails.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export { ItemService, ItemServiceDefinition, loadItemServiceConfig, ItemServiceConfig, } from './item-details-service.js';
|
|
2
|
+
export { OLOSettingsService, OLOSettingsServiceDefinition, loadOLOSettingsServiceConfig, type OLOSettingsServiceConfig, type OLOSettingsServiceAPI, } from './olo-settings-service.js';
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import { type Signal } from '@wix/services-definitions/core-services/signals';
|
|
2
|
+
import * as items from '@wix/auto_sdk_restaurants_items';
|
|
3
|
+
import { type LineItem } from '@wix/ecom/services';
|
|
4
|
+
/**
|
|
5
|
+
* API interface for the Item Detailsservice, providing reactive item data management.
|
|
6
|
+
* This service handles loading and managing a single item's data, loading state, and errors.
|
|
7
|
+
*
|
|
8
|
+
* @interface ItemServiceAPI
|
|
9
|
+
*/
|
|
10
|
+
export interface ItemServiceAPI {
|
|
11
|
+
/** Reactive signal containing the current item data */
|
|
12
|
+
item: Signal<items.Item>;
|
|
13
|
+
quantity: Signal<number>;
|
|
14
|
+
specialRequest: Signal<string>;
|
|
15
|
+
lineItem: Signal<LineItem>;
|
|
16
|
+
/** Reactive signal indicating if a item is currently being loaded */
|
|
17
|
+
isLoading: Signal<boolean>;
|
|
18
|
+
/** Reactive signal containing any error message, or null if no error */
|
|
19
|
+
error: Signal<string | null>;
|
|
20
|
+
/** Function to update the quantity of the item */
|
|
21
|
+
updateQuantity: (quantity: number) => void;
|
|
22
|
+
/** Function to update the special request of the item */
|
|
23
|
+
updateSpecialRequest: (specialRequest: string) => void;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Service definition for the Item service.
|
|
27
|
+
* This defines the contract that the ItemService must implement.
|
|
28
|
+
*
|
|
29
|
+
* @constant
|
|
30
|
+
*/
|
|
31
|
+
export declare const ItemServiceDefinition: string & {
|
|
32
|
+
__api: ItemServiceAPI;
|
|
33
|
+
__config: {};
|
|
34
|
+
isServiceDefinition?: boolean;
|
|
35
|
+
} & ItemServiceAPI;
|
|
36
|
+
/**
|
|
37
|
+
* Configuration interface required to initialize the ItemService.
|
|
38
|
+
* Contains the initial item data that will be loaded into the service.
|
|
39
|
+
*
|
|
40
|
+
* @interface ItemServiceConfig
|
|
41
|
+
*/
|
|
42
|
+
export interface ItemServiceConfig {
|
|
43
|
+
/** The initial item data to configure the service with */
|
|
44
|
+
item: items.Item;
|
|
45
|
+
itemId?: string;
|
|
46
|
+
operationId?: string;
|
|
47
|
+
}
|
|
48
|
+
export declare const ItemService: import("@wix/services-definitions").ServiceFactory<string & {
|
|
49
|
+
__api: ItemServiceAPI;
|
|
50
|
+
__config: {};
|
|
51
|
+
isServiceDefinition?: boolean;
|
|
52
|
+
} & ItemServiceAPI, ItemServiceConfig>;
|
|
53
|
+
/**
|
|
54
|
+
* Success result interface for item service configuration loading.
|
|
55
|
+
* Returned when a item is successfully found and loaded.
|
|
56
|
+
*
|
|
57
|
+
* @interface SuccessItemServiceConfigResult
|
|
58
|
+
*/
|
|
59
|
+
export interface SuccessItemServiceConfigResult {
|
|
60
|
+
/** Type "success" means that the item was found and the config is valid */
|
|
61
|
+
type: 'success';
|
|
62
|
+
/** The item config containing the loaded item data */
|
|
63
|
+
config: ItemServiceConfig;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Not found result interface for item service configuration loading.
|
|
67
|
+
* Returned when a item with the given id cannot be found.
|
|
68
|
+
*
|
|
69
|
+
* @interface NotFoundItemServiceConfigResult
|
|
70
|
+
*/
|
|
71
|
+
export interface NotFoundItemServiceConfigResult {
|
|
72
|
+
/** Type "notFound" means that the item was not found */
|
|
73
|
+
type: 'notFound';
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Loads item service configuration from the Wix Items API for SSR initialization.
|
|
77
|
+
* This function is designed to be used during Server-Side Rendering (SSR) to preload
|
|
78
|
+
* a specific item by id that will be used to configure the ItemService.
|
|
79
|
+
*
|
|
80
|
+
* @param itemSlug The item id to load
|
|
81
|
+
* @returns Promise that resolves to ItemServiceConfigResult (success with config or notFound)
|
|
82
|
+
*
|
|
83
|
+
* @example
|
|
84
|
+
* ```astro
|
|
85
|
+
* ---
|
|
86
|
+
* // Astro page example - pages/item/[id].astro
|
|
87
|
+
* import { loadItemServiceConfig } from '@wix/stores/services';
|
|
88
|
+
* import { Item } from '@wix/stores/components';
|
|
89
|
+
*
|
|
90
|
+
* // Get item id from URL params
|
|
91
|
+
* const { id } = Astro.params;
|
|
92
|
+
*
|
|
93
|
+
* // Load item data during SSR
|
|
94
|
+
* const itemResult = await loadItemServiceConfig(id);
|
|
95
|
+
*
|
|
96
|
+
* // Handle not found case
|
|
97
|
+
* if (itemResult.type === 'notFound') {
|
|
98
|
+
* return Astro.redirect('/404');
|
|
99
|
+
* }
|
|
100
|
+
* ---
|
|
101
|
+
*
|
|
102
|
+
* <Item.Root itemConfig={itemResult.config}>
|
|
103
|
+
* <Item.Name>
|
|
104
|
+
* {({ name }) => <h1>{name}</h1>}
|
|
105
|
+
* </Item.Name>
|
|
106
|
+
* </Item.Root>
|
|
107
|
+
* ```
|
|
108
|
+
*
|
|
109
|
+
* @example
|
|
110
|
+
* ```tsx
|
|
111
|
+
* // Next.js page example - pages/item/[id].tsx
|
|
112
|
+
* import { GetServerSideProps } from 'next';
|
|
113
|
+
* import { loadItemServiceConfig } from '@wix/stores/services';
|
|
114
|
+
* import { Item } from '@wix/stores/components';
|
|
115
|
+
*
|
|
116
|
+
* interface ItemPageProps {
|
|
117
|
+
* itemConfig: Extract<Awaited<ReturnType<typeof loadItemServiceConfig>>, { type: 'success' }>['config'];
|
|
118
|
+
* }
|
|
119
|
+
*
|
|
120
|
+
* export const getServerSideProps: GetServerSideProps<ItemPageProps> = async ({ params }) => {
|
|
121
|
+
* const id = params?.id as string;
|
|
122
|
+
*
|
|
123
|
+
* // Load item data during SSR
|
|
124
|
+
* const itemResult = await loadItemServiceConfig(id);
|
|
125
|
+
*
|
|
126
|
+
* // Handle not found case
|
|
127
|
+
* if (itemResult.type === 'notFound') {
|
|
128
|
+
* return {
|
|
129
|
+
* notFound: true,
|
|
130
|
+
* };
|
|
131
|
+
* }
|
|
132
|
+
*
|
|
133
|
+
* return {
|
|
134
|
+
* props: {
|
|
135
|
+
* itemConfig: itemResult.config,
|
|
136
|
+
* },
|
|
137
|
+
* };
|
|
138
|
+
* };
|
|
139
|
+
*
|
|
140
|
+
* export default function ItemPage({ itemConfig }: ItemPageProps) {
|
|
141
|
+
* return (
|
|
142
|
+
* <Item.Root itemConfig={itemConfig}>
|
|
143
|
+
* <Item.Name>
|
|
144
|
+
* {({ name }) => <h1>{name}</h1>}
|
|
145
|
+
* </Item.Name>
|
|
146
|
+
* </Item.Root>
|
|
147
|
+
* );
|
|
148
|
+
* }
|
|
149
|
+
* ```
|
|
150
|
+
*/
|
|
151
|
+
export declare function loadItemServiceConfig({ item, operationId, }: {
|
|
152
|
+
item: any;
|
|
153
|
+
operationId: string;
|
|
154
|
+
}): ItemServiceConfig;
|