mirror of
https://github.com/vercel/commerce.git
synced 2025-05-18 15:36:58 +00:00
feat: add manufacturer section
Signed-off-by: Chloe <pinkcloudvnn@gmail.com>
This commit is contained in:
parent
c5af5b3069
commit
3ac4b140c9
@ -4,8 +4,10 @@ import { notFound } from 'next/navigation';
|
||||
|
||||
import Breadcrumb from 'components/breadcrumb';
|
||||
import BreadcrumbHome from 'components/breadcrumb/breadcrumb-home';
|
||||
import FAQ from 'components/faq';
|
||||
import YMMFilters, { YMMFiltersPlaceholder } from 'components/filters';
|
||||
import Grid from 'components/grid';
|
||||
import Manufacturers from 'components/home-page/manufacturers';
|
||||
import ProductsList from 'components/layout/products-list';
|
||||
import { getProductsInCollection } from 'components/layout/products-list/actions';
|
||||
import FiltersContainer, {
|
||||
@ -82,42 +84,52 @@ export default async function CategorySearchPage(props: {
|
||||
}) {
|
||||
return (
|
||||
<>
|
||||
<div className="grid lg:grid-cols-3 lg:gap-x-10 xl:grid-cols-4">
|
||||
<aside className="hidden lg:block">
|
||||
<div className="mb-5">
|
||||
<Suspense fallback={<YMMFiltersPlaceholder />}>
|
||||
<YMMFilters />
|
||||
<div className="mx-auto mt-6 max-w-screen-2xl px-8 pb-10">
|
||||
<div className="grid lg:grid-cols-3 lg:gap-x-10 xl:grid-cols-4">
|
||||
<aside className="hidden lg:block">
|
||||
<div className="mb-5">
|
||||
<Suspense fallback={<YMMFiltersPlaceholder />}>
|
||||
<YMMFilters />
|
||||
</Suspense>
|
||||
</div>
|
||||
|
||||
<SubMenu collection={props.params.collection} />
|
||||
<h3 className="sr-only">Filters</h3>
|
||||
<Suspense
|
||||
fallback={<FiltersListPlaceholder />}
|
||||
key={`filters-${props.params.collection}`}
|
||||
>
|
||||
<FiltersContainer searchParams={props.searchParams} />
|
||||
<HelpfulLinks collection={props.params.collection} />
|
||||
</Suspense>
|
||||
</aside>
|
||||
<div className="lg:col-span-2 xl:col-span-3">
|
||||
<div className="mb-2">
|
||||
<Suspense fallback={<BreadcrumbHome />} key={`breadcrumb-${props.params.collection}`}>
|
||||
<Breadcrumb type="collection" handle={props.params.collection} />
|
||||
</Suspense>
|
||||
</div>
|
||||
<Suspense fallback={<HeaderPlaceholder />} key={`header-${props.params.collection}`}>
|
||||
<Header collection={props.params.collection} />
|
||||
</Suspense>
|
||||
|
||||
<Suspense
|
||||
fallback={<ProductsGridPlaceholder />}
|
||||
key={`products-${props.params.collection}`}
|
||||
>
|
||||
<CategoryPage {...props} />
|
||||
</Suspense>
|
||||
</div>
|
||||
|
||||
<SubMenu collection={props.params.collection} />
|
||||
<h3 className="sr-only">Filters</h3>
|
||||
<Suspense
|
||||
fallback={<FiltersListPlaceholder />}
|
||||
key={`filters-${props.params.collection}`}
|
||||
>
|
||||
<FiltersContainer searchParams={props.searchParams} />
|
||||
<HelpfulLinks collection={props.params.collection} />
|
||||
</Suspense>
|
||||
</aside>
|
||||
<div className="lg:col-span-2 xl:col-span-3">
|
||||
<div className="mb-2">
|
||||
<Suspense fallback={<BreadcrumbHome />} key={`breadcrumb-${props.params.collection}`}>
|
||||
<Breadcrumb type="collection" handle={props.params.collection} />
|
||||
</Suspense>
|
||||
</div>
|
||||
<Suspense fallback={<HeaderPlaceholder />} key={`header-${props.params.collection}`}>
|
||||
<Header collection={props.params.collection} />
|
||||
</Suspense>
|
||||
|
||||
<Suspense
|
||||
fallback={<ProductsGridPlaceholder />}
|
||||
key={`products-${props.params.collection}`}
|
||||
>
|
||||
<CategoryPage {...props} />
|
||||
</Suspense>
|
||||
</div>
|
||||
</div>
|
||||
<FAQ handle="plp-faqs" />
|
||||
<Suspense>
|
||||
<Manufacturers
|
||||
variant={
|
||||
(props.params.collection as string).includes('engines') ? 'engines' : 'transmissions'
|
||||
}
|
||||
/>
|
||||
</Suspense>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
@ -1,14 +1,9 @@
|
||||
import FAQ from 'components/faq';
|
||||
import Footer from 'components/layout/footer';
|
||||
import { Suspense } from 'react';
|
||||
|
||||
export default function SearchLayout({ children }: { children: React.ReactNode }) {
|
||||
return (
|
||||
<>
|
||||
<div className="mx-auto mt-6 min-h-[500px] max-w-screen-2xl px-8 pb-10 lg:min-h-[800px]">
|
||||
<Suspense>{children}</Suspense>
|
||||
</div>
|
||||
<FAQ handle="plp-faqs" />
|
||||
<div className="min-h-[500px] lg:min-h-[800px]">{children}</div>
|
||||
|
||||
<Footer />
|
||||
</>
|
||||
|
@ -6,7 +6,7 @@ import { Menu, Metaobject } from 'lib/shopify/types';
|
||||
import { createUrl, findParentCollection } from 'lib/utils';
|
||||
import get from 'lodash.get';
|
||||
import { useParams, useRouter, useSearchParams } from 'next/navigation';
|
||||
import { useState } from 'react';
|
||||
import { useEffect, useState } from 'react';
|
||||
import FilterField from './field';
|
||||
|
||||
type FiltersListProps = {
|
||||
@ -31,11 +31,13 @@ const FiltersList = ({ years, makes, models, menu, autoFocusField }: FiltersList
|
||||
PART_TYPES.find((type) => type.value === partTypeCollection) || null
|
||||
);
|
||||
|
||||
const makeIdFromSearchParams = searchParams.get(MAKE_FILTER_ID);
|
||||
|
||||
const [make, setMake] = useState<Metaobject | null>(
|
||||
(partType &&
|
||||
makes.find((make) =>
|
||||
searchParams.get(MAKE_FILTER_ID)
|
||||
? make.id === searchParams.get(MAKE_FILTER_ID)
|
||||
makeIdFromSearchParams
|
||||
? make.id === makeIdFromSearchParams
|
||||
: params.collection?.includes(make.name!.toLowerCase())
|
||||
)) ||
|
||||
null
|
||||
@ -52,6 +54,22 @@ const FiltersList = ({ years, makes, models, menu, autoFocusField }: FiltersList
|
||||
|
||||
const disabled = !partType || !make || !model || !year;
|
||||
|
||||
useEffect(() => {
|
||||
if (partType) {
|
||||
const _make = makes.find((make) =>
|
||||
makeIdFromSearchParams
|
||||
? make.id === makeIdFromSearchParams
|
||||
: params.collection?.includes(make.name!.toLowerCase())
|
||||
);
|
||||
|
||||
if (_make) {
|
||||
setMake(_make);
|
||||
setModel(null);
|
||||
setYear(null);
|
||||
}
|
||||
}
|
||||
}, [makeIdFromSearchParams, makes, params.collection, partType]);
|
||||
|
||||
const onChangeMake = (value: Metaobject | null) => {
|
||||
setMake(value);
|
||||
setModel(null);
|
||||
|
@ -2,14 +2,24 @@ import ManufacturersGrid from 'components/manufacturers-grid';
|
||||
import Tag from 'components/tag';
|
||||
import { getMetaobjects } from 'lib/shopify';
|
||||
|
||||
const Manufacturers = async () => {
|
||||
const Manufacturers = async ({
|
||||
variant = 'home'
|
||||
}: {
|
||||
variant?: 'engines' | 'transmissions' | 'home';
|
||||
}) => {
|
||||
const manufacturers = await getMetaobjects('make');
|
||||
const title: Record<typeof variant, string> = {
|
||||
engines: 'Engines',
|
||||
home: 'Parts',
|
||||
transmissions: 'Transmissions'
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="px-6 py-20">
|
||||
<div className="mx-auto flex max-w-7xl flex-col gap-3">
|
||||
<Tag text="Get Started" />
|
||||
<h3 className="mb-3 text-3xl font-semibold lg:text-4xl">Browse Parts By Manufacturer</h3>
|
||||
<ManufacturersGrid manufacturers={manufacturers} />
|
||||
<h3 className="mb-3 text-3xl font-semibold lg:text-4xl">{`Browse ${title[variant]} By Manufacturer`}</h3>
|
||||
<ManufacturersGrid manufacturers={manufacturers} variant={variant} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
@ -1,11 +1,12 @@
|
||||
import { GlobeAltIcon, StarIcon } from '@heroicons/react/24/outline';
|
||||
import { MAKE_FILTER_ID } from 'lib/constants';
|
||||
import { Metaobject } from 'lib/shopify/types';
|
||||
import ButtonGroup from './button-group';
|
||||
import ManufacturerItem from './item';
|
||||
|
||||
type ManufacturersGridProps = {
|
||||
manufacturers: Metaobject[];
|
||||
variant?: 'engine' | 'transmission' | 'home';
|
||||
variant?: 'engines' | 'transmissions' | 'home';
|
||||
};
|
||||
|
||||
const ManufacturersGrid = ({ manufacturers, variant = 'home' }: ManufacturersGridProps) => {
|
||||
@ -22,7 +23,15 @@ const ManufacturersGrid = ({ manufacturers, variant = 'home' }: ManufacturersGri
|
||||
<div className="mt-6 grid grid-cols-2 gap-x-12 gap-y-5 md:grid-cols-3 md:gap-y-8 lg:grid-cols-4 xl:grid-cols-5">
|
||||
{popularManufacturers.map((manufacturer) => (
|
||||
<div key={manufacturer.id} className="flex flex-col gap-2">
|
||||
<ManufacturerItem manufacturer={manufacturer} />
|
||||
{variant === 'home' ? (
|
||||
<ManufacturerItem manufacturer={manufacturer} />
|
||||
) : (
|
||||
<ManufacturerItem
|
||||
manufacturer={manufacturer}
|
||||
className={'rounded border border-primary px-2 py-1'}
|
||||
href={`/search/${variant}?${MAKE_FILTER_ID}=${manufacturer.id}`}
|
||||
/>
|
||||
)}
|
||||
{variant === 'home' && <ButtonGroup manufacturer={manufacturer} />}
|
||||
</div>
|
||||
))}
|
||||
@ -37,7 +46,15 @@ const ManufacturersGrid = ({ manufacturers, variant = 'home' }: ManufacturersGri
|
||||
.toSorted((a, b) => a.display_name!.localeCompare(b.display_name!))
|
||||
.map((manufacturer) => (
|
||||
<div key={manufacturer.id} className="flex flex-col gap-2">
|
||||
<ManufacturerItem manufacturer={manufacturer} />
|
||||
{variant === 'home' ? (
|
||||
<ManufacturerItem manufacturer={manufacturer} />
|
||||
) : (
|
||||
<ManufacturerItem
|
||||
manufacturer={manufacturer}
|
||||
className={'rounded border border-primary px-2 py-1'}
|
||||
href={`/search/${variant}?${MAKE_FILTER_ID}=${manufacturer.id}`}
|
||||
/>
|
||||
)}
|
||||
{variant === 'home' && <ButtonGroup manufacturer={manufacturer} />}
|
||||
</div>
|
||||
))}
|
||||
|
@ -1,16 +1,19 @@
|
||||
import ImageDisplay from 'components/page/image-display';
|
||||
import { Metaobject } from 'lib/shopify/types';
|
||||
import Link from 'next/link';
|
||||
import { Suspense } from 'react';
|
||||
import { twMerge } from 'tailwind-merge';
|
||||
|
||||
const ManufacturerItem = ({
|
||||
manufacturer,
|
||||
className
|
||||
className,
|
||||
href
|
||||
}: {
|
||||
manufacturer: Metaobject;
|
||||
className?: string;
|
||||
href?: string;
|
||||
}) => {
|
||||
return (
|
||||
const children = (
|
||||
<div className={twMerge('flex w-full flex-row items-center justify-between', className)}>
|
||||
<span className="text-sm leading-5">{manufacturer.display_name}</span>
|
||||
<div className="hidden md:block">
|
||||
@ -25,6 +28,11 @@ const ManufacturerItem = ({
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
if (href) {
|
||||
return <Link href={href}>{children}</Link>;
|
||||
}
|
||||
return children;
|
||||
};
|
||||
|
||||
export default ManufacturerItem;
|
||||
|
Loading…
x
Reference in New Issue
Block a user