mirror of
https://github.com/vercel/commerce.git
synced 2025-07-23 04:36:49 +00:00
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:
35
site/pages/404.tsx
Normal file
35
site/pages/404.tsx
Normal 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
86
site/pages/[...pages].tsx
Normal 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
29
site/pages/_app.tsx
Normal 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
17
site/pages/_document.tsx
Normal 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
4
site/pages/api/cart.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
import cartApi from '@framework/api/endpoints/cart'
|
||||
import commerce from '@lib/api/commerce'
|
||||
|
||||
export default cartApi(commerce)
|
4
site/pages/api/catalog/products.ts
Normal file
4
site/pages/api/catalog/products.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
import productsApi from '@framework/api/endpoints/catalog/products'
|
||||
import commerce from '@lib/api/commerce'
|
||||
|
||||
export default productsApi(commerce)
|
4
site/pages/api/checkout.ts
Normal file
4
site/pages/api/checkout.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
import checkoutApi from '@framework/api/endpoints/checkout'
|
||||
import commerce from '@lib/api/commerce'
|
||||
|
||||
export default checkoutApi(commerce)
|
4
site/pages/api/customer/address.ts
Normal file
4
site/pages/api/customer/address.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
import customerAddressApi from '@framework/api/endpoints/customer/address'
|
||||
import commerce from '@lib/api/commerce'
|
||||
|
||||
export default customerAddressApi(commerce)
|
4
site/pages/api/customer/card.ts
Normal file
4
site/pages/api/customer/card.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
import customerCardApi from '@framework/api/endpoints/customer/card'
|
||||
import commerce from '@lib/api/commerce'
|
||||
|
||||
export default customerCardApi(commerce)
|
4
site/pages/api/customer/index.ts
Normal file
4
site/pages/api/customer/index.ts
Normal 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
4
site/pages/api/login.ts
Normal 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
4
site/pages/api/logout.ts
Normal 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
4
site/pages/api/signup.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
import singupApi from '@framework/api/endpoints/signup'
|
||||
import commerce from '@lib/api/commerce'
|
||||
|
||||
export default singupApi(commerce)
|
4
site/pages/api/wishlist.ts
Normal file
4
site/pages/api/wishlist.ts
Normal 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
192
site/pages/cart.tsx
Normal 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 couldn’t 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
91
site/pages/index.tsx
Normal 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
42
site/pages/orders.tsx
Normal 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
|
81
site/pages/product/[slug].tsx
Normal file
81
site/pages/product/[slug].tsx
Normal 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
48
site/pages/profile.tsx
Normal 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
9
site/pages/search.tsx
Normal 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
|
16
site/pages/search/[category].tsx
Normal file
16
site/pages/search/[category].tsx
Normal 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
|
16
site/pages/search/designers/[name].tsx
Normal file
16
site/pages/search/designers/[name].tsx
Normal 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
|
16
site/pages/search/designers/[name]/[category].tsx
Normal file
16
site/pages/search/designers/[name]/[category].tsx
Normal 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
82
site/pages/wishlist.tsx
Normal 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
|
Reference in New Issue
Block a user