From 7ae036b385efea563bde34a4fc4c6a19483a5f35 Mon Sep 17 00:00:00 2001 From: Michael Novotny Date: Sun, 30 Jul 2023 13:18:31 -0500 Subject: [PATCH 01/20] Fixes add to cart for products with a single variant (#1127) --- components/cart/add-to-cart.tsx | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/components/cart/add-to-cart.tsx b/components/cart/add-to-cart.tsx index d737b6678..92e2d50b0 100644 --- a/components/cart/add-to-cart.tsx +++ b/components/cart/add-to-cart.tsx @@ -6,7 +6,7 @@ import { addItem } from 'components/cart/actions'; import LoadingDots from 'components/loading-dots'; import { ProductVariant } from 'lib/shopify/types'; import { useRouter, useSearchParams } from 'next/navigation'; -import { useEffect, useState, useTransition } from 'react'; +import { useTransition } from 'react'; export function AddToCart({ variants, @@ -15,21 +15,16 @@ export function AddToCart({ variants: ProductVariant[]; availableForSale: boolean; }) { - const [selectedVariantId, setSelectedVariantId] = useState(undefined); const router = useRouter(); const searchParams = useSearchParams(); const [isPending, startTransition] = useTransition(); - - useEffect(() => { - const variant = variants.find((variant: ProductVariant) => - variant.selectedOptions.every( - (option) => option.value === searchParams.get(option.name.toLowerCase()) - ) - ); - - setSelectedVariantId(variant?.id); - }, [searchParams, variants, setSelectedVariantId]); - + const defaultVariantId = variants.length === 1 ? variants[0]?.id : undefined; + const variant = variants.find((variant: ProductVariant) => + variant.selectedOptions.every( + (option) => option.value === searchParams.get(option.name.toLowerCase()) + ) + ); + const selectedVariantId = variant?.id || defaultVariantId; const title = !availableForSale ? 'Out of stock' : !selectedVariantId From 45afbc548eb5fbc4b5a7711cd1f27c6a63deca54 Mon Sep 17 00:00:00 2001 From: Kanji Yomoda Date: Mon, 31 Jul 2023 21:47:02 +0900 Subject: [PATCH 02/20] Fix typo in a comment (#1130) --- components/cart/modal.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/cart/modal.tsx b/components/cart/modal.tsx index 7c0c67b19..a6b45b9ae 100644 --- a/components/cart/modal.tsx +++ b/components/cart/modal.tsx @@ -25,7 +25,7 @@ export default function CartModal({ cart }: { cart: Cart | undefined }) { const closeCart = () => setIsOpen(false); useEffect(() => { - // Open cart modal when when quantity changes. + // Open cart modal when quantity changes. if (cart?.totalQuantity !== quantityRef.current) { // But only if it's not already open (quantity also changes when editing items in cart). if (!isOpen) { From 10b1d4bbae6a4576e4f5565236d8b4494f2774a1 Mon Sep 17 00:00:00 2001 From: Kanji Yomoda Date: Mon, 31 Jul 2023 22:30:00 +0900 Subject: [PATCH 03/20] Renames confusing variable name (#1131) --- app/product/[handle]/page.tsx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/app/product/[handle]/page.tsx b/app/product/[handle]/page.tsx index 63b205c92..815078b56 100644 --- a/app/product/[handle]/page.tsx +++ b/app/product/[handle]/page.tsx @@ -23,17 +23,17 @@ export async function generateMetadata({ if (!product) return notFound(); const { url, width, height, altText: alt } = product.featuredImage || {}; - const hide = !product.tags.includes(HIDDEN_PRODUCT_TAG); + const indexable = !product.tags.includes(HIDDEN_PRODUCT_TAG); return { title: product.seo.title || product.title, description: product.seo.description || product.description, robots: { - index: hide, - follow: hide, + index: indexable, + follow: indexable, googleBot: { - index: hide, - follow: hide + index: indexable, + follow: indexable } }, openGraph: url From 455a7327f34cd87a571db8ead8b5ae761771d9ca Mon Sep 17 00:00:00 2001 From: Michael Novotny Date: Mon, 31 Jul 2023 09:09:56 -0500 Subject: [PATCH 04/20] Fixes mobile tap targets (#1129) Co-authored-by: Lee Robinson --- components/layout/footer-menu.tsx | 4 ++-- components/layout/footer.tsx | 4 ++-- components/layout/navbar/mobile-menu.tsx | 27 +++++++++++++++--------- 3 files changed, 21 insertions(+), 14 deletions(-) diff --git a/components/layout/footer-menu.tsx b/components/layout/footer-menu.tsx index 696f61fc0..4f6387edd 100644 --- a/components/layout/footer-menu.tsx +++ b/components/layout/footer-menu.tsx @@ -15,11 +15,11 @@ const FooterMenuItem = ({ item }: { item: Menu }) => { }, [pathname, item.path]); return ( -
  • +
  • - + {SITE_NAME} @@ -40,7 +40,7 @@ export default async function Footer() {
    diff --git a/components/layout/navbar/mobile-menu.tsx b/components/layout/navbar/mobile-menu.tsx index 05654d9c1..6d798370e 100644 --- a/components/layout/navbar/mobile-menu.tsx +++ b/components/layout/navbar/mobile-menu.tsx @@ -32,8 +32,12 @@ export default function MobileMenu({ menu }: { menu: Menu[] }) { return ( <> - @@ -59,7 +63,11 @@ export default function MobileMenu({ menu }: { menu: Menu[] }) { >
    - @@ -67,14 +75,13 @@ export default function MobileMenu({ menu }: { menu: Menu[] }) {
    {menu.length ? ( -
      +
        {menu.map((item: Menu) => ( -
      • - +
      • + {item.title}
      • From 36b28b4aab975b71764a277981d62fc8a0903643 Mon Sep 17 00:00:00 2001 From: Michael Novotny Date: Mon, 31 Jul 2023 09:18:50 -0500 Subject: [PATCH 05/20] Makes search a bit wider on wider screens (#1128) Co-authored-by: Lee Robinson --- components/layout/navbar/search.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/layout/navbar/search.tsx b/components/layout/navbar/search.tsx index e6d9ce307..c7a410b9d 100644 --- a/components/layout/navbar/search.tsx +++ b/components/layout/navbar/search.tsx @@ -32,7 +32,7 @@ export default function Search() { } return ( -
        + Date: Mon, 31 Jul 2023 22:33:13 -0500 Subject: [PATCH 06/20] Moves revalidation logic to `lib` (#1132) --- app/api/revalidate/route.ts | 35 +++-------------------------------- lib/shopify/index.ts | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 32 deletions(-) diff --git a/app/api/revalidate/route.ts b/app/api/revalidate/route.ts index 94ddfff9b..47af2a4a4 100644 --- a/app/api/revalidate/route.ts +++ b/app/api/revalidate/route.ts @@ -1,37 +1,8 @@ -import { TAGS } from 'lib/constants'; -import { revalidateTag } from 'next/cache'; -import { headers } from 'next/headers'; +import { revalidate } from 'lib/shopify'; import { NextRequest, NextResponse } from 'next/server'; export const runtime = 'edge'; -// We always need to respond with a 200 status code to Shopify, -// otherwise it will continue to retry the request. -export async function POST(req: NextRequest): Promise { - const collectionWebhooks = ['collections/create', 'collections/delete', 'collections/update']; - const productWebhooks = ['products/create', 'products/delete', 'products/update']; - const topic = headers().get('x-shopify-topic') || 'unknown'; - const secret = req.nextUrl.searchParams.get('secret'); - const isCollectionUpdate = collectionWebhooks.includes(topic); - const isProductUpdate = productWebhooks.includes(topic); - - if (!secret || secret !== process.env.SHOPIFY_REVALIDATION_SECRET) { - console.error('Invalid revalidation secret.'); - return NextResponse.json({ status: 200 }); - } - - if (!isCollectionUpdate && !isProductUpdate) { - // We don't need to revalidate anything for any other topics. - return NextResponse.json({ status: 200 }); - } - - if (isCollectionUpdate) { - revalidateTag(TAGS.collections); - } - - if (isProductUpdate) { - revalidateTag(TAGS.products); - } - - return NextResponse.json({ status: 200, revalidated: true, now: Date.now() }); +export async function POST(req: NextRequest): Promise { + return revalidate(req); } diff --git a/lib/shopify/index.ts b/lib/shopify/index.ts index 64b5d24e8..a8804d045 100644 --- a/lib/shopify/index.ts +++ b/lib/shopify/index.ts @@ -1,5 +1,8 @@ import { HIDDEN_PRODUCT_TAG, SHOPIFY_GRAPHQL_API_ENDPOINT, TAGS } from 'lib/constants'; import { isShopifyError } from 'lib/type-guards'; +import { revalidateTag } from 'next/cache'; +import { headers } from 'next/headers'; +import { NextRequest, NextResponse } from 'next/server'; import { addToCartMutation, createCartMutation, @@ -408,3 +411,35 @@ export async function getProducts({ return reshapeProducts(removeEdgesAndNodes(res.body.data.products)); } + +// This is called from `app/api/revalidate.ts` so providers can control revalidation logic. +export async function revalidate(req: NextRequest): Promise { + // We always need to respond with a 200 status code to Shopify, + // otherwise it will continue to retry the request. + const collectionWebhooks = ['collections/create', 'collections/delete', 'collections/update']; + const productWebhooks = ['products/create', 'products/delete', 'products/update']; + const topic = headers().get('x-shopify-topic') || 'unknown'; + const secret = req.nextUrl.searchParams.get('secret'); + const isCollectionUpdate = collectionWebhooks.includes(topic); + const isProductUpdate = productWebhooks.includes(topic); + + if (!secret || secret !== process.env.SHOPIFY_REVALIDATION_SECRET) { + console.error('Invalid revalidation secret.'); + return NextResponse.json({ status: 200 }); + } + + if (!isCollectionUpdate && !isProductUpdate) { + // We don't need to revalidate anything for any other topics. + return NextResponse.json({ status: 200 }); + } + + if (isCollectionUpdate) { + revalidateTag(TAGS.collections); + } + + if (isProductUpdate) { + revalidateTag(TAGS.products); + } + + return NextResponse.json({ status: 200, revalidated: true, now: Date.now() }); +} From 71c9cb96face87b3649ebc7d820b2f70f4bba7bf Mon Sep 17 00:00:00 2001 From: Michael Novotny Date: Tue, 1 Aug 2023 20:18:56 -0500 Subject: [PATCH 07/20] Uses url instead of `setState` for image gallery (#1133) --- components/product/gallery.tsx | 60 +++++++++++++++++++--------------- 1 file changed, 34 insertions(+), 26 deletions(-) diff --git a/components/product/gallery.tsx b/components/product/gallery.tsx index 8636a1cc9..99742a917 100644 --- a/components/product/gallery.tsx +++ b/components/product/gallery.tsx @@ -2,33 +2,40 @@ import { ArrowLeftIcon, ArrowRightIcon } from '@heroicons/react/24/outline'; import { GridTileImage } from 'components/grid/tile'; +import { createUrl } from 'lib/utils'; import Image from 'next/image'; -import { useState } from 'react'; +import Link from 'next/link'; +import { usePathname, useSearchParams } from 'next/navigation'; export function Gallery({ images }: { images: { src: string; altText: string }[] }) { - const [currentImageIndex, setCurrentImageIndex] = useState(0); + const pathname = usePathname(); + const searchParams = useSearchParams(); + const imageSearchParam = searchParams.get('image'); + const imageIndex = imageSearchParam ? parseInt(imageSearchParam) : 0; - function handleNavigate(direction: 'next' | 'previous') { - if (direction === 'next') { - setCurrentImageIndex(currentImageIndex + 1 < images.length ? currentImageIndex + 1 : 0); - } else { - setCurrentImageIndex(currentImageIndex === 0 ? images.length - 1 : currentImageIndex - 1); - } - } + const nextSearchParams = new URLSearchParams(searchParams.toString()); + const nextImageIndex = imageIndex + 1 < images.length ? imageIndex + 1 : 0; + nextSearchParams.set('image', nextImageIndex.toString()); + const nextUrl = createUrl(pathname, nextSearchParams); + + const previousSearchParams = new URLSearchParams(searchParams.toString()); + const previousImageIndex = imageIndex === 0 ? images.length - 1 : imageIndex - 1; + previousSearchParams.set('image', previousImageIndex.toString()); + const previousUrl = createUrl(pathname, previousSearchParams); const buttonClassName = - 'h-full px-6 transition-all ease-in-out hover:scale-110 hover:text-black dark:hover:text-white'; + 'h-full px-6 transition-all ease-in-out hover:scale-110 hover:text-black dark:hover:text-white flex items-center justify-center'; return (
        - {images[currentImageIndex] && ( + {images[imageIndex] && ( {images[currentImageIndex]?.altText )} @@ -36,21 +43,17 @@ export function Gallery({ images }: { images: { src: string; altText: string }[] {images.length > 1 ? (
        - +
        - +
        ) : null} @@ -59,13 +62,18 @@ export function Gallery({ images }: { images: { src: string; altText: string }[] {images.length > 1 ? (
        {images.map((image, index) => { - const isActive = index === currentImageIndex; + const isActive = index === imageIndex; + const imageSearchParams = new URLSearchParams(searchParams.toString()); + + imageSearchParams.set('image', index.toString()); + return ( - + ); })}
        From 1d5242eef366a79a06d68825f7d71aa51557df61 Mon Sep 17 00:00:00 2001 From: Michael Novotny Date: Tue, 1 Aug 2023 20:34:45 -0500 Subject: [PATCH 08/20] Adds better sitemap error handling (#1134) * Adds better sitemap error handling * Removes extra `flat` --------- Co-authored-by: Lee Robinson --- app/sitemap.ts | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/app/sitemap.ts b/app/sitemap.ts index d8cdfd2ea..46d39669c 100644 --- a/app/sitemap.ts +++ b/app/sitemap.ts @@ -1,11 +1,16 @@ import { getCollections, getPages, getProducts } from 'lib/shopify'; import { MetadataRoute } from 'next'; +type Route = { + url: string; + lastModified: string; +}; + const baseUrl = process.env.NEXT_PUBLIC_VERCEL_URL ? `https://${process.env.NEXT_PUBLIC_VERCEL_URL}` : 'http://localhost:3000'; -export default async function sitemap(): Promise>> { +export default async function sitemap(): Promise { const routesMap = [''].map((route) => ({ url: `${baseUrl}${route}`, lastModified: new Date().toISOString() @@ -32,9 +37,13 @@ export default async function sitemap(): Promise Date: Wed, 2 Aug 2023 09:04:44 -0500 Subject: [PATCH 09/20] Small visual tweaks. (#1137) --- app/search/page.tsx | 2 +- components/layout/navbar/index.tsx | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/search/page.tsx b/app/search/page.tsx index 5f4b60c01..2f7a53bd4 100644 --- a/app/search/page.tsx +++ b/app/search/page.tsx @@ -24,7 +24,7 @@ export default async function SearchPage({ return ( <> {searchValue ? ( -

        +

        {products.length === 0 ? 'There are no products that match ' : `Showing ${products.length} ${resultsText} for `} diff --git a/components/layout/navbar/index.tsx b/components/layout/navbar/index.tsx index 09341c646..2683942c9 100644 --- a/components/layout/navbar/index.tsx +++ b/components/layout/navbar/index.tsx @@ -30,12 +30,12 @@ export default async function Navbar() {

        {menu.length ? ( -
          +
            {menu.map((item: Menu) => (
          • {item.title} From 9c813577e1deaf69166ef96fc72e24c4bd98ca04 Mon Sep 17 00:00:00 2001 From: Michael Novotny Date: Wed, 2 Aug 2023 21:07:35 -0500 Subject: [PATCH 10/20] Optimizes image sizes (#1140) --- app/product/[handle]/page.tsx | 31 ++++++++-------- components/carousel.tsx | 35 +++++++++--------- components/cart/modal.tsx | 4 +- components/grid/three-items.tsx | 12 +++--- components/layout/product-grid-items.tsx | 6 +-- components/product/gallery.tsx | 47 ++++++++++++------------ 6 files changed, 69 insertions(+), 66 deletions(-) diff --git a/app/product/[handle]/page.tsx b/app/product/[handle]/page.tsx index 815078b56..d59423364 100644 --- a/app/product/[handle]/page.tsx +++ b/app/product/[handle]/page.tsx @@ -82,8 +82,8 @@ export default async function ProductPage({ params }: { params: { handle: string }} />
            -
            -
            +
            +
            ({ src: image.url, @@ -92,7 +92,7 @@ export default async function ProductPage({ params }: { params: { handle: string />
            -
            +
            @@ -115,14 +115,13 @@ async function RelatedProducts({ id }: { id: string }) { return (

            Related Products

            -
            - {relatedProducts.map((product, i) => { - return ( - +
              + {relatedProducts.map((product) => ( +
            • + - ); - })} -
            +
          • + ))} +
        ); } diff --git a/components/carousel.tsx b/components/carousel.tsx index d67ba5deb..a4c58bd5d 100644 --- a/components/carousel.tsx +++ b/components/carousel.tsx @@ -10,27 +10,28 @@ export async function Carousel() { return (
        -
        +
          {[...products, ...products].map((product, i) => ( - - - + + + + ))} -
        +
    ); } diff --git a/components/cart/modal.tsx b/components/cart/modal.tsx index a6b45b9ae..4fbfcc6ad 100644 --- a/components/cart/modal.tsx +++ b/components/cart/modal.tsx @@ -111,7 +111,7 @@ export default function CartModal({ cart }: { cart: Cart | undefined }) { >
    {
    -

    +

    {item.quantity}

    diff --git a/components/grid/three-items.tsx b/components/grid/three-items.tsx index 4a680fc36..abb379e5c 100644 --- a/components/grid/three-items.tsx +++ b/components/grid/three-items.tsx @@ -6,13 +6,15 @@ import Link from 'next/link'; function ThreeItemGridItem({ item, size }: { item: Product; size: 'full' | 'half' }) { return (
    - + +
    diff --git a/components/layout/product-grid-items.tsx b/components/layout/product-grid-items.tsx index d9060adbb..ea8a5ebf7 100644 --- a/components/layout/product-grid-items.tsx +++ b/components/layout/product-grid-items.tsx @@ -8,7 +8,7 @@ export default function ProductGridItems({ products }: { products: Product[] }) <> {products.map((product) => ( - + diff --git a/components/product/gallery.tsx b/components/product/gallery.tsx index 99742a917..d1f567aef 100644 --- a/components/product/gallery.tsx +++ b/components/product/gallery.tsx @@ -27,13 +27,13 @@ export function Gallery({ images }: { images: { src: string; altText: string }[] 'h-full px-6 transition-all ease-in-out hover:scale-110 hover:text-black dark:hover:text-white flex items-center justify-center'; return ( -
    -
    + <> +
    {images[imageIndex] && ( {images[imageIndex]?.altText {images.length > 1 ? ( -
    +
      {images.map((image, index) => { const isActive = index === imageIndex; const imageSearchParams = new URLSearchParams(searchParams.toString()); @@ -68,25 +68,26 @@ export function Gallery({ images }: { images: { src: string; altText: string }[] imageSearchParams.set('image', index.toString()); return ( - - - +
    • + + + +
    • ); })} -
    + ) : null} -
    + ); } From 9e1388f97409ec7a5bba9da1f0a0b3bdb1e7c13b Mon Sep 17 00:00:00 2001 From: Michael Novotny Date: Wed, 2 Aug 2023 21:17:11 -0500 Subject: [PATCH 11/20] Updates favicon (#1141) Co-authored-by: Lee Robinson --- app/favicon.ico | Bin 535 -> 15086 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/app/favicon.ico b/app/favicon.ico index c4826c94780efdd7e92092dc77fd4388fd8cd7f5..dc7d8431e47ee24c71eebaffe30786769b348353 100644 GIT binary patch literal 15086 zcmd^GTWAzX6m4-g@sXH`@A%578(qZ@6^)AEx+seJA)+9DC<(qIf}bu*kok~BOho(? zMKOx(j~|Mt_~Qfw1wjdF^h0Abh?s;#^B@nC+`Xsl>g}%X>Y3@8NoLrAo9cSpd(W+R z)vXxDC}Xs-bg98%*!ZW!FiH)>2#3vh$S@i>EyN-6D}FJIzq!EgT!vYUGA5*p-)}#I zSbt~DniZNndGh+g!ot4_3JPi_Oqfv1RG*)p-^A3y^o^;Dshg=MNrDW>f=tM6VqLGH zlXYJQ24DfEIB@4poH((Jd82uGdF|uJj~^U2ZXAsy0RylA6Jsl9JMz8km_B`a5$c-D z_l+c8Ki$9vjKFHQVa}X6c}Vx;&7?eF1!idj+9i|gU9CG{1!mx%J$rVD`_?11Os2$z>2Y9|^LwUa)#1Z9=6+PG%g^+5U}t)r={R-x zfF0|#EWG+X@0z8$BxzV>Er=BQk>gsAbd-kl0s;a7J+qP{2r=1trX3UsDCr_Rvlu>yhZ_l1R#B*XoHUK+Q zw_TUtH|npVqJsMR`bhVC{`@)3pFiJa18l!^>5?Z~M@I+k+__VgtT#Sa_{7cQiiFJF3MM`C+>J8j*%)zt>5=d!Xg z>hJHT+S*#0Idi6~uc%4VKI}V|@87>qQ>RXK;KR6>GGz+gym^y$?b_wC zPlwejJsJEG$KAVkwQYcT>cD{mE{x#iy*q_MAxHo6!swTl41UN(8*JRTky=_>v^HQq zoi}futBwSQh%~xs_+8`aBbSO ziCSA*J#A=gY!quU`dhNNC4VaMLng-Zg$oy4_y-3E>BNZ>t~p5J2pXmuKk9bz;>A>7 zU+=Kt@#DwD_e_p;EGT9>U#js#Hu}-gqesR507i6nb|$^f+A-U|(}5pjdD^sT^x(k* z(FQd&HN^KEDX)9jVd9Vb{9?D=?;CBfWy=#$y%dyaI!pQ)E?Q>^zh1o-@?7h$ns zG$PD3j3~m<|Ai66M;V41BKiOPi@15(!Z+@7x&I0b&;j2u{Os`IqYT2md-qaNQIRhO)-UEYsZR|d8-7{bv)X?j zK763%%a>dCPq@>$diAQk2;I7MOW^XW1J*C*R8_BxXhS+0KmZK&g+Qf13kPAl8D|Q`oV*Cz&P*j?sj0n+m9tnmRNNl<;MyWu^+NvBl;qI?Dk(>T^*H_ zl%!q1tb;Xc)>va5eQ^K&{Z=20WwSj$QTrt?>H%+Y@VkBcwlxN2e!QWnKjC-j=!@{Z zWBkKUkA4xaPJ21lFZQYSv_!t=&Yhc-@0Rt8J#r#C?PY_EIXge=7yEO2+HiieesMM! zPMvmLtY4f<>}kXKZJvonbpJil=Z}#-f8h)`lIKt8$8VU<-&N}Q`eXWHL&)=p@a3;v zyH=zvSg^pcA7g$|SCXIO;=OWDPY-?m{8{j@jdbP875e)1t7Bge9xgBHS@HuP_FHe? zzP0uM*cai5EicMx~-}zG!tkWD18q& z91g8P9LFIBawD!nqPLNzX@~*cYeVL{xh%`8IA246xMAjtM{H0O z#XaI}uPuMcaNF4!wqQV8vbJooQpy>9U|Y%-+HJ=|!$|LFOZOE>+KwX+=nO3?LP^^V zP44%5iGi*N%eh5S6#Y9mNs=4kX7c|j&=rpEgUi)lCuam%)h zAIShV9!d>19n06sgedYM_@0(1%p7L!Tml6Dp;h<7=sJ7{a+uHanD`9SpXXo1cMyJ_ Z{{e%1|CY$w7P0^U002ovPDHLkV1nrA+7|!- From 80bb15a7dcfa89873284b5d549bb72aac269e0ac Mon Sep 17 00:00:00 2001 From: Emir Morgan <53477261+emirmorgan@users.noreply.github.com> Date: Fri, 4 Aug 2023 00:04:44 +0300 Subject: [PATCH 12/20] Disable scrolling to the top when switching between gallery images with arrow buttons (#1139) --- components/product/gallery.tsx | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/components/product/gallery.tsx b/components/product/gallery.tsx index d1f567aef..eabc500e3 100644 --- a/components/product/gallery.tsx +++ b/components/product/gallery.tsx @@ -47,11 +47,17 @@ export function Gallery({ images }: { images: { src: string; altText: string }[] aria-label="Previous product image" href={previousUrl} className={buttonClassName} + scroll={false} >
    - +
    From 9044baf44ec556f3cdf6c61781647f5820d2d49f Mon Sep 17 00:00:00 2001 From: Michael Novotny Date: Thu, 3 Aug 2023 19:02:51 -0500 Subject: [PATCH 13/20] Removes priority on third grid item on home page (#1143) --- components/grid/three-items.tsx | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/components/grid/three-items.tsx b/components/grid/three-items.tsx index abb379e5c..23b3f8991 100644 --- a/components/grid/three-items.tsx +++ b/components/grid/three-items.tsx @@ -3,7 +3,15 @@ import { getCollectionProducts } from 'lib/shopify'; import type { Product } from 'lib/shopify/types'; import Link from 'next/link'; -function ThreeItemGridItem({ item, size }: { item: Product; size: 'full' | 'half' }) { +function ThreeItemGridItem({ + item, + size, + priority +}: { + item: Product; + size: 'full' | 'half'; + priority?: boolean; +}) { return (
    - - + +
    ); From 0e13cfc3dd8e1d0471657fba92aa38397fb9c14b Mon Sep 17 00:00:00 2001 From: Michael Novotny Date: Thu, 3 Aug 2023 20:24:37 -0500 Subject: [PATCH 14/20] Updates to Node 18 (#1144) --- .nvmrc | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.nvmrc b/.nvmrc index b6a7d89c6..3c032078a 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -16 +18 diff --git a/package.json b/package.json index 6fd83bd41..21d2dba9a 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "private": true, "packageManager": "pnpm@8.2.0", "engines": { - "node": ">=16", + "node": ">=18", "pnpm": ">=7" }, "scripts": { From ef92d578cd6e845a7725ac98c7d22dbc6834354b Mon Sep 17 00:00:00 2001 From: Michael Novotny Date: Thu, 3 Aug 2023 21:17:02 -0500 Subject: [PATCH 15/20] Adds more home page carousel products for wide screens (#1142) --- components/carousel.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/components/carousel.tsx b/components/carousel.tsx index a4c58bd5d..286d4dfea 100644 --- a/components/carousel.tsx +++ b/components/carousel.tsx @@ -8,10 +8,13 @@ export async function Carousel() { if (!products?.length) return null; + // Purposefully duplicating products to make the carousel loop and not run out of products on wide screens. + const carouselProducts = [...products, ...products, ...products]; + return (