Monorepo with Turborepo (#651)

* Moved everything

* Figuring out how to make imports work

* Updated exports

* Added missing exports

* Added @vercel/commerce-local to `site`

* Updated commerce config

* Updated exports and commerce config

* Updated commerce hoc

* Fixed exports in local

* Added publish config

* Updated imports in site

* It's actually working

* Don't use debugger in dev for better speeds

* Improved DX when editing packages

* Set up eslint with husky

* Updated prettier config

* Added prettier setup to every package

* Moved bigcommerce

* Moved Bigcommerce to src and package updates

* Updated setup of bigcommerce

* Moved definitions script

* Moved commercejs

* Move to src

* Fixed types in commercejs

* Moved kibocommerce

* Moved kibocommerce to src

* Added package/tsconfig to kibocommerce

* Fixed imports and other things

* Moved ordercloud

* Moved ordercloud to src

* Fixed imports

* Added missing prettier files

* Moved Saleor

* Moved Saleor to src

* Fixed imports

* Replaced all imports to @commerce

* Added prettierignore/rc to all providers

* Moved shopify to src

* Build shopify in packages

* Moved Spree

* Moved spree to src

* Updated spree

* Moved swell

* Moved swell to src

* Fixed type imports in swell

* Moved Vendure to packages

* Moved vendure to src

* Fixed imports in vendure

* Added codegen to saleor

* Updated codegen setup for shopify

* Added codegen to vendure

* Added codegen to kibocommerce

* Added all packages to site's deps

* Updated codegen setup in bigcommerce

* Minor fixes

* Updated providers' names in site

* Updated packages based on Bel's changes

* Updated turbo to latest

* Fixed ts complains

* Set npm engine in root

* New lockfile install

* remove engines

* Regen lockfile

* Switched from npm to yarn

* Updated typesVersions in all packages

* Moved dep

* Updated SWR to the just released 1.2.0

* Removed "isolatedModules" from packages

* Updated list of providers and default

* Updated swell declaration

* Removed next import from kibocommerce

* Added COMMERCE_PROVIDER log

* Added another log

* Updated turbo config

* Updated docs

* Removed test logs

Co-authored-by: Jared Palmer <jared@jaredpalmer.com>
This commit is contained in:
Luis Alvarez D
2022-02-01 14:14:05 -05:00
committed by GitHub
parent d0ef346189
commit 0afe686fe9
1326 changed files with 9109 additions and 19494 deletions

35
site/pages/404.tsx Normal file
View File

@@ -0,0 +1,35 @@
import type { GetStaticPropsContext } from 'next'
import commerce from '@lib/api/commerce'
import { Layout } from '@components/common'
import { Text } from '@components/ui'
export async function getStaticProps({
preview,
locale,
locales,
}: GetStaticPropsContext) {
const config = { locale, locales }
const { pages } = await commerce.getAllPages({ config, preview })
const { categories, brands } = await commerce.getSiteInfo({ config, preview })
return {
props: {
pages,
categories,
brands,
},
revalidate: 200,
}
}
export default function NotFound() {
return (
<div className="max-w-2xl mx-8 sm:mx-auto py-20 flex flex-col items-center justify-center fit">
<Text variant="heading">Not Found</Text>
<Text className="">
The requested page doesn't exist or you don't have access to it.
</Text>
</div>
)
}
NotFound.Layout = Layout

86
site/pages/[...pages].tsx Normal file
View File

@@ -0,0 +1,86 @@
import type {
GetStaticPathsContext,
GetStaticPropsContext,
InferGetStaticPropsType,
} from 'next'
import commerce from '@lib/api/commerce'
import { Text } from '@components/ui'
import { Layout } from '@components/common'
import getSlug from '@lib/get-slug'
import { missingLocaleInPages } from '@lib/usage-warns'
import type { Page } from '@commerce/types/page'
import { useRouter } from 'next/router'
export async function getStaticProps({
preview,
params,
locale,
locales,
}: GetStaticPropsContext<{ pages: string[] }>) {
const config = { locale, locales }
const pagesPromise = commerce.getAllPages({ config, preview })
const siteInfoPromise = commerce.getSiteInfo({ config, preview })
const { pages } = await pagesPromise
const { categories } = await siteInfoPromise
const path = params?.pages.join('/')
const slug = locale ? `${locale}/${path}` : path
const pageItem = pages.find((p: Page) =>
p.url ? getSlug(p.url) === slug : false
)
const data =
pageItem &&
(await commerce.getPage({
variables: { id: pageItem.id! },
config,
preview,
}))
const page = data?.page
if (!page) {
// We throw to make sure this fails at build time as this is never expected to happen
throw new Error(`Page with slug '${slug}' not found`)
}
return {
props: { pages, page, categories },
revalidate: 60 * 60, // Every hour
}
}
export async function getStaticPaths({ locales }: GetStaticPathsContext) {
const config = { locales }
const { pages }: { pages: Page[] } = await commerce.getAllPages({ config })
const [invalidPaths, log] = missingLocaleInPages()
const paths = pages
.map((page) => page.url)
.filter((url) => {
if (!url || !locales) return url
// If there are locales, only include the pages that include one of the available locales
if (locales.includes(getSlug(url).split('/')[0])) return url
invalidPaths.push(url)
})
log()
return {
paths,
fallback: 'blocking',
}
}
export default function Pages({
page,
}: InferGetStaticPropsType<typeof getStaticProps>) {
const router = useRouter()
return router.isFallback ? (
<h1>Loading...</h1> // TODO (BC) Add Skeleton Views
) : (
<div className="max-w-2xl mx-8 sm:mx-auto py-20">
{page?.body && <Text html={page.body} />}
</div>
)
}
Pages.Layout = Layout

29
site/pages/_app.tsx Normal file
View File

@@ -0,0 +1,29 @@
import '@assets/main.css'
import '@assets/chrome-bug.css'
import 'keen-slider/keen-slider.min.css'
import { FC, useEffect } from 'react'
import type { AppProps } from 'next/app'
import { Head } from '@components/common'
import { ManagedUIContext } from '@components/ui/context'
const Noop: FC = ({ children }) => <>{children}</>
export default function MyApp({ Component, pageProps }: AppProps) {
const Layout = (Component as any).Layout || Noop
useEffect(() => {
document.body.classList?.remove('loading')
}, [])
return (
<>
<Head />
<ManagedUIContext>
<Layout pageProps={pageProps}>
<Component {...pageProps} />
</Layout>
</ManagedUIContext>
</>
)
}

17
site/pages/_document.tsx Normal file
View File

@@ -0,0 +1,17 @@
import Document, { Head, Html, Main, NextScript } from 'next/document'
class MyDocument extends Document {
render() {
return (
<Html>
<Head />
<body className="loading">
<Main />
<NextScript />
</body>
</Html>
)
}
}
export default MyDocument

4
site/pages/api/cart.ts Normal file
View File

@@ -0,0 +1,4 @@
import cartApi from '@framework/api/endpoints/cart'
import commerce from '@lib/api/commerce'
export default cartApi(commerce)

View File

@@ -0,0 +1,4 @@
import productsApi from '@framework/api/endpoints/catalog/products'
import commerce from '@lib/api/commerce'
export default productsApi(commerce)

View File

@@ -0,0 +1,4 @@
import checkoutApi from '@framework/api/endpoints/checkout'
import commerce from '@lib/api/commerce'
export default checkoutApi(commerce)

View File

@@ -0,0 +1,4 @@
import customerAddressApi from '@framework/api/endpoints/customer/address'
import commerce from '@lib/api/commerce'
export default customerAddressApi(commerce)

View File

@@ -0,0 +1,4 @@
import customerCardApi from '@framework/api/endpoints/customer/card'
import commerce from '@lib/api/commerce'
export default customerCardApi(commerce)

View File

@@ -0,0 +1,4 @@
import customerApi from '@framework/api/endpoints/customer'
import commerce from '@lib/api/commerce'
export default customerApi(commerce)

4
site/pages/api/login.ts Normal file
View File

@@ -0,0 +1,4 @@
import loginApi from '@framework/api/endpoints/login'
import commerce from '@lib/api/commerce'
export default loginApi(commerce)

4
site/pages/api/logout.ts Normal file
View File

@@ -0,0 +1,4 @@
import logoutApi from '@framework/api/endpoints/logout'
import commerce from '@lib/api/commerce'
export default logoutApi(commerce)

4
site/pages/api/signup.ts Normal file
View File

@@ -0,0 +1,4 @@
import singupApi from '@framework/api/endpoints/signup'
import commerce from '@lib/api/commerce'
export default singupApi(commerce)

View File

@@ -0,0 +1,4 @@
import wishlistApi from '@framework/api/endpoints/wishlist'
import commerce from '@lib/api/commerce'
export default wishlistApi(commerce)

192
site/pages/cart.tsx Normal file
View File

@@ -0,0 +1,192 @@
import type { GetStaticPropsContext } from 'next'
import useCart from '@framework/cart/use-cart'
import usePrice from '@framework/product/use-price'
import commerce from '@lib/api/commerce'
import { Layout } from '@components/common'
import { Button, Text } from '@components/ui'
import { Bag, Cross, Check, MapPin, CreditCard } from '@components/icons'
import { CartItem } from '@components/cart'
import { useUI } from '@components/ui/context'
export async function getStaticProps({
preview,
locale,
locales,
}: GetStaticPropsContext) {
const config = { locale, locales }
const pagesPromise = commerce.getAllPages({ config, preview })
const siteInfoPromise = commerce.getSiteInfo({ config, preview })
const { pages } = await pagesPromise
const { categories } = await siteInfoPromise
return {
props: { pages, categories },
}
}
export default function Cart() {
const error = null
const success = null
const { data, isLoading, isEmpty } = useCart()
const { openSidebar, setSidebarView } = useUI()
const { price: subTotal } = usePrice(
data && {
amount: Number(data.subtotalPrice),
currencyCode: data.currency.code,
}
)
const { price: total } = usePrice(
data && {
amount: Number(data.totalPrice),
currencyCode: data.currency.code,
}
)
const goToCheckout = () => {
openSidebar()
setSidebarView('CHECKOUT_VIEW')
}
return (
<div className="grid lg:grid-cols-12 w-full max-w-7xl mx-auto">
<div className="lg:col-span-8">
{isLoading || isEmpty ? (
<div className="flex-1 px-12 py-24 flex flex-col justify-center items-center ">
<span className="border border-dashed border-secondary flex items-center justify-center w-16 h-16 bg-primary p-12 rounded-lg text-primary">
<Bag className="absolute" />
</span>
<h2 className="pt-6 text-2xl font-bold tracking-wide text-center">
Your cart is empty
</h2>
<p className="text-accent-6 px-10 text-center pt-2">
Biscuit oat cake wafer icing ice cream tiramisu pudding cupcake.
</p>
</div>
) : error ? (
<div className="flex-1 px-4 flex flex-col justify-center items-center">
<span className="border border-white rounded-full flex items-center justify-center w-16 h-16">
<Cross width={24} height={24} />
</span>
<h2 className="pt-6 text-xl font-light text-center">
We couldnt process the purchase. Please check your card
information and try again.
</h2>
</div>
) : success ? (
<div className="flex-1 px-4 flex flex-col justify-center items-center">
<span className="border border-white rounded-full flex items-center justify-center w-16 h-16">
<Check />
</span>
<h2 className="pt-6 text-xl font-light text-center">
Thank you for your order.
</h2>
</div>
) : (
<div className="px-4 sm:px-6 flex-1">
<Text variant="pageHeading">My Cart</Text>
<Text variant="sectionHeading">Review your Order</Text>
<ul className="py-6 space-y-6 sm:py-0 sm:space-y-0 sm:divide-y sm:divide-accent-2 border-b border-accent-2">
{data!.lineItems.map((item: any) => (
<CartItem
key={item.id}
item={item}
currencyCode={data?.currency.code!}
/>
))}
</ul>
<div className="my-6">
<Text>
Before you leave, take a look at these items. We picked them
just for you
</Text>
<div className="flex py-6 space-x-6">
{[1, 2, 3, 4, 5, 6].map((x) => (
<div
key={x}
className="border border-accent-3 w-full h-24 bg-accent-2 bg-opacity-50 transform cursor-pointer hover:scale-110 duration-75"
/>
))}
</div>
</div>
</div>
)}
</div>
<div className="lg:col-span-4">
<div className="flex-shrink-0 px-4 py-24 sm:px-6">
{process.env.COMMERCE_CUSTOMCHECKOUT_ENABLED && (
<>
{/* Shipping Address */}
{/* Only available with customCheckout set to true - Meaning that the provider does offer checkout functionality. */}
<div className="rounded-md border border-accent-2 px-6 py-6 mb-4 text-center flex items-center justify-center cursor-pointer hover:border-accent-4">
<div className="mr-5">
<MapPin />
</div>
<div className="text-sm text-center font-medium">
<span className="uppercase">+ Add Shipping Address</span>
{/* <span>
1046 Kearny Street.<br/>
San Franssisco, California
</span> */}
</div>
</div>
{/* Payment Method */}
{/* Only available with customCheckout set to true - Meaning that the provider does offer checkout functionality. */}
<div className="rounded-md border border-accent-2 px-6 py-6 mb-4 text-center flex items-center justify-center cursor-pointer hover:border-accent-4">
<div className="mr-5">
<CreditCard />
</div>
<div className="text-sm text-center font-medium">
<span className="uppercase">+ Add Payment Method</span>
{/* <span>VISA #### #### #### 2345</span> */}
</div>
</div>
</>
)}
<div className="border-t border-accent-2">
<ul className="py-3">
<li className="flex justify-between py-1">
<span>Subtotal</span>
<span>{subTotal}</span>
</li>
<li className="flex justify-between py-1">
<span>Taxes</span>
<span>Calculated at checkout</span>
</li>
<li className="flex justify-between py-1">
<span>Estimated Shipping</span>
<span className="font-bold tracking-wide">FREE</span>
</li>
</ul>
<div className="flex justify-between border-t border-accent-2 py-3 font-bold mb-10">
<span>Total</span>
<span>{total}</span>
</div>
</div>
<div className="flex flex-row justify-end">
<div className="w-full lg:w-72">
{isEmpty ? (
<Button href="/" Component="a" width="100%">
Continue Shopping
</Button>
) : (
<>
{process.env.COMMERCE_CUSTOMCHECKOUT_ENABLED ? (
<Button Component="a" width="100%" onClick={goToCheckout}>
Proceed to Checkout ({total})
</Button>
) : (
<Button href="/checkout" Component="a" width="100%">
Proceed to Checkout
</Button>
)}
</>
)}
</div>
</div>
</div>
</div>
</div>
)
}
Cart.Layout = Layout

91
site/pages/index.tsx Normal file
View File

@@ -0,0 +1,91 @@
import commerce from '@lib/api/commerce'
import { Layout } from '@components/common'
import { ProductCard } from '@components/product'
import { Grid, Marquee, Hero } from '@components/ui'
// import HomeAllProductsGrid from '@components/common/HomeAllProductsGrid'
import type { GetStaticPropsContext, InferGetStaticPropsType } from 'next'
export async function getStaticProps({
preview,
locale,
locales,
}: GetStaticPropsContext) {
const config = { locale, locales }
const productsPromise = commerce.getAllProducts({
variables: { first: 6 },
config,
preview,
// Saleor provider only
...({ featured: true } as any),
})
const pagesPromise = commerce.getAllPages({ config, preview })
const siteInfoPromise = commerce.getSiteInfo({ config, preview })
const { products } = await productsPromise
const { pages } = await pagesPromise
const { categories, brands } = await siteInfoPromise
return {
props: {
products,
categories,
brands,
pages,
},
revalidate: 60,
}
}
export default function Home({
products,
}: InferGetStaticPropsType<typeof getStaticProps>) {
return (
<>
<Grid variant="filled">
{products.slice(0, 3).map((product: any, i: number) => (
<ProductCard
key={product.id}
product={product}
imgProps={{
width: i === 0 ? 1080 : 540,
height: i === 0 ? 1080 : 540,
priority: true,
}}
/>
))}
</Grid>
<Marquee variant="secondary">
{products.slice(0, 3).map((product: any, i: number) => (
<ProductCard key={product.id} product={product} variant="slim" />
))}
</Marquee>
<Hero
headline=" Dessert dragée halvah croissant."
description="Cupcake ipsum dolor sit amet lemon drops pastry cotton candy. Sweet carrot cake macaroon bonbon croissant fruitcake jujubes macaroon oat cake. Soufflé bonbon caramels jelly beans. Tiramisu sweet roll cheesecake pie carrot cake. "
/>
<Grid layout="B" variant="filled">
{products.slice(0, 3).map((product: any, i: number) => (
<ProductCard
key={product.id}
product={product}
imgProps={{
width: i === 0 ? 1080 : 540,
height: i === 0 ? 1080 : 540,
}}
/>
))}
</Grid>
<Marquee>
{products.slice(3).map((product: any, i: number) => (
<ProductCard key={product.id} product={product} variant="slim" />
))}
</Marquee>
{/* <HomeAllProductsGrid
newestProducts={products}
categories={categories}
brands={brands}
/> */}
</>
)
}
Home.Layout = Layout

42
site/pages/orders.tsx Normal file
View File

@@ -0,0 +1,42 @@
import type { GetStaticPropsContext } from 'next'
import commerce from '@lib/api/commerce'
import { Bag } from '@components/icons'
import { Layout } from '@components/common'
import { Container, Text } from '@components/ui'
export async function getStaticProps({
preview,
locale,
locales,
}: GetStaticPropsContext) {
const config = { locale, locales }
const pagesPromise = commerce.getAllPages({ config, preview })
const siteInfoPromise = commerce.getSiteInfo({ config, preview })
const { pages } = await pagesPromise
const { categories } = await siteInfoPromise
return {
props: { pages, categories },
}
}
export default function Orders() {
return (
<Container>
<Text variant="pageHeading">My Orders</Text>
<div className="flex-1 p-24 flex flex-col justify-center items-center ">
<span className="border border-dashed border-secondary rounded-full flex items-center justify-center w-16 h-16 p-12 bg-primary text-primary">
<Bag className="absolute" />
</span>
<h2 className="pt-6 text-2xl font-bold tracking-wide text-center">
No orders found
</h2>
<p className="text-accent-6 px-10 text-center pt-2">
Biscuit oat cake wafer icing ice cream tiramisu pudding cupcake.
</p>
</div>
</Container>
)
}
Orders.Layout = Layout

View File

@@ -0,0 +1,81 @@
import type {
GetStaticPathsContext,
GetStaticPropsContext,
InferGetStaticPropsType,
} from 'next'
import { useRouter } from 'next/router'
import commerce from '@lib/api/commerce'
import { Layout } from '@components/common'
import { ProductView } from '@components/product'
export async function getStaticProps({
params,
locale,
locales,
preview,
}: GetStaticPropsContext<{ slug: string }>) {
const config = { locale, locales }
const pagesPromise = commerce.getAllPages({ config, preview })
const siteInfoPromise = commerce.getSiteInfo({ config, preview })
const productPromise = commerce.getProduct({
variables: { slug: params!.slug },
config,
preview,
})
const allProductsPromise = commerce.getAllProducts({
variables: { first: 4 },
config,
preview,
})
const { pages } = await pagesPromise
const { categories } = await siteInfoPromise
const { product } = await productPromise
const { products: relatedProducts } = await allProductsPromise
if (!product) {
throw new Error(`Product with slug '${params!.slug}' not found`)
}
return {
props: {
pages,
product,
relatedProducts,
categories,
},
revalidate: 200,
}
}
export async function getStaticPaths({ locales }: GetStaticPathsContext) {
const { products } = await commerce.getAllProductPaths()
return {
paths: locales
? locales.reduce<string[]>((arr, locale) => {
// Add a product path for every locale
products.forEach((product: any) => {
arr.push(`/${locale}/product${product.path}`)
})
return arr
}, [])
: products.map((product: any) => `/product${product.path}`),
fallback: 'blocking',
}
}
export default function Slug({
product,
relatedProducts,
}: InferGetStaticPropsType<typeof getStaticProps>) {
const router = useRouter()
return router.isFallback ? (
<h1>Loading...</h1>
) : (
<ProductView product={product} relatedProducts={relatedProducts} />
)
}
Slug.Layout = Layout

48
site/pages/profile.tsx Normal file
View File

@@ -0,0 +1,48 @@
import type { GetStaticPropsContext } from 'next'
import useCustomer from '@framework/customer/use-customer'
import commerce from '@lib/api/commerce'
import { Layout } from '@components/common'
import { Container, Text } from '@components/ui'
export async function getStaticProps({
preview,
locale,
locales,
}: GetStaticPropsContext) {
const config = { locale, locales }
const pagesPromise = commerce.getAllPages({ config, preview })
const siteInfoPromise = commerce.getSiteInfo({ config, preview })
const { pages } = await pagesPromise
const { categories } = await siteInfoPromise
return {
props: { pages, categories },
}
}
export default function Profile() {
const { data } = useCustomer()
return (
<Container>
<Text variant="pageHeading">My Profile</Text>
{data && (
<div className="grid lg:grid-cols-12">
<div className="lg:col-span-8 pr-4">
<div>
<Text variant="sectionHeading">Full Name</Text>
<span>
{data.firstName} {data.lastName}
</span>
</div>
<div className="mt-5">
<Text variant="sectionHeading">Email</Text>
<span>{data.email}</span>
</div>
</div>
</div>
)}
</Container>
)
}
Profile.Layout = Layout

9
site/pages/search.tsx Normal file
View File

@@ -0,0 +1,9 @@
import { getSearchStaticProps } from '@lib/search-props'
import type { GetStaticPropsContext } from 'next'
import Search from '@components/search'
export async function getStaticProps(context: GetStaticPropsContext) {
return getSearchStaticProps(context)
}
export default Search

View File

@@ -0,0 +1,16 @@
import { getSearchStaticProps } from '@lib/search-props'
import type { GetStaticPathsResult, GetStaticPropsContext } from 'next'
import Search from '@components/search'
export async function getStaticProps(context: GetStaticPropsContext) {
return getSearchStaticProps(context)
}
export function getStaticPaths(): GetStaticPathsResult {
return {
paths: [],
fallback: 'blocking',
}
}
export default Search

View File

@@ -0,0 +1,16 @@
import { getSearchStaticProps } from '@lib/search-props'
import type { GetStaticPathsResult, GetStaticPropsContext } from 'next'
import Search from '@components/search'
export async function getStaticProps(context: GetStaticPropsContext) {
return getSearchStaticProps(context)
}
export function getStaticPaths(): GetStaticPathsResult {
return {
paths: [],
fallback: 'blocking',
}
}
export default Search

View File

@@ -0,0 +1,16 @@
import { getSearchStaticProps } from '@lib/search-props'
import type { GetStaticPathsResult, GetStaticPropsContext } from 'next'
import Search from '@components/search'
export async function getStaticProps(context: GetStaticPropsContext) {
return getSearchStaticProps(context)
}
export function getStaticPaths(): GetStaticPathsResult {
return {
paths: [],
fallback: 'blocking',
}
}
export default Search

82
site/pages/wishlist.tsx Normal file
View File

@@ -0,0 +1,82 @@
import type { GetStaticPropsContext } from 'next'
import commerce from '@lib/api/commerce'
import { Heart } from '@components/icons'
import { Layout } from '@components/common'
import { Text, Container, Skeleton } from '@components/ui'
import { useCustomer } from '@framework/customer'
import { WishlistCard } from '@components/wishlist'
import useWishlist from '@framework/wishlist/use-wishlist'
import rangeMap from '@lib/range-map'
export async function getStaticProps({
preview,
locale,
locales,
}: GetStaticPropsContext) {
// Disabling page if Feature is not available
if (!process.env.COMMERCE_WISHLIST_ENABLED) {
return {
notFound: true,
}
}
const config = { locale, locales }
const pagesPromise = commerce.getAllPages({ config, preview })
const siteInfoPromise = commerce.getSiteInfo({ config, preview })
const { pages } = await pagesPromise
const { categories } = await siteInfoPromise
return {
props: {
pages,
categories,
},
}
}
export default function Wishlist() {
const { data: customer } = useCustomer()
// @ts-ignore Shopify - Fix this types
const { data, isLoading, isEmpty } = useWishlist({ includeProducts: true })
return (
<Container>
<div className="mt-3 mb-20">
<Text variant="pageHeading">My Wishlist</Text>
<div className="group flex flex-col">
{isLoading ? (
<div className="grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3">
{rangeMap(12, (i) => (
<Skeleton key={i}>
<div className="w-60 h-60" />
</Skeleton>
))}
</div>
) : isEmpty ? (
<div className="flex-1 px-12 py-24 flex flex-col justify-center items-center ">
<span className="border border-dashed border-secondary flex items-center justify-center w-16 h-16 bg-primary p-12 rounded-lg text-primary">
<Heart className="absolute" />
</span>
<h2 className="pt-6 text-2xl font-bold tracking-wide text-center">
Your wishlist is empty
</h2>
<p className="text-accent-6 px-10 text-center pt-2">
Biscuit oat cake wafer icing ice cream tiramisu pudding cupcake.
</p>
</div>
) : (
<div className="grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3">
{data &&
// @ts-ignore Shopify - Fix this types
data.items?.map((item) => (
<WishlistCard key={item.id} item={item!} />
))}
</div>
)}
</div>
</div>
</Container>
)
}
Wishlist.Layout = Layout