From afbe39d19bc673385f56b132af1995dddfd3b48d Mon Sep 17 00:00:00 2001 From: ylakhdar Date: Mon, 4 Nov 2024 12:09:51 -0500 Subject: [PATCH] change the way cart items are passed https://coveord.atlassian.net/browse/KIT-3681 --- .../src/app/commerce-ssr-engine/types/common.ts | 6 ++++++ .../commerce/context/cart/headless-cart.ssr.ts | 15 ++++++++++----- packages/headless/src/ssr-commerce.index.ts | 1 + .../headless-ssr-commerce/app/listing/page.tsx | 8 +++++++- .../app/products/[productId]/page.tsx | 8 +++++++- .../headless-ssr-commerce/app/search/page.tsx | 8 +++++++- .../components/pages/product-page.tsx | 5 +++++ .../components/providers/listing-provider.tsx | 5 +++++ .../components/providers/search-provider.tsx | 5 +++++ .../samples/headless-ssr-commerce/lib/cart.ts | 6 ++++++ 10 files changed, 59 insertions(+), 8 deletions(-) create mode 100644 packages/samples/headless-ssr-commerce/lib/cart.ts diff --git a/packages/headless/src/app/commerce-ssr-engine/types/common.ts b/packages/headless/src/app/commerce-ssr-engine/types/common.ts index fdf21309c0..b773dd642f 100644 --- a/packages/headless/src/app/commerce-ssr-engine/types/common.ts +++ b/packages/headless/src/app/commerce-ssr-engine/types/common.ts @@ -210,6 +210,12 @@ export type UniversalControllerDefinitionWithoutProps< > = ControllerDefinitionWithoutProps & UniversalController; +export type UniversalControllerDefinitionWithProps< + TController extends Controller, + TProps, +> = ControllerDefinitionWithProps & + UniversalController; + export type SearchAndListingControllerDefinitionWithoutProps< TController extends Controller, > = ControllerDefinitionWithoutProps & diff --git a/packages/headless/src/controllers/commerce/context/cart/headless-cart.ssr.ts b/packages/headless/src/controllers/commerce/context/cart/headless-cart.ssr.ts index 997ccba91d..903c64708c 100644 --- a/packages/headless/src/controllers/commerce/context/cart/headless-cart.ssr.ts +++ b/packages/headless/src/controllers/commerce/context/cart/headless-cart.ssr.ts @@ -1,11 +1,15 @@ -import {UniversalControllerDefinitionWithoutProps} from '../../../../app/commerce-ssr-engine/types/common.js'; -import {Cart, buildCart, CartProps, CartInitialState} from './headless-cart.js'; +import {UniversalControllerDefinitionWithProps} from '../../../../app/commerce-ssr-engine/types/common.js'; +import {Cart, buildCart, CartInitialState} from './headless-cart.js'; export type {CartState, CartItem, CartProps} from './headless-cart.js'; export type {Cart, CartInitialState}; +export interface CartBuildProps { + initialState: CartInitialState; +} + export interface CartDefinition - extends UniversalControllerDefinitionWithoutProps {} + extends UniversalControllerDefinitionWithProps {} /** * Defines a `Cart` controller instance. @@ -15,11 +19,12 @@ export interface CartDefinition * * @internal */ -export function defineCart(props: CartProps = {}): CartDefinition { +export function defineCart(): CartDefinition { return { listing: true, search: true, standalone: true, - build: (engine) => buildCart(engine, props), + buildWithProps: (engine, props) => + buildCart(engine, {initialState: props.initialState}), }; } diff --git a/packages/headless/src/ssr-commerce.index.ts b/packages/headless/src/ssr-commerce.index.ts index 2ff8935483..f98661b8fe 100644 --- a/packages/headless/src/ssr-commerce.index.ts +++ b/packages/headless/src/ssr-commerce.index.ts @@ -192,6 +192,7 @@ export type { CartItem, CartProps, CartState, + CartBuildProps, CartDefinition, } from './controllers/commerce/context/cart/headless-cart.ssr.js'; export {defineCart} from './controllers/commerce/context/cart/headless-cart.ssr.js'; diff --git a/packages/samples/headless-ssr-commerce/app/listing/page.tsx b/packages/samples/headless-ssr-commerce/app/listing/page.tsx index 13fb122cfa..9f5a3ed44e 100644 --- a/packages/samples/headless-ssr-commerce/app/listing/page.tsx +++ b/packages/samples/headless-ssr-commerce/app/listing/page.tsx @@ -8,6 +8,7 @@ import {Recommendations} from '@/components/recommendation-list'; import Sort from '@/components/sort'; import StandaloneSearchBox from '@/components/standalone-search-box'; import Summary from '@/components/summary'; +import getCart from '@/lib/cart'; import {listingEngineDefinition} from '@/lib/commerce-engine'; import {NextJsNavigatorContext} from '@/lib/navigatorContextProvider'; import {headers} from 'next/headers'; @@ -22,8 +23,13 @@ export default async function Listing() { const navigatorContext = new NextJsNavigatorContext(headers()); listingEngineDefinition.setNavigatorContextProvider(() => navigatorContext); + // Fetches the cart items from an external service + const items = await getCart(); + // Fetches the static state of the app with initial state (when applicable) - const staticState = await listingEngineDefinition.fetchStaticState(); + const staticState = await listingEngineDefinition.fetchStaticState({ + controllers: {cart: {initialState: {items}}}, + }); //At this point in the app, this is the only part that is in the server side diff --git a/packages/samples/headless-ssr-commerce/app/products/[productId]/page.tsx b/packages/samples/headless-ssr-commerce/app/products/[productId]/page.tsx index 75a3c18303..335be6acc5 100644 --- a/packages/samples/headless-ssr-commerce/app/products/[productId]/page.tsx +++ b/packages/samples/headless-ssr-commerce/app/products/[productId]/page.tsx @@ -1,4 +1,5 @@ import ProductPage from '@/components/pages/product-page'; +import getCart from '@/lib/cart'; import {searchEngineDefinition} from '@/lib/commerce-engine'; import {NextJsNavigatorContext} from '@/lib/navigatorContextProvider'; import {headers} from 'next/headers'; @@ -13,8 +14,13 @@ export default async function ProductDescriptionPage({ const navigatorContext = new NextJsNavigatorContext(headers()); searchEngineDefinition.setNavigatorContextProvider(() => navigatorContext); + // Fetches the cart items from an external service + const items = await getCart(); + // Fetches the static state of the app with initial state (when applicable) - const staticState = await searchEngineDefinition.fetchStaticState(); + const staticState = await searchEngineDefinition.fetchStaticState({ + controllers: {cart: {initialState: {items}}}, + }); return ( <>

