@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.
Files changed (35) hide show
  1. package/cjs/dist/react/ItemDetails.d.ts +119 -0
  2. package/cjs/dist/react/ItemDetails.js +51 -0
  3. package/cjs/dist/react/core/ItemDetails.d.ts +50 -0
  4. package/cjs/dist/react/core/ItemDetails.js +73 -0
  5. package/cjs/dist/react/core/index.d.ts +1 -0
  6. package/cjs/dist/react/core/index.js +1 -0
  7. package/cjs/dist/react/index.d.ts +1 -0
  8. package/cjs/dist/react/index.js +1 -0
  9. package/cjs/dist/services/common-types.d.ts +3 -0
  10. package/cjs/dist/services/common-types.js +1 -0
  11. package/cjs/dist/services/index.d.ts +2 -0
  12. package/cjs/dist/services/index.js +2 -0
  13. package/cjs/dist/services/item-details-service.d.ts +154 -0
  14. package/cjs/dist/services/item-details-service.js +196 -0
  15. package/cjs/dist/services/olo-settings-service.d.ts +35 -0
  16. package/cjs/dist/services/olo-settings-service.js +43 -0
  17. package/dist/react/ItemDetails.d.ts +119 -0
  18. package/dist/react/ItemDetails.js +51 -0
  19. package/dist/react/core/ItemDetails.d.ts +50 -0
  20. package/dist/react/core/ItemDetails.js +73 -0
  21. package/dist/react/core/index.d.ts +1 -0
  22. package/dist/react/core/index.js +1 -0
  23. package/dist/react/index.d.ts +1 -0
  24. package/dist/react/index.js +1 -0
  25. package/dist/services/common-types.d.ts +3 -0
  26. package/dist/services/common-types.js +1 -0
  27. package/dist/services/index.d.ts +2 -0
  28. package/dist/services/index.js +2 -0
  29. package/dist/services/item-details-service.d.ts +154 -0
  30. package/dist/services/item-details-service.js +196 -0
  31. package/dist/services/olo-settings-service.d.ts +35 -0
  32. package/dist/services/olo-settings-service.js +43 -0
  33. package/package.json +64 -0
  34. package/react/package.json +4 -0
  35. package/services/package.json +4 -0
