diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 3ba3970..8e421a1 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -129,6 +129,9 @@ importers:
'@shopify/remix-oxygen':
specifier: ^2.0.1
version: 2.0.1(@shopify/oxygen-workers-types@3.17.3)
+ '@vercel/stega':
+ specifier: ^0.1.0
+ version: 0.1.0
class-variance-authority:
specifier: ^0.7.0
version: 0.7.0
diff --git a/templates/hydrogen-theme/app/components/CollectionCard.tsx b/templates/hydrogen-theme/app/components/CollectionCard.tsx
new file mode 100644
index 0000000..fa7e77b
--- /dev/null
+++ b/templates/hydrogen-theme/app/components/CollectionCard.tsx
@@ -0,0 +1,23 @@
+import {Link} from '@remix-run/react';
+import {Image} from '@shopify/hydrogen';
+import type {CollectionsQuery} from 'storefrontapi.generated';
+
+export function CollectionCard(props: {
+ collection: CollectionsQuery['collections']['nodes'][0];
+ className?: string;
+}) {
+ const {collection} = props;
+
+ return (
+
+
+ {collection.image && (
+
+ )}
+
+
+
+ );
+}
diff --git a/templates/hydrogen-theme/app/components/CollectionListGrid.tsx b/templates/hydrogen-theme/app/components/CollectionListGrid.tsx
new file mode 100644
index 0000000..de32240
--- /dev/null
+++ b/templates/hydrogen-theme/app/components/CollectionListGrid.tsx
@@ -0,0 +1,19 @@
+import type {CollectionsQuery} from 'storefrontapi.generated';
+import {flattenConnection} from '@shopify/hydrogen';
+import {CollectionCard} from './CollectionCard';
+
+export function CollectionListGrid(props: {
+ collections?: CollectionsQuery['collections'];
+}) {
+ const collections = flattenConnection(props.collections);
+
+ return collections?.length > 0 ? (
+
+ {collections.map((collection) => (
+ -
+
+
+ ))}
+
+ ) : null;
+}
diff --git a/templates/hydrogen-theme/app/components/sections/CollectionListSection.tsx b/templates/hydrogen-theme/app/components/sections/CollectionListSection.tsx
new file mode 100644
index 0000000..802ecd7
--- /dev/null
+++ b/templates/hydrogen-theme/app/components/sections/CollectionListSection.tsx
@@ -0,0 +1,44 @@
+import type {TypeFromSelection} from 'groqd';
+
+import type {COLLECTION_LIST_SECTION_FRAGMENT} from '~/qroq/sections';
+import type {loader as indexLoader} from '../../routes/_index';
+import type {SectionDefaultProps} from '~/lib/type';
+import {Await, useLoaderData} from '@remix-run/react';
+import {Suspense} from 'react';
+import {CollectionListGrid} from '../CollectionListGrid';
+
+type CollectionListSectionProps = TypeFromSelection<
+ typeof COLLECTION_LIST_SECTION_FRAGMENT
+>;
+
+export function CollectionListSection(
+ props: SectionDefaultProps & {data: CollectionListSectionProps},
+) {
+ const loaderData = useLoaderData();
+ const collectionListPromise = loaderData?.collectionListPromise;
+ const sectionGids = props.data.collections
+ ?.map((collection) => collection.store.gid)
+ .join(',');
+
+ return collectionListPromise ? (
+ Loading...}>
+
+ {(data) => {
+ // Resolve the collection list data from Shopify with the gids from Sanity
+ const collections = data.find(({collections}) => {
+ const gids = collections.nodes
+ .map((collection) => collection.id)
+ .join(',');
+ return sectionGids === gids ? collections : null;
+ })?.collections;
+
+ return (
+
+
+
+ );
+ }}
+
+
+ ) : null;
+}
diff --git a/templates/hydrogen-theme/app/components/sections/FeaturedCollectionSection.tsx b/templates/hydrogen-theme/app/components/sections/FeaturedCollectionSection.tsx
index b5ae2b3..df6389c 100644
--- a/templates/hydrogen-theme/app/components/sections/FeaturedCollectionSection.tsx
+++ b/templates/hydrogen-theme/app/components/sections/FeaturedCollectionSection.tsx
@@ -4,6 +4,7 @@ import {Await, useLoaderData} from '@remix-run/react';
import type {FEATURED_COLLECTION_SECTION_FRAGMENT} from '~/qroq/sections';
import type {loader as indexLoader} from '../../routes/_index';
+import type {SectionDefaultProps} from '~/lib/type';
import {ProductCardGrid} from '../ProductCardGrid';
import {flattenConnection} from '@shopify/hydrogen';
@@ -12,15 +13,21 @@ type FeaturedCollectionSectionProps = TypeFromSelection<
>;
export function FeaturedCollectionSection(
- props: FeaturedCollectionSectionProps,
+ props: SectionDefaultProps & {data: FeaturedCollectionSectionProps},
) {
const loaderData = useLoaderData();
const featuredCollectionPromise = loaderData?.featuredCollectionPromise;
+ const gid = props.data?.collection?.store.gid;
return featuredCollectionPromise ? (
Loading...}>
- {({collection}) => {
+ {(data) => {
+ // Resolve the collection data from Shopify with the gid from Sanity
+ const collection = data.find(
+ ({collection}) => gid?.includes(collection?.id!),
+ )?.collection;
+
const products =
collection?.products?.nodes &&
collection?.products?.nodes?.length > 1
diff --git a/templates/hydrogen-theme/app/graphql/queries.ts b/templates/hydrogen-theme/app/graphql/queries.ts
index 96cb97d..26ad3df 100644
--- a/templates/hydrogen-theme/app/graphql/queries.ts
+++ b/templates/hydrogen-theme/app/graphql/queries.ts
@@ -122,10 +122,11 @@ export const COLLECTIONS_QUERY = `#graphql
$language: LanguageCode
$first: Int
$last: Int
+ $query: String
$startCursor: String
$endCursor: String
) @inContext(country: $country, language: $language) {
- collections(first: $first, last: $last, before: $startCursor, after: $endCursor) {
+ collections(first: $first, last: $last, before: $startCursor, after: $endCursor, query: $query) {
nodes {
id
title
@@ -223,12 +224,12 @@ export const COLLECTION_QUERY = `#graphql
export const FEATURED_COLLECTION_QUERY = `#graphql
query FeaturedCollection(
- $handle: String!
+ $id: ID!
$country: CountryCode
$language: LanguageCode
$first: Int
) @inContext(country: $country, language: $language) {
- collection(handle: $handle) {
+ collection(id: $id) {
id
handle
title
diff --git a/templates/hydrogen-theme/app/hooks/useSanityData.tsx b/templates/hydrogen-theme/app/hooks/useSanityData.tsx
index b0568fc..0487479 100644
--- a/templates/hydrogen-theme/app/hooks/useSanityData.tsx
+++ b/templates/hydrogen-theme/app/hooks/useSanityData.tsx
@@ -41,6 +41,7 @@ export function useSanityData(initial: T) {
const params = sanity?.params;
const query = sanity?.query || '';
+ // Todo: find a way to avoid using useQuery hook in production when STEGA is disabled
const {data, loading, sourceMap} = useQuery(query || '', params, {
initial: initial as any,
});
diff --git a/templates/hydrogen-theme/app/lib/resolveShopifyPromises.ts b/templates/hydrogen-theme/app/lib/resolveShopifyPromises.ts
index f768acf..784d826 100644
--- a/templates/hydrogen-theme/app/lib/resolveShopifyPromises.ts
+++ b/templates/hydrogen-theme/app/lib/resolveShopifyPromises.ts
@@ -1,9 +1,12 @@
-import type {Storefront} from '@shopify/hydrogen';
+import {parseGid, type Storefront} from '@shopify/hydrogen';
import type {InferType} from 'groqd';
-import type {FeaturedCollectionQuery} from 'storefrontapi.generated';
+import type {
+ CollectionsQuery,
+ FeaturedCollectionQuery,
+} from 'storefrontapi.generated';
import type {PAGE_QUERY} from '~/qroq/queries';
-import {FEATURED_COLLECTION_QUERY} from '~/graphql/queries';
+import {COLLECTIONS_QUERY, FEATURED_COLLECTION_QUERY} from '~/graphql/queries';
type SanityPageData = InferType;
type PromiseResolverArgs = {
@@ -25,35 +28,78 @@ export function resolveShopifyPromises({
storefront,
});
- return {featuredCollectionPromise};
+ const collectionListPromise = resolveCollectionListPromise({
+ document,
+ storefront,
+ });
+
+ return {featuredCollectionPromise, collectionListPromise};
}
function resolveFeaturedCollectionPromise({
document,
storefront,
}: PromiseResolverArgs) {
- let featuredCollectionPromise: Promise | undefined;
+ const promises: Promise[] = [];
document.data?.sections?.forEach((section) => {
if (section._type === 'featuredCollectionSection') {
- const collectionHandle = section.collection?.store.slug.current;
+ const gid = section.collection?.store.gid;
- if (!collectionHandle) {
+ if (!gid) {
return undefined;
}
const promise = storefront.query(FEATURED_COLLECTION_QUERY, {
variables: {
- handle: collectionHandle,
+ id: gid,
first: 4,
country: storefront.i18n.country,
language: storefront.i18n.language,
},
});
- featuredCollectionPromise = promise;
+ promises.push(promise);
}
});
+ const featuredCollectionPromise = Promise.all(promises);
+
return featuredCollectionPromise;
}
+
+function resolveCollectionListPromise({
+ document,
+ storefront,
+}: PromiseResolverArgs) {
+ const promises: Promise[] = [];
+
+ document.data?.sections?.forEach((section) => {
+ if (section._type === 'collectionListSection') {
+ const first = section.collections?.length;
+ const ids = section.collections?.map(
+ (collection) => parseGid(collection.store.gid).id,
+ );
+ const query = ids?.map((id) => `(id:${id})`).join(' OR ');
+
+ if (!ids?.length || !first) {
+ return undefined;
+ }
+
+ const promise = storefront.query(COLLECTIONS_QUERY, {
+ variables: {
+ first,
+ query,
+ country: storefront.i18n.country,
+ language: storefront.i18n.language,
+ },
+ });
+
+ promises.push(promise);
+ }
+ });
+
+ const collectionListPromise = Promise.all(promises);
+
+ return collectionListPromise;
+}
diff --git a/templates/hydrogen-theme/app/lib/sectionRelsolver.ts b/templates/hydrogen-theme/app/lib/sectionRelsolver.ts
index 63b6171..6eb59fe 100644
--- a/templates/hydrogen-theme/app/lib/sectionRelsolver.ts
+++ b/templates/hydrogen-theme/app/lib/sectionRelsolver.ts
@@ -15,6 +15,11 @@ export const sections: {
}),
),
),
+ collectionListSection: lazy(() =>
+ import('../components/sections/CollectionListSection').then((module) => ({
+ default: module.CollectionListSection,
+ })),
+ ),
ctaSection: lazy(() =>
import('../components/sections/CtaSection').then((module) => ({
default: module.CtaSection,
diff --git a/templates/hydrogen-theme/app/qroq/sections.ts b/templates/hydrogen-theme/app/qroq/sections.ts
index d6a63e8..1ab847c 100644
--- a/templates/hydrogen-theme/app/qroq/sections.ts
+++ b/templates/hydrogen-theme/app/qroq/sections.ts
@@ -70,10 +70,26 @@ export const FEATURED_COLLECTION_SECTION_FRAGMENT = {
.deref()
.grab({
store: q('store').grab({
- slug: q.object({
- current: q.string(),
- _type: q.string(),
- }),
+ gid: q.string(),
+ }),
+ })
+ .nullable(),
+ settings: SECTION_SETTINGS_FRAGMENT,
+} satisfies Selection;
+
+/*
+|--------------------------------------------------------------------------
+| Collection List Section
+|--------------------------------------------------------------------------
+*/
+export const COLLECTION_LIST_SECTION_FRAGMENT = {
+ _type: z.enum(['collectionListSection']),
+ _key: q.string().nullable(),
+ collections: q('collections[]', {isArray: true})
+ .deref()
+ .grab({
+ store: q('store').grab({
+ gid: q.string(),
}),
})
.nullable(),
@@ -106,6 +122,7 @@ export const CTA_SECTION_FRAGMENT = {
export const SECTIONS_LIST_SELECTION = {
"_type == 'imageBannerSection'": IMAGE_BANNER_SECTION_FRAGMENT,
"_type == 'featuredCollectionSection'": FEATURED_COLLECTION_SECTION_FRAGMENT,
+ "_type == 'collectionListSection'": COLLECTION_LIST_SECTION_FRAGMENT,
"_type == 'ctaSection'": CTA_SECTION_FRAGMENT,
};
diff --git a/templates/hydrogen-theme/app/routes/($locale).$.tsx b/templates/hydrogen-theme/app/routes/($locale).$.tsx
index ec5460a..d83868e 100644
--- a/templates/hydrogen-theme/app/routes/($locale).$.tsx
+++ b/templates/hydrogen-theme/app/routes/($locale).$.tsx
@@ -27,10 +27,11 @@ export async function loader({context, params, request}: LoaderFunctionArgs) {
params: queryParams,
});
- const {featuredCollectionPromise} = resolveShopifyPromises({
- document: page,
- storefront,
- });
+ const {featuredCollectionPromise, collectionListPromise} =
+ resolveShopifyPromises({
+ document: page,
+ storefront,
+ });
if (!page.data) {
throw new Response(null, {
@@ -42,6 +43,7 @@ export async function loader({context, params, request}: LoaderFunctionArgs) {
return defer({
page,
featuredCollectionPromise,
+ collectionListPromise,
...sanityPreviewPayload({
query: PAGE_QUERY.query,
params: queryParams,
diff --git a/templates/hydrogen-theme/app/routes/($locale).collections._index.tsx b/templates/hydrogen-theme/app/routes/($locale).collections._index.tsx
index 8d83ec2..89c5e35 100644
--- a/templates/hydrogen-theme/app/routes/($locale).collections._index.tsx
+++ b/templates/hydrogen-theme/app/routes/($locale).collections._index.tsx
@@ -1,19 +1,13 @@
import type {LoaderFunctionArgs} from '@shopify/remix-oxygen';
import {json} from '@shopify/remix-oxygen';
-import {Link, useLoaderData} from '@remix-run/react';
-import {
- flattenConnection,
- getPaginationVariables,
- Image,
-} from '@shopify/hydrogen';
+import {useLoaderData} from '@remix-run/react';
+import {getPaginationVariables} from '@shopify/hydrogen';
-import type {CollectionsQuery} from 'storefrontapi.generated';
import {COLLECTIONS_QUERY} from '~/graphql/queries';
+import {CollectionListGrid} from '~/components/CollectionListGrid';
const PAGINATION_SIZE = 4;
-type Collection = CollectionsQuery['collections']['nodes'][0];
-
export const loader = async ({
request,
context: {storefront},
@@ -37,41 +31,7 @@ export default function Collections() {
return (
-
-
- );
-}
-
-function CollectionCardGrid(props: {
- collections: CollectionsQuery['collections'];
-}) {
- const collections =
- props.collections.nodes.length > 0
- ? flattenConnection(props.collections)
- : [];
-
- return collections.length > 0 ? (
-
- {collections.map((collection) => (
- -
-
-
- ))}
-
- ) : null;
-}
-
-function CollectionCard(props: {collection: Collection; className?: string}) {
- const {collection} = props;
-
- return (
-
-
- {collection.image &&
}
-
-
+
);
}
diff --git a/templates/hydrogen-theme/app/routes/_index.tsx b/templates/hydrogen-theme/app/routes/_index.tsx
index 2705ba6..36da7c7 100644
--- a/templates/hydrogen-theme/app/routes/_index.tsx
+++ b/templates/hydrogen-theme/app/routes/_index.tsx
@@ -1,12 +1,10 @@
import type {LoaderFunctionArgs} from '@shopify/remix-oxygen';
import {defer} from '@shopify/remix-oxygen';
-import type {FeaturedCollectionQuery} from 'storefrontapi.generated';
import PageRoute from './($locale).$';
import {PAGE_QUERY} from '~/qroq/queries';
import {sanityPreviewPayload} from '~/lib/sanity/sanity.payload.server';
import {DEFAULT_LOCALE} from 'countries';
-import {FEATURED_COLLECTION_QUERY} from '~/graphql/queries';
import {resolveShopifyPromises} from '~/lib/resolveShopifyPromises';
export async function loader({context}: LoaderFunctionArgs) {
@@ -23,10 +21,11 @@ export async function loader({context}: LoaderFunctionArgs) {
params: queryParams,
});
- const {featuredCollectionPromise} = resolveShopifyPromises({
- document: page,
- storefront,
- });
+ const {featuredCollectionPromise, collectionListPromise} =
+ resolveShopifyPromises({
+ document: page,
+ storefront,
+ });
if (!page.data) {
throw new Response(null, {
@@ -38,6 +37,7 @@ export async function loader({context}: LoaderFunctionArgs) {
return defer({
page,
featuredCollectionPromise,
+ collectionListPromise,
...sanityPreviewPayload({
query: PAGE_QUERY.query,
params: queryParams,
diff --git a/templates/hydrogen-theme/package.json b/templates/hydrogen-theme/package.json
index 864cd54..acd1d07 100644
--- a/templates/hydrogen-theme/package.json
+++ b/templates/hydrogen-theme/package.json
@@ -28,6 +28,7 @@
"@shopify/cli-hydrogen": "^6.0.2",
"@shopify/hydrogen": "^2023.10.2",
"@shopify/remix-oxygen": "^2.0.1",
+ "@vercel/stega": "^0.1.0",
"class-variance-authority": "^0.7.0",
"cva": "1.0.0-beta.1",
"framer-motion": "^10.16.12",
diff --git a/templates/hydrogen-theme/storefrontapi.generated.d.ts b/templates/hydrogen-theme/storefrontapi.generated.d.ts
index 538d199..345e5a7 100644
--- a/templates/hydrogen-theme/storefrontapi.generated.d.ts
+++ b/templates/hydrogen-theme/storefrontapi.generated.d.ts
@@ -466,6 +466,7 @@ export type CollectionsQueryVariables = StorefrontAPI.Exact<{
language?: StorefrontAPI.InputMaybe;
first?: StorefrontAPI.InputMaybe;
last?: StorefrontAPI.InputMaybe;
+ query?: StorefrontAPI.InputMaybe;
startCursor?: StorefrontAPI.InputMaybe<
StorefrontAPI.Scalars['String']['input']
>;
@@ -579,7 +580,7 @@ export type CollectionDetailsQuery = {
};
export type FeaturedCollectionQueryVariables = StorefrontAPI.Exact<{
- handle: StorefrontAPI.Scalars['String']['input'];
+ id: StorefrontAPI.Scalars['ID']['input'];
country?: StorefrontAPI.InputMaybe;
language?: StorefrontAPI.InputMaybe;
first?: StorefrontAPI.InputMaybe;
@@ -647,7 +648,7 @@ interface GeneratedQueryTypes {
return: VariantsQuery;
variables: VariantsQueryVariables;
};
- '#graphql\n query Collections(\n $country: CountryCode\n $language: LanguageCode\n $first: Int\n $last: Int\n $startCursor: String\n $endCursor: String\n ) @inContext(country: $country, language: $language) {\n collections(first: $first, last: $last, before: $startCursor, after: $endCursor) {\n nodes {\n id\n title\n description\n handle\n seo {\n description\n title\n }\n image {\n id\n url\n width\n height\n altText\n }\n }\n pageInfo {\n hasPreviousPage\n hasNextPage\n startCursor\n endCursor\n }\n }\n }\n': {
+ '#graphql\n query Collections(\n $country: CountryCode\n $language: LanguageCode\n $first: Int\n $last: Int\n $query: String\n $startCursor: String\n $endCursor: String\n ) @inContext(country: $country, language: $language) {\n collections(first: $first, last: $last, before: $startCursor, after: $endCursor, query: $query) {\n nodes {\n id\n title\n description\n handle\n seo {\n description\n title\n }\n image {\n id\n url\n width\n height\n altText\n }\n }\n pageInfo {\n hasPreviousPage\n hasNextPage\n startCursor\n endCursor\n }\n }\n }\n': {
return: CollectionsQuery;
variables: CollectionsQueryVariables;
};
@@ -655,7 +656,7 @@ interface GeneratedQueryTypes {
return: CollectionDetailsQuery;
variables: CollectionDetailsQueryVariables;
};
- '#graphql\n query FeaturedCollection(\n $handle: String!\n $country: CountryCode\n $language: LanguageCode\n $first: Int\n ) @inContext(country: $country, language: $language) {\n collection(handle: $handle) {\n id\n handle\n title\n description\n image {\n id\n url\n width\n height\n altText\n }\n products(\n first: $first,\n ) {\n nodes {\n ...ProductCard\n }\n }\n }\n }\n #graphql\n fragment ProductCard on Product {\n id\n title\n publishedAt\n handle\n vendor\n variants(first: 1) {\n nodes {\n id\n availableForSale\n image {\n url\n altText\n width\n height\n }\n price {\n amount\n currencyCode\n }\n compareAtPrice {\n amount\n currencyCode\n }\n selectedOptions {\n name\n value\n }\n product {\n handle\n title\n }\n }\n }\n }\n\n': {
+ '#graphql\n query FeaturedCollection(\n $id: ID!\n $country: CountryCode\n $language: LanguageCode\n $first: Int\n ) @inContext(country: $country, language: $language) {\n collection(id: $id) {\n id\n handle\n title\n description\n image {\n id\n url\n width\n height\n altText\n }\n products(\n first: $first,\n ) {\n nodes {\n ...ProductCard\n }\n }\n }\n }\n #graphql\n fragment ProductCard on Product {\n id\n title\n publishedAt\n handle\n vendor\n variants(first: 1) {\n nodes {\n id\n availableForSale\n image {\n url\n altText\n width\n height\n }\n price {\n amount\n currencyCode\n }\n compareAtPrice {\n amount\n currencyCode\n }\n selectedOptions {\n name\n value\n }\n product {\n handle\n title\n }\n }\n }\n }\n\n': {
return: FeaturedCollectionQuery;
variables: FeaturedCollectionQueryVariables;
};
diff --git a/templates/hydrogen-theme/studio/schemas/index.ts b/templates/hydrogen-theme/studio/schemas/index.ts
index 640d77a..cde4622 100644
--- a/templates/hydrogen-theme/studio/schemas/index.ts
+++ b/templates/hydrogen-theme/studio/schemas/index.ts
@@ -30,10 +30,16 @@ import socialLinksOnly from './objects/footers/socialLinksOnly';
import overlayOpacity from './objects/global/overlayOpacity';
import contentAlignment from './objects/global/contentAlignment';
import featuredCollection from './objects/sections/featuredCollection';
+import collectionListSection from './objects/sections/collectionListSection';
const singletons = [home, header, footer, settings, themeContent];
const documents = [page, color, collection, product, blogPost, productVariant];
-const sections = [imageBannerSection, featuredCollection, ctaSection];
+const sections = [
+ imageBannerSection,
+ featuredCollection,
+ collectionListSection,
+ ctaSection,
+];
const footers = [socialLinksOnly];
const objects = [
footersList,
diff --git a/templates/hydrogen-theme/studio/schemas/objects/global/sectionsList.ts b/templates/hydrogen-theme/studio/schemas/objects/global/sectionsList.ts
index f2d477a..4425324 100644
--- a/templates/hydrogen-theme/studio/schemas/objects/global/sectionsList.ts
+++ b/templates/hydrogen-theme/studio/schemas/objects/global/sectionsList.ts
@@ -14,6 +14,9 @@ export default defineField({
{
type: 'featuredCollectionSection',
},
+ {
+ type: 'collectionListSection',
+ },
{
type: 'ctaSection',
},
diff --git a/templates/hydrogen-theme/studio/schemas/objects/sections/collectionListSection.tsx b/templates/hydrogen-theme/studio/schemas/objects/sections/collectionListSection.tsx
new file mode 100644
index 0000000..017ad13
--- /dev/null
+++ b/templates/hydrogen-theme/studio/schemas/objects/sections/collectionListSection.tsx
@@ -0,0 +1,58 @@
+import {LayoutGrid} from 'lucide-react';
+import {defineField} from 'sanity';
+
+export default defineField({
+ name: 'collectionListSection',
+ title: 'Collection List',
+ type: 'object',
+ fields: [
+ defineField({
+ name: 'collections',
+ type: 'array',
+ options: {
+ layout: 'grid',
+ },
+ of: [
+ defineField({
+ name: 'collection',
+ type: 'reference',
+ to: [{type: 'collection'}],
+ }),
+ ],
+ validation: (Rule: any) =>
+ Rule.custom((array: any) => {
+ return checkForDuplicates(array);
+ }),
+ }),
+ defineField({
+ type: 'sectionSettings',
+ name: 'settings',
+ }),
+ ],
+ preview: {
+ prepare() {
+ return {
+ title: 'Collection List',
+ media: () => ,
+ };
+ },
+ },
+});
+
+function checkForDuplicates(array?: T[]): string | true {
+ const uniqueSet = new Set();
+
+ if (!array || array.length === 0) {
+ return 'Please add at least one collection.';
+ }
+
+ for (const item of array as any) {
+ if (uniqueSet.has(item._ref)) {
+ return 'Duplicate collection found. Please remove it from the list.';
+ }
+
+ uniqueSet.add(item._ref);
+ }
+
+ return true;
+}
diff --git a/templates/hydrogen-theme/studio/schemas/objects/sections/featuredCollection.tsx b/templates/hydrogen-theme/studio/schemas/objects/sections/featuredCollection.tsx
index 44f1065..6eab68d 100644
--- a/templates/hydrogen-theme/studio/schemas/objects/sections/featuredCollection.tsx
+++ b/templates/hydrogen-theme/studio/schemas/objects/sections/featuredCollection.tsx
@@ -2,7 +2,7 @@ import {defineField} from 'sanity';
export default defineField({
name: 'featuredCollectionSection',
- title: 'Featured Collection Section',
+ title: 'Featured Collection',
type: 'object',
fields: [
defineField({
@@ -20,8 +20,6 @@ export default defineField({
collection: 'collection.store',
},
prepare({collection}: any) {
- console.log('collection', collection);
-
return {
title: collection.title,
subtitle: 'Featured Collection',
diff --git a/templates/hydrogen-theme/studio/static/assets/collectionListSection.png b/templates/hydrogen-theme/studio/static/assets/collectionListSection.png
new file mode 100644
index 0000000..dca9242
Binary files /dev/null and b/templates/hydrogen-theme/studio/static/assets/collectionListSection.png differ