4
0
forked from crowetic/commerce

update get product hook

This commit is contained in:
Greg Hoskin 2021-04-01 16:32:12 -06:00
parent 1ebf458fb2
commit 18936b7544
8 changed files with 103 additions and 131 deletions

View File

@ -1,8 +1,12 @@
import { swellConfig } from '../../index' import { swellConfig } from '../../index'
const fetchSwellApi = async (query: string, method: string) => { const fetchSwellApi = async (
query: string,
method: string,
variables: object | string
) => {
const { swell } = swellConfig const { swell } = swellConfig
const res = await swell[query][method]() const res = await swell[query][method](variables)
return res return res
} }

View File

@ -1,60 +1,28 @@
import { useMemo } from 'react' import useCart, { UseCart } from '@commerce/cart/use-cart'
import useCommerceCart, { import { Customer } from '@commerce/types'
FetchCartInput,
UseCart,
} from '@commerce/cart/use-cart'
import { Cart } from '../types'
import { SWRHook } from '@commerce/utils/types' import { SWRHook } from '@commerce/utils/types'
import { checkoutCreate, checkoutToCart } from './utils' import { normalizeCart } from '../utils/normalize'
import getCheckoutQuery from '../utils/queries/get-checkout-query' // import { getCustomerQuery, getCustomerToken } from '../utils'
export default useCommerceCart as UseCart<typeof handler> export default useCart as UseCart<typeof handler>
export const handler: SWRHook< export const handler: SWRHook<Customer | null> = {
Cart | null,
{},
FetchCartInput,
{ isEmpty?: boolean }
> = {
fetchOptions: { fetchOptions: {
query: 'cart', query: 'cart',
method: 'get', method: 'get',
}, },
async fetcher({ input: { cartId: checkoutId }, options, fetch }) { async fetcher({ options, fetch }) {
let checkout const data = await fetch<any | null>({
if (checkoutId) { ...options,
const data = await fetch({ })
...options, return data ? normalizeCart(data) : null
variables: {
checkoutId,
},
})
checkout = data.node
}
if (checkout?.completedAt || !checkoutId) {
checkout = await checkoutCreate(fetch)
}
// TODO: Fix this type
return checkoutToCart({ checkout } as any)
}, },
useHook: ({ useData }) => (input) => { useHook: ({ useData }) => (input) => {
const response = useData({ return useData({
swrOptions: { revalidateOnFocus: false, ...input?.swrOptions }, swrOptions: {
revalidateOnFocus: false,
...input?.swrOptions,
},
}) })
return useMemo(
() =>
Object.create(response, {
isEmpty: {
get() {
return (response.data?.lineItems.length ?? 0) <= 0
},
enumerable: true,
},
}),
[response]
)
}, },
} }

View File

@ -4,26 +4,27 @@ import {
SHOPIFY_COOKIE_EXPIRE, SHOPIFY_COOKIE_EXPIRE,
} from '../../const' } from '../../const'
import checkoutCreateMutation from '../../utils/mutations/checkout-create' // import checkoutCreateMutation from '../../utils/mutations/checkout-create'
import Cookies from 'js-cookie' import Cookies from 'js-cookie'
export const checkoutCreate = async (fetch: any) => { export const checkoutCreate = async (fetch: any) => {
const data = await fetch({ const cart = await fetch({
query: checkoutCreateMutation, query: 'cart',
method: 'get',
}) })
const checkout = data.checkoutCreate?.checkout // const checkout = data.checkoutCreate?.checkout
const checkoutId = checkout?.id const checkoutId = cart?.id
if (checkoutId) { // if (checkoutId) {
const options = { // const options = {
expires: SHOPIFY_COOKIE_EXPIRE, // expires: SHOPIFY_COOKIE_EXPIRE,
} // }
Cookies.set(SHOPIFY_CHECKOUT_ID_COOKIE, checkoutId, options) // Cookies.set(SHOPIFY_CHECKOUT_ID_COOKIE, checkoutId, options)
Cookies.set(SHOPIFY_CHECKOUT_URL_COOKIE, checkout?.webUrl, options) // Cookies.set(SHOPIFY_CHECKOUT_URL_COOKIE, checkout?.webUrl, options)
} // }
return checkout return cart
} }
export default checkoutCreate export default checkoutCreate

