Fixed page query, Changed use-search GraphQl query

This commit is contained in:
cond0r 2021-02-26 10:57:05 +02:00
parent 590bff576c
commit 3236de1b4c
11 changed files with 126 additions and 84 deletions

View File

@ -43,6 +43,7 @@ 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,

View File

@ -25,8 +25,7 @@ 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 = 'en-US' } = 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(

View File

@ -2,21 +2,21 @@ import { getConfig, ShopifyConfig } from '../api'
import getPageQuery from '../utils/queries/get-page-query' import getPageQuery from '../utils/queries/get-page-query'
import { Page } from './get-all-pages' import { Page } from './get-all-pages'
type PageVariables = { type Variables = {
id: string id: string
} }
export type GetPageResult<T extends { page?: any } = { page?: Page }> = T export type GetPageResult<T extends { page?: any } = { page?: Page }> = T
const getPage = async (options: { const getPage = async (options: {
variables: PageVariables variables: Variables
config: ShopifyConfig config: ShopifyConfig
preview?: boolean preview?: boolean
}): Promise<GetPageResult> => { }): Promise<GetPageResult> => {
let { config, variables } = options ?? {} let { config, variables } = options ?? {}
config = getConfig(config) config = getConfig(config)
const { locale = 'en-US' } = config const { locale } = config
const { data } = await config.fetch(getPageQuery, { const { data } = await config.fetch(getPageQuery, {
variables, variables,

View File

@ -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
} }
@ -33,16 +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) =>
// TODO: Fix this product type normalizeProduct(node as any)
normalizeProduct(p as any)
), ),
found: !!edges?.length, found: !!edges?.length,
} }

View File

@ -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}`,
}) })

View File

@ -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),
} }
} }

View File

@ -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

View File

@ -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) => {
let output: any = {
label: value, label: value,
hexColors: displayName === 'Color' ? [value] : null, }
})), if (displayName === 'Color') {
...rest, output = {
...output,
hexColors: [value],
}
}
return output
}),
} }
} }
@ -41,8 +51,16 @@ const normalizeProductImages = ({ edges }: ImageConnection) =>
})) }))
const normalizeProductVariants = ({ edges }: ProductVariantConnection) => { const normalizeProductVariants = ({ edges }: ProductVariantConnection) => {
return edges?.map(({ node: { id, selectedOptions } }) => ({ return edges?.map(
({
node: { id, selectedOptions, sku, title, priceV2, compareAtPriceV2 },
}) => ({
id, id,
name: title,
sku: sku ?? id,
price: +priceV2.amount,
listPrice: +compareAtPriceV2?.amount,
requiresShipping: true,
options: selectedOptions.map(({ name, value }: SelectedOption) => options: selectedOptions.map(({ name, value }: SelectedOption) =>
normalizeProductOption({ normalizeProductOption({
id, id,
@ -50,10 +68,11 @@ const normalizeProductVariants = ({ edges }: ProductVariantConnection) => {
values: [value], 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: [],
} }

View File

@ -1,15 +1,9 @@
export const productsFragment = ` export const productConnection = `
products( pageInfo {
first: $first
sortKey: $sortKey
reverse: $reverse
query: $query
) {
pageInfo {
hasNextPage hasNextPage
hasPreviousPage hasPreviousPage
} }
edges { edges {
node { node {
id id
title title
@ -37,7 +31,16 @@ products(
} }
} }
} }
} }`
export const productsFragment = `
products(
first: $first
sortKey: $sortKey
reverse: $reverse
query: $query
) {
${productConnection}
} }
` `

View File

@ -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}
}
}
} }
} }
` `

View File

@ -32,6 +32,7 @@ const getProductQuery = /* GraphQL */ `
node { node {
id id
title title
sku
selectedOptions { selectedOptions {
name name
value value