mirror of
https://github.com/vercel/commerce.git
synced 2025-05-20 08:26:59 +00:00
home: add type nav & homepage collection routes
This commit is contained in:
parent
ae9d6d7c4b
commit
c174b6ad79
@ -1,7 +1,14 @@
|
||||
import { TypesNav } from '/components/home.js';
|
||||
|
||||
export default function RootLayout({ children }) {
|
||||
return (
|
||||
<html lang='en'>
|
||||
<body>{children}</body>
|
||||
<body>
|
||||
<nav>
|
||||
<TypesNav />
|
||||
</nav>
|
||||
<main>{children}</main>
|
||||
</body>
|
||||
</html>
|
||||
);
|
||||
}
|
||||
|
106
app/page.js
106
app/page.js
@ -1,107 +1,5 @@
|
||||
import Link from 'next/link';
|
||||
import Image from 'next/image';
|
||||
|
||||
import { getCollectionProducts } from 'lib/shopify';
|
||||
|
||||
const formatPrice = ({ amount, currencyCode }) => {
|
||||
const USDollar = new Intl.NumberFormat('en-US', {
|
||||
style: 'currency',
|
||||
currency: currencyCode,
|
||||
});
|
||||
|
||||
return USDollar.format(amount);
|
||||
};
|
||||
|
||||
const formatPriceRange = ({ maxVariantPrice, minVariantPrice }) => {
|
||||
if (maxVariantPrice.amount == minVariantPrice.amount) {
|
||||
return `${formatPrice(maxVariantPrice)}`;
|
||||
} else {
|
||||
return `${formatPrice(minVariantPrice)} - ${formatPrice(
|
||||
maxVariantPrice
|
||||
)}`;
|
||||
}
|
||||
};
|
||||
|
||||
const PriceRanges = ({ priceRange, compareAtPriceRange, availableForSale }) => {
|
||||
const onSale =
|
||||
(compareAtPriceRange?.minVariantPrice?.amount ?? 0) >
|
||||
(priceRange?.minVariantPrice?.amount ?? 0) ||
|
||||
(compareAtPriceRange?.maxVariantPrice?.amount ?? 0) >
|
||||
(priceRange?.maxVariantPrice?.amount ?? 0);
|
||||
const isForSale = (priceRange?.maxVariantPrice?.amount ?? 0) > 0;
|
||||
|
||||
return (
|
||||
<p>
|
||||
{availableForSale ? (
|
||||
isForSale && (
|
||||
<>
|
||||
<>
|
||||
{onSale && (
|
||||
<span className={'original-price'}>
|
||||
{formatPriceRange(compareAtPriceRange)}{' '}
|
||||
</span>
|
||||
)}
|
||||
</>
|
||||
<span>{formatPriceRange(priceRange)}</span>
|
||||
</>
|
||||
)
|
||||
) : (
|
||||
<span>Sold Out</span>
|
||||
)}
|
||||
</p>
|
||||
);
|
||||
};
|
||||
|
||||
export async function HomeProduct({ product }) {
|
||||
const featuredImage = product?.images?.[0];
|
||||
const collections = product?.collections?.nodes;
|
||||
|
||||
return (
|
||||
<Link href={`/${product?.handle}`}>
|
||||
<Image
|
||||
src={featuredImage?.url}
|
||||
alt={featuredImage?.altText}
|
||||
width={featuredImage?.width}
|
||||
height={featuredImage?.height}
|
||||
/>
|
||||
<p>{product?.title}</p>
|
||||
{collections && collections.length > 0 && (
|
||||
<p>{`(${collections
|
||||
?.map(collection => collection?.title)
|
||||
.join(', ')})`}</p>
|
||||
)}
|
||||
<PriceRanges {...product} />
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
import { HomeProductsList } from '/components/home.js';
|
||||
|
||||
export default async function HomePage() {
|
||||
const collection = process.env.HOMEPAGE_COLLECTION;
|
||||
const products = await getCollectionProducts({
|
||||
collection,
|
||||
});
|
||||
|
||||
// console.log({ collection, products });
|
||||
// const num = 4;
|
||||
// console.log({
|
||||
// price: products[num].priceRange,
|
||||
// compareAt: products[num].compareAtPriceRange,
|
||||
// title: products[num].title,
|
||||
// });
|
||||
|
||||
return (
|
||||
<>
|
||||
{products.length === 0 ? (
|
||||
<p>{`No products found`}</p>
|
||||
) : (
|
||||
<ul>
|
||||
{products?.map(product => (
|
||||
<li key={product?.handle}>
|
||||
<HomeProduct {...{ product }} />
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
return <HomeProductsList collection={process.env.HOMEPAGE_COLLECTION} />;
|
||||
}
|
||||
|
13
app/search/[collection]/page.js
Normal file
13
app/search/[collection]/page.js
Normal file
@ -0,0 +1,13 @@
|
||||
import { getCollections } from 'lib/shopify';
|
||||
|
||||
import { HomeProductsList } from '/components/home.js';
|
||||
|
||||
export async function generateStaticParams() {
|
||||
const collections = await getCollections();
|
||||
|
||||
return collections.map(collection => ({ collection: collection.handle }));
|
||||
}
|
||||
|
||||
export default async function CollectionPage({ params: { collection } }) {
|
||||
return <HomeProductsList collection={collection} />;
|
||||
}
|
128
components/home.js
Normal file
128
components/home.js
Normal file
@ -0,0 +1,128 @@
|
||||
import Link from 'next/link';
|
||||
import Image from 'next/image';
|
||||
|
||||
import { getCollectionProducts, getMenu } from 'lib/shopify';
|
||||
|
||||
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 = ({
|
||||
priceRange,
|
||||
compareAtPriceRange,
|
||||
availableForSale,
|
||||
}) => {
|
||||
const onSale =
|
||||
(compareAtPriceRange?.minVariantPrice?.amount ?? 0) >
|
||||
(priceRange?.minVariantPrice?.amount ?? 0) ||
|
||||
(compareAtPriceRange?.maxVariantPrice?.amount ?? 0) >
|
||||
(priceRange?.maxVariantPrice?.amount ?? 0);
|
||||
const isForSale = (priceRange?.maxVariantPrice?.amount ?? 0) > 0;
|
||||
|
||||
return (
|
||||
<p>
|
||||
{availableForSale ? (
|
||||
isForSale && (
|
||||
<>
|
||||
<>
|
||||
{onSale && (
|
||||
<span className={'original-price'}>
|
||||
{formatPriceRange(compareAtPriceRange)}{' '}
|
||||
</span>
|
||||
)}
|
||||
</>
|
||||
<span>{formatPriceRange(priceRange)}</span>
|
||||
</>
|
||||
)
|
||||
) : (
|
||||
<span>Sold Out</span>
|
||||
)}
|
||||
</p>
|
||||
);
|
||||
};
|
||||
|
||||
export async function HomeProduct({ product }) {
|
||||
const featuredImage = product?.images?.[0];
|
||||
const collections = product?.collections?.nodes;
|
||||
|
||||
return (
|
||||
<Link href={`/${product?.handle}`}>
|
||||
<Image
|
||||
src={featuredImage?.url}
|
||||
alt={featuredImage?.altText}
|
||||
width={featuredImage?.width}
|
||||
height={featuredImage?.height}
|
||||
/>
|
||||
<p>{product?.title}</p>
|
||||
{collections && collections.length > 0 && (
|
||||
<p>{`(${collections
|
||||
?.map(collection => collection?.title)
|
||||
.join(', ')})`}</p>
|
||||
)}
|
||||
<PriceRanges {...product} />
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
|
||||
//TODO: suspense
|
||||
export async function HomeProductsList({ collection }) {
|
||||
const products = await getCollectionProducts({
|
||||
collection,
|
||||
});
|
||||
|
||||
// console.log({ collection, products });
|
||||
// const num = 4;
|
||||
// console.log({
|
||||
// price: products[num].priceRange,
|
||||
// compareAt: products[num].compareAtPriceRange,
|
||||
// title: products[num].title,
|
||||
// });
|
||||
|
||||
return (
|
||||
<>
|
||||
{products.length === 0 ? (
|
||||
<p>{`No products found`}</p>
|
||||
) : (
|
||||
<ul>
|
||||
{products?.map(product => (
|
||||
<li key={product?.handle}>
|
||||
<HomeProduct {...{ product }} />
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
//TODO: suspense
|
||||
export async function TypesNav() {
|
||||
const typesMenu = await getMenu('types-nav');
|
||||
|
||||
// console.log({ typesMenu });
|
||||
|
||||
return (
|
||||
<ul>
|
||||
{typesMenu?.map(menuItem => (
|
||||
<li key={menuItem?.path}>
|
||||
<Link href={menuItem?.path}>{menuItem?.title}</Link>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user