View File

@ -1,31 +1,33 @@
import { HookFetcherFn } from '@commerce/utils/types' import { HookFetcherFn } from '@commerce/utils/types'
import { Cart } from '@commerce/types' import { Cart } from '@commerce/types'
import { checkoutCreate, checkoutToCart } from '.' // import { checkoutCreate, checkoutToCart } from '.'
import { FetchCartInput } from '@commerce/cart/use-cart' import { FetchCartInput } from '@commerce/cart/use-cart'
import { data } from 'autoprefixer'
import { normalizeCart } from '../../utils'
const fetcher: HookFetcherFn<Cart | null, FetchCartInput> = async ({ const fetcher: HookFetcherFn<Cart | null, FetchCartInput> = async ({
options, options,
input: { cartId: checkoutId }, // input: { cartId: checkoutId },
fetch, fetch,
}) => { }) => {
let checkout let checkout
if (checkoutId) { // if (checkoutId) {
const data = await fetch({ const data = await fetch({
...options, query: 'cart',
variables: { method: 'get',
checkoutId, // variables: { category: categoryId },
}, })
}) // checkout = data.node
checkout = data.node // }
}
if (checkout?.completedAt || !checkoutId) { // if (checkout?.completedAt || !checkoutId) {
checkout = await checkoutCreate(fetch) // checkout = await checkoutCreate(fetch)
} // }
// TODO: Fix this type // TODO: Fix this type
return checkoutToCart({ checkout } as any) // return checkoutToCart({ checkout } as any)
return normalizeCart(data)
} }
export default fetcher export default fetcher

View File

