From 83856a494108ad18257a2bc355a0d5620c75513b Mon Sep 17 00:00:00 2001 From: Alex Date: Wed, 4 Sep 2024 21:47:12 -0500 Subject: [PATCH 1/2] Squashed commit of the following: commit 408d6eb7583470eb84fd0e85895f97dad864b981 Author: Alex Date: Wed Sep 4 21:28:45 2024 -0500 added content commit af62089872de543c8f741c3092f431a8b790feec Author: Alex Date: Wed Sep 4 20:43:02 2024 -0500 fixed product recommendations commit 5c921be7b1eab4ea3b4acc922d2bde842bb0c5c8 Author: Alex Date: Wed Sep 4 20:33:28 2024 -0500 fixed cart total commit 63e150e822ab0b4f7690221ee5d1eafaaf5f930a Author: Alex Date: Wed Sep 4 20:14:47 2024 -0500 fixed update cart commit 85bd6bee403e19c7b3f66c0d6e938a8432cee62b Author: Alex Date: Wed Sep 4 19:00:42 2024 -0500 remove unnecessary cookie usage from sfcc calls commit 2401bed81143508993fdd403d9d5a419ac8904e5 Author: Alex Date: Wed Sep 4 18:55:39 2024 -0500 fixed issue with broken getCart commit f8cc8c3c3c1c64d7cf4b69a60ed87497ad626e65 Author: Alex Date: Wed Sep 4 18:23:03 2024 -0500 updated lib/sfcc for guest tokens commit bd6129e3ca15125c87c8186e9ff27d835fb2f683 Author: Alex Date: Wed Sep 4 15:19:40 2024 -0500 added now required channel_id commit eeb805fd11219d8512c1cadefe047019d63d4b60 Author: Alex Date: Tue Sep 3 17:43:27 2024 -0500 split out scapi commit e4f3bb1c827137245367152c1ff0401db76e7082 Author: Alex Date: Tue Sep 3 16:55:11 2024 -0500 carried over sfcc work commit 2616869f56f330f44ad3dfff9ad488eaaf1dbe51 Author: Alex Date: Thu Aug 22 15:03:30 2024 -0400 initial sfcc work --- .env.example | 17 +- app/[page]/opengraph-image.tsx | 7 +- app/[page]/page.tsx | 8 +- app/api/revalidate/route.ts | 2 +- app/layout.tsx | 2 +- app/page.tsx | 3 +- app/product/[handle]/page.tsx | 4 +- app/search/[collection]/opengraph-image.tsx | 2 +- app/search/[collection]/page.tsx | 4 +- app/search/page.tsx | 4 +- app/sitemap.ts | 5 +- components/carousel.tsx | 2 +- components/cart/actions.ts | 7 +- components/cart/add-to-cart.tsx | 3 +- components/cart/cart-context.tsx | 2 +- components/cart/delete-item-button.tsx | 2 +- components/cart/edit-item-quantity-button.tsx | 2 +- components/grid/three-items.tsx | 4 +- components/layout/footer-menu.tsx | 2 +- components/layout/footer.tsx | 2 +- components/layout/navbar/index.tsx | 4 +- components/layout/navbar/mobile-menu.tsx | 2 +- components/layout/product-grid-items.tsx | 2 +- components/layout/search/collections.tsx | 2 +- components/layout/search/filter/index.tsx | 2 +- components/product/product-description.tsx | 2 +- components/product/variant-selector.tsx | 2 +- components/welcome-toast.tsx | 3 +- lib/constants.ts | 46 +- lib/sfcc/constants.ts | 50 + lib/sfcc/content.ts | 205 ++++ lib/sfcc/index.ts | 631 ++++++++++++ lib/sfcc/ocapi.ts | 34 + lib/sfcc/scapi.ts | 55 ++ lib/{ => sfcc}/type-guards.ts | 14 +- lib/sfcc/types.ts | 146 +++ lib/sfcc/utils.ts | 89 ++ lib/shopify/fragments/cart.ts | 53 - lib/shopify/fragments/image.ts | 10 - lib/shopify/fragments/product.ts | 64 -- lib/shopify/fragments/seo.ts | 8 - lib/shopify/index.ts | 455 --------- lib/shopify/mutations/cart.ts | 45 - lib/shopify/queries/cart.ts | 10 - lib/shopify/queries/collection.ts | 56 -- lib/shopify/queries/menu.ts | 10 - lib/shopify/queries/page.ts | 41 - lib/shopify/queries/product.ts | 32 - lib/shopify/types.ts | 272 ------ lib/utils.ts | 28 - next.config.js | 4 + package.json | 3 +- pnpm-lock.yaml | 919 +++++++++++++++++- 53 files changed, 2236 insertions(+), 1147 deletions(-) create mode 100644 lib/sfcc/constants.ts create mode 100644 lib/sfcc/content.ts create mode 100644 lib/sfcc/index.ts create mode 100644 lib/sfcc/ocapi.ts create mode 100644 lib/sfcc/scapi.ts rename lib/{ => sfcc}/type-guards.ts (70%) create mode 100644 lib/sfcc/types.ts create mode 100644 lib/sfcc/utils.ts delete mode 100644 lib/shopify/fragments/cart.ts delete mode 100644 lib/shopify/fragments/image.ts delete mode 100644 lib/shopify/fragments/product.ts delete mode 100644 lib/shopify/fragments/seo.ts delete mode 100644 lib/shopify/index.ts delete mode 100644 lib/shopify/mutations/cart.ts delete mode 100644 lib/shopify/queries/cart.ts delete mode 100644 lib/shopify/queries/collection.ts delete mode 100644 lib/shopify/queries/menu.ts delete mode 100644 lib/shopify/queries/page.ts delete mode 100644 lib/shopify/queries/product.ts delete mode 100644 lib/shopify/types.ts diff --git a/.env.example b/.env.example index 9ff0463db..33b89cddb 100644 --- a/.env.example +++ b/.env.example @@ -1,7 +1,10 @@ -COMPANY_NAME="Vercel Inc." -TWITTER_CREATOR="@vercel" -TWITTER_SITE="https://nextjs.org/commerce" -SITE_NAME="Next.js Commerce" -SHOPIFY_REVALIDATION_SECRET="" -SHOPIFY_STOREFRONT_ACCESS_TOKEN="" -SHOPIFY_STORE_DOMAIN="[your-shopify-store-subdomain].myshopify.com" +NEXT_PUBLIC_VERCEL_URL="http://localhost:3000" +SFCC_CLIENT_ID="" +SFCC_ORGANIZATIONID="f_ecom_0000_000" +SFCC_SECRET="" +SFCC_SHORTCODE="000123" +SFCC_SITEID="RefArch" +SITE_NAME="ACME Store" +SFCC_SANDBOX_DOMAIN="zylq-002.dx.commercecloud.salesforce.com" +SFCC_OPENCOMMERCE_SHOP_API_ENDPOINT="/s/RefArch/dw/shop/v24_5" +SFCC_REVALIDATION_SECRET="" \ No newline at end of file diff --git a/app/[page]/opengraph-image.tsx b/app/[page]/opengraph-image.tsx index 2fd59281e..51dea7444 100644 --- a/app/[page]/opengraph-image.tsx +++ b/app/[page]/opengraph-image.tsx @@ -1,10 +1,13 @@ import OpengraphImage from 'components/opengraph-image'; -import { getPage } from 'lib/shopify'; +import { getPage } from 'lib/sfcc/content'; export const runtime = 'edge'; export default async function Image({ params }: { params: { page: string } }) { - const page = await getPage(params.page); + const page = getPage(params.page); + + if (!page) return; + const title = page.seo?.title || page.title; return await OpengraphImage({ title }); diff --git a/app/[page]/page.tsx b/app/[page]/page.tsx index 02aaf1366..c60d6257c 100644 --- a/app/[page]/page.tsx +++ b/app/[page]/page.tsx @@ -1,7 +1,7 @@ import type { Metadata } from 'next'; import Prose from 'components/prose'; -import { getPage } from 'lib/shopify'; +import { getPage } from 'lib/sfcc/content'; import { notFound } from 'next/navigation'; export async function generateMetadata({ @@ -9,7 +9,7 @@ export async function generateMetadata({ }: { params: { page: string }; }): Promise { - const page = await getPage(params.page); + const page = getPage(params.page); if (!page) return notFound(); @@ -24,8 +24,8 @@ export async function generateMetadata({ }; } -export default async function Page({ params }: { params: { page: string } }) { - const page = await getPage(params.page); +export default function Page({ params }: { params: { page: string } }) { + const page = getPage(params.page); if (!page) return notFound(); diff --git a/app/api/revalidate/route.ts b/app/api/revalidate/route.ts index 4ecc0b45d..d744ff093 100644 --- a/app/api/revalidate/route.ts +++ b/app/api/revalidate/route.ts @@ -1,4 +1,4 @@ -import { revalidate } from 'lib/shopify'; +import { revalidate } from 'lib/sfcc'; import { NextRequest, NextResponse } from 'next/server'; export async function POST(req: NextRequest): Promise { diff --git a/app/layout.tsx b/app/layout.tsx index 3b09ab7e4..e902fa9c2 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -2,7 +2,7 @@ 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 { getCart } from 'lib/sfcc'; import { ensureStartsWith } from 'lib/utils'; import { cookies } from 'next/headers'; import { ReactNode } from 'react'; diff --git a/app/page.tsx b/app/page.tsx index 7d407ede8..ec906d45a 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -3,7 +3,8 @@ import { ThreeItemGrid } from 'components/grid/three-items'; import Footer from 'components/layout/footer'; export const metadata = { - description: 'High-performance ecommerce store built with Next.js, Vercel, and Shopify.', + description: + 'High-performance ecommerce store built with Next.js, Vercel, and Salesforce Commerce Cloud.', openGraph: { type: 'website' } diff --git a/app/product/[handle]/page.tsx b/app/product/[handle]/page.tsx index e2280675d..be61a906f 100644 --- a/app/product/[handle]/page.tsx +++ b/app/product/[handle]/page.tsx @@ -7,8 +7,8 @@ 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'; -import { Image } from 'lib/shopify/types'; +import { getProduct, getProductRecommendations } from 'lib/sfcc'; +import { Image } from 'lib/sfcc/types'; import Link from 'next/link'; import { Suspense } from 'react'; diff --git a/app/search/[collection]/opengraph-image.tsx b/app/search/[collection]/opengraph-image.tsx index 9eb9c47f7..a7328fd80 100644 --- a/app/search/[collection]/opengraph-image.tsx +++ b/app/search/[collection]/opengraph-image.tsx @@ -1,5 +1,5 @@ import OpengraphImage from 'components/opengraph-image'; -import { getCollection } from 'lib/shopify'; +import { fetchCollection as getCollection } from 'lib/sfcc/scapi'; export const runtime = 'edge'; diff --git a/app/search/[collection]/page.tsx b/app/search/[collection]/page.tsx index e25542bfc..794aa1af6 100644 --- a/app/search/[collection]/page.tsx +++ b/app/search/[collection]/page.tsx @@ -1,10 +1,10 @@ -import { getCollection, getCollectionProducts } from 'lib/shopify'; import { Metadata } from 'next'; import { notFound } from 'next/navigation'; import Grid from 'components/grid'; import ProductGridItems from 'components/layout/product-grid-items'; -import { defaultSort, sorting } from 'lib/constants'; +import { getCollection, getCollectionProducts } from 'lib/sfcc'; +import { defaultSort, sorting } from 'lib/sfcc/constants'; export async function generateMetadata({ params diff --git a/app/search/page.tsx b/app/search/page.tsx index 60f11b189..e7b68fb52 100644 --- a/app/search/page.tsx +++ b/app/search/page.tsx @@ -1,7 +1,7 @@ import Grid from 'components/grid'; import ProductGridItems from 'components/layout/product-grid-items'; -import { defaultSort, sorting } from 'lib/constants'; -import { getProducts } from 'lib/shopify'; +import { getProducts } from 'lib/sfcc'; +import { defaultSort, sorting } from 'lib/sfcc/constants'; export const metadata = { title: 'Search', diff --git a/app/sitemap.ts b/app/sitemap.ts index 8f31ee94f..278fca7d5 100644 --- a/app/sitemap.ts +++ b/app/sitemap.ts @@ -1,5 +1,6 @@ -import { getCollections, getPages, getProducts } from 'lib/shopify'; -import { validateEnvironmentVariables } from 'lib/utils'; +import { getCollections, getProducts } from 'lib/sfcc'; +import { getPages } from 'lib/sfcc/content'; +import { validateEnvironmentVariables } from 'lib/sfcc/utils'; import { MetadataRoute } from 'next'; type Route = { diff --git a/components/carousel.tsx b/components/carousel.tsx index 751cf4b48..fc4893034 100644 --- a/components/carousel.tsx +++ b/components/carousel.tsx @@ -1,4 +1,4 @@ -import { getCollectionProducts } from 'lib/shopify'; +import { getCollectionProducts } from 'lib/sfcc'; import Link from 'next/link'; import { GridTileImage } from './grid/tile'; diff --git a/components/cart/actions.ts b/components/cart/actions.ts index a2c592557..55086024f 100644 --- a/components/cart/actions.ts +++ b/components/cart/actions.ts @@ -1,7 +1,7 @@ 'use server'; import { TAGS } from 'lib/constants'; -import { addToCart, createCart, getCart, removeFromCart, updateCart } from 'lib/shopify'; +import { addToCart, createCart, getCart, removeFromCart, updateCart } from 'lib/sfcc'; import { revalidateTag } from 'next/cache'; import { cookies } from 'next/headers'; import { redirect } from 'next/navigation'; @@ -114,5 +114,8 @@ export async function redirectToCheckout() { export async function createCartAndSetCookie() { let cart = await createCart(); - cookies().set('cartId', cart.id!); + // set the cartId to the same duration as the guest + cookies().set('cartId', cart.id!, { + maxAge: 60 * 30 + }); } diff --git a/components/cart/add-to-cart.tsx b/components/cart/add-to-cart.tsx index 8bcebb06b..5e0c5b213 100644 --- a/components/cart/add-to-cart.tsx +++ b/components/cart/add-to-cart.tsx @@ -4,7 +4,7 @@ import { PlusIcon } from '@heroicons/react/24/outline'; import clsx from 'clsx'; import { addItem } from 'components/cart/actions'; import { useProduct } from 'components/product/product-context'; -import { Product, ProductVariant } from 'lib/shopify/types'; +import { Product, ProductVariant } from 'lib/sfcc/types'; import { useFormState } from 'react-dom'; import { useCart } from './cart-context'; @@ -27,7 +27,6 @@ function SubmitButton({ ); } - console.log(selectedVariantId); if (!selectedVariantId) { return (