- {/* Decorative image and overlay */}
-
- {heroImage ? (
-
}>
-
-
- ) : (
-
+ {/* Decorative image and overlay */}
+
+ {heroImage ? (
+ }>
+
- )}
-
-
-
-
-
+
+ ) : (
+
+ )}
+
+
+
+
+
+
Best Price Guarantee
We will match or beat any competitor's pricing.
-
- }>
-
-
-
+
+
+ }>
+
+
diff --git a/components/layout/products-list/index.tsx b/components/layout/products-list/index.tsx
index 1eb6fae6a..3ebc98efc 100644
--- a/components/layout/products-list/index.tsx
+++ b/components/layout/products-list/index.tsx
@@ -1,9 +1,12 @@
'use client';
+import { Button } from '@headlessui/react';
+import clsx from 'clsx';
import Grid from 'components/grid';
import { GridTileImage } from 'components/grid/tile';
+import LoadingDots from 'components/loading-dots';
import { Product } from 'lib/shopify/types';
-import { useEffect, useRef, useState } from 'react';
+import { useState } from 'react';
import { getProductsInCollection, searchProducts } from './actions';
const ProductsList = ({
@@ -22,16 +25,15 @@ const ProductsList = ({
}) => {
const [products, setProducts] = useState(initialProducts);
const [_pageInfo, setPageInfo] = useState(pageInfo);
- const lastElement = useRef(null);
+ const [isLoading, setIsLoading] = useState(false);
- useEffect(() => {
- const lastElementRef = lastElement.current;
-
- const loadMoreProducts = async () => {
+ const handleClickLoadMore = async () => {
+ try {
const params = {
searchParams,
afterCursor: _pageInfo.endCursor
};
+ setIsLoading(true);
const { products, pageInfo } =
page === 'collection'
? await getProductsInCollection(params)
@@ -42,42 +44,45 @@ const ProductsList = ({
hasNextPage: pageInfo.hasNextPage,
endCursor: pageInfo.endCursor
});
- };
- const observer = new IntersectionObserver(
- (entries) => {
- if (entries[0]?.isIntersecting) {
- loadMoreProducts();
- }
- },
- { threshold: 1 }
- );
- lastElementRef && observer.observe(lastElementRef);
-
- return () => {
- if (lastElementRef) {
- observer.unobserve(lastElementRef);
- }
- };
- }, [_pageInfo.endCursor, page, searchParams]);
+ } catch (error) {
+ console.log('Failed to fetch products', error);
+ } finally {
+ setIsLoading(false);
+ }
+ };
return (
<>
- {products.map((product, index) => (
-
-
-
- ))}
+
+ {products.map((product) => (
+
+
+
+ ))}
+
+ {_pageInfo.hasNextPage && (
+
+
+
+ )}
>
);
};
diff --git a/components/layout/search/collection-link.tsx b/components/layout/search/collection-link.tsx
new file mode 100644
index 000000000..2f9e3a667
--- /dev/null
+++ b/components/layout/search/collection-link.tsx
@@ -0,0 +1,25 @@
+import { getCollection } from 'lib/shopify';
+import { cn } from 'lib/utils';
+import Link from 'next/link';
+
+const CollectionLink = async ({
+ collectionLinkId,
+ anchorText,
+ className
+}: {
+ collectionLinkId: string;
+ anchorText: string;
+ className?: string;
+}) => {
+ const collection = await getCollection({ id: collectionLinkId });
+
+ if (!collection) return null;
+
+ return (
+
+ {anchorText}
+
+ );
+};
+
+export default CollectionLink;
diff --git a/components/layout/search/header.tsx b/components/layout/search/header.tsx
index 01c96898b..5dd9d0664 100644
--- a/components/layout/search/header.tsx
+++ b/components/layout/search/header.tsx
@@ -1,13 +1,49 @@
-import { getCollection } from 'lib/shopify';
+import { getCollection, getMetaobjectsByIds } from 'lib/shopify';
+import { Suspense } from 'react';
+import CollectionLink from './collection-link';
+
+const HelpfulLinks = async ({ ids }: { ids: string[] | null }) => {
+ if (!ids?.length) return null;
+
+ const links = await getMetaobjectsByIds(ids);
+
+ return (
+
+ {links.map((link) => (
+
+ ))}
+
+ );
+};
+
+const HelpfulLinksPlaceholder = () => {
+ return (
+
+ );
+};
const Header = async ({ collection }: { collection: string }) => {
const collectionData = await getCollection({ handle: collection });
return collectionData ? (
-
-
{collectionData.title}
-
{collectionData.description}
-
+ <>
+
+
{collectionData.title}
+
{collectionData.description}
+
+ }>
+
+
+ >
) : null;
};
@@ -18,4 +54,5 @@ export const HeaderPlaceholder = () => {
);
};
+
export default Header;
diff --git a/components/layout/search/helpful-links.tsx b/components/layout/search/helpful-links.tsx
index 546fa2d15..f922cf574 100644
--- a/components/layout/search/helpful-links.tsx
+++ b/components/layout/search/helpful-links.tsx
@@ -1,23 +1,6 @@
import { getCollection, getMetaobjectsByIds } from 'lib/shopify';
-import Link from 'next/link';
+import CollectionLink from './collection-link';
-const LinkItem = async ({
- collectionLinkId,
- anchorText
-}: {
- collectionLinkId: string;
- anchorText: string;
-}) => {
- const collection = await getCollection({ id: collectionLinkId });
-
- if (!collection) return null;
-
- return (
-
- {anchorText}
-
- );
-};
const HelpfulLinks = async ({ collection }: { collection: string }) => {
const collectionData = await getCollection({ handle: collection });
if (!collectionData || !collectionData.helpfulLinks) return null;
@@ -30,7 +13,7 @@ const HelpfulLinks = async ({ collection }: { collection: string }) => {
{helpfulLinks.map((link) => (
-
diff --git a/lib/shopify/index.ts b/lib/shopify/index.ts
index ad869c077..4ed191852 100644
--- a/lib/shopify/index.ts
+++ b/lib/shopify/index.ts
@@ -175,6 +175,7 @@ const reshapeCollection = (collection: ShopifyCollection): Collection | undefine
return {
...collection,
helpfulLinks: parseMetaFieldValue(collection.helpfulLinks),
+ helpfulLinksTop: parseMetaFieldValue(collection.helpfulLinksTop),
path: `/search/${collection.handle}`
};
};
@@ -530,7 +531,8 @@ export async function getCollections(): Promise {
},
path: '/search',
updatedAt: new Date().toISOString(),
- helpfulLinks: null
+ helpfulLinks: null,
+ helpfulLinksTop: null
},
// Filter out the `hidden` collections.
// Collections that start with `hidden-*` need to be hidden on the search page.
diff --git a/lib/shopify/queries/collection.ts b/lib/shopify/queries/collection.ts
index f59aec8f1..306e3cf9e 100644
--- a/lib/shopify/queries/collection.ts
+++ b/lib/shopify/queries/collection.ts
@@ -12,6 +12,9 @@ const collectionFragment = /* GraphQL */ `
helpfulLinks: metafield(namespace: "custom", key: "helpful_links") {
value
}
+ helpfulLinksTop: metafield(namespace: "custom", key: "helpful_links_top") {
+ value
+ }
updatedAt
}
${seoFragment}
diff --git a/lib/shopify/types.ts b/lib/shopify/types.ts
index cd20d4dd4..2ed837f0e 100644
--- a/lib/shopify/types.ts
+++ b/lib/shopify/types.ts
@@ -40,9 +40,10 @@ export type CartItem = {
addOnProduct?: CartItem & { quantity: number };
};
-export type Collection = Omit & {
+export type Collection = Omit & {
path: string;
helpfulLinks: string[] | null;
+ helpfulLinksTop: string[] | null;
};
export type Image = {
@@ -225,6 +226,7 @@ export type ShopifyCollection = {
seo: SEO;
updatedAt: string;
helpfulLinks: { value: string } | null;
+ helpfulLinksTop: { value: string } | null;
};
export type ShopifyProduct = {