@@ -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,3 @@
1
+ import * as currentCart from '@wix/auto_sdk_ecom_current-cart';
2
+ export type LineItem = currentCart.LineItem;
3
+ export type DescriptionLine = currentCart.DescriptionLine;
@@ -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,2 @@
1
+ export { ItemService, ItemServiceDefinition, loadItemServiceConfig, } from './item-details-service.js';
2
+ export { OLOSettingsService, OLOSettingsServiceDefinition, loadOLOSettingsServiceConfig, } 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;
@@ -0,0 +1,196 @@
1
+ import { defineService, implementService } from '@wix/services-definitions';
2
+ import { SignalsServiceDefinition, } from '@wix/services-definitions/core-services/signals';
3
+ /**
4
+ * Service definition for the Item service.
5
+ * This defines the contract that the ItemService must implement.
6
+ *
7
+ * @constant
8
+ */
9
+ export const ItemServiceDefinition = defineService('item');
10
+ /**
11
+ * Implementation of the Item service that manages reactive item data.
12
+ * This service provides signals for item data, loading state, and error handling,
13
+ * along with methods to dynamically load items.
14
+ *
15
+ * @example
16
+ * ```tsx
17
+ * import { ItemService, ItemServiceDefinition } from '@wix/stores/services';
18
+ * import { useService } from '@wix/services-manager-react';
19
+ *
20
+ * function ItemComponent({ itemConfig }) {
21
+ * return (
22
+ * <ServiceProvider services={createServicesMap([
23
+ * [ItemServiceDefinition, ItemService.withConfig(itemConfig)]
24
+ * ])}>
25
+ * <ItemDisplay />
26
+ * </ServiceProvider>
27
+ * );
28
+ * }
29
+ *
30
+ * function ItemDisplay() {
31
+ * const itemService = useService(ItemServiceDefinition);
32
+ * const item = itemService.item.get();
33
+ * const isLoading = itemService.isLoading.get();
34
+ * const error = itemService.error.get();
35
+ *
36
+ * if (isLoading) return <div>Loading...</div>;
37
+ * if (error) return <div>Error: {error}</div>;
38
+ *
39
+ * return <h1>{item.name}</h1>;
40
+ * }
41
+ * ```
42
+ */
43
+ const APP_ID = '9a5d83fd-8570-482e-81ab-cfa88942ee60';
44
+ export const ItemService = implementService.withConfig()(ItemServiceDefinition, ({ getService, config }) => {
45
+ const signalsService = getService(SignalsServiceDefinition);
46
+ const item = signalsService.signal(config.item);
47
+ const isLoading = signalsService.signal(!!config.item);
48
+ const error = signalsService.signal(config.item ? null : 'Item not found');
49
+ const quantity = signalsService.signal(1);
50
+ const specialRequest = signalsService.signal('');
51
+ const lineItem = signalsService.signal({});
52
+ if (config.item) {
53
+ console.log('config.item', config.item);
54
+ lineItem.set({
55
+ quantity: quantity.get(),
56
+ catalogReference: {
57
+ // @ts-expect-error - item is not typed
58
+ catalogItemId: config.item._id,
59
+ appId: APP_ID,
60
+ options: {
61
+ operationId: config.operationId,
62
+ // @ts-expect-error - item is not typed
63
+ menuId: config.item.menuId,
64
+ // @ts-expect-error - item is not typed
65
+ sectionId: config.item.sectionId,
66
+ },
67
+ },
68
+ });
69
+ }
70
+ const updateQuantity = (_quantity) => {
71
+ quantity.set(_quantity);
72
+ const _lineItem = lineItem.get();
73
+ lineItem.set({
74
+ ..._lineItem,
75
+ quantity: _quantity,
76
+ });
77
+ };
78
+ const updateSpecialRequest = (_specialRequest) => {
79
+ specialRequest.set(_specialRequest);
80
+ const _lineItem = lineItem.get();
81
+ lineItem.set({
82
+ ..._lineItem,
83
+ catalogReference: {
84
+ ..._lineItem.catalogReference,
85
+ options: {
86
+ ..._lineItem.catalogReference?.options,
87
+ specialRequest: _specialRequest,
88
+ },
89
+ },
90
+ });
91
+ };
92
+ return {
93
+ item,
94
+ quantity,
95
+ updateQuantity,
96
+ updateSpecialRequest,
97
+ isLoading,
98
+ error,
99
+ specialRequest,
100
+ lineItem,
101
+ };
102
+ });
103
+ /**
104
+ * Loads item service configuration from the Wix Items API for SSR initialization.
105
+ * This function is designed to be used during Server-Side Rendering (SSR) to preload
106
+ * a specific item by id that will be used to configure the ItemService.
107
+ *
108
+ * @param itemSlug The item id to load
109
+ * @returns Promise that resolves to ItemServiceConfigResult (success with config or notFound)
110
+ *
111
+ * @example
112
+ * ```astro
113
+ * ---
114
+ * // Astro page example - pages/item/[id].astro
115
+ * import { loadItemServiceConfig } from '@wix/stores/services';
116
+ * import { Item } from '@wix/stores/components';
117
+ *
118
+ * // Get item id from URL params
119
+ * const { id } = Astro.params;
120
+ *
121
+ * // Load item data during SSR
122
+ * const itemResult = await loadItemServiceConfig(id);
123
+ *
124
+ * // Handle not found case
125
+ * if (itemResult.type === 'notFound') {
126
+ * return Astro.redirect('/404');
127
+ * }
128
+ * ---
129
+ *
130
+ * <Item.Root itemConfig={itemResult.config}>
131
+ * <Item.Name>
132
+ * {({ name }) => <h1>{name}</h1>}
133
+ * </Item.Name>
134
+ * </Item.Root>
135
+ * ```
136
+ *
137
+ * @example
138
+ * ```tsx
139
+ * // Next.js page example - pages/item/[id].tsx
140
+ * import { GetServerSideProps } from 'next';
141
+ * import { loadItemServiceConfig } from '@wix/stores/services';
142
+ * import { Item } from '@wix/stores/components';
143
+ *
144
+ * interface ItemPageProps {
145
+ * itemConfig: Extract<Awaited<ReturnType<typeof loadItemServiceConfig>>, { type: 'success' }>['config'];
146
+ * }
147
+ *
148
+ * export const getServerSideProps: GetServerSideProps<ItemPageProps> = async ({ params }) => {
149
+ * const id = params?.id as string;
150
+ *
151
+ * // Load item data during SSR
152
+ * const itemResult = await loadItemServiceConfig(id);
153
+ *
154
+ * // Handle not found case
155
+ * if (itemResult.type === 'notFound') {
156
+ * return {
157
+ * notFound: true,
158
+ * };
159
+ * }
160
+ *
161
+ * return {
162
+ * props: {
163
+ * itemConfig: itemResult.config,
164
+ * },
165
+ * };
166
+ * };
167
+ *
168
+ * export default function ItemPage({ itemConfig }: ItemPageProps) {
169
+ * return (
170
+ * <Item.Root itemConfig={itemConfig}>
171
+ * <Item.Name>
172
+ * {({ name }) => <h1>{name}</h1>}
173
+ * </Item.Name>
174
+ * </Item.Root>
175
+ * );
176
+ * }
177
+ * ```
178
+ */
179
+ export function loadItemServiceConfig({ item, operationId, }) {
180
+ return { item, operationId };
181
+ }
182
+ // try {
183
+ // if (item === null) {
184
+ // return { item: null };
185
+ // }
186
+ // console.log('loadItemServiceConfig', item);
187
+ // const itemResponse = await loadItemById(item._id);
188
+ // console.log('itemResponse', itemResponse);
189
+ // if (!itemResponse) {
190
+ // return { item: itemResponse, item };
191
+ // }
192
+ // return { item: itemResponse };
193
+ // } catch (error) {
194
+ // console.error(`Failed to load item "${itemId}":`, error);
195
+ // return { item: null, itemId };
196
+ // }}