@ -8,9 +8,11 @@ const fetcher: Fetcher = async ({ method = 'get', variables, query }) => {
if (Array.isArray(variables)) { if (Array.isArray(variables)) {
const arg1 = variables[0] const arg1 = variables[0]
const arg2 = variables[1] const arg2 = variables[1]
// console.log('fetcher', query, method, variables);
const response = await swell[query][method](arg1, arg2) const response = await swell[query][method](arg1, arg2)
return handleFetchResponse(response) return handleFetchResponse(response)
} else { } else {
// console.log('fetcher', query, method, variables);
const response = await swell[query][method](variables) const response = await swell[query][method](variables)
return handleFetchResponse(response) return handleFetchResponse(response)
} }

View File

@ -18,11 +18,7 @@ const getProduct = async (options: {
let { config, variables } = options ?? {} let { config, variables } = options ?? {}
config = getConfig(config) config = getConfig(config)
const { data }: GraphQLFetcherResult = await config.fetch(getProductQuery, { const product = await config.fetchSwell('products', 'get', variables.slug)
variables,
})
const { productByHandle: product } = data
return { return {
product: product ? normalizeProduct(product) : null, product: product ? normalizeProduct(product) : null,

View File

@ -32,8 +32,8 @@ export const handler: SWRHook<
const { results, count: found } = await fetch({ const { results, count: found } = await fetch({
query: 'products', query: 'products',
method: 'get', method: 'list',
// variables: { categoryId }, variables: { category: categoryId },
}) })
const products = results.map((product) => normalizeProduct(product)) const products = results.map((product) => normalizeProduct(product))

View File

@ -47,31 +47,28 @@ const normalizeProductOption = ({
} }
const normalizeProductImages = (images) => const normalizeProductImages = (images) =>
images?.map(({ file, ...rest }) => ({ images?.map(({ file, id }) => ({
url: file.url, url: file.url,
...rest, id,
})) }))
const normalizeProductVariants = ({ edges }: ProductVariantConnection) => { const normalizeProductVariants = (variants) => {
return edges?.map( // console.log('variant', variants);
({ return variants?.map(({ id, name, values, price, stock_status }) => ({
node: { id, selectedOptions, sku, title, priceV2, compareAtPriceV2 }, id,
}) => ({ name,
id, sku: sku ?? id,
name: title, price,
sku: sku ?? id, listPrice: price,
price: +priceV2.amount, // requiresShipping: true,
listPrice: +compareAtPriceV2?.amount, options: values.map(({ name, value }: SelectedOption) =>
requiresShipping: true, normalizeProductOption({
options: selectedOptions.map(({ name, value }: SelectedOption) => id,
normalizeProductOption({ name,
id, values: [value],
name, })
values: [value], ),
}) }))
),
})
)
} }
export function normalizeProduct(productNode: SwellProduct): Product { export function normalizeProduct(productNode: SwellProduct): Product {
@ -91,13 +88,13 @@ export function normalizeProduct(productNode: SwellProduct): Product {
const product = { const product = {
id, id,
name, name,
vendor, vendor: 'our brands',
description, description,
path: `/${slug}`, path: `/${slug}`,
slug, slug,
price, price,
images: normalizeProductImages(images), images: normalizeProductImages(images),
variants: variants ? normalizeProductVariants(variants) : [], variants: [], //variants ? normalizeProductVariants(options) : [],
options: options ? options.map((o) => normalizeProductOption(o)) : [], options: options ? options.map((o) => normalizeProductOption(o)) : [],
...rest, ...rest,
} }
@ -105,21 +102,19 @@ export function normalizeProduct(productNode: SwellProduct): Product {
return product return product
} }
export function normalizeCart(checkout: Checkout): Cart { export function normalizeCart(cart: Checkout): Cart {
return { return {
id: checkout.id, id: cart.id,
customerId: '', customerId: cart.account_id,
email: '', email: '',
createdAt: checkout.createdAt, createdAt: cart.date_created,
currency: { currency: cart.currency,
code: checkout.totalPriceV2?.currencyCode, taxesIncluded: cart.tax_included_total,
}, lineItems: cart.items?.map(normalizeLineItem),
taxesIncluded: checkout.taxesIncluded, lineItemsSubtotalPrice: +cart.sub_total,
lineItems: checkout.lineItems?.edges.map(normalizeLineItem), subtotalPrice: +cart.sub_total,
lineItemsSubtotalPrice: +checkout.subtotalPriceV2?.amount, totalPrice: cart.grand_total,
subtotalPrice: +checkout.subtotalPriceV2?.amount, discounts: cart.discounts,
totalPrice: checkout.totalPriceV2?.amount,
discounts: [],
} }
} }
@ -133,30 +128,34 @@ export function normalizeCustomer(customer: SwellCustomer): Customer {
} }
function normalizeLineItem({ function normalizeLineItem({
node: { id, title, variant, quantity }, id,
product,
price,
variant,
quantity,
}: CheckoutLineItemEdge): LineItem { }: CheckoutLineItemEdge): LineItem {
return { return {
id, id,
variantId: String(variant?.id), variantId: String(variant?.id),
productId: String(variant?.id), productId: String(product?.id),
name: `${title}`, name: product.name,
quantity, quantity,
variant: { variant: {
id: String(variant?.id), id: String(variant?.id),
sku: variant?.sku ?? '', sku: variant?.sku ?? '',
name: variant?.title!, name: variant?.name!,
image: { image: {
url: variant?.image?.originalSrc, url: product?.images[0].file.url,
}, },
requiresShipping: variant?.requiresShipping ?? false, requiresShipping: false,
price: variant?.priceV2?.amount, price: price,
listPrice: variant?.compareAtPriceV2?.amount, listPrice: price,
}, },
path: '', path: '',
discounts: [], discounts: [],
options: [ options: [
{ {
value: variant?.title, value: variant?.name,
}, },
], ],
} }