Sell only available products / fix out of stock

This commit is contained in:
cond0r 2021-03-27 19:09:00 +02:00
parent 81ac0dd1d4
commit c2e5eb8501
8 changed files with 43 additions and 20 deletions

View File

@ -146,8 +146,12 @@ const ProductView: FC<Props> = ({ product }) => {
className={s.button}
onClick={addToCart}
loading={loading}
disabled={variant?.availableForSale === false}
>
Add to Cart
{variant?.isInStock === false &&
variant?.availableForSale === false
? 'Out Of Stock'
: 'Add To Cart'}
</Button>
</div>
</div>

View File

@ -190,6 +190,12 @@ 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
// The total sellable quantity of the variant for online sales channels.
quantityAvailable?: number
}
interface ProductPrice {

View File

@ -10,11 +10,14 @@ export const handler: SWRHook<Customer | null> = {
query: getCustomerQuery,
},
async fetcher({ options, fetch }) {
const customerAccessToken = getCustomerToken()
if (customerAccessToken) {
const data = await fetch<any | null>({
...options,
variables: { customerAccessToken: getCustomerToken() },
variables: { customerAccessToken },
})
return data.customer ?? null
}
},
useHook: ({ useData }) => (input) => {
return useData({

View File

@ -18,9 +18,7 @@ export interface LineItem extends Core.LineItem {
* Cart mutations
*/
export type Product = Core.Product & {
totalInventory?: Maybe<Scalars['Int']>
}
export type Product = Core.Product
export type OptionSelections = {
option_id: number

View File

@ -7,7 +7,7 @@ export const getSearchVariables = ({
categoryId,
sort,
}: SearchProductsInput) => {
let query = ''
let query = 'available_for_sale:true'
if (search) {
query += ` product_type:${search} OR title:${search} OR tag:${search}`

View File

@ -51,15 +51,27 @@ const normalizeProductImages = ({ edges }: ImageConnection) =>
const normalizeProductVariants = ({ edges }: ProductVariantConnection) => {
return edges?.map(
({
node: { id, selectedOptions, sku, title, priceV2, compareAtPriceV2 },
node: {
id,
title,
sku,
priceV2,
compareAtPriceV2,
selectedOptions,
requiresShipping,
availableForSale,
quantityAvailable,
},
}) => {
return {
id,
name: title,
sku: sku ?? id,
sku: sku ?? '',
price: +priceV2.amount,
listPrice: +compareAtPriceV2?.amount,
requiresShipping: true,
requiresShipping,
availableForSale,
isInStock: Boolean(Number(quantityAvailable) > 0),
options: selectedOptions.map(({ name, value }: SelectedOption) => {
const options = normalizeProductOption({
id,
@ -84,7 +96,6 @@ export function normalizeProduct(productNode: ShopifyProduct): Product {
handle,
priceRange,
options,
totalInventory,
...rest
} = productNode
@ -98,7 +109,6 @@ export function normalizeProduct(productNode: ShopifyProduct): Product {
price: money(priceRange?.minVariantPrice),
images: normalizeProductImages(images),
variants: variants ? normalizeProductVariants(variants) : [],
totalInventory,
options: options
? options
.filter((o) => o.name !== 'Title') // By default Shopify adds a 'Title' name when there's only one option. We don't need it. https://community.shopify.com/c/Shopify-APIs-SDKs/Adding-new-product-variant-is-automatically-adding-quot-Default/td-p/358095

View File

@ -10,7 +10,7 @@ edges {
vendor
handle
description
totalInventory
availableForSale
priceRange {
minVariantPrice {
amount
@ -48,7 +48,7 @@ products(
const getAllProductsQuery = /* GraphQL */ `
query getAllProducts(
$first: Int = 250
$query: String = ""
$query: String = "available_for_sale:true"
$sortKey: ProductSortKeys = RELEVANCE
$reverse: Boolean = false
) {

View File

@ -8,7 +8,6 @@ const getProductQuery = /* GraphQL */ `
vendor
description
descriptionHtml
totalInventory
options {
id
name
@ -34,6 +33,9 @@ const getProductQuery = /* GraphQL */ `
id
title
sku
availableForSale
requiresShipping
quantityAvailable
selectedOptions {
name
value