feat: implement browse by manufacturers section

Signed-off-by: Chloe <pinkcloudvnn@gmail.com>
This commit is contained in:
Chloe
2024-06-09 12:30:18 +07:00
parent 882d1db67c
commit 9e9573c7be
19 changed files with 220 additions and 54 deletions

View File

@@ -0,0 +1,37 @@
'use client';
import { ArrowRightIcon } from '@heroicons/react/16/solid';
import { MAKE_FILTER_ID } from 'lib/constants';
import { Metaobject } from 'lib/shopify/types';
import { createUrl } from 'lib/utils';
import { useRouter, useSearchParams } from 'next/navigation';
const ButtonGroup = ({ manufacturer }: { manufacturer: Metaobject }) => {
const searchParams = useSearchParams();
const _newSearchParams = new URLSearchParams(searchParams.toString());
const router = useRouter();
const handleClick = (type: 'engines' | 'transmissions') => {
_newSearchParams.set(MAKE_FILTER_ID, manufacturer.id);
router.push(createUrl(`/search/${type}`, _newSearchParams));
};
return (
<div className="flex flex-col items-start justify-between gap-2 md:flex-row md:items-center md:gap-0">
<button
className="flex items-center gap-1 rounded border border-primary px-1 py-0.5 text-xs text-primary"
onClick={() => handleClick('engines')}
>
Engines <ArrowRightIcon className="size-3" />
</button>
<button
className="flex items-center gap-1 rounded border border-transparent bg-primary/10 px-1 py-0.5 text-xs text-primary"
onClick={() => handleClick('transmissions')}
>
Transmissions <ArrowRightIcon className="size-3" />
</button>
</div>
);
};
export default ButtonGroup;

View File

@@ -0,0 +1,49 @@
import { GlobeAltIcon, StarIcon } from '@heroicons/react/24/outline';
import { Metaobject } from 'lib/shopify/types';
import ButtonGroup from './button-group';
import ManufacturerItem from './item';
type ManufacturersGridProps = {
manufacturers: Metaobject[];
variant?: 'engine' | 'transmission' | 'home';
};
const ManufacturersGrid = ({ manufacturers, variant = 'home' }: ManufacturersGridProps) => {
const popularManufacturers = manufacturers.filter(
(manufacturer) => manufacturer.is_popular === 'true'
);
return (
<div className="h-auto max-h-[700px] w-full overflow-auto rounded px-10 py-6 shadow">
<p className="flex items-center gap-2">
<StarIcon className="size-4" />
<span className="text-sm font-medium text-blue-800">Popular Manufacturers</span>
</p>
<div className="mt-6 grid grid-cols-2 gap-x-12 gap-y-7 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5">
{popularManufacturers.map((manufacturer) => (
<div key={manufacturer.id} className="flex flex-col gap-3">
<ManufacturerItem manufacturer={manufacturer} />
{variant === 'home' && <ButtonGroup manufacturer={manufacturer} />}
</div>
))}
</div>
<hr className="my-10 w-full" />
<p className="flex items-center gap-2">
<GlobeAltIcon className="size-4" />
<span className="text-sm font-medium text-blue-800">All Manufacturers</span>
</p>
<div className="mt-6 grid grid-cols-2 gap-x-12 gap-y-7 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5">
{manufacturers
.toSorted((a, b) => a.display_name!.localeCompare(b.display_name!))
.map((manufacturer) => (
<div key={manufacturer.id} className="flex flex-col gap-3">
<ManufacturerItem manufacturer={manufacturer} />
{variant === 'home' && <ButtonGroup manufacturer={manufacturer} />}
</div>
))}
</div>
</div>
);
};
export default ManufacturersGrid;

View File

@@ -0,0 +1,29 @@
import ImageDisplay from 'components/page/image-display';
import { Metaobject } from 'lib/shopify/types';
import { Suspense } from 'react';
import { twMerge } from 'tailwind-merge';
const ManufacturerItem = ({
manufacturer,
className
}: {
manufacturer: Metaobject;
className?: string;
}) => {
return (
<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">
<Suspense>
<ImageDisplay
fileId={manufacturer.logo as string}
title={manufacturer.display_name || 'Logo'}
className="aspect-2 h-auto w-auto"
/>
</Suspense>
</div>
</div>
);
};
export default ManufacturerItem;