From 9a4c995bb68535b83fba07406fd31d59ff28fefd Mon Sep 17 00:00:00 2001 From: Lee Robinson Date: Sun, 28 Jul 2024 22:58:59 -0500 Subject: [PATCH] Make image, variant, and cart updates faster with `useOptimistic` (#1365) --- app/layout.tsx | 21 +- app/page.tsx | 2 +- app/product/[handle]/page.tsx | 11 +- app/search/loading.tsx | 2 +- components/cart/actions.ts | 97 ++++--- components/cart/add-to-cart.tsx | 45 ++- components/cart/cart-context.tsx | 184 ++++++++++++ components/cart/delete-item-button.tsx | 10 +- components/cart/edit-item-quantity-button.tsx | 7 +- components/cart/index.tsx | 14 - components/cart/modal.tsx | 272 +++++++----------- components/layout/footer.tsx | 6 +- components/layout/navbar/index.tsx | 10 +- components/layout/navbar/search.tsx | 2 +- components/product/gallery.tsx | 57 ++-- components/product/product-context.tsx | 81 ++++++ components/product/product-description.tsx | 11 +- components/product/variant-selector.tsx | 119 ++++---- components/welcome-toast.tsx | 35 +++ lib/shopify/index.ts | 9 +- lib/shopify/types.ts | 13 +- package.json | 3 +- pnpm-lock.yaml | 14 + tsconfig.json | 3 +- 24 files changed, 644 insertions(+), 384 deletions(-) create mode 100644 components/cart/cart-context.tsx delete mode 100644 components/cart/index.tsx create mode 100644 components/product/product-context.tsx create mode 100644 components/welcome-toast.tsx diff --git a/app/layout.tsx b/app/layout.tsx index 1e17f31d3b..3b09ab7e4f 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -1,7 +1,12 @@ -import Navbar from 'components/layout/navbar'; +import { CartProvider } from 'components/cart/cart-context'; +import { Navbar } from 'components/layout/navbar'; +import { WelcomeToast } from 'components/welcome-toast'; import { GeistSans } from 'geist/font/sans'; +import { getCart } from 'lib/shopify'; import { ensureStartsWith } from 'lib/utils'; +import { cookies } from 'next/headers'; import { ReactNode } from 'react'; +import { Toaster } from 'sonner'; import './globals.css'; const { TWITTER_CREATOR, TWITTER_SITE, SITE_NAME } = process.env; @@ -32,11 +37,21 @@ export const metadata = { }; export default async function RootLayout({ children }: { children: ReactNode }) { + const cartId = cookies().get('cartId')?.value; + // Don't await the fetch, pass the Promise to the context provider + const cart = getCart(cartId); + return ( - -
{children}
+ + +
+ {children} + + +
+
); diff --git a/app/page.tsx b/app/page.tsx index 0fad0ac289..7d407ede83 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -9,7 +9,7 @@ export const metadata = { } }; -export default async function HomePage() { +export default function HomePage() { return ( <> diff --git a/app/product/[handle]/page.tsx b/app/product/[handle]/page.tsx index 8b2d5c2cf4..e2280675de 100644 --- a/app/product/[handle]/page.tsx +++ b/app/product/[handle]/page.tsx @@ -4,6 +4,7 @@ import { notFound } from 'next/navigation'; import { GridTileImage } from 'components/grid/tile'; import Footer from 'components/layout/footer'; import { Gallery } from 'components/product/gallery'; +import { ProductProvider } from 'components/product/product-context'; import { ProductDescription } from 'components/product/product-description'; import { HIDDEN_PRODUCT_TAG } from 'lib/constants'; import { getProduct, getProductRecommendations } from 'lib/shopify'; @@ -72,7 +73,7 @@ export default async function ProductPage({ params }: { params: { handle: string }; return ( - <> +