mirror of
https://github.com/vercel/commerce.git
synced 2025-05-18 15:36:58 +00:00
integrate with PLP content metafields
This commit is contained in:
parent
045f4b4036
commit
0fc51f5d53
@ -86,10 +86,10 @@ const FiltersList = ({ makes = [], menu, autoFocusField }: FiltersListProps) =>
|
|||||||
setLoadingAttribute(undefined);
|
setLoadingAttribute(undefined);
|
||||||
};
|
};
|
||||||
|
|
||||||
if (make?.id && models.length === 0) {
|
if (models.length === 0) {
|
||||||
getModels();
|
getModels();
|
||||||
}
|
}
|
||||||
}, [make?.id, modelIdFromSearchParams, models.length]);
|
}, [modelIdFromSearchParams, models.length]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const getYears = async () => {
|
const getYears = async () => {
|
||||||
@ -105,10 +105,10 @@ const FiltersList = ({ makes = [], menu, autoFocusField }: FiltersListProps) =>
|
|||||||
setLoadingAttribute(undefined);
|
setLoadingAttribute(undefined);
|
||||||
};
|
};
|
||||||
|
|
||||||
if (model?.id && years.length === 0) {
|
if (years.length === 0) {
|
||||||
getYears();
|
getYears();
|
||||||
}
|
}
|
||||||
}, [model?.id, yearIdFromSearchParams, years.length]);
|
}, [yearIdFromSearchParams, years.length]);
|
||||||
|
|
||||||
const onChangeMake = async (value: Metaobject | null) => {
|
const onChangeMake = async (value: Metaobject | null) => {
|
||||||
setMake(value);
|
setMake(value);
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
|
import { cn } from 'lib/utils';
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
|
|
||||||
type Text = {
|
type Text = {
|
||||||
@ -16,14 +17,38 @@ type Content =
|
|||||||
children: Array<{ type: 'listItem'; children: Text[] }>;
|
children: Array<{ type: 'listItem'; children: Text[] }>;
|
||||||
}
|
}
|
||||||
| { type: 'listItem'; children: Text[] }
|
| { type: 'listItem'; children: Text[] }
|
||||||
| { type: 'link'; children: Text[]; target: string; title: string; url: string };
|
| { type: 'link'; children: Text[]; target: string; title: string; url: string }
|
||||||
|
| {
|
||||||
|
type: 'heading';
|
||||||
|
level: number;
|
||||||
|
children: Text[];
|
||||||
|
};
|
||||||
|
|
||||||
const RichTextBlock = ({ block }: { block: Content }) => {
|
const RichTextBlock = ({ block, className }: { block: Content; className?: string }) => {
|
||||||
if (block.type === 'text') {
|
if (block.type === 'text') {
|
||||||
return block.bold ? (
|
return block.bold ? (
|
||||||
<strong className="font-semibold">{block.value}</strong>
|
<strong className="font-semibold">{block.value}</strong>
|
||||||
) : (
|
) : (
|
||||||
<span className="font-normal">{block.value}</span>
|
<span className={cn('font-normal', className)}>{block.value}</span>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (block.type === 'heading') {
|
||||||
|
const Heading = `h${block.level}` as keyof JSX.IntrinsicElements;
|
||||||
|
return (
|
||||||
|
<Heading
|
||||||
|
className={clsx('text-black-700', {
|
||||||
|
'text-3xl': block.level === 2,
|
||||||
|
'text-2xl': block.level === 3,
|
||||||
|
'text-lg': block.level === 4,
|
||||||
|
'text-base': block.level === 5,
|
||||||
|
'text-sm': block.level === 6
|
||||||
|
})}
|
||||||
|
>
|
||||||
|
{block.children.map((child, index) => (
|
||||||
|
<RichTextBlock key={index} block={child} className="font-semibold" />
|
||||||
|
))}
|
||||||
|
</Heading>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,18 +8,18 @@ const DefaultContent = async () => {
|
|||||||
handle: { handle: 'default-plp-content', type: 'plp_content' }
|
handle: { handle: 'default-plp-content', type: 'plp_content' }
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!defaultPLPContent) return null;
|
if (!defaultPLPContent) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
const sectionIds = defaultPLPContent.sections ? JSON.parse(defaultPLPContent.sections) : [];
|
const { id, type, title, ...fields } = defaultPLPContent;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="space-y-3">
|
<div>
|
||||||
<Tag text="Learn More" />
|
<Tag text="Learn More" />
|
||||||
<h3 className="mb-3 text-3xl font-semibold text-black-700 lg:text-4xl">
|
<h3 className="mb-5 mt-3 text-3xl font-semibold text-black-700 lg:text-4xl">{title}</h3>
|
||||||
{defaultPLPContent.title}
|
|
||||||
</h3>
|
|
||||||
<Suspense fallback={<TabsPlaceholder />}>
|
<Suspense fallback={<TabsPlaceholder />}>
|
||||||
<Tabs tabItemIds={sectionIds} />
|
<Tabs fields={fields} />
|
||||||
</Suspense>
|
</Suspense>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -3,15 +3,17 @@ import { Metaobject } from 'lib/shopify/types';
|
|||||||
import { Suspense } from 'react';
|
import { Suspense } from 'react';
|
||||||
import Tabs, { TabsPlaceholder } from './tabs';
|
import Tabs, { TabsPlaceholder } from './tabs';
|
||||||
|
|
||||||
const DynamicContent = async ({ content }: { content: Metaobject }) => {
|
const DynamicContent = ({ content }: { content: Metaobject }) => {
|
||||||
const sectionIds = content.sections ? JSON.parse(content.sections) : [];
|
const { id, type, title, ...fields } = content;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="space-y-3">
|
<div>
|
||||||
<Tag text="Learn More" />
|
<Tag text="Learn More" />
|
||||||
<h3 className="mb-3 text-3xl font-semibold text-black-700 lg:text-4xl">{content.title}</h3>
|
<h3 className="mb-5 mt-3 text-3xl font-semibold text-black-700 lg:text-4xl">
|
||||||
|
{content.title}
|
||||||
|
</h3>
|
||||||
<Suspense fallback={<TabsPlaceholder />}>
|
<Suspense fallback={<TabsPlaceholder />}>
|
||||||
<Tabs tabItemIds={sectionIds} />
|
<Tabs fields={fields} />
|
||||||
</Suspense>
|
</Suspense>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -1,41 +1,30 @@
|
|||||||
import { ChevronRightIcon } from '@heroicons/react/24/solid';
|
import { ChevronRightIcon } from '@heroicons/react/24/solid';
|
||||||
import PageContent from 'components/page/page-content';
|
import RichTextDisplay from 'components/page/rich-text-display';
|
||||||
import { getMetaobjectsByIds } from 'lib/shopify';
|
import startCase from 'lodash.startcase';
|
||||||
import { Tab, TabGroup, TabList, TabPanel, TabPanels } from './tab-components';
|
import { Tab, TabGroup, TabList, TabPanel, TabPanels } from './tab-components';
|
||||||
|
|
||||||
const TabPanelContent = async ({ ids }: { ids: string[] }) => {
|
const Tabs = ({ fields }: { fields: { [key: string]: string } }) => {
|
||||||
const content = await getMetaobjectsByIds(ids);
|
const keys = Object.keys(fields);
|
||||||
|
|
||||||
return (
|
|
||||||
<TabPanel className="flex min-w-full flex-col space-y-5">
|
|
||||||
{content.map((block) => (
|
|
||||||
<PageContent key={block.id} block={block} />
|
|
||||||
))}
|
|
||||||
</TabPanel>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const Tabs = async ({ tabItemIds }: { tabItemIds: string[] }) => {
|
|
||||||
const tabItems = await getMetaobjectsByIds(tabItemIds);
|
|
||||||
if (!tabItems || tabItems.length === 0) return null;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TabGroup vertical>
|
<TabGroup vertical>
|
||||||
<div className="flex w-full gap-x-10">
|
<div className="flex w-full gap-x-10">
|
||||||
<TabList className="flex shrink-0 basis-1/4 flex-col gap-2">
|
<TabList className="flex shrink-0 basis-1/4 flex-col gap-2">
|
||||||
{tabItems.map((item) => (
|
{keys.map((key) => (
|
||||||
<Tab
|
<Tab
|
||||||
key={item.id}
|
key={key}
|
||||||
className="flex items-center justify-between rounded-sm bg-gray-200/60 p-3 text-left text-sm font-medium text-black-700 focus:outline-none focus:ring-0 data-[selected]:bg-primary data-[selected]:text-white"
|
className="flex items-center justify-between rounded-sm bg-gray-200/60 p-3 text-left text-sm font-medium text-black-700 focus:outline-none focus:ring-0 data-[selected]:bg-primary data-[selected]:text-white"
|
||||||
>
|
>
|
||||||
{item.title}
|
{startCase(key)}
|
||||||
<ChevronRightIcon className="size-4" />
|
<ChevronRightIcon className="size-4" />
|
||||||
</Tab>
|
</Tab>
|
||||||
))}
|
))}
|
||||||
</TabList>
|
</TabList>
|
||||||
<TabPanels className="flex basis-3/4">
|
<TabPanels className="flex basis-3/4">
|
||||||
{tabItems.map((item) => (
|
{keys.map((key) => (
|
||||||
<TabPanelContent key={item.id} ids={item.content ? JSON.parse(item.content) : []} />
|
<TabPanel className="flex min-w-full flex-col space-y-5">
|
||||||
|
<RichTextDisplay contentBlocks={JSON.parse(fields[key] || '{}').children} />
|
||||||
|
</TabPanel>
|
||||||
))}
|
))}
|
||||||
</TabPanels>
|
</TabPanels>
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user