diff --git a/components/product/ProductView/ProductView.tsx b/components/product/ProductView/ProductView.tsx index 05e7a1cee..6f1a2de68 100644 --- a/components/product/ProductView/ProductView.tsx +++ b/components/product/ProductView/ProductView.tsx @@ -146,8 +146,12 @@ const ProductView: FC = ({ product }) => { className={s.button} onClick={addToCart} loading={loading} + disabled={variant?.availableForSale === false} > - Add to Cart + {variant?.isInStock === false && + variant?.availableForSale === false + ? 'Sold Out' + : 'Add To Cart'} diff --git a/framework/commerce/types.ts b/framework/commerce/types.ts index a398070ac..9c1a04e6d 100644 --- a/framework/commerce/types.ts +++ b/framework/commerce/types.ts @@ -190,6 +190,10 @@ interface ProductImage { interface ProductVariant2 { id: string | number options: ProductOption[] + // Indicates whether this product variant is in stock. + isInStock?: boolean + // Indicates if the product variant is available for sale. + availableForSale?: boolean } interface ProductPrice { diff --git a/framework/shopify/customer/use-customer.tsx b/framework/shopify/customer/use-customer.tsx index 137f0da74..4e8033fb2 100644 --- a/framework/shopify/customer/use-customer.tsx +++ b/framework/shopify/customer/use-customer.tsx @@ -10,11 +10,14 @@ export const handler: SWRHook = { query: getCustomerQuery, }, async fetcher({ options, fetch }) { - const data = await fetch({ - ...options, - variables: { customerAccessToken: getCustomerToken() }, - }) - return data.customer ?? null + const customerAccessToken = getCustomerToken() + if (customerAccessToken) { + const data = await fetch({ + ...options, + variables: { customerAccessToken }, + }) + return data.customer + } }, useHook: ({ useData }) => (input) => { return useData({ diff --git a/framework/shopify/utils/checkout-to-cart.ts b/framework/shopify/utils/checkout-to-cart.ts index 034ff11d7..04ed45c4e 100644 --- a/framework/shopify/utils/checkout-to-cart.ts +++ b/framework/shopify/utils/checkout-to-cart.ts @@ -27,22 +27,15 @@ export type CheckoutPayload = | CheckoutQuery const checkoutToCart = (checkoutPayload?: Maybe): Cart => { - if (!checkoutPayload) { - throw new CommerceError({ - message: 'Missing checkout payload from response', - }) - } - - const checkout = checkoutPayload?.checkout throwUserErrors(checkoutPayload?.checkoutUserErrors) - if (!checkout) { + if (!checkoutPayload?.checkout) { throw new CommerceError({ message: 'Missing checkout object from response', }) } - return normalizeCart(checkout) + return normalizeCart(checkoutPayload?.checkout) } export default checkoutToCart diff --git a/framework/shopify/utils/get-search-variables.ts b/framework/shopify/utils/get-search-variables.ts index c1b40ae5d..70df496ac 100644 --- a/framework/shopify/utils/get-search-variables.ts +++ b/framework/shopify/utils/get-search-variables.ts @@ -10,11 +10,11 @@ export const getSearchVariables = ({ let query = '' if (search) { - query += `product_type:${search} OR title:${search} OR tag:${search}` + query += `product_type:${search} OR title:${search} OR tag:${search} ` } if (brandId) { - query += `${search ? ' AND ' : ''}vendor:${brandId}` + query += `${search ? 'AND ' : ''}vendor:${brandId}` } return { diff --git a/framework/shopify/utils/normalize.ts b/framework/shopify/utils/normalize.ts index 25bdca053..89c2fbc8e 100644 --- a/framework/shopify/utils/normalize.ts +++ b/framework/shopify/utils/normalize.ts @@ -53,7 +53,17 @@ const normalizeProductImages = ({ edges }: ImageConnection) => const normalizeProductVariants = ({ edges }: ProductVariantConnection) => { return edges?.map( ({ - node: { id, selectedOptions, sku, title, priceV2, compareAtPriceV2 }, + node: { + id, + selectedOptions, + sku, + title, + priceV2, + compareAtPriceV2, + requiresShipping, + availableForSale, + quantityAvailable, + }, }) => { return { id, @@ -61,7 +71,9 @@ const normalizeProductVariants = ({ edges }: ProductVariantConnection) => { sku: sku ?? id, price: +priceV2.amount, listPrice: +compareAtPriceV2?.amount, - requiresShipping: true, + requiresShipping, + availableForSale, + isInStock: Number(quantityAvailable) > 0, options: selectedOptions.map(({ name, value }: SelectedOption) => { const options = normalizeProductOption({ id, diff --git a/framework/shopify/utils/queries/get-all-products-query.ts b/framework/shopify/utils/queries/get-all-products-query.ts index 5eb44c7a7..947045869 100644 --- a/framework/shopify/utils/queries/get-all-products-query.ts +++ b/framework/shopify/utils/queries/get-all-products-query.ts @@ -7,6 +7,7 @@ edges { node { id title + availableForSale vendor handle description diff --git a/framework/shopify/utils/queries/get-product-query.ts b/framework/shopify/utils/queries/get-product-query.ts index 5c109901b..e9875bb42 100644 --- a/framework/shopify/utils/queries/get-product-query.ts +++ b/framework/shopify/utils/queries/get-product-query.ts @@ -33,6 +33,9 @@ const getProductQuery = /* GraphQL */ ` id title sku + availableForSale + quantityAvailable + requiresShipping selectedOptions { name value