mirror of
https://github.com/vercel/commerce.git
synced 2025-05-20 08:26:59 +00:00
home: style product grid items
This commit is contained in:
parent
5b9af9bcdb
commit
3456bf254f
@ -1,3 +1,4 @@
|
|||||||
.main {
|
.main {
|
||||||
padding: 0 60px;
|
padding: 0 60px;
|
||||||
|
padding-bottom: 364px;
|
||||||
}
|
}
|
||||||
|
@ -5,8 +5,8 @@ import Image from 'next/image';
|
|||||||
|
|
||||||
import { getCollectionProducts, getMenu } from 'lib/shopify';
|
import { getCollectionProducts, getMenu } from 'lib/shopify';
|
||||||
|
|
||||||
import { PriceRanges } from '/components/price.js';
|
|
||||||
import styles from './styles.module.scss';
|
import styles from './styles.module.scss';
|
||||||
|
import { PriceRanges } from '/components/price';
|
||||||
|
|
||||||
export async function HomeProduct({ product }) {
|
export async function HomeProduct({ product }) {
|
||||||
const typesMenu = await getMenu('types-nav');
|
const typesMenu = await getMenu('types-nav');
|
||||||
@ -17,23 +17,26 @@ export async function HomeProduct({ product }) {
|
|||||||
?.map(col => col?.title)
|
?.map(col => col?.title)
|
||||||
?.filter(col => types?.includes(col?.toLowerCase()));
|
?.filter(col => types?.includes(col?.toLowerCase()));
|
||||||
|
|
||||||
console.log({ collections });
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Link
|
<Link
|
||||||
href={`/product/${product?.handle}`}
|
href={`/product/${product?.handle}`}
|
||||||
className={styles.homeProduct}
|
className={styles.homeProduct}
|
||||||
>
|
>
|
||||||
|
{/* TODO: optimize srcset (adjusting based on featured status) */}
|
||||||
<Image
|
<Image
|
||||||
src={featuredImage?.url}
|
src={featuredImage?.url}
|
||||||
alt={featuredImage?.altText}
|
alt={featuredImage?.altText}
|
||||||
width={featuredImage?.width}
|
width={featuredImage?.width}
|
||||||
height={featuredImage?.height}
|
height={featuredImage?.height}
|
||||||
/>
|
/>
|
||||||
<p>{product?.title}</p>
|
<div>
|
||||||
{collections && collections.length > 0 && (
|
<p className={styles.title}>{product?.title}</p>
|
||||||
<p>{`(${collections.join(', ')})`}</p>
|
{collections && collections.length > 0 && (
|
||||||
)}
|
<p className={styles.collections}>{`(${collections.join(
|
||||||
|
', '
|
||||||
|
)})`}</p>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
<PriceRanges product={product} />
|
<PriceRanges product={product} />
|
||||||
</Link>
|
</Link>
|
||||||
);
|
);
|
||||||
|
@ -56,4 +56,14 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.homeProduct {
|
.homeProduct {
|
||||||
|
text-decoration-line: none;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 10px;
|
||||||
|
|
||||||
|
.title,
|
||||||
|
.collections {
|
||||||
|
@include typography.subheader;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,23 +1,5 @@
|
|||||||
export const formatPrice = ({ amount, currencyCode }) => {
|
import styles from './styles.module.scss';
|
||||||
const USDollar = new Intl.NumberFormat('en-US', {
|
|
||||||
style: 'currency',
|
|
||||||
currency: currencyCode,
|
|
||||||
});
|
|
||||||
|
|
||||||
return USDollar.format(amount);
|
|
||||||
};
|
|
||||||
|
|
||||||
export const formatPriceRange = ({ maxVariantPrice, minVariantPrice }) => {
|
|
||||||
if (maxVariantPrice.amount == minVariantPrice.amount) {
|
|
||||||
return `${formatPrice(maxVariantPrice)}`;
|
|
||||||
} else {
|
|
||||||
return `${formatPrice(minVariantPrice)} - ${formatPrice(
|
|
||||||
maxVariantPrice
|
|
||||||
)}`;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
//TODO: might be safer not to destructure keys from `product`, use nullish coalescing instead
|
|
||||||
export const productAvailableForSale = product =>
|
export const productAvailableForSale = product =>
|
||||||
product?.availableForSale ?? false;
|
product?.availableForSale ?? false;
|
||||||
export const productOnSale = product =>
|
export const productOnSale = product =>
|
||||||
@ -29,6 +11,28 @@ export const productIsForSale = product =>
|
|||||||
(product?.priceRange?.maxVariantPrice?.amount ?? 0) > 0;
|
(product?.priceRange?.maxVariantPrice?.amount ?? 0) > 0;
|
||||||
export const productHasOptions = product =>
|
export const productHasOptions = product =>
|
||||||
product?.options?.[0]?.values?.length > 1 ?? false;
|
product?.options?.[0]?.values?.length > 1 ?? false;
|
||||||
|
export const variantAvailableForSale = variant =>
|
||||||
|
variant?.availableForSale ?? false;
|
||||||
|
export const variantOnSale = variant =>
|
||||||
|
(variant?.compareAtPrice?.amount ?? 0) > (variant?.price?.amount ?? 0);
|
||||||
|
|
||||||
|
export const formatPrice = ({ amount, currencyCode }) => {
|
||||||
|
const USDollar = new Intl.NumberFormat('en-US', {
|
||||||
|
style: 'currency',
|
||||||
|
currency: currencyCode,
|
||||||
|
});
|
||||||
|
|
||||||
|
return USDollar.format(amount);
|
||||||
|
};
|
||||||
|
export const formatPriceRange = ({ maxVariantPrice, minVariantPrice }) => {
|
||||||
|
if (maxVariantPrice.amount == minVariantPrice.amount) {
|
||||||
|
return `${formatPrice(maxVariantPrice)}`;
|
||||||
|
} else {
|
||||||
|
return `${formatPrice(minVariantPrice)} - ${formatPrice(
|
||||||
|
maxVariantPrice
|
||||||
|
)}`;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
export const PriceRanges = ({ product }) => {
|
export const PriceRanges = ({ product }) => {
|
||||||
const availableForSale = productAvailableForSale(product);
|
const availableForSale = productAvailableForSale(product);
|
||||||
@ -36,20 +40,22 @@ export const PriceRanges = ({ product }) => {
|
|||||||
const isForSale = productIsForSale(product);
|
const isForSale = productIsForSale(product);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<p>
|
<p className={styles.priceRanges}>
|
||||||
{availableForSale ? (
|
{availableForSale ? (
|
||||||
isForSale && (
|
isForSale && (
|
||||||
<>
|
<>
|
||||||
<>
|
<>
|
||||||
{onSale && (
|
{onSale && (
|
||||||
<span className={'original-price'}>
|
<span className={styles.originalPrice}>
|
||||||
{formatPriceRange(
|
{formatPriceRange(
|
||||||
product?.compareAtPriceRange
|
product?.compareAtPriceRange
|
||||||
)}{' '}
|
)}{' '}
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
<span>{formatPriceRange(product?.priceRange)}</span>
|
<span>{`${formatPriceRange(product?.priceRange)} ${
|
||||||
|
product?.priceRange?.maxVariantPrice?.currencyCode
|
||||||
|
}`}</span>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
) : (
|
) : (
|
||||||
@ -59,11 +65,6 @@ export const PriceRanges = ({ product }) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const variantAvailableForSale = variant =>
|
|
||||||
variant?.availableForSale ?? false;
|
|
||||||
export const variantOnSale = variant =>
|
|
||||||
(variant?.compareAtPrice?.amount ?? 0) > (variant?.price?.amount ?? 0);
|
|
||||||
|
|
||||||
export const VariantPrice = ({ variant, quantity }) => {
|
export const VariantPrice = ({ variant, quantity }) => {
|
||||||
const availableForSale = variantAvailableForSale(variant);
|
const availableForSale = variantAvailableForSale(variant);
|
||||||
const onSale = variantOnSale(variant);
|
const onSale = variantOnSale(variant);
|
@ -9,7 +9,7 @@ import {
|
|||||||
productHasOptions,
|
productHasOptions,
|
||||||
productIsForSale,
|
productIsForSale,
|
||||||
VariantPrice,
|
VariantPrice,
|
||||||
} from '/components/price.js';
|
} from '/components/price';
|
||||||
|
|
||||||
export const productVariant = ({ product, selectedOptions }) => {
|
export const productVariant = ({ product, selectedOptions }) => {
|
||||||
const hasOptions = productHasOptions(product);
|
const hasOptions = productHasOptions(product);
|
||||||
|
@ -26,6 +26,8 @@
|
|||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
line-height: 20px; /* 100% */
|
line-height: 20px; /* 100% */
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
|
font-variant-numeric: lining-nums tabular-nums slashed-zero;
|
||||||
|
font-feature-settings: 'case' on;
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin body {
|
@mixin body {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user