Skip to content

Commit 02147a8

Browse files
committed
feat: Add out-of-stock/backorder message to product lists
1 parent d77f69d commit 02147a8

12 files changed

Lines changed: 176 additions & 54 deletions

File tree

core/app/[locale]/(default)/(faceted)/brand/[slug]/page-data.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,11 @@ const BrandPageQuery = graphql(`
1616
}
1717
}
1818
settings {
19+
inventory {
20+
defaultOutOfStockMessage
21+
showOutOfStockMessage
22+
showBackorderMessage
23+
}
1924
storefront {
2025
catalog {
2126
productComparisonsEnabled

core/app/[locale]/(default)/(faceted)/brand/[slug]/page.tsx

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import { getFilterParsers } from '@/vibes/soul/sections/products-list-section/fi
1111
import { getSessionCustomerAccessToken } from '~/auth';
1212
import { facetsTransformer } from '~/data-transformers/facets-transformer';
1313
import { pageInfoTransformer } from '~/data-transformers/page-info-transformer';
14-
import { pricesTransformer } from '~/data-transformers/prices-transformer';
14+
import { productCardTransformer } from '~/data-transformers/product-card-transformer';
1515
import { getPreferredCurrencyCode } from '~/lib/currency';
1616

1717
import { MAX_COMPARE_LIMIT } from '../../../compare/page-data';
@@ -132,16 +132,15 @@ export default async function Brand(props: Props) {
132132
const search = await streamableFacetedSearch;
133133
const products = search.products.items;
134134

135-
return products.map((product) => ({
136-
id: product.entityId.toString(),
137-
title: product.name,
138-
href: product.path,
139-
image: product.defaultImage
140-
? { src: product.defaultImage.url, alt: product.defaultImage.altText }
141-
: undefined,
142-
price: pricesTransformer(product.prices, format),
143-
subtitle: product.brand?.name ?? undefined,
144-
}));
135+
const { defaultOutOfStockMessage, showOutOfStockMessage, showBackorderMessage } =
136+
settings?.inventory || {};
137+
138+
return productCardTransformer(
139+
products,
140+
format,
141+
showOutOfStockMessage ? defaultOutOfStockMessage : undefined,
142+
showBackorderMessage,
143+
);
145144
});
146145

147146
const streamableTotalCount = Streamable.from(async () => {

core/app/[locale]/(default)/(faceted)/category/[slug]/page-data.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,11 @@ const CategoryPageQuery = graphql(
3535
}
3636
}
3737
settings {
38+
inventory {
39+
defaultOutOfStockMessage
40+
showOutOfStockMessage
41+
showBackorderMessage
42+
}
3843
storefront {
3944
catalog {
4045
productComparisonsEnabled

core/app/[locale]/(default)/(faceted)/category/[slug]/page.tsx

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import { getFilterParsers } from '@/vibes/soul/sections/products-list-section/fi
1212
import { getSessionCustomerAccessToken } from '~/auth';
1313
import { facetsTransformer } from '~/data-transformers/facets-transformer';
1414
import { pageInfoTransformer } from '~/data-transformers/page-info-transformer';
15-
import { pricesTransformer } from '~/data-transformers/prices-transformer';
15+
import { productCardTransformer } from '~/data-transformers/product-card-transformer';
1616
import { getPreferredCurrencyCode } from '~/lib/currency';
1717

1818
import { MAX_COMPARE_LIMIT } from '../../../compare/page-data';
@@ -145,16 +145,15 @@ export default async function Category(props: Props) {
145145
const search = await streamableFacetedSearch;
146146
const products = search.products.items;
147147

148-
return products.map((product) => ({
149-
id: product.entityId.toString(),
150-
title: product.name,
151-
href: product.path,
152-
image: product.defaultImage
153-
? { src: product.defaultImage.url, alt: product.defaultImage.altText }
154-
: undefined,
155-
price: pricesTransformer(product.prices, format),
156-
subtitle: product.brand?.name ?? undefined,
157-
}));
148+
const { defaultOutOfStockMessage, showOutOfStockMessage, showBackorderMessage } =
149+
settings?.inventory || {};
150+
151+
return productCardTransformer(
152+
products,
153+
format,
154+
showOutOfStockMessage ? defaultOutOfStockMessage : undefined,
155+
showBackorderMessage,
156+
);
158157
});
159158

160159
const streamableTotalCount = Streamable.from(async () => {

core/app/[locale]/(default)/(faceted)/search/page-data.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@ const SearchPageQuery = graphql(`
88
query SearchPageQuery {
99
site {
1010
settings {
11+
inventory {
12+
defaultOutOfStockMessage
13+
showOutOfStockMessage
14+
showBackorderMessage
15+
}
1116
storefront {
1217
catalog {
1318
productComparisonsEnabled

core/app/[locale]/(default)/(faceted)/search/page.tsx

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { getFilterParsers } from '@/vibes/soul/sections/products-list-section/fi
1010
import { getSessionCustomerAccessToken } from '~/auth';
1111
import { facetsTransformer } from '~/data-transformers/facets-transformer';
1212
import { pageInfoTransformer } from '~/data-transformers/page-info-transformer';
13-
import { pricesTransformer } from '~/data-transformers/prices-transformer';
13+
import { productCardTransformer } from '~/data-transformers/product-card-transformer';
1414
import { getPreferredCurrencyCode } from '~/lib/currency';
1515

1616
import { MAX_COMPARE_LIMIT } from '../../compare/page-data';
@@ -117,16 +117,15 @@ export default async function Search(props: Props) {
117117
const search = await streamableFacetedSearch;
118118
const products = search.products.items;
119119

120-
return products.map((product) => ({
121-
id: product.entityId.toString(),
122-
title: product.name,
123-
href: product.path,
124-
image: product.defaultImage
125-
? { src: product.defaultImage.url, alt: product.defaultImage.altText }
126-
: undefined,
127-
price: pricesTransformer(product.prices, format),
128-
subtitle: product.brand?.name ?? undefined,
129-
}));
120+
const { defaultOutOfStockMessage, showOutOfStockMessage, showBackorderMessage } =
121+
settings?.inventory || {};
122+
123+
return productCardTransformer(
124+
products,
125+
format,
126+
showOutOfStockMessage ? defaultOutOfStockMessage : undefined,
127+
showBackorderMessage,
128+
);
130129
});
131130

132131
const streamableTitle = Streamable.from(async () => {

core/app/[locale]/(default)/page-data.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,13 @@ const HomePageQuery = graphql(
6161
}
6262
}
6363
}
64+
settings {
65+
inventory {
66+
defaultOutOfStockMessage
67+
showOutOfStockMessage
68+
showBackorderMessage
69+
}
70+
}
6471
}
6572
}
6673
`,

core/app/[locale]/(default)/page.tsx

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,15 +36,31 @@ export default async function Home({ params }: Props) {
3636

3737
const featuredProducts = removeEdgesAndNodes(data.site.featuredProducts);
3838

39-
return productCardTransformer(featuredProducts, format);
39+
const { defaultOutOfStockMessage, showOutOfStockMessage, showBackorderMessage } =
40+
data.site.settings?.inventory || {};
41+
42+
return productCardTransformer(
43+
featuredProducts,
44+
format,
45+
showOutOfStockMessage ? defaultOutOfStockMessage : undefined,
46+
showBackorderMessage,
47+
);
4048
});
4149

4250
const streamableNewestProducts = Streamable.from(async () => {
4351
const data = await streamablePageData;
4452

4553
const newestProducts = removeEdgesAndNodes(data.site.newestProducts);
4654

47-
return productCardTransformer(newestProducts, format);
55+
const { defaultOutOfStockMessage, showOutOfStockMessage, showBackorderMessage } =
56+
data.site.settings?.inventory || {};
57+
58+
return productCardTransformer(
59+
newestProducts,
60+
format,
61+
showOutOfStockMessage ? defaultOutOfStockMessage : undefined,
62+
showBackorderMessage,
63+
);
4864
});
4965

5066
return (

core/components/product-card/fragment.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import { PricingFragment } from '~/client/fragments/pricing';
22
import { graphql } from '~/client/graphql';
33

4+
import { ProductVariantsInventoryFragment } from '../product-variants-inventory/fragment';
5+
46
export const ProductCardFragment = graphql(
57
`
68
fragment ProductCardFragment on Product {
@@ -15,12 +17,21 @@ export const ProductCardFragment = graphql(
1517
name
1618
path
1719
}
20+
inventory {
21+
hasVariantInventory
22+
isInStock
23+
aggregated {
24+
availableForBackorder
25+
unlimitedBackorder
26+
}
27+
}
1828
reviewSummary {
1929
numberOfReviews
2030
averageRating
2131
}
2232
...PricingFragment
33+
...ProductVariantsInventoryFragment
2334
}
2435
`,
25-
[PricingFragment],
36+
[PricingFragment, ProductVariantsInventoryFragment],
2637
);
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { graphql } from '~/client/graphql';
2+
3+
export const ProductVariantsInventoryFragment = graphql(`
4+
fragment ProductVariantsInventoryFragment on Product {
5+
variants {
6+
edges {
7+
node {
8+
entityId
9+
sku
10+
inventory {
11+
byLocation {
12+
edges {
13+
node {
14+
locationEntityId
15+
backorderMessage
16+
}
17+
}
18+
}
19+
}
20+
}
21+
}
22+
}
23+
}
24+
`);

0 commit comments

Comments
 (0)