From 4ffb965688f81c866ae4a6304b13357a9a119449 Mon Sep 17 00:00:00 2001 From: Thomas Frost Date: Sat, 20 Jul 2024 20:54:32 -0700 Subject: [PATCH] fix(refactor): refactor code for isolation --- app/(landing)/[ContentLandingPage]/page.tsx | 78 ++++--------------- components/carousel.tsx | 2 +- components/cart/actions.ts | 2 +- components/cart/add-to-cart.tsx | 3 +- components/cart/delete-item-button.tsx | 3 +- components/cart/edit-item-quantity-button.tsx | 3 +- components/cart/index.tsx | 2 +- components/cart/modal.tsx | 3 +- components/grid/three-items.tsx | 3 +- components/layout/search/collections.tsx | 5 +- components/product/product-description.tsx | 3 +- lib/aspire/index.ts | 53 +++++++++++++ lib/aspire/types.ts | 28 +++++++ lib/shopify/index.ts | 4 +- lib/shopify/types.ts | 27 ------- 15 files changed, 117 insertions(+), 102 deletions(-) create mode 100644 lib/aspire/index.ts create mode 100644 lib/aspire/types.ts diff --git a/app/(landing)/[ContentLandingPage]/page.tsx b/app/(landing)/[ContentLandingPage]/page.tsx index 608258520..6704ea948 100644 --- a/app/(landing)/[ContentLandingPage]/page.tsx +++ b/app/(landing)/[ContentLandingPage]/page.tsx @@ -3,78 +3,34 @@ import OpenCart from 'components/cart/open-cart'; import { GridTileImage } from 'components/grid/tile'; import { Gallery } from 'components/product/gallery'; import { ProductDescription } from 'components/product/product-description'; -import { getProductById, getProductRecommendations } from 'lib/shopify'; -import { ContentLandingPages, Image, Store } from 'lib/shopify/types'; +import { getContentLandingPageConfig } from 'lib/aspire'; +import { Store } from 'lib/aspire/types'; +import { getProductRecommendations } from 'lib/shopify'; +import { Image } from 'lib/shopify/types'; import Link from 'next/link'; import { Suspense } from 'react'; -const lookupContentLandingPage = async (contentLandingPageId: string) => { - const contentLandingPages: ContentLandingPages = { - ABC: { - contentLandingPageId: 'ABC', - content: { - contentId: 'ABC-123', - contentUrl: 'https://vercel.com' - }, - brand: { - brandId: '123456789', - companyName: 'Vercel' - }, - store: { - domain: 'https://test-app-furie.myshopify.com', - key: '30f0c9b2ee5c69d6c0de2e7a048eb6b4' - }, - productId: 'gid://shopify/Product/8587441176812' - }, - '123': { - contentLandingPageId: '123', - content: { - contentId: '123-ABC', - contentUrl: 'https://vercel.com' - }, - brand: { - brandId: '123456789', - companyName: 'Vercel' - }, - store: { - domain: 'https://quickstart-ba952e54.myshopify.com', - key: '8efbd119747c632000b04ed68313abf1' - }, - productId: 'gid://shopify/Product/7913032548543' - } - }; - - const contentLandingPage = contentLandingPages[contentLandingPageId]; - - if (!contentLandingPage) { - throw new Error('Content Landing Page not found'); - } - - const product = await getProductById(contentLandingPage.store, contentLandingPage?.productId); - return { ...contentLandingPage, product }; -}; - export default async function Page({ params }: { params: { ContentLandingPage: string } }) { - const instance = await lookupContentLandingPage(params.ContentLandingPage); + const config = await getContentLandingPageConfig(params.ContentLandingPage); - if (!instance.product) { + if (!config.product) { return
Product not found
; } const productJsonLd = { '@context': 'https://schema.org', '@type': 'Product', - name: instance.product.title, - description: instance.product.description, - image: instance.product.featuredImage.url, + name: config.product.title, + description: config.product.description, + image: config.product.featuredImage.url, offers: { '@type': 'AggregateOffer', - availability: instance.product.availableForSale + availability: config.product.availableForSale ? 'https://schema.org/InStock' : 'https://schema.org/OutOfStock', - priceCurrency: instance.product.priceRange.minVariantPrice.currencyCode, - highPrice: instance.product.priceRange.maxVariantPrice.amount, - lowPrice: instance.product.priceRange.minVariantPrice.amount + priceCurrency: config.product.priceRange.minVariantPrice.currencyCode, + highPrice: config.product.priceRange.maxVariantPrice.amount, + lowPrice: config.product.priceRange.minVariantPrice.amount } }; @@ -93,7 +49,7 @@ export default async function Page({ params }: { params: { ContentLandingPage: s
}> - +
@@ -107,7 +63,7 @@ export default async function Page({ params }: { params: { ContentLandingPage: s } > ({ + images={config.product.images.map((image: Image) => ({ src: image.url, altText: image.altText }))} @@ -116,10 +72,10 @@ export default async function Page({ params }: { params: { ContentLandingPage: s
- +
- + ); diff --git a/components/carousel.tsx b/components/carousel.tsx index 078d47756..c39f589c2 100644 --- a/components/carousel.tsx +++ b/components/carousel.tsx @@ -1,5 +1,5 @@ +import { Store } from 'lib/aspire/types'; import { getCollectionProducts } from 'lib/shopify'; -import { Store } from 'lib/shopify/types'; import Link from 'next/link'; import { GridTileImage } from './grid/tile'; diff --git a/components/cart/actions.ts b/components/cart/actions.ts index 58ff495ed..105a4d17e 100644 --- a/components/cart/actions.ts +++ b/components/cart/actions.ts @@ -1,8 +1,8 @@ 'use server'; +import { Store } from 'lib/aspire/types'; import { TAGS } from 'lib/constants'; import { addToCart, createCart, getCart, removeFromCart, updateCart } from 'lib/shopify'; -import { Store } from 'lib/shopify/types'; import { revalidateTag } from 'next/cache'; import { cookies } from 'next/headers'; diff --git a/components/cart/add-to-cart.tsx b/components/cart/add-to-cart.tsx index f571fe003..b0376bb47 100644 --- a/components/cart/add-to-cart.tsx +++ b/components/cart/add-to-cart.tsx @@ -4,7 +4,8 @@ import { PlusIcon } from '@heroicons/react/24/outline'; import clsx from 'clsx'; import { addItem } from 'components/cart/actions'; import LoadingDots from 'components/loading-dots'; -import { ProductVariant, Store } from 'lib/shopify/types'; +import { Store } from 'lib/aspire/types'; +import { ProductVariant } from 'lib/shopify/types'; import { useSearchParams } from 'next/navigation'; import { useFormState, useFormStatus } from 'react-dom'; diff --git a/components/cart/delete-item-button.tsx b/components/cart/delete-item-button.tsx index 5d6f5a27d..a8c7448f2 100644 --- a/components/cart/delete-item-button.tsx +++ b/components/cart/delete-item-button.tsx @@ -4,7 +4,8 @@ import { XMarkIcon } from '@heroicons/react/24/outline'; import clsx from 'clsx'; import { removeItem } from 'components/cart/actions'; import LoadingDots from 'components/loading-dots'; -import type { CartItem, Store } from 'lib/shopify/types'; +import { Store } from 'lib/aspire/types'; +import type { CartItem } from 'lib/shopify/types'; import { useFormState, useFormStatus } from 'react-dom'; function SubmitButton() { diff --git a/components/cart/edit-item-quantity-button.tsx b/components/cart/edit-item-quantity-button.tsx index fca015390..b423c56e4 100644 --- a/components/cart/edit-item-quantity-button.tsx +++ b/components/cart/edit-item-quantity-button.tsx @@ -4,7 +4,8 @@ import { MinusIcon, PlusIcon } from '@heroicons/react/24/outline'; import clsx from 'clsx'; import { updateItemQuantity } from 'components/cart/actions'; import LoadingDots from 'components/loading-dots'; -import type { CartItem, Store } from 'lib/shopify/types'; +import { Store } from 'lib/aspire/types'; +import type { CartItem } from 'lib/shopify/types'; import { useFormState, useFormStatus } from 'react-dom'; function SubmitButton({ type }: { type: 'plus' | 'minus' }) { diff --git a/components/cart/index.tsx b/components/cart/index.tsx index 3facb9746..fc77dfc5b 100644 --- a/components/cart/index.tsx +++ b/components/cart/index.tsx @@ -1,5 +1,5 @@ +import { Store } from 'lib/aspire/types'; import { getCart } from 'lib/shopify'; -import { Store } from 'lib/shopify/types'; import { cookies } from 'next/headers'; import CartModal from './modal'; diff --git a/components/cart/modal.tsx b/components/cart/modal.tsx index 9e2d02136..1c8776c33 100644 --- a/components/cart/modal.tsx +++ b/components/cart/modal.tsx @@ -3,8 +3,9 @@ import { Dialog, Transition } from '@headlessui/react'; import { ShoppingCartIcon } from '@heroicons/react/24/outline'; import Price from 'components/price'; +import { Store } from 'lib/aspire/types'; import { DEFAULT_OPTION } from 'lib/constants'; -import type { Cart, Store } from 'lib/shopify/types'; +import type { Cart } from 'lib/shopify/types'; import { createUrl } from 'lib/utils'; import Image from 'next/image'; import Link from 'next/link'; diff --git a/components/grid/three-items.tsx b/components/grid/three-items.tsx index 26d30b1d3..36c9d32bd 100644 --- a/components/grid/three-items.tsx +++ b/components/grid/three-items.tsx @@ -1,6 +1,7 @@ import { GridTileImage } from 'components/grid/tile'; +import { Store } from 'lib/aspire/types'; import { getCollectionProducts } from 'lib/shopify'; -import type { Product, Store } from 'lib/shopify/types'; +import type { Product } from 'lib/shopify/types'; import Link from 'next/link'; function ThreeItemGridItem({ diff --git a/components/layout/search/collections.tsx b/components/layout/search/collections.tsx index 3af60a029..e6ed3d2e3 100644 --- a/components/layout/search/collections.tsx +++ b/components/layout/search/collections.tsx @@ -1,8 +1,7 @@ import clsx from 'clsx'; -import { Suspense } from 'react'; - +import { Store } from 'lib/aspire/types'; import { getCollections } from 'lib/shopify'; -import { Store } from 'lib/shopify/types'; +import { Suspense } from 'react'; import FilterList from './filter'; async function CollectionList({ store }: { store: Store }) { diff --git a/components/product/product-description.tsx b/components/product/product-description.tsx index 03dfc652a..df8f2f149 100644 --- a/components/product/product-description.tsx +++ b/components/product/product-description.tsx @@ -1,7 +1,8 @@ import { AddToCart } from 'components/cart/add-to-cart'; import Price from 'components/price'; import Prose from 'components/prose'; -import { Product, Store } from 'lib/shopify/types'; +import { Store } from 'lib/aspire/types'; +import { Product } from 'lib/shopify/types'; import { Suspense } from 'react'; import { VariantSelector } from './variant-selector'; diff --git a/lib/aspire/index.ts b/lib/aspire/index.ts new file mode 100644 index 000000000..ff125231c --- /dev/null +++ b/lib/aspire/index.ts @@ -0,0 +1,53 @@ +import { getProductById } from 'lib/shopify'; +import { ContentLandingPages } from './types'; + +export async function getContentLandingPageConfig(contentLandingPageId: string) { + const contentLandingPages: ContentLandingPages = { + ABC: { + contentLandingPageId: '01J39NYS5HKXE9J4R0BMDKH845', + slug: 'ABC', + content: { + contentId: '01J39NY002BQ5FDH6BFJR78V8E', + contentUrl: 'https://vercel.com' + }, + brand: { + brandId: '01J39NXQGAKT82JQWEYXP9MFE3', + companyName: 'Vercel' + }, + store: { + storeId: '01J39NYCJY8ZW27ES9BB7KEVXN', + domain: 'https://test-app-furie.myshopify.com', + key: '30f0c9b2ee5c69d6c0de2e7a048eb6b4' + }, + productId: 'gid://shopify/Product/8587441176812' + }, + '123': { + contentLandingPageId: '123', + slug: '123', + content: { + contentId: '01J39P1K9DY9XM2B5Y9T5RVJNP', + contentUrl: 'https://vercel.com' + }, + brand: { + brandId: '123456789', + companyName: 'Vercel' + }, + store: { + storeId: 'quickstart-ba952e54', + domain: 'https://quickstart-ba952e54.myshopify.com', + key: '8efbd119747c632000b04ed68313abf1' + }, + productId: 'gid://shopify/Product/7913032548543' + } + }; + + const contentLandingPage = contentLandingPages[contentLandingPageId]; + + if (!contentLandingPage) { + throw new Error('Content Landing Page not found'); + } + + const product = await getProductById(contentLandingPage.store, contentLandingPage?.productId); + + return { ...contentLandingPage, product }; +} diff --git a/lib/aspire/types.ts b/lib/aspire/types.ts new file mode 100644 index 000000000..d27cf9c9c --- /dev/null +++ b/lib/aspire/types.ts @@ -0,0 +1,28 @@ +export type Brand = { + brandId: string; + companyName: string; +}; + +export type Content = { + contentId: string; + contentUrl: string; +}; + +export type ContentLandingPage = { + contentLandingPageId: string; + slug: string; + content: Content; + brand: Brand; + store: Store; + productId: string; +}; + +export type ContentLandingPages = { + [key: string]: ContentLandingPage; +}; + +export type Store = { + storeId: string; + domain: string; + key: string; +}; diff --git a/lib/shopify/index.ts b/lib/shopify/index.ts index a07db797b..2363cbe79 100644 --- a/lib/shopify/index.ts +++ b/lib/shopify/index.ts @@ -1,3 +1,4 @@ +import { Store } from 'lib/aspire/types'; import { HIDDEN_PRODUCT_TAG, SHOPIFY_GRAPHQL_API_ENDPOINT, TAGS } from 'lib/constants'; import { isShopifyError } from 'lib/type-guards'; import { revalidateTag } from 'next/cache'; @@ -47,8 +48,7 @@ import { ShopifyProductRecommendationsOperation, ShopifyProductsOperation, ShopifyRemoveFromCartOperation, - ShopifyUpdateCartOperation, - Store + ShopifyUpdateCartOperation } from './types'; /* diff --git a/lib/shopify/types.ts b/lib/shopify/types.ts index 63df92740..9ead614ff 100644 --- a/lib/shopify/types.ts +++ b/lib/shopify/types.ts @@ -8,33 +8,6 @@ export type Edge = { node: T; }; -export type Brand = { - brandId: string; - companyName: string; -}; - -export type Content = { - contentId: string; - contentUrl: string; -}; - -export type ContentLandingPage = { - contentLandingPageId: string; - content: Content; - brand: Brand; - store: Store; - productId: string; -}; - -export type ContentLandingPages = { - [key: string]: ContentLandingPage; -}; - -export type Store = { - domain: string; - key: string; -}; - export type Cart = Omit & { lines: CartItem[]; };