diff --git a/app/layout.js b/app/layout.js index 0a6c987eb..1e34aa55b 100644 --- a/app/layout.js +++ b/app/layout.js @@ -1,7 +1,14 @@ +import { TypesNav } from '/components/home.js'; + export default function RootLayout({ children }) { return ( <html lang='en'> - <body>{children}</body> + <body> + <nav> + <TypesNav /> + </nav> + <main>{children}</main> + </body> </html> ); } diff --git a/app/page.js b/app/page.js index 309de48bb..f2dfb5949 100644 --- a/app/page.js +++ b/app/page.js @@ -1,107 +1,5 @@ -import Link from 'next/link'; -import Image from 'next/image'; - -import { getCollectionProducts } from 'lib/shopify'; - -const formatPrice = ({ amount, currencyCode }) => { - const USDollar = new Intl.NumberFormat('en-US', { - style: 'currency', - currency: currencyCode, - }); - - return USDollar.format(amount); -}; - -const formatPriceRange = ({ maxVariantPrice, minVariantPrice }) => { - if (maxVariantPrice.amount == minVariantPrice.amount) { - return `${formatPrice(maxVariantPrice)}`; - } else { - return `${formatPrice(minVariantPrice)} - ${formatPrice( - maxVariantPrice - )}`; - } -}; - -const PriceRanges = ({ priceRange, compareAtPriceRange, availableForSale }) => { - const onSale = - (compareAtPriceRange?.minVariantPrice?.amount ?? 0) > - (priceRange?.minVariantPrice?.amount ?? 0) || - (compareAtPriceRange?.maxVariantPrice?.amount ?? 0) > - (priceRange?.maxVariantPrice?.amount ?? 0); - const isForSale = (priceRange?.maxVariantPrice?.amount ?? 0) > 0; - - return ( - <p> - {availableForSale ? ( - isForSale && ( - <> - <> - {onSale && ( - <span className={'original-price'}> - {formatPriceRange(compareAtPriceRange)}{' '} - </span> - )} - </> - <span>{formatPriceRange(priceRange)}</span> - </> - ) - ) : ( - <span>Sold Out</span> - )} - </p> - ); -}; - -export async function HomeProduct({ product }) { - const featuredImage = product?.images?.[0]; - const collections = product?.collections?.nodes; - - return ( - <Link href={`/${product?.handle}`}> - <Image - src={featuredImage?.url} - alt={featuredImage?.altText} - width={featuredImage?.width} - height={featuredImage?.height} - /> - <p>{product?.title}</p> - {collections && collections.length > 0 && ( - <p>{`(${collections - ?.map(collection => collection?.title) - .join(', ')})`}</p> - )} - <PriceRanges {...product} /> - </Link> - ); -} +import { HomeProductsList } from '/components/home.js'; export default async function HomePage() { - const collection = process.env.HOMEPAGE_COLLECTION; - const products = await getCollectionProducts({ - collection, - }); - - // console.log({ collection, products }); - // const num = 4; - // console.log({ - // price: products[num].priceRange, - // compareAt: products[num].compareAtPriceRange, - // title: products[num].title, - // }); - - return ( - <> - {products.length === 0 ? ( - <p>{`No products found`}</p> - ) : ( - <ul> - {products?.map(product => ( - <li key={product?.handle}> - <HomeProduct {...{ product }} /> - </li> - ))} - </ul> - )} - </> - ); + return <HomeProductsList collection={process.env.HOMEPAGE_COLLECTION} />; } diff --git a/app/search/[collection]/page.js b/app/search/[collection]/page.js new file mode 100644 index 000000000..f03932240 --- /dev/null +++ b/app/search/[collection]/page.js @@ -0,0 +1,13 @@ +import { getCollections } from 'lib/shopify'; + +import { HomeProductsList } from '/components/home.js'; + +export async function generateStaticParams() { + const collections = await getCollections(); + + return collections.map(collection => ({ collection: collection.handle })); +} + +export default async function CollectionPage({ params: { collection } }) { + return <HomeProductsList collection={collection} />; +} diff --git a/components/home.js b/components/home.js new file mode 100644 index 000000000..c1ee30c72 --- /dev/null +++ b/components/home.js @@ -0,0 +1,128 @@ +import Link from 'next/link'; +import Image from 'next/image'; + +import { getCollectionProducts, getMenu } from 'lib/shopify'; + +export const formatPrice = ({ amount, currencyCode }) => { + const USDollar = new Intl.NumberFormat('en-US', { + style: 'currency', + currency: currencyCode, + }); + + return USDollar.format(amount); +}; + +export const formatPriceRange = ({ maxVariantPrice, minVariantPrice }) => { + if (maxVariantPrice.amount == minVariantPrice.amount) { + return `${formatPrice(maxVariantPrice)}`; + } else { + return `${formatPrice(minVariantPrice)} - ${formatPrice( + maxVariantPrice + )}`; + } +}; + +export const PriceRanges = ({ + priceRange, + compareAtPriceRange, + availableForSale, +}) => { + const onSale = + (compareAtPriceRange?.minVariantPrice?.amount ?? 0) > + (priceRange?.minVariantPrice?.amount ?? 0) || + (compareAtPriceRange?.maxVariantPrice?.amount ?? 0) > + (priceRange?.maxVariantPrice?.amount ?? 0); + const isForSale = (priceRange?.maxVariantPrice?.amount ?? 0) > 0; + + return ( + <p> + {availableForSale ? ( + isForSale && ( + <> + <> + {onSale && ( + <span className={'original-price'}> + {formatPriceRange(compareAtPriceRange)}{' '} + </span> + )} + </> + <span>{formatPriceRange(priceRange)}</span> + </> + ) + ) : ( + <span>Sold Out</span> + )} + </p> + ); +}; + +export async function HomeProduct({ product }) { + const featuredImage = product?.images?.[0]; + const collections = product?.collections?.nodes; + + return ( + <Link href={`/${product?.handle}`}> + <Image + src={featuredImage?.url} + alt={featuredImage?.altText} + width={featuredImage?.width} + height={featuredImage?.height} + /> + <p>{product?.title}</p> + {collections && collections.length > 0 && ( + <p>{`(${collections + ?.map(collection => collection?.title) + .join(', ')})`}</p> + )} + <PriceRanges {...product} /> + </Link> + ); +} + +//TODO: suspense +export async function HomeProductsList({ collection }) { + const products = await getCollectionProducts({ + collection, + }); + + // console.log({ collection, products }); + // const num = 4; + // console.log({ + // price: products[num].priceRange, + // compareAt: products[num].compareAtPriceRange, + // title: products[num].title, + // }); + + return ( + <> + {products.length === 0 ? ( + <p>{`No products found`}</p> + ) : ( + <ul> + {products?.map(product => ( + <li key={product?.handle}> + <HomeProduct {...{ product }} /> + </li> + ))} + </ul> + )} + </> + ); +} + +//TODO: suspense +export async function TypesNav() { + const typesMenu = await getMenu('types-nav'); + + // console.log({ typesMenu }); + + return ( + <ul> + {typesMenu?.map(menuItem => ( + <li key={menuItem?.path}> + <Link href={menuItem?.path}>{menuItem?.title}</Link> + </li> + ))} + </ul> + ); +}