forked from crowetic/commerce
Shopify Provier Updates (#212)
* changes * Adding shopify commit * Changed to query page by id * Fixed page query, Changed use-search GraphQl query * Update use-search.tsx * remove unused util * Changed cookie expiration * Update tsconfig.json Co-authored-by: okbel <curciobel@gmail.com>
This commit is contained in:
parent
751011767a
commit
641ce0aa64
@ -3,4 +3,4 @@ BIGCOMMERCE_STOREFRONT_API_TOKEN=
|
|||||||
BIGCOMMERCE_STORE_API_URL=
|
BIGCOMMERCE_STORE_API_URL=
|
||||||
BIGCOMMERCE_STORE_API_TOKEN=
|
BIGCOMMERCE_STORE_API_TOKEN=
|
||||||
BIGCOMMERCE_STORE_API_CLIENT_ID=
|
BIGCOMMERCE_STORE_API_CLIENT_ID=
|
||||||
BIGCOMMERCE_CHANNEL_ID=
|
BIGCOMMERCE_CHANNEL_ID=
|
||||||
|
@ -5,6 +5,7 @@ import {
|
|||||||
API_TOKEN,
|
API_TOKEN,
|
||||||
SHOPIFY_CHECKOUT_ID_COOKIE,
|
SHOPIFY_CHECKOUT_ID_COOKIE,
|
||||||
SHOPIFY_CUSTOMER_TOKEN_COOKIE,
|
SHOPIFY_CUSTOMER_TOKEN_COOKIE,
|
||||||
|
SHOPIFY_COOKIE_EXPIRE,
|
||||||
} from '../const'
|
} from '../const'
|
||||||
|
|
||||||
if (!API_URL) {
|
if (!API_URL) {
|
||||||
@ -43,10 +44,11 @@ export class Config {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const config = new Config({
|
const config = new Config({
|
||||||
|
locale: 'en-US',
|
||||||
commerceUrl: API_URL,
|
commerceUrl: API_URL,
|
||||||
apiToken: API_TOKEN!,
|
apiToken: API_TOKEN!,
|
||||||
cartCookie: SHOPIFY_CHECKOUT_ID_COOKIE,
|
cartCookie: SHOPIFY_CHECKOUT_ID_COOKIE,
|
||||||
cartCookieMaxAge: 60 * 60 * 24 * 30,
|
cartCookieMaxAge: SHOPIFY_COOKIE_EXPIRE,
|
||||||
fetch: fetchGraphqlApi,
|
fetch: fetchGraphqlApi,
|
||||||
customerCookie: SHOPIFY_CUSTOMER_TOKEN_COOKIE,
|
customerCookie: SHOPIFY_CUSTOMER_TOKEN_COOKIE,
|
||||||
})
|
})
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import {
|
import {
|
||||||
SHOPIFY_CHECKOUT_ID_COOKIE,
|
SHOPIFY_CHECKOUT_ID_COOKIE,
|
||||||
SHOPIFY_CHECKOUT_URL_COOKIE,
|
SHOPIFY_CHECKOUT_URL_COOKIE,
|
||||||
|
SHOPIFY_COOKIE_EXPIRE,
|
||||||
} from '../../const'
|
} from '../../const'
|
||||||
|
|
||||||
import checkoutCreateMutation from '../../utils/mutations/checkout-create'
|
import checkoutCreateMutation from '../../utils/mutations/checkout-create'
|
||||||
@ -15,8 +16,11 @@ export const checkoutCreate = async (fetch: any) => {
|
|||||||
const checkoutId = checkout?.id
|
const checkoutId = checkout?.id
|
||||||
|
|
||||||
if (checkoutId) {
|
if (checkoutId) {
|
||||||
Cookies.set(SHOPIFY_CHECKOUT_ID_COOKIE, checkoutId)
|
const options = {
|
||||||
Cookies.set(SHOPIFY_CHECKOUT_URL_COOKIE, checkout?.webUrl)
|
expires: SHOPIFY_COOKIE_EXPIRE,
|
||||||
|
}
|
||||||
|
Cookies.set(SHOPIFY_CHECKOUT_ID_COOKIE, checkoutId, options)
|
||||||
|
Cookies.set(SHOPIFY_CHECKOUT_URL_COOKIE, checkout?.webUrl, options)
|
||||||
}
|
}
|
||||||
|
|
||||||
return checkout
|
return checkout
|
||||||
|
@ -25,12 +25,13 @@ const getAllPages = async (options?: {
|
|||||||
}): Promise<ReturnType> => {
|
}): Promise<ReturnType> => {
|
||||||
let { config, variables = { first: 250 } } = options ?? {}
|
let { config, variables = { first: 250 } } = options ?? {}
|
||||||
config = getConfig(config)
|
config = getConfig(config)
|
||||||
|
const { locale } = config
|
||||||
const { data } = await config.fetch(getAllPagesQuery, { variables })
|
const { data } = await config.fetch(getAllPagesQuery, { variables })
|
||||||
|
|
||||||
const pages = data.pages?.edges?.map(
|
const pages = data.pages?.edges?.map(
|
||||||
({ node: { title: name, handle, ...node } }: PageEdge) => ({
|
({ node: { title: name, handle, ...node } }: PageEdge) => ({
|
||||||
...node,
|
...node,
|
||||||
url: `/${handle}`,
|
url: `/${locale}/${handle}`,
|
||||||
name,
|
name,
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
@ -3,33 +3,32 @@ import getPageQuery from '../utils/queries/get-page-query'
|
|||||||
import { Page } from './get-all-pages'
|
import { Page } from './get-all-pages'
|
||||||
|
|
||||||
type Variables = {
|
type Variables = {
|
||||||
slug: string
|
id: string
|
||||||
}
|
}
|
||||||
|
|
||||||
type ReturnType = {
|
export type GetPageResult<T extends { page?: any } = { page?: Page }> = T
|
||||||
page: Page
|
|
||||||
}
|
|
||||||
|
|
||||||
const getPage = async (options: {
|
const getPage = async (options: {
|
||||||
variables: Variables
|
variables: Variables
|
||||||
config: ShopifyConfig
|
config: ShopifyConfig
|
||||||
preview?: boolean
|
preview?: boolean
|
||||||
}): Promise<ReturnType> => {
|
}): Promise<GetPageResult> => {
|
||||||
let { config, variables } = options ?? {}
|
let { config, variables } = options ?? {}
|
||||||
|
|
||||||
config = getConfig(config)
|
config = getConfig(config)
|
||||||
|
const { locale } = config
|
||||||
|
|
||||||
const { data } = await config.fetch(getPageQuery, {
|
const { data } = await config.fetch(getPageQuery, {
|
||||||
variables,
|
variables,
|
||||||
})
|
})
|
||||||
|
const page = data.node
|
||||||
const { pageByHandle: page } = data
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
page: page
|
page: page
|
||||||
? {
|
? {
|
||||||
...page,
|
...page,
|
||||||
name: page.title,
|
name: page.title,
|
||||||
url: page?.handle,
|
url: `/${locale}/${page.handle}`,
|
||||||
}
|
}
|
||||||
: null,
|
: null,
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,8 @@ export const SHOPIFY_CUSTOMER_TOKEN_COOKIE = 'shopify_customerToken'
|
|||||||
|
|
||||||
export const STORE_DOMAIN = process.env.NEXT_PUBLIC_SHOPIFY_STORE_DOMAIN
|
export const STORE_DOMAIN = process.env.NEXT_PUBLIC_SHOPIFY_STORE_DOMAIN
|
||||||
|
|
||||||
|
export const SHOPIFY_COOKIE_EXPIRE = 30
|
||||||
|
|
||||||
export const API_URL = `https://${STORE_DOMAIN}/api/2021-01/graphql.json`
|
export const API_URL = `https://${STORE_DOMAIN}/api/2021-01/graphql.json`
|
||||||
|
|
||||||
export const API_TOKEN = process.env.NEXT_PUBLIC_SHOPIFY_STOREFRONT_ACCESS_TOKEN
|
export const API_TOKEN = process.env.NEXT_PUBLIC_SHOPIFY_STOREFRONT_ACCESS_TOKEN
|
||||||
|
@ -4,6 +4,7 @@ import useSearch, { UseSearch } from '@commerce/product/use-search'
|
|||||||
import { ProductEdge } from '../schema'
|
import { ProductEdge } from '../schema'
|
||||||
import {
|
import {
|
||||||
getAllProductsQuery,
|
getAllProductsQuery,
|
||||||
|
getCollectionProductsQuery,
|
||||||
getSearchVariables,
|
getSearchVariables,
|
||||||
normalizeProduct,
|
normalizeProduct,
|
||||||
} from '../utils'
|
} from '../utils'
|
||||||
@ -14,8 +15,8 @@ export default useSearch as UseSearch<typeof handler>
|
|||||||
|
|
||||||
export type SearchProductsInput = {
|
export type SearchProductsInput = {
|
||||||
search?: string
|
search?: string
|
||||||
categoryId?: number
|
categoryId?: string
|
||||||
brandId?: number
|
brandId?: string
|
||||||
sort?: string
|
sort?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -23,6 +24,7 @@ export type SearchProductsData = {
|
|||||||
products: Product[]
|
products: Product[]
|
||||||
found: boolean
|
found: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export const handler: SWRHook<
|
export const handler: SWRHook<
|
||||||
SearchProductsData,
|
SearchProductsData,
|
||||||
SearchProductsInput,
|
SearchProductsInput,
|
||||||
@ -32,18 +34,30 @@ export const handler: SWRHook<
|
|||||||
query: getAllProductsQuery,
|
query: getAllProductsQuery,
|
||||||
},
|
},
|
||||||
async fetcher({ input, options, fetch }) {
|
async fetcher({ input, options, fetch }) {
|
||||||
const resp = await fetch({
|
const { categoryId, brandId } = input
|
||||||
query: options?.query,
|
|
||||||
|
const data = await fetch({
|
||||||
|
query: categoryId ? getCollectionProductsQuery : options.query,
|
||||||
method: options?.method,
|
method: options?.method,
|
||||||
variables: getSearchVariables(input),
|
variables: getSearchVariables(input),
|
||||||
})
|
})
|
||||||
const edges = resp.products?.edges
|
|
||||||
|
let edges
|
||||||
|
|
||||||
|
if (categoryId) {
|
||||||
|
edges = data.node?.products?.edges ?? []
|
||||||
|
if (brandId) {
|
||||||
|
edges = edges.filter(
|
||||||
|
({ node: { vendor } }: ProductEdge) => vendor === brandId
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
edges = data.products?.edges ?? []
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
products: edges?.map(({ node: p }: ProductEdge) =>
|
products: edges.map(({ node }: ProductEdge) => normalizeProduct(node)),
|
||||||
// TODO: Fix this product type
|
found: !!edges.length,
|
||||||
normalizeProduct(p as any)
|
|
||||||
),
|
|
||||||
found: !!edges?.length,
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
useHook: ({ useData }) => (input = {}) => {
|
useHook: ({ useData }) => (input = {}) => {
|
||||||
|
@ -1,12 +1,21 @@
|
|||||||
import Cookies from 'js-cookie'
|
import Cookies, { CookieAttributes } from 'js-cookie'
|
||||||
import { SHOPIFY_CUSTOMER_TOKEN_COOKIE } from '../const'
|
import { SHOPIFY_COOKIE_EXPIRE, SHOPIFY_CUSTOMER_TOKEN_COOKIE } from '../const'
|
||||||
|
|
||||||
export const getCustomerToken = () => Cookies.get(SHOPIFY_CUSTOMER_TOKEN_COOKIE)
|
export const getCustomerToken = () => Cookies.get(SHOPIFY_CUSTOMER_TOKEN_COOKIE)
|
||||||
|
|
||||||
export const setCustomerToken = (token: string | null, options?: any) => {
|
export const setCustomerToken = (
|
||||||
|
token: string | null,
|
||||||
|
options?: CookieAttributes
|
||||||
|
) => {
|
||||||
if (!token) {
|
if (!token) {
|
||||||
Cookies.remove(SHOPIFY_CUSTOMER_TOKEN_COOKIE)
|
Cookies.remove(SHOPIFY_CUSTOMER_TOKEN_COOKIE)
|
||||||
} else {
|
} else {
|
||||||
Cookies.set(SHOPIFY_CUSTOMER_TOKEN_COOKIE, token, options)
|
Cookies.set(
|
||||||
|
SHOPIFY_CUSTOMER_TOKEN_COOKIE,
|
||||||
|
token,
|
||||||
|
options ?? {
|
||||||
|
expires: SHOPIFY_COOKIE_EXPIRE,
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,8 +17,8 @@ const getCategories = async (config: ShopifyConfig): Promise<Category[]> => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
data.collections?.edges?.map(
|
data.collections?.edges?.map(
|
||||||
({ node: { title: name, handle } }: CollectionEdge) => ({
|
({ node: { id: entityId, title: name, handle } }: CollectionEdge) => ({
|
||||||
entityId: handle,
|
entityId,
|
||||||
name,
|
name,
|
||||||
path: `/${handle}`,
|
path: `/${handle}`,
|
||||||
})
|
})
|
||||||
|
@ -2,9 +2,9 @@ import getSortVariables from './get-sort-variables'
|
|||||||
import type { SearchProductsInput } from '../product/use-search'
|
import type { SearchProductsInput } from '../product/use-search'
|
||||||
|
|
||||||
export const getSearchVariables = ({
|
export const getSearchVariables = ({
|
||||||
categoryId,
|
|
||||||
brandId,
|
brandId,
|
||||||
search,
|
search,
|
||||||
|
categoryId,
|
||||||
sort,
|
sort,
|
||||||
}: SearchProductsInput) => {
|
}: SearchProductsInput) => {
|
||||||
let query = ''
|
let query = ''
|
||||||
@ -13,17 +13,14 @@ export const getSearchVariables = ({
|
|||||||
query += `product_type:${search} OR title:${search} OR tag:${search}`
|
query += `product_type:${search} OR title:${search} OR tag:${search}`
|
||||||
}
|
}
|
||||||
|
|
||||||
if (categoryId) {
|
|
||||||
query += `tag:${categoryId}`
|
|
||||||
}
|
|
||||||
|
|
||||||
if (brandId) {
|
if (brandId) {
|
||||||
query += `${categoryId ? ' AND ' : ''}vendor:${brandId}`
|
query += `${search ? ' AND ' : ''}vendor:${brandId}`
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
categoryId,
|
||||||
query,
|
query,
|
||||||
...getSortVariables(sort),
|
...getSortVariables(sort, !!categoryId),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
const getSortVariables = (sort?: string) => {
|
const getSortVariables = (sort?: string, isCategory = false) => {
|
||||||
let output = {}
|
let output = {}
|
||||||
switch (sort) {
|
switch (sort) {
|
||||||
case 'price-asc':
|
case 'price-asc':
|
||||||
@ -21,7 +21,7 @@ const getSortVariables = (sort?: string) => {
|
|||||||
break
|
break
|
||||||
case 'latest-desc':
|
case 'latest-desc':
|
||||||
output = {
|
output = {
|
||||||
sortKey: 'CREATED_AT',
|
sortKey: isCategory ? 'CREATED' : 'CREATED_AT',
|
||||||
reverse: true,
|
reverse: true,
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
import { Product } from '@commerce/types'
|
||||||
|
|
||||||
import {
|
import {
|
||||||
Product as ShopifyProduct,
|
Product as ShopifyProduct,
|
||||||
Checkout,
|
Checkout,
|
||||||
@ -5,8 +7,8 @@ import {
|
|||||||
SelectedOption,
|
SelectedOption,
|
||||||
ImageConnection,
|
ImageConnection,
|
||||||
ProductVariantConnection,
|
ProductVariantConnection,
|
||||||
ProductOption,
|
|
||||||
MoneyV2,
|
MoneyV2,
|
||||||
|
ProductOption,
|
||||||
} from '../schema'
|
} from '../schema'
|
||||||
|
|
||||||
import type { Cart, LineItem } from '../types'
|
import type { Cart, LineItem } from '../types'
|
||||||
@ -19,18 +21,26 @@ const money = ({ amount, currencyCode }: MoneyV2) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const normalizeProductOption = ({
|
const normalizeProductOption = ({
|
||||||
|
id,
|
||||||
name: displayName,
|
name: displayName,
|
||||||
values,
|
values,
|
||||||
...rest
|
|
||||||
}: ProductOption) => {
|
}: ProductOption) => {
|
||||||
return {
|
return {
|
||||||
__typename: 'MultipleChoiceOption',
|
__typename: 'MultipleChoiceOption',
|
||||||
|
id,
|
||||||
displayName,
|
displayName,
|
||||||
values: values.map((value) => ({
|
values: values.map((value) => {
|
||||||
label: value,
|
let output: any = {
|
||||||
hexColors: displayName === 'Color' ? [value] : null,
|
label: value,
|
||||||
})),
|
}
|
||||||
...rest,
|
if (displayName === 'Color') {
|
||||||
|
output = {
|
||||||
|
...output,
|
||||||
|
hexColors: [value],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return output
|
||||||
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -41,19 +51,28 @@ const normalizeProductImages = ({ edges }: ImageConnection) =>
|
|||||||
}))
|
}))
|
||||||
|
|
||||||
const normalizeProductVariants = ({ edges }: ProductVariantConnection) => {
|
const normalizeProductVariants = ({ edges }: ProductVariantConnection) => {
|
||||||
return edges?.map(({ node: { id, selectedOptions } }) => ({
|
return edges?.map(
|
||||||
id,
|
({
|
||||||
options: selectedOptions.map(({ name, value }: SelectedOption) =>
|
node: { id, selectedOptions, sku, title, priceV2, compareAtPriceV2 },
|
||||||
normalizeProductOption({
|
}) => ({
|
||||||
id,
|
id,
|
||||||
name,
|
name: title,
|
||||||
values: [value],
|
sku: sku ?? id,
|
||||||
})
|
price: +priceV2.amount,
|
||||||
),
|
listPrice: +compareAtPriceV2?.amount,
|
||||||
}))
|
requiresShipping: true,
|
||||||
|
options: selectedOptions.map(({ name, value }: SelectedOption) =>
|
||||||
|
normalizeProductOption({
|
||||||
|
id,
|
||||||
|
name,
|
||||||
|
values: [value],
|
||||||
|
})
|
||||||
|
),
|
||||||
|
})
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function normalizeProduct(productNode: ShopifyProduct): any {
|
export function normalizeProduct(productNode: ShopifyProduct): Product {
|
||||||
const {
|
const {
|
||||||
id,
|
id,
|
||||||
title: name,
|
title: name,
|
||||||
@ -95,8 +114,8 @@ export function normalizeCart(checkout: Checkout): Cart {
|
|||||||
},
|
},
|
||||||
taxesIncluded: checkout.taxesIncluded,
|
taxesIncluded: checkout.taxesIncluded,
|
||||||
lineItems: checkout.lineItems?.edges.map(normalizeLineItem),
|
lineItems: checkout.lineItems?.edges.map(normalizeLineItem),
|
||||||
lineItemsSubtotalPrice: checkout.subtotalPriceV2?.amount,
|
lineItemsSubtotalPrice: +checkout.subtotalPriceV2?.amount,
|
||||||
subtotalPrice: checkout.subtotalPriceV2?.amount,
|
subtotalPrice: +checkout.subtotalPriceV2?.amount,
|
||||||
totalPrice: checkout.totalPriceV2?.amount,
|
totalPrice: checkout.totalPriceV2?.amount,
|
||||||
discounts: [],
|
discounts: [],
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,38 @@
|
|||||||
|
export const productConnection = `
|
||||||
|
pageInfo {
|
||||||
|
hasNextPage
|
||||||
|
hasPreviousPage
|
||||||
|
}
|
||||||
|
edges {
|
||||||
|
node {
|
||||||
|
id
|
||||||
|
title
|
||||||
|
vendor
|
||||||
|
handle
|
||||||
|
description
|
||||||
|
priceRange {
|
||||||
|
minVariantPrice {
|
||||||
|
amount
|
||||||
|
currencyCode
|
||||||
|
}
|
||||||
|
}
|
||||||
|
images(first: 1) {
|
||||||
|
pageInfo {
|
||||||
|
hasNextPage
|
||||||
|
hasPreviousPage
|
||||||
|
}
|
||||||
|
edges {
|
||||||
|
node {
|
||||||
|
originalSrc
|
||||||
|
altText
|
||||||
|
width
|
||||||
|
height
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}`
|
||||||
|
|
||||||
export const productsFragment = `
|
export const productsFragment = `
|
||||||
products(
|
products(
|
||||||
first: $first
|
first: $first
|
||||||
@ -5,39 +40,7 @@ products(
|
|||||||
reverse: $reverse
|
reverse: $reverse
|
||||||
query: $query
|
query: $query
|
||||||
) {
|
) {
|
||||||
pageInfo {
|
${productConnection}
|
||||||
hasNextPage
|
|
||||||
hasPreviousPage
|
|
||||||
}
|
|
||||||
edges {
|
|
||||||
node {
|
|
||||||
id
|
|
||||||
title
|
|
||||||
vendor
|
|
||||||
handle
|
|
||||||
description
|
|
||||||
priceRange {
|
|
||||||
minVariantPrice {
|
|
||||||
amount
|
|
||||||
currencyCode
|
|
||||||
}
|
|
||||||
}
|
|
||||||
images(first: 1) {
|
|
||||||
pageInfo {
|
|
||||||
hasNextPage
|
|
||||||
hasPreviousPage
|
|
||||||
}
|
|
||||||
edges {
|
|
||||||
node {
|
|
||||||
originalSrc
|
|
||||||
altText
|
|
||||||
width
|
|
||||||
height
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
|
@ -1,16 +1,23 @@
|
|||||||
import { productsFragment } from './get-all-products-query'
|
import { productConnection } from './get-all-products-query'
|
||||||
|
|
||||||
const getCollectionProductsQuery = /* GraphQL */ `
|
const getCollectionProductsQuery = /* GraphQL */ `
|
||||||
query getProductsFromCollection(
|
query getProductsFromCollection(
|
||||||
$categoryHandle: String!
|
$categoryId: ID!
|
||||||
$first: Int = 250
|
$first: Int = 250
|
||||||
$query: String = ""
|
$sortKey: ProductCollectionSortKeys = RELEVANCE
|
||||||
$sortKey: ProductSortKeys = RELEVANCE
|
|
||||||
$reverse: Boolean = false
|
$reverse: Boolean = false
|
||||||
) {
|
) {
|
||||||
collectionByHandle(handle: $categoryHandle)
|
node(id: $categoryId) {
|
||||||
{
|
id
|
||||||
${productsFragment}
|
... on Collection {
|
||||||
|
products(
|
||||||
|
first: $first
|
||||||
|
sortKey: $sortKey
|
||||||
|
reverse: $reverse
|
||||||
|
) {
|
||||||
|
${productConnection}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
export const getPageQuery = /* GraphQL */ `
|
export const getPageQuery = /* GraphQL */ `
|
||||||
query getPageBySlug($slug: String!) {
|
query($id: ID!) {
|
||||||
pageByHandle(handle: $slug) {
|
node(id: $id) {
|
||||||
id
|
id
|
||||||
title
|
... on Page {
|
||||||
handle
|
title
|
||||||
body
|
handle
|
||||||
bodySummary
|
body
|
||||||
url
|
bodySummary
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
@ -32,6 +32,7 @@ const getProductQuery = /* GraphQL */ `
|
|||||||
node {
|
node {
|
||||||
id
|
id
|
||||||
title
|
title
|
||||||
|
sku
|
||||||
selectedOptions {
|
selectedOptions {
|
||||||
name
|
name
|
||||||
value
|
value
|
||||||
|
@ -1,68 +0,0 @@
|
|||||||
// TODO: Fix the types in this file
|
|
||||||
// import { Product, Image } from '../types'
|
|
||||||
|
|
||||||
type Product = any
|
|
||||||
type Image = any
|
|
||||||
|
|
||||||
export default function toCommerceProducts(products: Product[]) {
|
|
||||||
return products.map((product: Product) => {
|
|
||||||
return {
|
|
||||||
id: product.id,
|
|
||||||
entityId: product.id,
|
|
||||||
name: product.title,
|
|
||||||
slug: product.handle,
|
|
||||||
title: product.title,
|
|
||||||
vendor: product.vendor,
|
|
||||||
description: product.descriptionHtml,
|
|
||||||
path: `/${product.handle}`,
|
|
||||||
price: {
|
|
||||||
value: +product.variants[0].price,
|
|
||||||
currencyCode: 'USD', // TODO
|
|
||||||
},
|
|
||||||
images: product.images.map((image: Image) => {
|
|
||||||
return {
|
|
||||||
url: image.src,
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
// TODO: Fix the variant type
|
|
||||||
variants: product.variants.map((variant: any) => {
|
|
||||||
return {
|
|
||||||
id: variant.id,
|
|
||||||
// TODO: Fix the selectedOption type
|
|
||||||
options: variant.selectedOptions.map((selectedOption: any) => {
|
|
||||||
return {
|
|
||||||
__typename: 'MultipleChoiceOption',
|
|
||||||
displayName: selectedOption.name,
|
|
||||||
values: [
|
|
||||||
{
|
|
||||||
node: {
|
|
||||||
id: variant.id,
|
|
||||||
label: selectedOption.value,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
// TODO: Fix the option type
|
|
||||||
productOptions: product.options.map((option: any) => {
|
|
||||||
return {
|
|
||||||
__typename: 'MultipleChoiceOption',
|
|
||||||
displayName: option.name,
|
|
||||||
// TODO: Fix the value type
|
|
||||||
values: option.values.map((value: any) => {
|
|
||||||
return {
|
|
||||||
node: {
|
|
||||||
entityId: 1,
|
|
||||||
label: value.value,
|
|
||||||
hexColors: [value.value],
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
options: [],
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
@ -2,9 +2,7 @@
|
|||||||
// Shopify doesn't have a wishlist
|
// Shopify doesn't have a wishlist
|
||||||
|
|
||||||
import { HookFetcher } from '@commerce/utils/types'
|
import { HookFetcher } from '@commerce/utils/types'
|
||||||
import useCommerceWishlist from '@commerce/wishlist/use-wishlist'
|
|
||||||
import { Product } from '../schema'
|
import { Product } from '../schema'
|
||||||
import useCustomer from '../customer/use-customer'
|
|
||||||
|
|
||||||
const defaultOpts = {}
|
const defaultOpts = {}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user