mirror of
https://github.com/vercel/commerce.git
synced 2025-05-18 07:26:59 +00:00
Changes
This commit is contained in:
parent
96836b1969
commit
025a89bc73
@ -16,6 +16,12 @@ interface Props {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const LEGAL_PAGES = ['terms-of-use', 'shipping-returns', 'privacy-policy']
|
const LEGAL_PAGES = ['terms-of-use', 'shipping-returns', 'privacy-policy']
|
||||||
|
const links = [
|
||||||
|
{
|
||||||
|
name: 'Home',
|
||||||
|
href: '/',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
const Footer: FC<Props> = ({ className, pages }) => {
|
const Footer: FC<Props> = ({ className, pages }) => {
|
||||||
const { sitePages, legalPages } = usePages(pages)
|
const { sitePages, legalPages } = usePages(pages)
|
||||||
@ -37,27 +43,15 @@ const Footer: FC<Props> = ({ className, pages }) => {
|
|||||||
</div>
|
</div>
|
||||||
<div className="col-span-1 lg:col-span-2">
|
<div className="col-span-1 lg:col-span-2">
|
||||||
<ul className="flex flex-initial flex-col md:flex-1">
|
<ul className="flex flex-initial flex-col md:flex-1">
|
||||||
<li className="py-3 md:py-0 md:pb-4">
|
{links.map(({ href, name }) => (
|
||||||
<Link href="/">
|
<li className="py-3 md:py-0 md:pb-4">
|
||||||
<a className="text-primary hover:text-accent-6 transition ease-in-out duration-150">
|
<Link href={href}>
|
||||||
Home
|
<a className="text-primary hover:text-accent-6 transition ease-in-out duration-150">
|
||||||
</a>
|
{name}
|
||||||
</Link>
|
</a>
|
||||||
</li>
|
</Link>
|
||||||
<li className="py-3 md:py-0 md:pb-4">
|
</li>
|
||||||
<Link href="/">
|
))}
|
||||||
<a className="text-primary hover:text-accent-6 transition ease-in-out duration-150">
|
|
||||||
Careers
|
|
||||||
</a>
|
|
||||||
</Link>
|
|
||||||
</li>
|
|
||||||
<li className="py-3 md:py-0 md:pb-4">
|
|
||||||
<Link href="/blog">
|
|
||||||
<a className="text-primary hover:text-accent-6 transition ease-in-out duration-150">
|
|
||||||
Blog
|
|
||||||
</a>
|
|
||||||
</Link>
|
|
||||||
</li>
|
|
||||||
{sitePages.map((page) => (
|
{sitePages.map((page) => (
|
||||||
<li key={page.url} className="py-3 md:py-0 md:pb-4">
|
<li key={page.url} className="py-3 md:py-0 md:pb-4">
|
||||||
<Link href={page.url!}>
|
<Link href={page.url!}>
|
||||||
|
@ -11,6 +11,7 @@ interface Props {
|
|||||||
product: Product
|
product: Product
|
||||||
variant?: 'slim' | 'simple'
|
variant?: 'slim' | 'simple'
|
||||||
imgProps?: Omit<ImageProps, 'src'>
|
imgProps?: Omit<ImageProps, 'src'>
|
||||||
|
noNameTag: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
const placeholderImg = '/product-img-placeholder.svg'
|
const placeholderImg = '/product-img-placeholder.svg'
|
||||||
@ -20,17 +21,20 @@ const ProductCard: FC<Props> = ({
|
|||||||
product,
|
product,
|
||||||
variant,
|
variant,
|
||||||
imgProps,
|
imgProps,
|
||||||
|
noNameTag = false,
|
||||||
...props
|
...props
|
||||||
}) => (
|
}) => (
|
||||||
<Link href={`/product/${product.slug}`} {...props}>
|
<Link href={`/product/${product.slug}`} {...props}>
|
||||||
<a className={cn(s.root, { [s.simple]: variant === 'simple' }, className)}>
|
<a className={cn(s.root, { [s.simple]: variant === 'simple' }, className)}>
|
||||||
{variant === 'slim' ? (
|
{variant === 'slim' ? (
|
||||||
<div className="relative overflow-hidden box-border">
|
<div className="relative overflow-hidden box-border ">
|
||||||
<div className="absolute inset-0 flex items-center justify-end mr-8 z-20">
|
{!noNameTag && (
|
||||||
<span className="bg-black text-white inline-block p-3 font-bold text-xl break-words">
|
<div className="absolute inset-0 flex items-center justify-end mr-8 z-20">
|
||||||
{product.name}
|
<span className="bg-black text-white inline-block p-3 font-bold text-xl break-words">
|
||||||
</span>
|
{product.name}
|
||||||
</div>
|
</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
{product?.images && (
|
{product?.images && (
|
||||||
<Image
|
<Image
|
||||||
quality="85"
|
quality="85"
|
||||||
@ -46,17 +50,19 @@ const ProductCard: FC<Props> = ({
|
|||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
<div className={s.squareBg} />
|
<div className={s.squareBg} />
|
||||||
<div className="flex flex-row justify-between box-border w-full z-20 absolute">
|
<div className="flex flex-row justify-between box-border w-full z-20 absolute bg-red">
|
||||||
<div className="absolute top-0 left-0 pr-16 max-w-full">
|
{!noNameTag && (
|
||||||
<h3 className={s.productTitle}>
|
<div className="absolute top-0 left-0 pr-16 max-w-full">
|
||||||
<span>{product.name}</span>
|
<h3 className={s.productTitle}>
|
||||||
</h3>
|
<span>{product.name}</span>
|
||||||
<span className={s.productPrice}>
|
</h3>
|
||||||
{product.price.value}
|
<span className={s.productPrice}>
|
||||||
|
{product.price.value}
|
||||||
{product.price.currencyCode}
|
|
||||||
</span>
|
{product.price.currencyCode}
|
||||||
</div>
|
</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
{process.env.COMMERCE_WISHLIST_ENABLED && (
|
{process.env.COMMERCE_WISHLIST_ENABLED && (
|
||||||
<WishlistButton
|
<WishlistButton
|
||||||
className={s.wishlistButton}
|
className={s.wishlistButton}
|
||||||
|
@ -69,7 +69,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.img {
|
.sliderContainer .img {
|
||||||
@apply w-full h-auto max-h-full object-cover;
|
@apply w-full h-auto max-h-full object-cover;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,9 +84,11 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.wishlistButton {
|
.wishlistButton {
|
||||||
@apply absolute z-30 top-6 right-0 bg-primary text-primary w-10 h-10 flex items-center justify-center font-semibold leading-6 cursor-pointer;
|
@apply absolute z-30 top-6 right-0 bg-primary text-primary
|
||||||
|
w-10 h-10 flex items-center justify-center font-semibold
|
||||||
|
leading-6 cursor-pointer px-6;
|
||||||
|
|
||||||
@screen lg {
|
@screen lg {
|
||||||
@apply right-0 top-0 text-black bg-white w-14 h-14;
|
@apply top-6 right-0 text-black bg-white w-14 h-14;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,24 +1,27 @@
|
|||||||
import cn from 'classnames'
|
import cn from 'classnames'
|
||||||
import Image from 'next/image'
|
import Image from 'next/image'
|
||||||
import { NextSeo } from 'next-seo'
|
import { NextSeo } from 'next-seo'
|
||||||
import { FC, useEffect, useState } from 'react'
|
|
||||||
import s from './ProductView.module.css'
|
import s from './ProductView.module.css'
|
||||||
import { Swatch, ProductSlider } from '@components/product'
|
import { FC, useEffect, useState } from 'react'
|
||||||
import { Button, Container, Text, useUI } from '@components/ui'
|
|
||||||
import type { Product } from '@commerce/types'
|
import type { Product } from '@commerce/types'
|
||||||
import usePrice from '@framework/product/use-price'
|
import usePrice from '@framework/product/use-price'
|
||||||
import { useAddItem } from '@framework/cart'
|
|
||||||
import { getVariant, SelectedOptions } from '../helpers'
|
import { getVariant, SelectedOptions } from '../helpers'
|
||||||
import WishlistButton from '@components/wishlist/WishlistButton'
|
import { Swatch, ProductSlider } from '@components/product'
|
||||||
|
import { Button, Container, Text, useUI } from '@components/ui'
|
||||||
|
import { useAddItem } from '@framework/cart'
|
||||||
import Collapse from '@components/ui/Collapse'
|
import Collapse from '@components/ui/Collapse'
|
||||||
|
import Skeleton from '@components/ui/Skeleton'
|
||||||
|
import ProductCard from '@components/product/ProductCard'
|
||||||
|
import WishlistButton from '@components/wishlist/WishlistButton'
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
children?: any
|
children?: any
|
||||||
product: Product
|
product: Product
|
||||||
|
relatedProducts: Product[]
|
||||||
className?: string
|
className?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
const ProductView: FC<Props> = ({ product }) => {
|
const ProductView: FC<Props> = ({ product, relatedProducts }) => {
|
||||||
const addItem = useAddItem()
|
const addItem = useAddItem()
|
||||||
const { price } = usePrice({
|
const { price } = usePrice({
|
||||||
amount: product.price.value,
|
amount: product.price.value,
|
||||||
@ -173,10 +176,28 @@ const ProductView: FC<Props> = ({ product }) => {
|
|||||||
</div>
|
</div>
|
||||||
<section className="py-12 px-6">
|
<section className="py-12 px-6">
|
||||||
<Text variant="sectionHeading">Related Products</Text>
|
<Text variant="sectionHeading">Related Products</Text>
|
||||||
<div className="grid grid-cols-4 py-3 gap-5 h-48">
|
<div className="grid grid-cols-4 py-3 gap-10">
|
||||||
{Array.from({ length: 4 }).map((i) => (
|
{relatedProducts.map((p) => (
|
||||||
<div className="bg-accent-6" />
|
<div className="animated fadeIn bg-accent-0 border border-accent-3">
|
||||||
|
<ProductCard
|
||||||
|
variant="simple"
|
||||||
|
key={p.path}
|
||||||
|
className="animated fadeIn"
|
||||||
|
product={p}
|
||||||
|
noNameTag
|
||||||
|
imgProps={{
|
||||||
|
width: 275,
|
||||||
|
height: 275,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
))}
|
))}
|
||||||
|
{/* {Array.from({ length: 4 }).map((_, i) => (
|
||||||
|
<Skeleton
|
||||||
|
key={i}
|
||||||
|
className="w-full animated fadeIn bg-accent-0 border border-accent-3"
|
||||||
|
/>
|
||||||
|
))} */}
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</Container>
|
</Container>
|
||||||
|
@ -11,6 +11,7 @@ import { getConfig } from '@framework/api'
|
|||||||
import getProduct from '@framework/product/get-product'
|
import getProduct from '@framework/product/get-product'
|
||||||
import getAllPages from '@framework/common/get-all-pages'
|
import getAllPages from '@framework/common/get-all-pages'
|
||||||
import getAllProductPaths from '@framework/product/get-all-product-paths'
|
import getAllProductPaths from '@framework/product/get-all-product-paths'
|
||||||
|
import getAllProducts from '@framework/product/get-all-products'
|
||||||
|
|
||||||
export async function getStaticProps({
|
export async function getStaticProps({
|
||||||
params,
|
params,
|
||||||
@ -19,6 +20,11 @@ export async function getStaticProps({
|
|||||||
}: GetStaticPropsContext<{ slug: string }>) {
|
}: GetStaticPropsContext<{ slug: string }>) {
|
||||||
const config = getConfig({ locale })
|
const config = getConfig({ locale })
|
||||||
const { pages } = await getAllPages({ config, preview })
|
const { pages } = await getAllPages({ config, preview })
|
||||||
|
const { products: relatedProducts } = await getAllProducts({
|
||||||
|
variables: { first: 4 },
|
||||||
|
config,
|
||||||
|
preview,
|
||||||
|
})
|
||||||
const { product } = await getProduct({
|
const { product } = await getProduct({
|
||||||
variables: { slug: params!.slug },
|
variables: { slug: params!.slug },
|
||||||
config,
|
config,
|
||||||
@ -33,6 +39,7 @@ export async function getStaticProps({
|
|||||||
props: {
|
props: {
|
||||||
pages,
|
pages,
|
||||||
product,
|
product,
|
||||||
|
relatedProducts,
|
||||||
},
|
},
|
||||||
revalidate: 200,
|
revalidate: 200,
|
||||||
}
|
}
|
||||||
@ -57,13 +64,14 @@ export async function getStaticPaths({ locales }: GetStaticPathsContext) {
|
|||||||
|
|
||||||
export default function Slug({
|
export default function Slug({
|
||||||
product,
|
product,
|
||||||
|
relatedProducts,
|
||||||
}: InferGetStaticPropsType<typeof getStaticProps>) {
|
}: InferGetStaticPropsType<typeof getStaticProps>) {
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
|
||||||
return router.isFallback ? (
|
return router.isFallback ? (
|
||||||
<h1>Loading...</h1> // TODO (BC) Add Skeleton Views
|
<h1>Loading...</h1>
|
||||||
) : (
|
) : (
|
||||||
<ProductView product={product as any} />
|
<ProductView product={product as any} relatedProducts={relatedProducts} />
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -325,8 +325,7 @@ export default function Search({
|
|||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
There are no products that match the selected category &
|
There are no products that match the selected category.
|
||||||
designer
|
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</span>
|
</span>
|
||||||
@ -362,7 +361,7 @@ export default function Search({
|
|||||||
<Skeleton
|
<Skeleton
|
||||||
key={i}
|
key={i}
|
||||||
className="w-full animated fadeIn"
|
className="w-full animated fadeIn"
|
||||||
height={325}
|
height={480}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</Grid>
|
</Grid>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user