mirror of
https://github.com/vercel/commerce.git
synced 2025-07-22 20:26:49 +00:00
feat: getAllProducts and getProductBySlug
This commit is contained in:
@@ -25,3 +25,4 @@ NEXT_PUBLIC_VENDURE_SHOP_API_URL=
|
|||||||
NEXT_PUBLIC_VENDURE_LOCAL_URL=
|
NEXT_PUBLIC_VENDURE_LOCAL_URL=
|
||||||
|
|
||||||
NEXT_PUBLIC_WOOCOMMERCE_SHOP_API_URL=
|
NEXT_PUBLIC_WOOCOMMERCE_SHOP_API_URL=
|
||||||
|
NEXT_PUBLIC_WOOCOMMERCE_IMAGES_DOMAIN=
|
||||||
|
@@ -23,7 +23,7 @@ export function selectDefaultOptionFromProduct(
|
|||||||
updater: Dispatch<SetStateAction<SelectedOptions>>
|
updater: Dispatch<SetStateAction<SelectedOptions>>
|
||||||
) {
|
) {
|
||||||
// Selects the default option
|
// Selects the default option
|
||||||
product.variants[0].options?.forEach((v) => {
|
product?.variants[0]?.options?.forEach((v) => {
|
||||||
updater((choices) => ({
|
updater((choices) => ({
|
||||||
...choices,
|
...choices,
|
||||||
[v.displayName.toLowerCase()]: v.values[0].label.toLowerCase(),
|
[v.displayName.toLowerCase()]: v.values[0].label.toLowerCase(),
|
||||||
|
@@ -6,10 +6,9 @@ import { GetAllProductPathsOperation } from '../../types/product'
|
|||||||
import {
|
import {
|
||||||
GetAllProductPathsQuery,
|
GetAllProductPathsQuery,
|
||||||
GetAllProductPathsQueryVariables,
|
GetAllProductPathsQueryVariables,
|
||||||
ProductEdge,
|
|
||||||
} from '../../schema'
|
} from '../../schema'
|
||||||
import type { ShopifyConfig, Provider } from '..'
|
import type { WooCommerceConfig, Provider } from '..'
|
||||||
import { getAllProductsQuery } from '../../utils'
|
import getAllProductsQuery from '../../wp/queries/get-all-products-paths-query'
|
||||||
|
|
||||||
export default function getAllProductPathsOperation({
|
export default function getAllProductPathsOperation({
|
||||||
commerce,
|
commerce,
|
||||||
@@ -18,13 +17,13 @@ export default function getAllProductPathsOperation({
|
|||||||
T extends GetAllProductPathsOperation
|
T extends GetAllProductPathsOperation
|
||||||
>(opts?: {
|
>(opts?: {
|
||||||
variables?: T['variables']
|
variables?: T['variables']
|
||||||
config?: ShopifyConfig
|
config?: WooCommerceConfig
|
||||||
}): Promise<T['data']>
|
}): Promise<T['data']>
|
||||||
|
|
||||||
async function getAllProductPaths<T extends GetAllProductPathsOperation>(
|
async function getAllProductPaths<T extends GetAllProductPathsOperation>(
|
||||||
opts: {
|
opts: {
|
||||||
variables?: T['variables']
|
variables?: T['variables']
|
||||||
config?: ShopifyConfig
|
config?: WooCommerceConfig
|
||||||
} & OperationOptions
|
} & OperationOptions
|
||||||
): Promise<T['data']>
|
): Promise<T['data']>
|
||||||
|
|
||||||
@@ -34,7 +33,7 @@ export default function getAllProductPathsOperation({
|
|||||||
variables,
|
variables,
|
||||||
}: {
|
}: {
|
||||||
query?: string
|
query?: string
|
||||||
config?: ShopifyConfig
|
config?: WooCommerceConfig
|
||||||
variables?: T['variables']
|
variables?: T['variables']
|
||||||
} = {}): Promise<T['data']> {
|
} = {}): Promise<T['data']> {
|
||||||
config = commerce.getConfig(config)
|
config = commerce.getConfig(config)
|
||||||
@@ -45,9 +44,11 @@ export default function getAllProductPathsOperation({
|
|||||||
>(query, { variables })
|
>(query, { variables })
|
||||||
|
|
||||||
return {
|
return {
|
||||||
products: data.products.edges.map(({ node: { handle } }) => ({
|
products: data?.products?.edges
|
||||||
path: `/${handle}`,
|
? data.products.edges.map(({ node: { slug } }) => ({
|
||||||
})),
|
path: `/${slug}`,
|
||||||
|
}))
|
||||||
|
: [],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -6,12 +6,14 @@ import { GetAllProductsOperation } from '../../types/product'
|
|||||||
import {
|
import {
|
||||||
GetAllProductsQuery,
|
GetAllProductsQuery,
|
||||||
GetAllProductsQueryVariables,
|
GetAllProductsQueryVariables,
|
||||||
Product as WooCommerceProduct,
|
SimpleProduct,
|
||||||
} from '../../schema'
|
} from '../../schema'
|
||||||
import type { WooCommerceConfig, Provider } from '..'
|
import type { WooCommerceConfig, Provider } from '..'
|
||||||
import getAllProductsQuery from '../../utils/queries/get-all-products-query'
|
import getAllProductsQuery from '../../wp/queries/get-all-products-query'
|
||||||
import { normalizeProduct } from '../../utils'
|
import { normalizeProduct } from '../../utils'
|
||||||
|
|
||||||
|
import type { Product } from '../../types/product'
|
||||||
|
|
||||||
export default function getAllProductsOperation({
|
export default function getAllProductsOperation({
|
||||||
commerce,
|
commerce,
|
||||||
}: OperationContext<Provider>) {
|
}: OperationContext<Provider>) {
|
||||||
@@ -40,7 +42,7 @@ export default function getAllProductsOperation({
|
|||||||
preview?: boolean
|
preview?: boolean
|
||||||
} = {}): Promise<T['data']> {
|
} = {}): Promise<T['data']> {
|
||||||
const { fetch, locale } = commerce.getConfig(config)
|
const { fetch, locale } = commerce.getConfig(config)
|
||||||
|
// console.log({ a: 'reza', query, variables, config, fetch, locale })
|
||||||
try {
|
try {
|
||||||
const { data } = await fetch<
|
const { data } = await fetch<
|
||||||
GetAllProductsQuery,
|
GetAllProductsQuery,
|
||||||
@@ -56,18 +58,18 @@ export default function getAllProductsOperation({
|
|||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
console.log({ data })
|
|
||||||
return {
|
let products: Product[] = []
|
||||||
products: [],
|
|
||||||
|
if (data?.products?.edges) {
|
||||||
|
data?.products?.edges?.map(({ node }) =>
|
||||||
|
products.push(normalizeProduct(node as SimpleProduct))
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// return {
|
return {
|
||||||
// products: data?.products?.edges
|
products,
|
||||||
// ? data.products.edges.map(({ node }) =>
|
}
|
||||||
// normalizeProduct(node as WooCommerceProduct)
|
|
||||||
// )
|
|
||||||
// : [],
|
|
||||||
// }
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
throw e
|
throw e
|
||||||
}
|
}
|
||||||
|
@@ -3,23 +3,24 @@ import type {
|
|||||||
OperationOptions,
|
OperationOptions,
|
||||||
} from '@commerce/api/operations'
|
} from '@commerce/api/operations'
|
||||||
import { GetProductOperation } from '../../types/product'
|
import { GetProductOperation } from '../../types/product'
|
||||||
import { normalizeProduct, getProductQuery } from '../../utils'
|
import { normalizeProduct } from '../../utils'
|
||||||
import type { ShopifyConfig, Provider } from '..'
|
import getProductQuery from '../../wp/queries/get-product-query'
|
||||||
import { GetProductBySlugQuery, Product as ShopifyProduct } from '../../schema'
|
import type { WooCommerceConfig, Provider } from '..'
|
||||||
|
import { GetProductBySlugQuery, SimpleProduct } from '../../schema'
|
||||||
|
|
||||||
export default function getProductOperation({
|
export default function getProductOperation({
|
||||||
commerce,
|
commerce,
|
||||||
}: OperationContext<Provider>) {
|
}: OperationContext<Provider>) {
|
||||||
async function getProduct<T extends GetProductOperation>(opts: {
|
async function getProduct<T extends GetProductOperation>(opts: {
|
||||||
variables: T['variables']
|
variables: T['variables']
|
||||||
config?: Partial<ShopifyConfig>
|
config?: Partial<WooCommerceConfig>
|
||||||
preview?: boolean
|
preview?: boolean
|
||||||
}): Promise<T['data']>
|
}): Promise<T['data']>
|
||||||
|
|
||||||
async function getProduct<T extends GetProductOperation>(
|
async function getProduct<T extends GetProductOperation>(
|
||||||
opts: {
|
opts: {
|
||||||
variables: T['variables']
|
variables: T['variables']
|
||||||
config?: Partial<ShopifyConfig>
|
config?: Partial<WooCommerceConfig>
|
||||||
preview?: boolean
|
preview?: boolean
|
||||||
} & OperationOptions
|
} & OperationOptions
|
||||||
): Promise<T['data']>
|
): Promise<T['data']>
|
||||||
@@ -31,13 +32,13 @@ export default function getProductOperation({
|
|||||||
}: {
|
}: {
|
||||||
query?: string
|
query?: string
|
||||||
variables: T['variables']
|
variables: T['variables']
|
||||||
config?: Partial<ShopifyConfig>
|
config?: Partial<WooCommerceConfig>
|
||||||
preview?: boolean
|
preview?: boolean
|
||||||
}): Promise<T['data']> {
|
}): Promise<T['data']> {
|
||||||
const { fetch, locale } = commerce.getConfig(cfg)
|
const { fetch, locale } = commerce.getConfig(cfg)
|
||||||
|
|
||||||
const {
|
const {
|
||||||
data: { productByHandle },
|
data: { product },
|
||||||
} = await fetch<GetProductBySlugQuery>(
|
} = await fetch<GetProductBySlugQuery>(
|
||||||
query,
|
query,
|
||||||
{
|
{
|
||||||
@@ -53,8 +54,8 @@ export default function getProductOperation({
|
|||||||
)
|
)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...(productByHandle && {
|
...(product && {
|
||||||
product: normalizeProduct(productByHandle as ShopifyProduct),
|
product: normalizeProduct(product as SimpleProduct),
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
// export { default as getAllPages } from './get-all-pages'
|
// export { default as getAllPages } from './get-all-pages'
|
||||||
// export { default as getPage } from './get-page'
|
// export { default as getPage } from './get-page'
|
||||||
export { default as getAllProducts } from './get-all-products'
|
export { default as getAllProducts } from './get-all-products'
|
||||||
// export { default as getAllProductPaths } from './get-all-product-paths'
|
export { default as getAllProductPaths } from './get-all-product-paths'
|
||||||
// export { default as getProduct } from './get-product'
|
export { default as getProduct } from './get-product'
|
||||||
export { default as getSiteInfo } from './get-site-info'
|
export { default as getSiteInfo } from './get-site-info'
|
||||||
// export { default as login } from './login'
|
// export { default as login } from './login'
|
||||||
|
@@ -9,56 +9,21 @@ const fetchGraphqlApi: GraphQLFetcher = async (
|
|||||||
{ variables } = {},
|
{ variables } = {},
|
||||||
fetchOptions
|
fetchOptions
|
||||||
) => {
|
) => {
|
||||||
try {
|
const res = await fetch(API_URL, {
|
||||||
console.log({
|
...fetchOptions,
|
||||||
resss: {
|
method: 'POST',
|
||||||
API_URL,
|
headers: {
|
||||||
...fetchOptions,
|
...fetchOptions?.headers,
|
||||||
method: 'POST',
|
'Content-Type': 'application/json',
|
||||||
headers: {
|
},
|
||||||
...fetchOptions?.headers,
|
body: JSON.stringify({
|
||||||
'Content-Type': 'application/json',
|
query,
|
||||||
},
|
variables,
|
||||||
body: JSON.stringify({
|
}),
|
||||||
query,
|
})
|
||||||
variables,
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
const res = await fetch(API_URL, {
|
const result = await res.json()
|
||||||
...fetchOptions,
|
|
||||||
method: 'POST',
|
|
||||||
headers: {
|
|
||||||
...fetchOptions?.headers,
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
},
|
|
||||||
body: JSON.stringify({
|
|
||||||
query,
|
|
||||||
variables,
|
|
||||||
}),
|
|
||||||
})
|
|
||||||
|
|
||||||
const { data, errors, status } = await res.json()
|
return result
|
||||||
|
|
||||||
if (errors) {
|
|
||||||
console.log({ errors: errors[0].extensions })
|
|
||||||
console.log(getError(errors, status))
|
|
||||||
}
|
|
||||||
|
|
||||||
return { data, res }
|
|
||||||
} catch (err) {
|
|
||||||
console.log({ err })
|
|
||||||
console.log(
|
|
||||||
getError(
|
|
||||||
[
|
|
||||||
{
|
|
||||||
message: `${err} \n Most likely related to an unexpected output. e.g the store might be protected with password or not available.`,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
500
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
export default fetchGraphqlApi
|
export default fetchGraphqlApi
|
||||||
|
@@ -10,7 +10,7 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"generates": {
|
"generates": {
|
||||||
"./framework/woocommerce/schema.d.ts": {
|
"./framework/woocommerce/schema.ts": {
|
||||||
"plugins": ["typescript", "typescript-operations"],
|
"plugins": ["typescript", "typescript-operations"],
|
||||||
"config": {
|
"config": {
|
||||||
"scalars": {
|
"scalars": {
|
||||||
|
18785
framework/woocommerce/schema.ts
Normal file
18785
framework/woocommerce/schema.ts
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,197 +1,58 @@
|
|||||||
import type { Page } from '../types/page'
|
import type { Product, ProductImage } from '../types/product'
|
||||||
import type { Product } from '../types/product'
|
|
||||||
import type { Cart, LineItem } from '../types/cart'
|
|
||||||
import type { Category } from '../types/site'
|
|
||||||
|
|
||||||
import {
|
import { SimpleProduct, ProductToMediaItemConnection } from '../schema'
|
||||||
Product as ShopifyProduct,
|
|
||||||
Checkout,
|
|
||||||
CheckoutLineItemEdge,
|
|
||||||
SelectedOption,
|
|
||||||
ImageConnection,
|
|
||||||
ProductVariantConnection,
|
|
||||||
MoneyV2,
|
|
||||||
ProductOption,
|
|
||||||
Page as ShopifyPage,
|
|
||||||
PageEdge,
|
|
||||||
Collection,
|
|
||||||
} from '../schema'
|
|
||||||
import { colorMap } from '@lib/colors'
|
|
||||||
|
|
||||||
const money = ({ amount, currencyCode }: MoneyV2) => {
|
const normalizeProductImages = ({
|
||||||
return {
|
edges,
|
||||||
value: +amount,
|
}: ProductToMediaItemConnection): ProductImage[] => {
|
||||||
currencyCode,
|
const edges_ =
|
||||||
}
|
edges
|
||||||
}
|
?.filter((edge) => edge?.node)
|
||||||
|
.map(({ node }) => {
|
||||||
const normalizeProductOption = ({
|
return {
|
||||||
id,
|
url: node.sourceUrl,
|
||||||
name: displayName,
|
alt: node.altText ?? node.title,
|
||||||
values,
|
|
||||||
}: ProductOption) => {
|
|
||||||
return {
|
|
||||||
__typename: 'MultipleChoiceOption',
|
|
||||||
id,
|
|
||||||
displayName: displayName.toLowerCase(),
|
|
||||||
values: values.map((value) => {
|
|
||||||
let output: any = {
|
|
||||||
label: value,
|
|
||||||
}
|
|
||||||
if (displayName.match(/colou?r/gi)) {
|
|
||||||
const mapedColor = colorMap[value.toLowerCase().replace(/ /g, '')]
|
|
||||||
if (mapedColor) {
|
|
||||||
output = {
|
|
||||||
...output,
|
|
||||||
hexColors: [mapedColor],
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}) ?? []
|
||||||
return output
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const normalizeProductImages = ({ edges }: ImageConnection) =>
|
return edges_
|
||||||
edges?.map(({ node: { originalSrc: url, ...rest } }) => ({
|
|
||||||
url,
|
|
||||||
...rest,
|
|
||||||
}))
|
|
||||||
|
|
||||||
const normalizeProductVariants = ({ edges }: ProductVariantConnection) => {
|
|
||||||
return edges?.map(
|
|
||||||
({
|
|
||||||
node: {
|
|
||||||
id,
|
|
||||||
selectedOptions,
|
|
||||||
sku,
|
|
||||||
title,
|
|
||||||
priceV2,
|
|
||||||
compareAtPriceV2,
|
|
||||||
requiresShipping,
|
|
||||||
availableForSale,
|
|
||||||
},
|
|
||||||
}) => {
|
|
||||||
return {
|
|
||||||
id,
|
|
||||||
name: title,
|
|
||||||
sku: sku ?? id,
|
|
||||||
price: +priceV2.amount,
|
|
||||||
listPrice: +compareAtPriceV2?.amount,
|
|
||||||
requiresShipping,
|
|
||||||
availableForSale,
|
|
||||||
options: selectedOptions.map(({ name, value }: SelectedOption) => {
|
|
||||||
const options = normalizeProductOption({
|
|
||||||
id,
|
|
||||||
name,
|
|
||||||
values: [value],
|
|
||||||
})
|
|
||||||
|
|
||||||
return options
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function normalizeProduct({
|
export function normalizeProduct({
|
||||||
id,
|
id,
|
||||||
title: name,
|
name,
|
||||||
vendor,
|
sku,
|
||||||
images,
|
|
||||||
variants,
|
|
||||||
description,
|
description,
|
||||||
descriptionHtml,
|
shortDescription,
|
||||||
handle,
|
slug,
|
||||||
priceRange,
|
image,
|
||||||
options,
|
galleryImages,
|
||||||
metafields,
|
price,
|
||||||
...rest
|
...rest
|
||||||
}: ShopifyProduct): Product {
|
}: SimpleProduct): Product {
|
||||||
return {
|
const images: ProductToMediaItemConnection = galleryImages ?? { edges: [] }
|
||||||
|
|
||||||
|
if (image) {
|
||||||
|
images.edges?.push({ node: image })
|
||||||
|
}
|
||||||
|
|
||||||
|
const product = {
|
||||||
id,
|
id,
|
||||||
name,
|
options: [],
|
||||||
vendor,
|
variants: [],
|
||||||
path: `/${handle}`,
|
name: name ?? id,
|
||||||
slug: handle?.replace(/^\/+|\/+$/g, ''),
|
sku: sku ?? 'sku',
|
||||||
price: money(priceRange?.minVariantPrice),
|
path: slug ?? id,
|
||||||
|
slug: slug?.replace(/^\/+|\/+$/g, ''),
|
||||||
images: normalizeProductImages(images),
|
images: normalizeProductImages(images),
|
||||||
variants: variants ? normalizeProductVariants(variants) : [],
|
price: { value: 0, currencyCode: 'USD' },
|
||||||
options: options
|
description: description ?? shortDescription ?? '',
|
||||||
? options
|
descriptionHtml: description ?? shortDescription ?? '',
|
||||||
.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
|
|
||||||
.map((o) => normalizeProductOption(o))
|
|
||||||
: [],
|
|
||||||
...(description && { description }),
|
|
||||||
...(descriptionHtml && { descriptionHtml }),
|
|
||||||
...rest,
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
export function normalizeCart(checkout: Checkout): Cart {
|
if (price) {
|
||||||
return {
|
product.price.value = Number(price.substring(1))
|
||||||
id: checkout.id,
|
|
||||||
url: checkout.webUrl,
|
|
||||||
customerId: '',
|
|
||||||
email: '',
|
|
||||||
createdAt: checkout.createdAt,
|
|
||||||
currency: {
|
|
||||||
code: checkout.totalPriceV2?.currencyCode,
|
|
||||||
},
|
|
||||||
taxesIncluded: checkout.taxesIncluded,
|
|
||||||
lineItems: checkout.lineItems?.edges.map(normalizeLineItem),
|
|
||||||
lineItemsSubtotalPrice: +checkout.subtotalPriceV2?.amount,
|
|
||||||
subtotalPrice: +checkout.subtotalPriceV2?.amount,
|
|
||||||
totalPrice: checkout.totalPriceV2?.amount,
|
|
||||||
discounts: [],
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return product
|
||||||
}
|
}
|
||||||
|
|
||||||
function normalizeLineItem({
|
|
||||||
node: { id, title, variant, quantity },
|
|
||||||
}: CheckoutLineItemEdge): LineItem {
|
|
||||||
return {
|
|
||||||
id,
|
|
||||||
variantId: String(variant?.id),
|
|
||||||
productId: String(variant?.id),
|
|
||||||
name: `${title}`,
|
|
||||||
quantity,
|
|
||||||
variant: {
|
|
||||||
id: String(variant?.id),
|
|
||||||
sku: variant?.sku ?? '',
|
|
||||||
name: variant?.title!,
|
|
||||||
image: {
|
|
||||||
url: variant?.image?.originalSrc || '/product-img-placeholder.svg',
|
|
||||||
},
|
|
||||||
requiresShipping: variant?.requiresShipping ?? false,
|
|
||||||
price: variant?.priceV2?.amount,
|
|
||||||
listPrice: variant?.compareAtPriceV2?.amount,
|
|
||||||
},
|
|
||||||
path: String(variant?.product?.handle),
|
|
||||||
discounts: [],
|
|
||||||
options: variant?.title == 'Default Title' ? [] : variant?.selectedOptions,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const normalizePage = (
|
|
||||||
{ title: name, handle, ...page }: ShopifyPage,
|
|
||||||
locale: string = 'en-US'
|
|
||||||
): Page => ({
|
|
||||||
...page,
|
|
||||||
url: `/${locale}/${handle}`,
|
|
||||||
name,
|
|
||||||
})
|
|
||||||
|
|
||||||
export const normalizePages = (edges: PageEdge[], locale?: string): Page[] =>
|
|
||||||
edges?.map((edge) => normalizePage(edge.node, locale))
|
|
||||||
|
|
||||||
export const normalizeCategory = ({
|
|
||||||
title: name,
|
|
||||||
handle,
|
|
||||||
id,
|
|
||||||
}: Collection): Category => ({
|
|
||||||
id,
|
|
||||||
name,
|
|
||||||
slug: handle,
|
|
||||||
path: `/${handle}`,
|
|
||||||
})
|
|
||||||
|
@@ -0,0 +1,17 @@
|
|||||||
|
const getAllProductsPathsQuery = /* GraphQL */ `
|
||||||
|
query getAllProductPaths($first: Int = 250, $cursor: String) {
|
||||||
|
products(first: $first, after: $cursor) {
|
||||||
|
pageInfo {
|
||||||
|
hasNextPage
|
||||||
|
hasPreviousPage
|
||||||
|
}
|
||||||
|
edges {
|
||||||
|
node {
|
||||||
|
slug
|
||||||
|
}
|
||||||
|
cursor
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
export default getAllProductsPathsQuery
|
@@ -9,9 +9,43 @@ const getAllProductsQuery = /* GraphQL */ `
|
|||||||
node {
|
node {
|
||||||
id
|
id
|
||||||
name
|
name
|
||||||
|
sku
|
||||||
|
galleryImages {
|
||||||
|
edges {
|
||||||
|
node {
|
||||||
|
id
|
||||||
|
srcSet
|
||||||
|
title
|
||||||
|
sourceUrl
|
||||||
|
mediaItemUrl
|
||||||
|
altText
|
||||||
|
sizes
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
image {
|
image {
|
||||||
uri
|
id
|
||||||
|
srcSet
|
||||||
|
title
|
||||||
|
sourceUrl
|
||||||
|
mediaItemUrl
|
||||||
altText
|
altText
|
||||||
|
sizes
|
||||||
|
}
|
||||||
|
description
|
||||||
|
link
|
||||||
|
shortDescription
|
||||||
|
slug
|
||||||
|
... on SimpleProduct {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
price
|
||||||
|
content
|
||||||
|
uri
|
||||||
|
slug
|
||||||
|
shortDescription
|
||||||
|
regularPrice
|
||||||
|
salePrice
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
48
framework/woocommerce/wp/queries/get-product-query.ts
Normal file
48
framework/woocommerce/wp/queries/get-product-query.ts
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
const getProductQuery = /* GraphQL */ `
|
||||||
|
query getProductBySlug($slug: ID!) {
|
||||||
|
product(id: $slug, idType: SLUG) {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
sku
|
||||||
|
galleryImages {
|
||||||
|
edges {
|
||||||
|
node {
|
||||||
|
id
|
||||||
|
srcSet
|
||||||
|
title
|
||||||
|
sourceUrl
|
||||||
|
mediaItemUrl
|
||||||
|
altText
|
||||||
|
sizes
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
image {
|
||||||
|
id
|
||||||
|
srcSet
|
||||||
|
title
|
||||||
|
sourceUrl
|
||||||
|
mediaItemUrl
|
||||||
|
altText
|
||||||
|
sizes
|
||||||
|
}
|
||||||
|
description
|
||||||
|
link
|
||||||
|
shortDescription
|
||||||
|
slug
|
||||||
|
... on SimpleProduct {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
price
|
||||||
|
content
|
||||||
|
uri
|
||||||
|
slug
|
||||||
|
shortDescription
|
||||||
|
regularPrice
|
||||||
|
salePrice
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
export default getProductQuery
|
@@ -1,72 +0,0 @@
|
|||||||
const getProductQuery = /* GraphQL */ `
|
|
||||||
query getProductBySlug($slug: String!) {
|
|
||||||
productByHandle(handle: $slug) {
|
|
||||||
id
|
|
||||||
handle
|
|
||||||
availableForSale
|
|
||||||
title
|
|
||||||
productType
|
|
||||||
vendor
|
|
||||||
description
|
|
||||||
descriptionHtml
|
|
||||||
options {
|
|
||||||
id
|
|
||||||
name
|
|
||||||
values
|
|
||||||
}
|
|
||||||
priceRange {
|
|
||||||
maxVariantPrice {
|
|
||||||
amount
|
|
||||||
currencyCode
|
|
||||||
}
|
|
||||||
minVariantPrice {
|
|
||||||
amount
|
|
||||||
currencyCode
|
|
||||||
}
|
|
||||||
}
|
|
||||||
variants(first: 250) {
|
|
||||||
pageInfo {
|
|
||||||
hasNextPage
|
|
||||||
hasPreviousPage
|
|
||||||
}
|
|
||||||
edges {
|
|
||||||
node {
|
|
||||||
id
|
|
||||||
title
|
|
||||||
sku
|
|
||||||
availableForSale
|
|
||||||
requiresShipping
|
|
||||||
selectedOptions {
|
|
||||||
name
|
|
||||||
value
|
|
||||||
}
|
|
||||||
priceV2 {
|
|
||||||
amount
|
|
||||||
currencyCode
|
|
||||||
}
|
|
||||||
compareAtPriceV2 {
|
|
||||||
amount
|
|
||||||
currencyCode
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
images(first: 250) {
|
|
||||||
pageInfo {
|
|
||||||
hasNextPage
|
|
||||||
hasPreviousPage
|
|
||||||
}
|
|
||||||
edges {
|
|
||||||
node {
|
|
||||||
originalSrc
|
|
||||||
altText
|
|
||||||
width
|
|
||||||
height
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`
|
|
||||||
|
|
||||||
export default getProductQuery
|
|
@@ -10,6 +10,7 @@ const isShopify = provider === 'shopify'
|
|||||||
const isSaleor = provider === 'saleor'
|
const isSaleor = provider === 'saleor'
|
||||||
const isSwell = provider === 'swell'
|
const isSwell = provider === 'swell'
|
||||||
const isVendure = provider === 'vendure'
|
const isVendure = provider === 'vendure'
|
||||||
|
// const isWooCommerce = provider === 'woocommerce'
|
||||||
|
|
||||||
module.exports = withCommerceConfig({
|
module.exports = withCommerceConfig({
|
||||||
commerce,
|
commerce,
|
||||||
@@ -17,6 +18,9 @@ module.exports = withCommerceConfig({
|
|||||||
locales: ['en-US', 'es'],
|
locales: ['en-US', 'es'],
|
||||||
defaultLocale: 'en-US',
|
defaultLocale: 'en-US',
|
||||||
},
|
},
|
||||||
|
images: {
|
||||||
|
domains: [process.env.NEXT_PUBLIC_WOOCOMMERCE_IMAGES_DOMAIN],
|
||||||
|
},
|
||||||
rewrites() {
|
rewrites() {
|
||||||
return [
|
return [
|
||||||
(isBC || isShopify || isSwell || isVendure) && {
|
(isBC || isShopify || isSwell || isVendure) && {
|
||||||
|
@@ -3,7 +3,7 @@ import commerce from '@lib/api/commerce'
|
|||||||
import { Layout } from '@components/common'
|
import { Layout } from '@components/common'
|
||||||
import { ProductCard } from '@components/product'
|
import { ProductCard } from '@components/product'
|
||||||
import { Grid, Marquee, Hero } from '@components/ui'
|
import { Grid, Marquee, Hero } from '@components/ui'
|
||||||
// import HomeAllProductsGrid from '@components/common/HomeAllProductsGrid'
|
import HomeAllProductsGrid from '@components/common/HomeAllProductsGrid'
|
||||||
import type { GetStaticPropsContext, InferGetStaticPropsType } from 'next'
|
import type { GetStaticPropsContext, InferGetStaticPropsType } from 'next'
|
||||||
|
|
||||||
export async function getStaticProps({
|
export async function getStaticProps({
|
||||||
@@ -13,7 +13,7 @@ export async function getStaticProps({
|
|||||||
}: GetStaticPropsContext) {
|
}: GetStaticPropsContext) {
|
||||||
const config = { locale, locales }
|
const config = { locale, locales }
|
||||||
const productsPromise = await commerce.getAllProducts({
|
const productsPromise = await commerce.getAllProducts({
|
||||||
variables: { first: 6 },
|
variables: { first: 12 },
|
||||||
config,
|
config,
|
||||||
preview,
|
preview,
|
||||||
// // Saleor provider only
|
// // Saleor provider only
|
||||||
@@ -21,22 +21,13 @@ export async function getStaticProps({
|
|||||||
})
|
})
|
||||||
// // const pagesPromise = commerce.getAllPages({ config, preview })
|
// // const pagesPromise = commerce.getAllPages({ config, preview })
|
||||||
// // const siteInfoPromise = commerce.getSiteInfo({ config, preview })
|
// // const siteInfoPromise = commerce.getSiteInfo({ config, preview })
|
||||||
// // const { products } = await productsPromise
|
const { products } = await productsPromise
|
||||||
// // const { pages } = await pagesPromise
|
// // const { pages } = await pagesPromise
|
||||||
// // const { categories, brands } = await siteInfoPromise
|
// // const { categories, brands } = await siteInfoPromise
|
||||||
console.log({
|
|
||||||
query: {
|
|
||||||
variables: { first: 6 },
|
|
||||||
config,
|
|
||||||
preview,
|
|
||||||
// // Saleor provider only
|
|
||||||
// ...({ featured: true } as any),
|
|
||||||
},
|
|
||||||
productsPromise,
|
|
||||||
})
|
|
||||||
return {
|
return {
|
||||||
props: {
|
props: {
|
||||||
products: [],
|
products,
|
||||||
// categories,
|
// categories,
|
||||||
// brands,
|
// brands,
|
||||||
// pages,
|
// pages,
|
||||||
@@ -82,17 +73,17 @@ export default function Home({
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</Grid>
|
</Grid>*/}
|
||||||
<Marquee>
|
<Marquee>
|
||||||
{products.slice(3).map((product: any, i: number) => (
|
{products.slice(3).map((product: any, i: number) => (
|
||||||
<ProductCard key={product.id} product={product} variant="slim" />
|
<ProductCard key={product.id} product={product} variant="slim" />
|
||||||
))}
|
))}
|
||||||
</Marquee> */}
|
</Marquee>
|
||||||
{/* <HomeAllProductsGrid
|
<HomeAllProductsGrid
|
||||||
newestProducts={products}
|
products={products}
|
||||||
categories={categories}
|
categories={[]} //{categories}
|
||||||
brands={brands}
|
brands={[]} //{brands}
|
||||||
/> */}
|
/>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@@ -15,23 +15,24 @@ export async function getStaticProps({
|
|||||||
preview,
|
preview,
|
||||||
}: GetStaticPropsContext<{ slug: string }>) {
|
}: GetStaticPropsContext<{ slug: string }>) {
|
||||||
const config = { locale, locales }
|
const config = { locale, locales }
|
||||||
const pagesPromise = commerce.getAllPages({ config, preview })
|
// const pagesPromise = commerce.getAllPages({ config, preview })
|
||||||
const siteInfoPromise = commerce.getSiteInfo({ config, preview })
|
// const siteInfoPromise = commerce.getSiteInfo({ config, preview })
|
||||||
|
|
||||||
const productPromise = commerce.getProduct({
|
const productPromise = commerce.getProduct({
|
||||||
variables: { slug: params!.slug },
|
variables: { slug: params!.slug },
|
||||||
config,
|
config,
|
||||||
preview,
|
preview,
|
||||||
})
|
})
|
||||||
|
|
||||||
const allProductsPromise = await commerce.getAllProducts({
|
// const allProductsPromise = await commerce.getAllProducts({
|
||||||
variables: { first: 4 },
|
// variables: { first: 4 },
|
||||||
config,
|
// config,
|
||||||
preview,
|
// preview,
|
||||||
})
|
// })
|
||||||
const { pages } = await pagesPromise
|
// const { pages } = await pagesPromise
|
||||||
const { categories } = await siteInfoPromise
|
// const { categories } = await siteInfoPromise
|
||||||
const { product } = await productPromise
|
const { product } = await productPromise
|
||||||
const { products: relatedProducts } = await allProductsPromise
|
// const { products: relatedProducts } = await allProductsPromise
|
||||||
|
|
||||||
if (!product) {
|
if (!product) {
|
||||||
throw new Error(`Product with slug '${params!.slug}' not found`)
|
throw new Error(`Product with slug '${params!.slug}' not found`)
|
||||||
@@ -39,10 +40,10 @@ export async function getStaticProps({
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
props: {
|
props: {
|
||||||
pages,
|
// pages,
|
||||||
product,
|
product,
|
||||||
relatedProducts,
|
relatedProducts: [],
|
||||||
categories,
|
// categories,
|
||||||
},
|
},
|
||||||
revalidate: 200,
|
revalidate: 200,
|
||||||
}
|
}
|
||||||
@@ -67,7 +68,7 @@ export async function getStaticPaths({ locales }: GetStaticPathsContext) {
|
|||||||
|
|
||||||
export default function Slug({
|
export default function Slug({
|
||||||
product,
|
product,
|
||||||
relatedProducts,
|
relatedProducts = [],
|
||||||
}: InferGetStaticPropsType<typeof getStaticProps>) {
|
}: InferGetStaticPropsType<typeof getStaticProps>) {
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user