Product description page

diff --git a/packages/samples/headless-ssr-commerce/app/search/page.tsx b/packages/samples/headless-ssr-commerce/app/search/page.tsx index a3f7fa0169..133620203f 100644 --- a/packages/samples/headless-ssr-commerce/app/search/page.tsx +++ b/packages/samples/headless-ssr-commerce/app/search/page.tsx @@ -7,6 +7,7 @@ import SearchBox from '@/components/search-box'; import ShowMore from '@/components/show-more'; import Summary from '@/components/summary'; import Triggers from '@/components/triggers/triggers'; +import getCart from '@/lib/cart'; import {searchEngineDefinition} from '@/lib/commerce-engine'; import {NextJsNavigatorContext} from '@/lib/navigatorContextProvider'; import {headers} from 'next/headers'; @@ -16,8 +17,13 @@ export default async function Search() { const navigatorContext = new NextJsNavigatorContext(headers()); searchEngineDefinition.setNavigatorContextProvider(() => navigatorContext); + // Fetches the cart items from an external service + const items = await getCart(); + // Fetches the static state of the app with initial state (when applicable) - const staticState = await searchEngineDefinition.fetchStaticState(); + const staticState = await searchEngineDefinition.fetchStaticState({ + controllers: {cart: {initialState: {items}}}, + }); return ( { setHydratedState({engine, controllers}); diff --git a/packages/samples/headless-ssr-commerce/components/providers/listing-provider.tsx b/packages/samples/headless-ssr-commerce/components/providers/listing-provider.tsx index c3ff82b4ea..a7a75551d4 100644 --- a/packages/samples/headless-ssr-commerce/components/providers/listing-provider.tsx +++ b/packages/samples/headless-ssr-commerce/components/providers/listing-provider.tsx @@ -29,6 +29,11 @@ export default function ListingProvider({ listingEngineDefinition .hydrateStaticState({ searchAction: staticState.searchAction, + controllers: { + cart: { + initialState: {items: staticState.controllers.cart.state.items}, + }, + }, }) .then(({engine, controllers}) => { setHydratedState({engine, controllers}); diff --git a/packages/samples/headless-ssr-commerce/components/providers/search-provider.tsx b/packages/samples/headless-ssr-commerce/components/providers/search-provider.tsx index a4f3ab8fc8..fe864f70a0 100644 --- a/packages/samples/headless-ssr-commerce/components/providers/search-provider.tsx +++ b/packages/samples/headless-ssr-commerce/components/providers/search-provider.tsx @@ -29,6 +29,11 @@ export default function SearchProvider({ searchEngineDefinition .hydrateStaticState({ searchAction: staticState.searchAction, + controllers: { + cart: { + initialState: {items: staticState.controllers.cart.state.items}, + }, + }, }) .then(({engine, controllers}) => { setHydratedState({engine, controllers}); diff --git a/packages/samples/headless-ssr-commerce/lib/cart.ts b/packages/samples/headless-ssr-commerce/lib/cart.ts new file mode 100644 index 0000000000..4ce9577073 --- /dev/null +++ b/packages/samples/headless-ssr-commerce/lib/cart.ts @@ -0,0 +1,6 @@ +import {CartItem} from '@coveo/headless-react/ssr-commerce'; + +export default async function getCart(): Promise { + 'use server'; + return [{name: 'item1', price: 10, quantity: 1, productId: 'xxx'}]; +}