New Release (#371)

* Custom Checkout Progress

* Updates to Checkout

* Custom Checkout Progress

* Adding tabs

* Adding Collapse

* Adding Collapse

* Improving Sidebar Scroll

* Modif footer

* Changes

* More design updates

* sidebar cart

* More design updates

* More design updates

* More design updates

* More design updates

* Types

* Types

* Design Updates

* More changes

* More changes

* More changes

* Changes

* Changes

* Changes

* New tailwind required changes

* Sidebar Styling issues with Mobile

* Latest changes - Normalizing cart

* Styling Fixes

* New changes

* Changes

* latest

* Refactor and Renaming some UI Props

* Adding Quantity Component

* Adding Rating Component

* Rating Component

* More updates

* User Select disabled, plus hidding horizontal scroll bars

* Changes

* Adding ProductOptions Component and more helpers

* Styling updates

* Styling updates

* Fix for slim tags

* Missmatch with RightArrow

* Footer updates and some styles

* Latest Updates

* Latest Updates

* Latest Updates

* Removing Portal, since it's not needed. We might add it later I'd rather not to.

* Removing Portal, since it's not needed. We might add it later I'd rather not to.

* Sam backdrop filter

* General UI Improvements

* General UI Improvements

* Search now with Geist Colors

* Now with Geist Colors

* Changes

* Scroll for Mobile on IOs devises

* LoadingDots Working (:

* Changes

* More Changes

* Perf changes

* More perf changes

* Fade to the Nametags in the ProductCard

* changes

* Search issue ui

* Search issue ui

* Make sure to only refresh navbar and modals when required

* Index revalidate

* Fixed image issue

* hide album scroll on windows

* Fix scrollbar

* Changing

* Adding 404 with Layout

* Removing Toast

* Adding Assets

* Adding Assets

* Progress with LocalProvider

* New productTag

* Only images for the drop

* changes

* Empty SWRhooks

* Adding Local Provider

* Working local

* Working view of a LocalProvider

* More updates

* Changes

* Removed react-ticker

* default to local if no env available

* default to local if no env available

* add missing `@` to css import

* rewrite search rewrites to multiple pages

* allow requests in getStaticProps to execute in parallel

* make type import explicit

* add a tsconfig.js file

* use local provider in tsconfig.js

* avoid a circular dependency

* Saleor was not in the providers list

* avoid circular dependency in bigcommerce

* Adding more to the Local Provider (#366)

* Adding more data

* Adding more data

* optimize assets (#370)

* Optimize assets (#372)

* optimize assets

* remove assets

* remove assets

* cart enabled

* Adding saleor

* Changes with Webpack

* Changes

Co-authored-by: Luis Alvarez <luis@vercel.com>
Co-authored-by: Tobias Koppers <tobias.koppers@googlemail.com>
Co-authored-by: Shu Ding <g@shud.in>
This commit is contained in:
B
2021-06-15 20:23:17 -03:00
committed by GitHub
parent 3c9b90f453
commit 78cc378a72
202 changed files with 15406 additions and 2201 deletions

35
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

View File

@@ -8,6 +8,7 @@ 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({
@@ -17,11 +18,15 @@ export async function getStaticProps({
locales,
}: GetStaticPropsContext<{ pages: string[] }>) {
const config = { locale, locales }
const { pages } = await commerce.getAllPages({ config, preview })
const { categories } = await commerce.getSiteInfo({ config, preview })
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) => (p.url ? getSlug(p.url) === slug : false))
const pageItem = pages.find((p: Page) =>
p.url ? getSlug(p.url) === slug : false
)
const data =
pageItem &&
(await commerce.getPage({
@@ -45,7 +50,7 @@ export async function getStaticProps({
export async function getStaticPaths({ locales }: GetStaticPathsContext) {
const config = { locales }
const { pages } = await commerce.getAllPages({ config })
const { pages }: { pages: Page[] } = await commerce.getAllPages({ config })
const [invalidPaths, log] = missingLocaleInPages()
const paths = pages
.map((page) => page.url)

View File

@@ -13,8 +13,10 @@ export async function getStaticProps({
locales,
}: GetStaticPropsContext) {
const config = { locale, locales }
const { pages } = await commerce.getAllPages({ config, preview })
const { categories } = await commerce.getSiteInfo({ config, preview })
const pagesPromise = commerce.getAllPages({ config, preview })
const siteInfoPromise = commerce.getSiteInfo({ config, preview })
const { pages } = await pagesPromise
const { categories } = await siteInfoPromise
return {
props: { pages, categories },
}
@@ -49,7 +51,7 @@ export default function Cart() {
<h2 className="pt-6 text-2xl font-bold tracking-wide text-center">
Your cart is empty
</h2>
<p className="text-accents-6 px-10 text-center pt-2">
<p className="text-accent-6 px-10 text-center pt-2">
Biscuit oat cake wafer icing ice cream tiramisu pudding cupcake.
</p>
</div>
@@ -76,8 +78,8 @@ export default function Cart() {
<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-accents-2 border-b border-accents-2">
{data!.lineItems.map((item) => (
<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}
@@ -94,7 +96,7 @@ export default function Cart() {
{[1, 2, 3, 4, 5, 6].map((x) => (
<div
key={x}
className="border border-accents-3 w-full h-24 bg-accents-2 bg-opacity-50 transform cursor-pointer hover:scale-110 duration-75"
className="border border-accent-3 w-full h-24 bg-accent-2 bg-opacity-50 transform cursor-pointer hover:scale-110 duration-75"
/>
))}
</div>
@@ -108,7 +110,7 @@ export default function Cart() {
<>
{/* Shipping Address */}
{/* Only available with customCheckout set to true - Meaning that the provider does offer checkout functionality. */}
<div className="rounded-md border border-accents-2 px-6 py-6 mb-4 text-center flex items-center justify-center cursor-pointer hover:border-accents-4">
<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>
@@ -122,7 +124,7 @@ export default function Cart() {
</div>
{/* Payment Method */}
{/* Only available with customCheckout set to true - Meaning that the provider does offer checkout functionality. */}
<div className="rounded-md border border-accents-2 px-6 py-6 mb-4 text-center flex items-center justify-center cursor-pointer hover:border-accents-4">
<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>
@@ -133,7 +135,7 @@ export default function Cart() {
</div>
</>
)}
<div className="border-t border-accents-2">
<div className="border-t border-accent-2">
<ul className="py-3">
<li className="flex justify-between py-1">
<span>Subtotal</span>
@@ -148,7 +150,7 @@ export default function Cart() {
<span className="font-bold tracking-wide">FREE</span>
</li>
</ul>
<div className="flex justify-between border-t border-accents-2 py-3 font-bold mb-10">
<div className="flex justify-between border-t border-accent-2 py-3 font-bold mb-10">
<span>Total</span>
<span>{total}</span>
</div>

View File

@@ -11,15 +11,18 @@ export async function getStaticProps({
locales,
}: GetStaticPropsContext) {
const config = { locale, locales }
const { products } = await commerce.getAllProducts({
variables: { first: 12 },
const productsPromise = commerce.getAllProducts({
variables: { first: 6 },
config,
preview,
// Saleor provider only
...({ featured: true } as any),
})
const { categories, brands } = await commerce.getSiteInfo({ config, preview })
const { pages } = await commerce.getAllPages({ config, preview })
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: {
@@ -28,7 +31,7 @@ export async function getStaticProps({
brands,
pages,
},
revalidate: 14400,
revalidate: 60,
}
}
@@ -37,8 +40,8 @@ export default function Home({
}: InferGetStaticPropsType<typeof getStaticProps>) {
return (
<>
<Grid>
{products.slice(0, 3).map((product, i) => (
<Grid variant="filled">
{products.slice(0, 3).map((product: any, i: number) => (
<ProductCard
key={product.id}
product={product}
@@ -50,22 +53,16 @@ export default function Home({
))}
</Grid>
<Marquee variant="secondary">
{products.slice(0, 3).map((product, i) => (
{products.slice(0, 3).map((product: any, i: number) => (
<ProductCard key={product.id} product={product} variant="slim" />
))}
</Marquee>
<Hero
headline="Release Details: The Yeezy BOOST 350 V2 Natural'"
description="
The Yeezy BOOST 350 V2 lineup continues to grow. We recently had the
Carbon iteration, and now release details have been locked in for
this Natural joint. Revealed by Yeezy Mafia earlier this year, the
shoe was originally called Abez, which translated to Tin in
Hebrew. Its now undergone a name change, and will be referred to as
Natural."
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">
{products.slice(0, 3).map((product, i) => (
<Grid layout="B" variant="filled">
{products.slice(0, 3).map((product: any, i: number) => (
<ProductCard
key={product.id}
product={product}
@@ -77,7 +74,7 @@ export default function Home({
))}
</Grid>
<Marquee>
{products.slice(0, 3).map((product, i) => (
{products.slice(3).map((product: any, i: number) => (
<ProductCard key={product.id} product={product} variant="slim" />
))}
</Marquee>

View File

@@ -10,8 +10,10 @@ export async function getStaticProps({
locales,
}: GetStaticPropsContext) {
const config = { locale, locales }
const { pages } = await commerce.getAllPages({ config, preview })
const { categories } = await commerce.getSiteInfo({ config, preview })
const pagesPromise = commerce.getAllPages({ config, preview })
const siteInfoPromise = commerce.getSiteInfo({ config, preview })
const { pages } = await pagesPromise
const { categories } = await siteInfoPromise
return {
props: { pages, categories },
@@ -29,7 +31,7 @@ export default function Orders() {
<h2 className="pt-6 text-2xl font-bold tracking-wide text-center">
No orders found
</h2>
<p className="text-accents-6 px-10 text-center pt-2">
<p className="text-accent-6 px-10 text-center pt-2">
Biscuit oat cake wafer icing ice cream tiramisu pudding cupcake.
</p>
</div>

View File

@@ -15,13 +15,23 @@ export async function getStaticProps({
preview,
}: GetStaticPropsContext<{ slug: string }>) {
const config = { locale, locales }
const { pages } = await commerce.getAllPages({ config, preview })
const { product } = await commerce.getProduct({
const pagesPromise = commerce.getAllPages({ config, preview })
const siteInfoPromise = commerce.getSiteInfo({ config, preview })
const productPromise = commerce.getProduct({
variables: { slug: params!.slug },
config,
preview,
})
const { categories } = await commerce.getSiteInfo({ 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`)
@@ -31,6 +41,7 @@ export async function getStaticProps({
props: {
pages,
product,
relatedProducts,
categories,
},
revalidate: 200,
@@ -44,25 +55,26 @@ export async function getStaticPaths({ locales }: GetStaticPathsContext) {
paths: locales
? locales.reduce<string[]>((arr, locale) => {
// Add a product path for every locale
products.forEach((product) => {
products.forEach((product: any) => {
arr.push(`/${locale}/product${product.path}`)
})
return arr
}, [])
: products.map((product) => `/product${product.path}`),
: 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> // TODO (BC) Add Skeleton Views
<h1>Loading...</h1>
) : (
<ProductView product={product as any} />
<ProductView product={product} relatedProducts={relatedProducts} />
)
}

View File

@@ -10,8 +10,10 @@ export async function getStaticProps({
locales,
}: GetStaticPropsContext) {
const config = { locale, locales }
const { pages } = await commerce.getAllPages({ config, preview })
const { categories } = await commerce.getSiteInfo({ config, preview })
const pagesPromise = commerce.getAllPages({ config, preview })
const siteInfoPromise = commerce.getSiteInfo({ config, preview })
const { pages } = await pagesPromise
const { categories } = await siteInfoPromise
return {
props: { pages, categories },

View File

@@ -1,466 +1,9 @@
import cn from 'classnames'
import type { GetStaticPropsContext, InferGetStaticPropsType } from 'next'
import Link from 'next/link'
import { useState } from 'react'
import { useRouter } from 'next/router'
import { getSearchStaticProps } from '@lib/search-props'
import type { GetStaticPropsContext } from 'next'
import Search from '@components/search'
import { Layout } from '@components/common'
import { ProductCard } from '@components/product'
import type { Product } from '@commerce/types/product'
import { Container, Grid, Skeleton } from '@components/ui'
import useSearch from '@framework/product/use-search'
import commerce from '@lib/api/commerce'
import rangeMap from '@lib/range-map'
import {
filterQuery,
getCategoryPath,
getDesignerPath,
useSearchMeta,
} from '@lib/search'
// TODO(bc) Remove this. This should come from the API
import getSlug from '@lib/get-slug'
const SORT = Object.entries({
'latest-desc': 'Latest arrivals',
'trending-desc': 'Trending',
'price-asc': 'Price: Low to high',
'price-desc': 'Price: High to low',
})
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 async function getStaticProps(context: GetStaticPropsContext) {
return getSearchStaticProps(context)
}
export default function Search({
categories,
brands,
}: InferGetStaticPropsType<typeof getStaticProps>) {
const [activeFilter, setActiveFilter] = useState('')
const [toggleFilter, setToggleFilter] = useState(false)
const router = useRouter()
const { asPath, locale } = router
const { q, sort } = router.query
// `q` can be included but because categories and designers can't be searched
// in the same way of products, it's better to ignore the search input if one
// of those is selected
const query = filterQuery({ sort })
const { pathname, category, brand } = useSearchMeta(asPath)
const activeCategory = categories.find((cat) => cat.slug === category)
const activeBrand = brands.find(
(b) => getSlug(b.node.path) === `brands/${brand}`
)?.node
const { data } = useSearch({
search: typeof q === 'string' ? q : '',
categoryId: activeCategory?.id,
brandId: (activeBrand as any)?.entityId,
sort: typeof sort === 'string' ? sort : '',
locale,
})
const handleClick = (event: any, filter: string) => {
if (filter !== activeFilter) {
setToggleFilter(true)
} else {
setToggleFilter(!toggleFilter)
}
setActiveFilter(filter)
}
return (
<Container>
<div className="grid grid-cols-1 lg:grid-cols-12 gap-4 mt-3 mb-20">
<div className="col-span-8 lg:col-span-2 order-1 lg:order-none">
{/* Categories */}
<div className="relative inline-block w-full">
<div className="lg:hidden">
<span className="rounded-md shadow-sm">
<button
type="button"
onClick={(e) => handleClick(e, 'categories')}
className="flex justify-between w-full rounded-sm border border-gray-300 px-4 py-3 bg-white text-sm leading-5 font-medium text-gray-700 hover:text-gray-500 focus:outline-none focus:border-blue-300 focus:shadow-outline-normal active:bg-gray-50 active:text-gray-800 transition ease-in-out duration-150"
id="options-menu"
aria-haspopup="true"
aria-expanded="true"
>
{activeCategory?.name
? `Category: ${activeCategory?.name}`
: 'All Categories'}
<svg
className="-mr-1 ml-2 h-5 w-5"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
>
<path
fillRule="evenodd"
d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z"
clipRule="evenodd"
/>
</svg>
</button>
</span>
</div>
<div
className={`origin-top-left absolute lg:relative left-0 mt-2 w-full rounded-md shadow-lg lg:shadow-none z-10 mb-10 lg:block ${
activeFilter !== 'categories' || toggleFilter !== true
? 'hidden'
: ''
}`}
>
<div className="rounded-sm bg-white shadow-xs lg:bg-none lg:shadow-none">
<div
role="menu"
aria-orientation="vertical"
aria-labelledby="options-menu"
>
<ul>
<li
className={cn(
'block text-sm leading-5 text-gray-700 lg:text-base lg:no-underline lg:font-bold lg:tracking-wide hover:bg-gray-100 lg:hover:bg-transparent hover:text-gray-900 focus:outline-none focus:bg-gray-100 focus:text-gray-900',
{
underline: !activeCategory?.name,
}
)}
>
<Link
href={{ pathname: getCategoryPath('', brand), query }}
>
<a
onClick={(e) => handleClick(e, 'categories')}
className={
'block lg:inline-block px-4 py-2 lg:p-0 lg:my-2 lg:mx-4'
}
>
All Categories
</a>
</Link>
</li>
{categories.map((cat) => (
<li
key={cat.path}
className={cn(
'block text-sm leading-5 text-gray-700 hover:bg-gray-100 lg:hover:bg-transparent hover:text-gray-900 focus:outline-none focus:bg-gray-100 focus:text-gray-900',
{
underline: activeCategory?.id === cat.id,
}
)}
>
<Link
href={{
pathname: getCategoryPath(cat.path, brand),
query,
}}
>
<a
onClick={(e) => handleClick(e, 'categories')}
className={
'block lg:inline-block px-4 py-2 lg:p-0 lg:my-2 lg:mx-4'
}
>
{cat.name}
</a>
</Link>
</li>
))}
</ul>
</div>
</div>
</div>
</div>
{/* Designs */}
<div className="relative inline-block w-full">
<div className="lg:hidden mt-3">
<span className="rounded-md shadow-sm">
<button
type="button"
onClick={(e) => handleClick(e, 'brands')}
className="flex justify-between w-full rounded-sm border border-gray-300 px-4 py-3 bg-white text-sm leading-5 font-medium text-gray-900 hover:text-gray-500 focus:outline-none focus:border-blue-300 focus:shadow-outline-normal active:bg-gray-50 active:text-gray-800 transition ease-in-out duration-150"
id="options-menu"
aria-haspopup="true"
aria-expanded="true"
>
{activeBrand?.name
? `Design: ${activeBrand?.name}`
: 'All Designs'}
<svg
className="-mr-1 ml-2 h-5 w-5"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
>
<path
fillRule="evenodd"
d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z"
clipRule="evenodd"
/>
</svg>
</button>
</span>
</div>
<div
className={`origin-top-left absolute lg:relative left-0 mt-2 w-full rounded-md shadow-lg lg:shadow-none z-10 mb-10 lg:block ${
activeFilter !== 'brands' || toggleFilter !== true
? 'hidden'
: ''
}`}
>
<div className="rounded-sm bg-white shadow-xs lg:bg-none lg:shadow-none">
<div
role="menu"
aria-orientation="vertical"
aria-labelledby="options-menu"
>
<ul>
<li
className={cn(
'block text-sm leading-5 text-gray-700 lg:text-base lg:no-underline lg:font-bold lg:tracking-wide hover:bg-gray-100 lg:hover:bg-transparent hover:text-gray-900 focus:outline-none focus:bg-gray-100 focus:text-gray-900',
{
underline: !activeBrand?.name,
}
)}
>
<Link
href={{
pathname: getDesignerPath('', category),
query,
}}
>
<a
onClick={(e) => handleClick(e, 'brands')}
className={
'block lg:inline-block px-4 py-2 lg:p-0 lg:my-2 lg:mx-4'
}
>
All Designers
</a>
</Link>
</li>
{brands.flatMap(({ node }) => (
<li
key={node.path}
className={cn(
'block text-sm leading-5 text-gray-700 hover:bg-gray-100 lg:hover:bg-transparent hover:text-gray-900 focus:outline-none focus:bg-gray-100 focus:text-gray-900',
{
// @ts-ignore Shopify - Fix this types
underline: activeBrand?.entityId === node.entityId,
}
)}
>
<Link
href={{
pathname: getDesignerPath(node.path, category),
query,
}}
>
<a
onClick={(e) => handleClick(e, 'brands')}
className={
'block lg:inline-block px-4 py-2 lg:p-0 lg:my-2 lg:mx-4'
}
>
{node.name}
</a>
</Link>
</li>
))}
</ul>
</div>
</div>
</div>
</div>
</div>
{/* Products */}
<div className="col-span-8 order-3 lg:order-none">
{(q || activeCategory || activeBrand) && (
<div className="mb-12 transition ease-in duration-75">
{data ? (
<>
<span
className={cn('animated', {
fadeIn: data.found,
hidden: !data.found,
})}
>
Showing {data.products.length} results{' '}
{q && (
<>
for "<strong>{q}</strong>"
</>
)}
</span>
<span
className={cn('animated', {
fadeIn: !data.found,
hidden: data.found,
})}
>
{q ? (
<>
There are no products that match "<strong>{q}</strong>"
</>
) : (
<>
There are no products that match the selected category &
designer
</>
)}
</span>
</>
) : q ? (
<>
Searching for: "<strong>{q}</strong>"
</>
) : (
<>Searching...</>
)}
</div>
)}
{data ? (
<Grid layout="normal">
{data.products.map((product: Product) => (
<ProductCard
variant="simple"
key={product.path}
className="animated fadeIn"
product={product}
imgProps={{
width: 480,
height: 480,
}}
/>
))}
</Grid>
) : (
<Grid layout="normal">
{rangeMap(12, (i) => (
<Skeleton
key={i}
className="w-full animated fadeIn"
height={325}
/>
))}
</Grid>
)}
</div>
{/* Sort */}
<div className="col-span-8 lg:col-span-2 order-2 lg:order-none">
<div className="relative inline-block w-full">
<div className="lg:hidden">
<span className="rounded-md shadow-sm">
<button
type="button"
onClick={(e) => handleClick(e, 'sort')}
className="flex justify-between w-full rounded-sm border border-gray-300 px-4 py-3 bg-white text-sm leading-5 font-medium text-gray-700 hover:text-gray-500 focus:outline-none focus:border-blue-300 focus:shadow-outline-normal active:bg-gray-50 active:text-gray-800 transition ease-in-out duration-150"
id="options-menu"
aria-haspopup="true"
aria-expanded="true"
>
{sort ? `Sort: ${sort}` : 'Relevance'}
<svg
className="-mr-1 ml-2 h-5 w-5"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
>
<path
fillRule="evenodd"
d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z"
clipRule="evenodd"
/>
</svg>
</button>
</span>
</div>
<div
className={`origin-top-left absolute lg:relative left-0 mt-2 w-full rounded-md shadow-lg lg:shadow-none z-10 mb-10 lg:block ${
activeFilter !== 'sort' || toggleFilter !== true ? 'hidden' : ''
}`}
>
<div className="rounded-sm bg-white shadow-xs lg:bg-none lg:shadow-none">
<div
role="menu"
aria-orientation="vertical"
aria-labelledby="options-menu"
>
<ul>
<li
className={cn(
'block text-sm leading-5 text-gray-700 lg:text-base lg:no-underline lg:font-bold lg:tracking-wide hover:bg-gray-100 lg:hover:bg-transparent hover:text-gray-900 focus:outline-none focus:bg-gray-100 focus:text-gray-900',
{
underline: !sort,
}
)}
>
<Link href={{ pathname, query: filterQuery({ q }) }}>
<a
onClick={(e) => handleClick(e, 'sort')}
className={
'block lg:inline-block px-4 py-2 lg:p-0 lg:my-2 lg:mx-4'
}
>
Relevance
</a>
</Link>
</li>
{SORT.map(([key, text]) => (
<li
key={key}
className={cn(
'block text-sm leading-5 text-gray-700 hover:bg-gray-100 lg:hover:bg-transparent hover:text-gray-900 focus:outline-none focus:bg-gray-100 focus:text-gray-900',
{
underline: sort === key,
}
)}
>
<Link
href={{
pathname,
query: filterQuery({ q, sort: key }),
}}
>
<a
onClick={(e) => handleClick(e, 'sort')}
className={
'block lg:inline-block px-4 py-2 lg:p-0 lg:my-2 lg:mx-4'
}
>
{text}
</a>
</Link>
</li>
))}
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
</Container>
)
}
Search.Layout = Layout
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

View File

@@ -20,8 +20,10 @@ export async function getStaticProps({
}
const config = { locale, locales }
const { pages } = await commerce.getAllPages({ config, preview })
const { categories } = await commerce.getSiteInfo({ config, preview })
const pagesPromise = commerce.getAllPages({ config, preview })
const siteInfoPromise = commerce.getSiteInfo({ config, preview })
const { pages } = await pagesPromise
const { categories } = await siteInfoPromise
return {
props: {
@@ -49,7 +51,7 @@ export default function Wishlist() {
<h2 className="pt-6 text-2xl font-bold tracking-wide text-center">
Your wishlist is empty
</h2>
<p className="text-accents-6 px-10 text-center pt-2">
<p className="text-accent-6 px-10 text-center pt-2">
Biscuit oat cake wafer icing ice cream tiramisu pudding cupcake.
</p>
</div>