import cn from 'clsx'
import type { SearchPropsType } from '@lib/search-props'
import Link from 'next/link'
import { useState } from 'react'
import { useRouter } from 'next/router'
import type { Brand } from '@commerce/types/site'
import type { Product } from '@commerce/types/product'
import { Layout } from '@components/common'
import { ProductCard } from '@components/product'
import { Container, Skeleton } from '@components/ui'
import useSearch from '@framework/product/use-search'
import getSlug from '@lib/get-slug'
import rangeMap from '@lib/range-map'
const SORT = {
'trending-desc': 'Trending',
'latest-desc': 'Latest arrivals',
'price-asc': 'Price: Low to high',
'price-desc': 'Price: High to low',
}
import {
filterQuery,
getCategoryPath,
getDesignerPath,
useSearchMeta,
} from '@lib/search'
export default function Search({ categories, brands }: SearchPropsType) {
const [activeFilter, setActiveFilter] = useState('')
const [toggleFilter, setToggleFilter] = useState(false)
const router = useRouter()
const { asPath, locale } = router
const { q, sort } = router.query
// `q` can be included but because categories and designers can't be searched
// in the same way of products, it's better to ignore the search input if one
// of those is selected
const query = filterQuery({ sort })
const { pathname, category, brand } = useSearchMeta(asPath)
const activeCategory = categories.find((cat: any) => cat.slug === category)
const activeBrand = brands.find((b: Brand) => b.slug === brand)
const { data, error } = useSearch({
search: typeof q === 'string' ? q : '',
categoryId: activeCategory?.id,
brandId: activeBrand?.id,
sort: typeof sort === 'string' ? sort : '',
locale,
})
if (error) {
return
Failed to load
}
const handleClick = (event: any, filter: string) => {
if (filter !== activeFilter) {
setToggleFilter(true)
} else {
setToggleFilter(!toggleFilter)
}
setActiveFilter(filter)
}
return (
{/* Categories */}
handleClick(e, 'categories')}
className="flex justify-between w-full rounded-sm border border-accent-3 px-4 py-3 bg-accent-0 text-sm leading-5 font-medium text-accent-4 hover:text-accent-5 focus:outline-none focus:border-blue-300 focus:shadow-outline-normal active:bg-accent-1 active:text-accent-8 transition ease-in-out duration-150"
id="options-menu"
aria-haspopup="true"
aria-expanded="true"
>
{activeCategory?.name
? `Category: ${activeCategory?.name}`
: 'All Categories'}
{/* Designs */}
handleClick(e, 'brands')}
className="flex justify-between w-full rounded-sm border border-accent-3 px-4 py-3 bg-accent-0 text-sm leading-5 font-medium text-accent-8 hover:text-accent-5 focus:outline-none focus:border-blue-300 focus:shadow-outline-normal active:bg-accent-1 active:text-accent-8 transition ease-in-out duration-150"
id="options-menu"
aria-haspopup="true"
aria-expanded="true"
>
{activeBrand?.name
? `Design: ${activeBrand?.name}`
: 'All Designs'}
{/* Products */}
{(q || activeCategory || activeBrand) && (
{data ? (
<>
Showing {data.products.length} results{' '}
{q && (
<>
for "{q} "
>
)}
{q ? (
<>
There are no products that match "{q} "
>
) : (
<>
There are no products that match the selected category.
>
)}
>
) : q ? (
<>
Searching for: "{q} "
>
) : (
<>Searching...>
)}
)}
{data ? (
{data.products.map((product: Product) => (
))}
) : (
{rangeMap(12, (i) => (
))}
)}{' '}
{/* Sort */}
handleClick(e, 'sort')}
className="flex justify-between w-full rounded-sm border border-accent-3 px-4 py-3 bg-accent-0 text-sm leading-5 font-medium text-accent-4 hover:text-accent-5 focus:outline-none focus:border-blue-300 focus:shadow-outline-normal active:bg-accent-1 active:text-accent-8 transition ease-in-out duration-150"
id="options-menu"
aria-haspopup="true"
aria-expanded="true"
>
{sort ? SORT[sort as keyof typeof SORT] : 'Relevance'}
)
}
Search.Layout = Layout