mirror of
https://github.com/vercel/commerce.git
synced 2025-06-18 05:01:22 +00:00
Refactor Filter & Sort options to a generic component
This commit is contained in:
parent
c5ec6c0085
commit
fb02d52048
188
pages/search.tsx
188
pages/search.tsx
@ -1,4 +1,4 @@
|
|||||||
import {useState} from 'react'
|
import { FC, useState } from 'react'
|
||||||
import cn from 'classnames'
|
import cn from 'classnames'
|
||||||
import type { GetStaticPropsContext, InferGetStaticPropsType } from 'next'
|
import type { GetStaticPropsContext, InferGetStaticPropsType } from 'next'
|
||||||
import Link from 'next/link'
|
import Link from 'next/link'
|
||||||
@ -21,6 +21,18 @@ import {
|
|||||||
useSearchMeta,
|
useSearchMeta,
|
||||||
} from '@lib/search'
|
} from '@lib/search'
|
||||||
|
|
||||||
|
interface OptionLinkProps {
|
||||||
|
active: boolean
|
||||||
|
name: string
|
||||||
|
pathname: string
|
||||||
|
query: string
|
||||||
|
}
|
||||||
|
|
||||||
|
interface FilterOptionsProps {
|
||||||
|
pathname: string
|
||||||
|
title: string
|
||||||
|
}
|
||||||
|
|
||||||
export async function getStaticProps({
|
export async function getStaticProps({
|
||||||
preview,
|
preview,
|
||||||
locale,
|
locale,
|
||||||
@ -70,6 +82,43 @@ export default function Search({
|
|||||||
sort: typeof sort === 'string' ? sort : '',
|
sort: typeof sort === 'string' ? sort : '',
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const OptionLink: FC<OptionLinkProps> = ({
|
||||||
|
active,
|
||||||
|
name,
|
||||||
|
pathname,
|
||||||
|
query
|
||||||
|
}) => (
|
||||||
|
<li
|
||||||
|
className={cn('py-1 text-accents-8', {
|
||||||
|
underline: active,
|
||||||
|
})}
|
||||||
|
>
|
||||||
|
<Link
|
||||||
|
href={{
|
||||||
|
pathname,
|
||||||
|
query,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<a>{name}</a>
|
||||||
|
</Link>
|
||||||
|
</li>
|
||||||
|
)
|
||||||
|
|
||||||
|
const FilterOptions: FC<FilterOptionsProps> = ({
|
||||||
|
pathname,
|
||||||
|
title,
|
||||||
|
children,
|
||||||
|
}) => (
|
||||||
|
<ul>
|
||||||
|
<li className="py-1 text-base font-bold tracking-wide">
|
||||||
|
<Link href={{ pathname, query }}>
|
||||||
|
<a>{title}</a>
|
||||||
|
</Link>
|
||||||
|
</li>
|
||||||
|
{children}
|
||||||
|
</ul>
|
||||||
|
)
|
||||||
|
|
||||||
const Sort = () => (
|
const Sort = () => (
|
||||||
<ul>
|
<ul>
|
||||||
<li className="py-1 text-base font-bold tracking-wide">Sort</li>
|
<li className="py-1 text-base font-bold tracking-wide">Sort</li>
|
||||||
@ -83,70 +132,13 @@ export default function Search({
|
|||||||
</Link>
|
</Link>
|
||||||
</li>
|
</li>
|
||||||
{SORT.map(([key, text]) => (
|
{SORT.map(([key, text]) => (
|
||||||
<li
|
<OptionLink
|
||||||
key={key}
|
key={key}
|
||||||
className={cn('py-1 text-accents-8', {
|
pathname={pathname}
|
||||||
underline: sort === key,
|
active={sort === key}
|
||||||
})}
|
name={text}
|
||||||
>
|
query={filterQuery({ q, sort: key })}
|
||||||
<Link href={{ pathname, query: filterQuery({ q, sort: key }) }}>
|
/>
|
||||||
<a>{text}</a>
|
|
||||||
</Link>
|
|
||||||
</li>
|
|
||||||
))}
|
|
||||||
</ul>
|
|
||||||
)
|
|
||||||
|
|
||||||
const Categories = () => (
|
|
||||||
<ul className="mb-6 md:mb-10">
|
|
||||||
<li className="py-1 text-base font-bold tracking-wide">
|
|
||||||
<Link href={{ pathname: getCategoryPath('', brand), query }}>
|
|
||||||
<a>All Categories</a>
|
|
||||||
</Link>
|
|
||||||
</li>
|
|
||||||
{categories.map((cat) => (
|
|
||||||
<li
|
|
||||||
key={cat.path}
|
|
||||||
className={cn('py-1 text-accents-8', {
|
|
||||||
underline: activeCategory?.entityId === cat.entityId,
|
|
||||||
})}
|
|
||||||
>
|
|
||||||
<Link
|
|
||||||
href={{
|
|
||||||
pathname: getCategoryPath(cat.path, brand),
|
|
||||||
query,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<a>{cat.name}</a>
|
|
||||||
</Link>
|
|
||||||
</li>
|
|
||||||
))}
|
|
||||||
</ul>
|
|
||||||
)
|
|
||||||
|
|
||||||
const Designers = () => (
|
|
||||||
<ul>
|
|
||||||
<li className="py-1 text-base font-bold tracking-wide">
|
|
||||||
<Link href={{ pathname: getDesignerPath('', category), query }}>
|
|
||||||
<a>All Designers</a>
|
|
||||||
</Link>
|
|
||||||
</li>
|
|
||||||
{brands.flatMap(({ node }) => (
|
|
||||||
<li
|
|
||||||
key={node.path}
|
|
||||||
className={cn('py-1 text-accents-8', {
|
|
||||||
underline: activeBrand?.entityId === node.entityId,
|
|
||||||
})}
|
|
||||||
>
|
|
||||||
<Link
|
|
||||||
href={{
|
|
||||||
pathname: getDesignerPath(node.path, category),
|
|
||||||
query,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<a>{node.name}</a>
|
|
||||||
</Link>
|
|
||||||
</li>
|
|
||||||
))}
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
)
|
)
|
||||||
@ -155,8 +147,38 @@ export default function Search({
|
|||||||
<Container>
|
<Container>
|
||||||
<div className="grid grid-cols-12 gap-4 mt-3 mb-20">
|
<div className="grid grid-cols-12 gap-4 mt-3 mb-20">
|
||||||
<div className="col-span-2 hidden md:block">
|
<div className="col-span-2 hidden md:block">
|
||||||
<Categories />
|
<FilterOptions
|
||||||
<Designers />
|
title="All Categories"
|
||||||
|
pathname={getCategoryPath('', brand)}
|
||||||
|
>
|
||||||
|
<>
|
||||||
|
{categories.map((cat) => (
|
||||||
|
<OptionLink
|
||||||
|
key={cat.path}
|
||||||
|
pathname={getCategoryPath(cat.path, brand)}
|
||||||
|
active={activeCategory?.entityId === cat.entityId}
|
||||||
|
name={cat.name}
|
||||||
|
query={query}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</>
|
||||||
|
</FilterOptions>
|
||||||
|
<FilterOptions
|
||||||
|
title="All Designers"
|
||||||
|
pathname={getDesignerPath('', category)}
|
||||||
|
>
|
||||||
|
<>
|
||||||
|
{brands.flatMap(({ node }) => (
|
||||||
|
<OptionLink
|
||||||
|
key={node.path}
|
||||||
|
pathname={getDesignerPath(node.path, category)}
|
||||||
|
active={activeBrand?.entityId === node.entityId}
|
||||||
|
name={node.name}
|
||||||
|
query={query}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</>
|
||||||
|
</FilterOptions>
|
||||||
</div>
|
</div>
|
||||||
<div className="col-span-12 md:col-span-8">
|
<div className="col-span-12 md:col-span-8">
|
||||||
{(q || activeCategory || activeBrand) && (
|
{(q || activeCategory || activeBrand) && (
|
||||||
@ -214,8 +236,38 @@ export default function Search({
|
|||||||
{showMobileMenu && (
|
{showMobileMenu && (
|
||||||
<div className="flex justify-between mt-4 md:hidden">
|
<div className="flex justify-between mt-4 md:hidden">
|
||||||
<div className="flex flex-col">
|
<div className="flex flex-col">
|
||||||
<Categories />
|
<FilterOptions
|
||||||
<Designers />
|
title="All Categories"
|
||||||
|
pathname={getCategoryPath('', brand)}
|
||||||
|
>
|
||||||
|
<>
|
||||||
|
{categories.map((cat) => (
|
||||||
|
<OptionLink
|
||||||
|
key={cat.path}
|
||||||
|
pathname={getCategoryPath(cat.path, brand)}
|
||||||
|
active={activeCategory?.entityId === cat.entityId}
|
||||||
|
name={cat.name}
|
||||||
|
query={query}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</>
|
||||||
|
</FilterOptions>
|
||||||
|
<FilterOptions
|
||||||
|
title="All Designers"
|
||||||
|
pathname={getDesignerPath('', category)}
|
||||||
|
>
|
||||||
|
<>
|
||||||
|
{brands.flatMap(({ node }) => (
|
||||||
|
<OptionLink
|
||||||
|
key={node.path}
|
||||||
|
pathname={getDesignerPath(node.path, category)}
|
||||||
|
active={activeBrand?.entityId === node.entityId}
|
||||||
|
name={node.name}
|
||||||
|
query={query}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</>
|
||||||
|
</FilterOptions>
|
||||||
</div>
|
</div>
|
||||||
<Sort />
|
<Sort />
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user