diff --git a/lib/bigcommerce/api/fragments/category-tree.ts b/lib/bigcommerce/api/fragments/category-tree.ts new file mode 100644 index 000000000..e26f17195 --- /dev/null +++ b/lib/bigcommerce/api/fragments/category-tree.ts @@ -0,0 +1,9 @@ +export const categoryTreeItemFragment = /* GraphQL */ ` + fragment categoryTreeItem on CategoryTreeItem { + entityId + name + path + description + productCount + } +` diff --git a/lib/bigcommerce/api/fragments/product.ts b/lib/bigcommerce/api/fragments/product.ts index 94753c948..501345cba 100644 --- a/lib/bigcommerce/api/fragments/product.ts +++ b/lib/bigcommerce/api/fragments/product.ts @@ -4,6 +4,9 @@ export const responsiveImageFragment = /* GraphQL */ ` urlMedium: url(width: $imgMediumWidth, height: $imgMediumHeight) urlLarge: url(width: $imgLargeWidth, height: $imgLargeHeight) urlXL: url(width: $imgXLWidth, height: $imgXLHeight) + urlOriginal + altText + isDefault } ` diff --git a/lib/bigcommerce/api/operations/get-site-info.ts b/lib/bigcommerce/api/operations/get-site-info.ts new file mode 100644 index 000000000..85929e9a0 --- /dev/null +++ b/lib/bigcommerce/api/operations/get-site-info.ts @@ -0,0 +1,68 @@ +import type { + GetSiteInfoQuery, + GetSiteInfoQueryVariables, +} from 'lib/bigcommerce/schema' +import type { RecursivePartial, RecursiveRequired } from '../utils/types' +import { BigcommerceConfig, getConfig } from '..' +import { categoryTreeItemFragment } from '../fragments/category-tree' + +// Get 3 levels of categories +export const getSiteInfoQuery = /* GraphQL */ ` + query getSiteInfo { + site { + categoryTree { + ...categoryTreeItem + children { + ...categoryTreeItem + children { + ...categoryTreeItem + } + } + } + } + } + ${categoryTreeItemFragment} +` + +export type CategoriesTree = NonNullable< + GetSiteInfoQuery['site']['categoryTree'] +> + +export type GetSiteInfoResult< + T extends { categories: any[] } = { categories: CategoriesTree } +> = T + +async function getSiteInfo(opts?: { + variables?: GetSiteInfoQueryVariables + config?: BigcommerceConfig +}): Promise + +async function getSiteInfo(opts: { + query: string + variables?: V + config?: BigcommerceConfig +}): Promise> + +async function getSiteInfo({ + query = getSiteInfoQuery, + variables, + config, +}: { + query?: string + variables?: GetSiteInfoQueryVariables + config?: BigcommerceConfig +} = {}): Promise { + config = getConfig(config) + // RecursivePartial forces the method to check for every prop in the data, which is + // required in case there's a custom `query` + const data = await config.fetch>(query, { + variables, + }) + const categories = data.site?.categoryTree + + return { + categories: (categories as RecursiveRequired) ?? [], + } +} + +export default getSiteInfo diff --git a/lib/bigcommerce/schema.d.ts b/lib/bigcommerce/schema.d.ts index e281cdaea..5741f32cd 100644 --- a/lib/bigcommerce/schema.d.ts +++ b/lib/bigcommerce/schema.d.ts @@ -121,6 +121,33 @@ export type BrandEdge = { cursor: Scalars['String'] } +/** Breadcrumb */ +export type Breadcrumb = { + __typename?: 'Breadcrumb' + /** Category id. */ + entityId: Scalars['Int'] + /** Name of the category. */ + name: Scalars['String'] +} + +/** A connection to a list of items. */ +export type BreadcrumbConnection = { + __typename?: 'BreadcrumbConnection' + /** Information to aid in pagination. */ + pageInfo: PageInfo + /** A list of edges. */ + edges?: Maybe>> +} + +/** An edge in a connection. */ +export type BreadcrumbEdge = { + __typename?: 'BreadcrumbEdge' + /** The item at the end of the edge. */ + node: Breadcrumb + /** A cursor for use in pagination. */ + cursor: Scalars['String'] +} + /** Bulk pricing tier that sets a fixed price for the product or variant. */ export type BulkPricingFixedPriceDiscount = BulkPricingTier & { __typename?: 'BulkPricingFixedPriceDiscount' @@ -197,11 +224,22 @@ export type Category = Node & { defaultImage?: Maybe /** Category description. */ description: Scalars['String'] + /** Category breadcrumbs. */ + breadcrumbs: BreadcrumbConnection products: ProductConnection /** Metafield data related to a category. */ metafields: MetafieldConnection } +/** Category */ +export type CategoryBreadcrumbsArgs = { + depth: Scalars['Int'] + before?: Maybe + after?: Maybe + first?: Maybe + last?: Maybe +} + /** Category */ export type CategoryProductsArgs = { before?: Maybe @@ -408,6 +446,8 @@ export type Image = { __typename?: 'Image' /** Absolute path to image using store CDN. */ url: Scalars['String'] + /** Absolute path to original image using store CDN. */ + urlOriginal: Scalars['String'] /** Text description of an image that can be used for SEO and/or accessibility purposes. */ altText: Scalars['String'] /** Indicates whether this is the primary image. */ @@ -1613,12 +1653,22 @@ export enum CurrencyCode { Zwr = 'ZWR', } -export type ResponsiveImageFragment = { __typename?: 'Image' } & { - urlSmall: Image['url'] - urlMedium: Image['url'] - urlLarge: Image['url'] - urlXL: Image['url'] -} +export type CategoryTreeItemFragment = { + __typename?: 'CategoryTreeItem' +} & Pick< + CategoryTreeItem, + 'entityId' | 'name' | 'path' | 'description' | 'productCount' +> + +export type ResponsiveImageFragment = { __typename?: 'Image' } & Pick< + Image, + 'urlOriginal' | 'altText' | 'isDefault' +> & { + urlSmall: Image['url'] + urlMedium: Image['url'] + urlLarge: Image['url'] + urlXL: Image['url'] + } export type ProductInfoFragment = { __typename?: 'Product' } & Pick< Product, @@ -1764,3 +1814,21 @@ export type GetProductQuery = { __typename?: 'Query' } & { } } } + +export type GetSiteInfoQueryVariables = Exact<{ [key: string]: never }> + +export type GetSiteInfoQuery = { __typename?: 'Query' } & { + site: { __typename?: 'Site' } & { + categoryTree: Array< + { __typename?: 'CategoryTreeItem' } & { + children: Array< + { __typename?: 'CategoryTreeItem' } & { + children: Array< + { __typename?: 'CategoryTreeItem' } & CategoryTreeItemFragment + > + } & CategoryTreeItemFragment + > + } & CategoryTreeItemFragment + > + } +} diff --git a/lib/bigcommerce/schema.graphql b/lib/bigcommerce/schema.graphql index 72a087b48..79de347fe 100644 --- a/lib/bigcommerce/schema.graphql +++ b/lib/bigcommerce/schema.graphql @@ -151,6 +151,51 @@ type BrandEdge { cursor: String! } +""" +Breadcrumb +""" +type Breadcrumb { + """ + Category id. + """ + entityId: Int! + + """ + Name of the category. + """ + name: String! +} + +""" +A connection to a list of items. +""" +type BreadcrumbConnection { + """ + Information to aid in pagination. + """ + pageInfo: PageInfo! + + """ + A list of edges. + """ + edges: [BreadcrumbEdge] +} + +""" +An edge in a connection. +""" +type BreadcrumbEdge { + """ + The item at the end of the edge. + """ + node: Breadcrumb! + + """ + A cursor for use in pagination. + """ + cursor: String! +} + """ Bulk pricing tier that sets a fixed price for the product or variant. """ @@ -299,6 +344,17 @@ type Category implements Node { Category description. """ description: String! + + """ + Category breadcrumbs. + """ + breadcrumbs( + depth: Int! + before: String + after: String + first: Int + last: Int + ): BreadcrumbConnection! products( before: String after: String @@ -667,6 +723,11 @@ type Image { """ url(width: Int!, height: Int): String! + """ + Absolute path to original image using store CDN. + """ + urlOriginal: String! + """ Text description of an image that can be used for SEO and/or accessibility purposes. """ diff --git a/pages/index.tsx b/pages/index.tsx index 8fbbd97aa..4eb0b0706 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -3,17 +3,20 @@ import getAllProducts from '@lib/bigcommerce/api/operations/get-all-products' import { Layout } from '@components/core' import { Grid, Marquee, Hero } from '@components/ui' import { ProductCard } from '@components/product' +import getSiteInfo from '@lib/bigcommerce/api/operations/get-site-info' export async function getStaticProps({ preview }: GetStaticPropsContext) { const { products } = await getAllProducts() + const { categories } = await getSiteInfo() return { - props: { products }, + props: { products, categories }, } } export default function Home({ products, + categories, }: InferGetStaticPropsType) { return ( <> @@ -38,9 +41,18 @@ export default function Home({ variant="secondary" wrapper={(p: any) => } /> -
-
- ALL CATEGORIES ACCESSORIES BAGS CLOTHING SHOES ALL DESIGNERS 032c 1017 +
+
+
    +
  • +

    All Categories

    +
  • + {categories.map((cat) => ( +
  • + {cat.name} +
  • + ))} +