Skip to content

Commit

Permalink
update sample
Browse files Browse the repository at this point in the history
  • Loading branch information
y-lakhdar committed Nov 15, 2024
1 parent 8d170d2 commit e60bfe5
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 5 deletions.
11 changes: 10 additions & 1 deletion packages/headless/src/app/commerce-ssr-engine/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,10 +97,19 @@ export function buildControllerDefinitions<
? definition['standalone'] === false
: false;

const unavailabeInRecs =
// TODO: use this disjunction pattern for all other conditions
(solutionType === SolutionType['recommendation'] &&
!('recommendation' in definition)) ||
('recommendation' in definition &&
definition['recommendation'] === false &&
solutionType === SolutionType['recommendation']);

if (
unavailableInSearchSolutionType ||
unavailableInListingSolutionType ||
unavailableInStandaloneSolutionType
unavailableInStandaloneSolutionType ||
unavailabeInRecs
) {
return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,15 @@ import FacetGenerator from '@/components/facets/facet-generator';
import Pagination from '@/components/pagination';
import ProductList from '@/components/product-list';
import ListingProvider from '@/components/providers/listing-provider';
import RecommendationProvider from '@/components/providers/recommendation-provider';
import Recommendations from '@/components/recommendation-list';
import Sort from '@/components/sort';
import StandaloneSearchBox from '@/components/standalone-search-box';
import Summary from '@/components/summary';
import {listingEngineDefinition} from '@/lib/commerce-engine';
import {
listingEngineDefinition,
recommendationEngineDefinition,
} from '@/lib/commerce-engine';
import {NextJsNavigatorContext} from '@/lib/navigatorContextProvider';
import {defaultContext} from '@/utils/context';
import {headers} from 'next/headers';
Expand Down Expand Up @@ -54,6 +58,11 @@ export default async function Listing({params}: {params: {category: string}}) {
},
});

const recStaticState = await recommendationEngineDefinition.fetchStaticState([
'popularBoughtRecs',
'popularViewedRecs',
]);

return (
<ListingProvider
staticState={staticState}
Expand Down Expand Up @@ -86,7 +95,12 @@ export default async function Listing({params}: {params: {category: string}}) {
</div>

<div style={{flex: 4}}>
<Recommendations />
<RecommendationProvider
staticState={recStaticState}
navigatorContext={navigatorContext.marshal}
>
<Recommendations />
</RecommendationProvider>
</div>
</div>
</ListingProvider>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export default function ListingProvider({
useEffect(() => {
listingEngineDefinition
.hydrateStaticState({
searchAction: staticState.searchAction,
searchActions: staticState.searchActions,
controllers: {
cart: {
initialState: {items: staticState.controllers.cart.state.items},
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
'use client';

import {
recommendationEngineDefinition,
RecommendationHydratedState,
RecommendationStaticState,
} from '@/lib/commerce-engine';
import {NavigatorContext} from '@coveo/headless-react/ssr-commerce';
import {PropsWithChildren, useEffect, useState} from 'react';

interface RecommendationPageProps {
staticState: RecommendationStaticState;
navigatorContext: NavigatorContext;
}

export default function RecommendationProvider({
staticState,
navigatorContext,
children,
}: PropsWithChildren<RecommendationPageProps>) {
const [hydratedState, setHydratedState] = useState<
RecommendationHydratedState | undefined
>(undefined);

// Setting the navigator context provider also in client-side before hydrating the application
recommendationEngineDefinition.setNavigatorContextProvider(
() => navigatorContext
);

useEffect(() => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(recommendationEngineDefinition.hydrateStaticState as any)({
searchActions: staticState.searchActions,
// controllers: { },
}).then(({engine, controllers}) => {
setHydratedState({engine, controllers});
// Refreshing recommendations in the browser after hydrating the state in the client-side
// Recommendation refresh in the server is not supported yet.
// controllers.popularBoughtRecs.refresh(); // FIXME: does not work
});
}, [staticState]);

if (hydratedState) {
return (
<recommendationEngineDefinition.HydratedStateProvider
engine={hydratedState.engine}
controllers={hydratedState.controllers}
>
<>{children}</>
</recommendationEngineDefinition.HydratedStateProvider>
);
} else {
return (
<recommendationEngineDefinition.StaticStateProvider
controllers={staticState.controllers}
>
{/* // TODO: Add KIT-3701: Type 'React.ReactNode' is not assignable to type 'import(".../node_modules/@types/react/index").ReactNode'.
Type 'bigint' is not assignable to type 'ReactNode'.*/}
<>{children}</>
</recommendationEngineDefinition.StaticStateProvider>
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export default function SearchProvider({
useEffect(() => {
searchEngineDefinition
.hydrateStaticState({
searchAction: staticState.searchAction,
searchActions: staticState.searchActions,
controllers: {
cart: {
initialState: {items: staticState.controllers.cart.state.items},
Expand Down

0 comments on commit e60bfe5

Please sign in to comment.