Skip to content

Commit

Permalink
Added products paths to getStaticPaths
Browse files Browse the repository at this point in the history
  • Loading branch information
lfades committed Oct 2, 2020
1 parent ca24a53 commit 390b2c3
Show file tree
Hide file tree
Showing 4 changed files with 102 additions and 25 deletions.
54 changes: 54 additions & 0 deletions lib/bigcommerce/api/operations/get-all-product-paths.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import type { GetAllProductPathsQuery } from 'lib/bigcommerce/schema';
import type { RecursivePartial, RecursiveRequired } from '../utils/types';
import { BigcommerceConfig, getConfig } from '..';

export const getAllProductPathsQuery = /* GraphQL */ `
query getAllProductPaths {
site {
products {
edges {
node {
path
}
}
}
}
}
`;

export interface GetAllProductPathsResult<T> {
products: T extends GetAllProductPathsQuery
? NonNullable<T['site']['products']['edges']>
: unknown;
}

async function getAllProductPaths(opts?: {
query?: string;
config?: BigcommerceConfig;
}): Promise<GetAllProductPathsResult<GetAllProductPathsQuery>>;

async function getAllProductPaths<T, V = any>(opts: {
query: string;
config?: BigcommerceConfig;
}): Promise<GetAllProductPathsResult<T>>;

async function getAllProductPaths({
query = getAllProductPathsQuery,
config = getConfig(),
}: {
query?: string;
config?: BigcommerceConfig;
} = {}): Promise<GetAllProductPathsResult<GetAllProductPathsQuery>> {
// 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<RecursivePartial<GetAllProductPathsQuery>>(
query
);
const products = data.site?.products?.edges;

return {
products: (products as RecursiveRequired<typeof products>) ?? [],
};
}

export default getAllProductPaths;
16 changes: 6 additions & 10 deletions lib/bigcommerce/api/operations/get-product.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,11 @@ import type {
} from 'lib/bigcommerce/schema';
import type { RecursivePartial, RecursiveRequired } from '../utils/types';
import { productInfoFragment } from '../fragments/product';
import {
BigcommerceConfig,
getConfig,
Images,
ProductImageVariables,
} from '..';
import { BigcommerceConfig, getConfig, Images } from '..';

export const getProductQuery = /* GraphQL */ `
query getProduct(
$slug: String!
$path: String!
$imgSmallWidth: Int = 320
$imgSmallHeight: Int
$imgMediumWidth: Int = 640
Expand All @@ -24,7 +19,7 @@ export const getProductQuery = /* GraphQL */ `
$imgXLHeight: Int
) {
site {
route(path: $slug) {
route(path: $path) {
node {
__typename
... on Product {
Expand All @@ -45,7 +40,7 @@ export interface GetProductResult<T> {
}

export type ProductVariables = Images &
Omit<GetProductQueryVariables, keyof ProductImageVariables>;
({ path: string; slug?: never } | { path?: never; slug: string });

async function getProduct(opts: {
query?: string;
Expand All @@ -61,7 +56,7 @@ async function getProduct<T, V = any>(opts: {

async function getProduct({
query = getProductQuery,
variables: vars,
variables: { slug, ...vars },
config = getConfig(),
}: {
query?: string;
Expand All @@ -71,6 +66,7 @@ async function getProduct({
const variables: GetProductQueryVariables = {
...config.imageVariables,
...vars,
path: slug ? `/${slug}/` : vars.path!,
};
const data = await config.fetch<RecursivePartial<GetProductQuery>>(query, {
variables,
Expand Down
22 changes: 21 additions & 1 deletion lib/bigcommerce/schema.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1713,6 +1713,26 @@ export type ProductInfoFragment = (
) }
);

export type GetAllProductPathsQueryVariables = Exact<{ [key: string]: never; }>;


export type GetAllProductPathsQuery = (
{ __typename?: 'Query' }
& { site: (
{ __typename?: 'Site' }
& { products: (
{ __typename?: 'ProductConnection' }
& { edges?: Maybe<Array<Maybe<(
{ __typename?: 'ProductEdge' }
& { node: (
{ __typename?: 'Product' }
& Pick<Product, 'path'>
) }
)>>> }
) }
) }
);

export type GetAllProductsQueryVariables = Exact<{
first?: Maybe<Scalars['Int']>;
imgSmallWidth?: Maybe<Scalars['Int']>;
Expand Down Expand Up @@ -1748,7 +1768,7 @@ export type GetAllProductsQuery = (
);

export type GetProductQueryVariables = Exact<{
slug: Scalars['String'];
path: Scalars['String'];
imgSmallWidth?: Maybe<Scalars['Int']>;
imgSmallHeight?: Maybe<Scalars['Int']>;
imgMediumWidth?: Maybe<Scalars['Int']>;
Expand Down
35 changes: 21 additions & 14 deletions pages/product/[slug].tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
import { GetStaticPropsContext, InferGetStaticPropsType } from "next";
import { useRouter } from "next/router";
import getProduct from "lib/bigcommerce/api/operations/get-product";
import { Layout } from "@components/core";
import { ProductView } from "@components/product";
import { GetStaticPropsContext, InferGetStaticPropsType } from 'next';
import { useRouter } from 'next/router';
import getProduct from 'lib/bigcommerce/api/operations/get-product';
import { Layout } from '@components/core';
import { ProductView } from '@components/product';
import getAllProductPaths from '@lib/bigcommerce/api/operations/get-all-product-paths';

export async function getStaticProps({
params,
}: GetStaticPropsContext<{ slug: string }>) {
const { product } = await getProduct({ variables: { slug: params!.slug } });

console.log("PRODUCT", product);

const productData = {
title: "T-Shirt",
title: 'T-Shirt',
description: `
Nothing undercover about this tee. Nope. This is the official Bad
Boys tee. Printed in white or black ink on Black, Brown, or Oatmeal.
Expand All @@ -21,29 +19,38 @@ export async function getStaticProps({
run. Printing starts when the drop ends. Reminder: Bad Boys For
Life. Shipping may take 10+ days due to COVID-19.
`,
price: "$50",
colors: ["black", "white", "pink"],
sizes: ["s", "m", "l", "xl", "xxl"],
price: '$50',
colors: ['black', 'white', 'pink'],
sizes: ['s', 'm', 'l', 'xl', 'xxl'],
};
return {
props: {
product,
productData,
},
revalidate: 200,
};
}

export async function getStaticPaths() {
const { products } = await getAllProductPaths();

return {
paths: [],
fallback: "unstable_blocking",
paths: products.map((product) => ({
params: { slug: product!.node.path },
})),
fallback: 'unstable_blocking',
};
}

export default function Home({
product,
productData,
}: InferGetStaticPropsType<typeof getStaticProps>) {
console.log('PRODUCT', product);

const router = useRouter();

return (
<Layout>
{router.isFallback ? (
Expand Down

0 comments on commit 390b2c3

Please sign in to comment.