Skip to content

Commit

Permalink
docs(headless): showcase the context controller in headless-ssr-comme…
Browse files Browse the repository at this point in the history
…rce (#4649)

https://coveord.atlassian.net/browse/KIT-3708

this PR adds better support for the context controller in
headless-ssr-commerce by adding a contextDropdown with a hardcoded list
of storefront associations.

---------

Co-authored-by: ylakhdar <[email protected]>
  • Loading branch information
alexprudhomme and y-lakhdar authored Nov 12, 2024
1 parent ea6085c commit 5e516a4
Show file tree
Hide file tree
Showing 6 changed files with 97 additions and 12 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import * as externalCartAPI from '@/actions/external-cart-api';
import BreadcrumbManager from '@/components/breadcrumb-manager';
import Cart from '@/components/cart';
import ContextDropdown from '@/components/context-dropdown';
import FacetGenerator from '@/components/facets/facet-generator';
import Pagination from '@/components/pagination';
import ProductList from '@/components/product-list';
Expand All @@ -11,6 +12,7 @@ import StandaloneSearchBox from '@/components/standalone-search-box';
import Summary from '@/components/summary';
import {listingEngineDefinition} from '@/lib/commerce-engine';
import {NextJsNavigatorContext} from '@/lib/navigatorContextProvider';
import {defaultContext} from '@/utils/context';
import {headers} from 'next/headers';
import {notFound} from 'next/navigation';

Expand Down Expand Up @@ -42,9 +44,9 @@ export default async function Listing({params}: {params: {category: string}}) {
controllers: {
cart: {initialState: {items}},
context: {
language: 'en',
country: 'US',
currency: 'USD',
language: defaultContext.language,
country: defaultContext.country,
currency: defaultContext.currency,
view: {
url: `https://sports.barca.group/browse/promotions/${matchedCategory}`,
},
Expand All @@ -57,6 +59,7 @@ export default async function Listing({params}: {params: {category: string}}) {
staticState={staticState}
navigatorContext={navigatorContext.marshal}
>
<ContextDropdown useCase="listing" />
<div style={{display: 'flex', flexDirection: 'row'}}>
<div style={{flex: 1}}>
<FacetGenerator />
Expand Down
9 changes: 6 additions & 3 deletions packages/samples/headless-ssr-commerce/app/cart/page.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import * as externalCartAPI from '@/actions/external-cart-api';
import Cart from '@/components/cart';
import ContextDropdown from '@/components/context-dropdown';
import SearchProvider from '@/components/providers/search-provider';
import {searchEngineDefinition} from '@/lib/commerce-engine';
import {NextJsNavigatorContext} from '@/lib/navigatorContextProvider';
import {defaultContext} from '@/utils/context';
import {headers} from 'next/headers';

export default async function Search() {
Expand All @@ -18,9 +20,9 @@ export default async function Search() {
controllers: {
cart: {initialState: {items}},
context: {
language: 'en',
country: 'US',
currency: 'USD',
language: defaultContext.language,
country: defaultContext.country,
currency: defaultContext.currency,
view: {
url: 'https://sports.barca.group/cart',
},
Expand All @@ -34,6 +36,7 @@ export default async function Search() {
navigatorContext={navigatorContext.marshal}
>
<div style={{display: 'flex', flexDirection: 'row'}}>
<ContextDropdown />
<Cart />
</div>
</SearchProvider>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import * as externalCartAPI from '@/actions/external-cart-api';
import ContextDropdown from '@/components/context-dropdown';
import ProductPage from '@/components/pages/product-page';
import {searchEngineDefinition} from '@/lib/commerce-engine';
import {NextJsNavigatorContext} from '@/lib/navigatorContextProvider';
import {defaultContext} from '@/utils/context';
import {headers} from 'next/headers';
import {Suspense} from 'react';

Expand All @@ -22,9 +24,9 @@ export default async function ProductDescriptionPage({
controllers: {
cart: {initialState: {items}},
context: {
language: 'en',
country: 'US',
currency: 'USD',
language: defaultContext.language,
country: defaultContext.country,
currency: defaultContext.currency,
view: {
url: `https://sports.barca.group/products/${params.productId}`,
},
Expand All @@ -34,6 +36,7 @@ export default async function ProductDescriptionPage({
return (
<>
<h2>Product description page</h2>
<ContextDropdown />
<Suspense fallback={<p>Loading...</p>}>
<ProductPage
staticState={staticState}
Expand Down
9 changes: 6 additions & 3 deletions packages/samples/headless-ssr-commerce/app/search/page.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import * as externalCartAPI from '@/actions/external-cart-api';
import BreadcrumbManager from '@/components/breadcrumb-manager';
import ContextDropdown from '@/components/context-dropdown';
import FacetGenerator from '@/components/facets/facet-generator';
import ProductList from '@/components/product-list';
import SearchProvider from '@/components/providers/search-provider';
Expand All @@ -10,6 +11,7 @@ import Summary from '@/components/summary';
import Triggers from '@/components/triggers/triggers';
import {searchEngineDefinition} from '@/lib/commerce-engine';
import {NextJsNavigatorContext} from '@/lib/navigatorContextProvider';
import {defaultContext} from '@/utils/context';
import {headers} from 'next/headers';

export default async function Search() {
Expand All @@ -25,9 +27,9 @@ export default async function Search() {
controllers: {
cart: {initialState: {items}},
context: {
language: 'en',
country: 'US',
currency: 'USD',
language: defaultContext.language,
country: defaultContext.country,
currency: defaultContext.currency,
view: {
url: 'https://sports.barca.group/search',
},
Expand All @@ -40,6 +42,7 @@ export default async function Search() {
staticState={staticState}
navigatorContext={navigatorContext.marshal}
>
<ContextDropdown useCase="search" />
<div style={{display: 'flex', flexDirection: 'row'}}>
<div style={{flex: 1}}>
<FacetGenerator />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
'use client';

import {useContext, useEngine} from '@/lib/commerce-engine';
import {
CommerceEngine,
ContextOptions,
loadProductListingActions,
loadSearchActions,
} from '@coveo/headless-react/ssr-commerce';

// A hardcoded list of storefront associations for switching app context by language, country, and currency.
// Found in the admin console under "Storefront Associations," this list is static for demonstration purposes.
// In a real application, these values would likely come from sources like environment variables or an API.
const storefrontAssociations = [
'en-CA-CAD',
'fr-CA-CAD',
'en-GB-GBP',
'en-US-USD',
];

export default function ContextDropdown({
useCase,
}: {
useCase?: 'listing' | 'search';
}) {
const {state, methods} = useContext();
const engine = useEngine();

return (
<div>
<p></p>
Context dropdown :
<select
value={`${state.language}-${state.country}-${state.currency}`}
onChange={(e) => {
const [language, country, currency] = e.target.value.split('-');
methods?.setLanguage(language);
methods?.setCountry(country);
methods?.setCurrency(currency as ContextOptions['currency']);

useCase === 'search'
? engine?.dispatch(
loadSearchActions(engine as CommerceEngine).executeSearch()
)
: useCase === 'listing' &&
engine?.dispatch(
loadProductListingActions(
engine as CommerceEngine
).fetchProductListing()
);
}}
>
{storefrontAssociations.map((association) => (
<option key={association} value={association}>
{association}
</option>
))}
</select>
<p></p>
</div>
);
}
11 changes: 11 additions & 0 deletions packages/samples/headless-ssr-commerce/utils/context.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import {ContextState} from '@coveo/headless-react/ssr-commerce';

export const defaultContext: {
language: string;
country: string;
currency: ContextState['currency'];
} = {
language: 'en',
country: 'US',
currency: 'USD',
};

0 comments on commit 5e516a4

Please sign in to comment.