import { Link } from '@chakra-ui/next-js' import { Alert, AlertDescription, AlertIcon, AlertTitle, Box, Button, ButtonGroup, Card, CardBody, Flex, HStack, Heading, IconButton, Image, Input, InputGroup, InputLeftElement, InputRightElement, LinkBox, LinkOverlay, Menu, MenuButton, MenuDivider, MenuItem, MenuList, SimpleGrid, Skeleton, Spinner, Table, Tbody, Td, Text, Tr, } from '@chakra-ui/react' import { useDebouncedCallback, useLocalStorageValue } from '@react-hookz/web' import { useRouter } from 'next/router' import { TbCheck, TbFilter, TbFilterEdit, TbLayoutGrid, TbLayoutList, TbMoodSad, TbSearch, TbX } from 'react-icons/tb' import useSWR from 'swr' import Pagination from '~/components/pagination' const PER_PAGE = 12 export const getStaticProps = async () => { const url = new URL(`${process.env.NEXT_PUBLIC_DIRECTUS_API_URL}/items/categories`) url.searchParams.append('fields[]', 'slug') url.searchParams.append('fields[]', 'name') url.searchParams.append('fields[]', 'subcategories.slug') url.searchParams.append('fields[]', 'subcategories.name') url.searchParams.append('sort', 'name') url.searchParams.append('limit', -1) url.searchParams.append( 'filter', JSON.stringify({ parent_id: { _null: true, }, }) ) const res = await fetch(url.toString()) const { data: categories } = await res.json() return { props: { categories } } } export default function VendorsPage({ categories }) { const router = useRouter() const { query: { page = 1, category = '', q: search = '' }, } = router const { value: perPage, set: setPerPage } = useLocalStorageValue('perPage', { defaultValue: PER_PAGE, initializeWithValue: false, }) const { value: layout, set: setLayout } = useLocalStorageValue('layout', { defaultValue: 'GRID', initializeWithValue: false, }) const setSearch = useDebouncedCallback( (q) => { router.replace({ query: { ...router.query, q } }) }, [router], 500 ) const { data, error, isLoading, isValidating } = useSWR(['vendors', page, perPage, search, category], async () => { if (!perPage) return await new Promise((r) => setTimeout(r, 2000)) const url = new URL(`${process.env.NEXT_PUBLIC_DIRECTUS_API_URL}/items/vendors`) url.searchParams.append('fields[]', '*') url.searchParams.append('limit', perPage) url.searchParams.append('page', page) url.searchParams.append('sort', 'name') url.searchParams.append('meta[]', 'filter_count') if (search !== '' || category !== '') { url.searchParams.append( 'filter', JSON.stringify({ _and: [ category !== '' ? { categories: { categories_id: { slug: { _eq: category } } } } : {}, search !== '' ? { _or: ['name', 'description', 'long_description', 'city'].map((s) => ({ [s]: { _contains: search }, })), } : {}, ], }) ) } const res = await fetch(url.toString()) if (!res.ok) { throw new Error('Oops') } return res.json() }) const { meta, data: vendors } = data || { meta: {}, data: [] } const lastPage = Math.max(1, Math.ceil(meta.filter_count / perPage)) if (!isNaN(lastPage) && page > lastPage) { router.replace({ query: { ...router.query, page: lastPage } }) } return ( <> Vendors {isValidating && } setSearch(ev.target.value.toLowerCase())} /> { ev.currentTarget.parentNode.childNodes[1].value = '' setSearch('') }} > {search !== '' && } : } /> {categories.map((cat) => ( } isDisabled={category === cat.slug}> {cat.name} ))} Clear } onClick={() => setLayout('GRID')} isDisabled={layout === 'GRID'} /> } onClick={() => setLayout('LIST')} isDisabled={layout === 'LIST'} /> {error && ( There was an error processing your request )} {layout === 'GRID' && ( {isLoading && new Array(perPage).fill(true).map((v, k) => ( ))} {!isLoading && vendors.map((v) => ( {v.name} {v.name} {v?.description?.substring(0, v?.description?.substring(0, 80).lastIndexOf(' '))} … ))} )} {layout === 'LIST' && ( <> {isLoading && ( {new Array(perPage).fill(true).map((v, k) => ( ))}
)} {!isLoading && ( {vendors.map((v) => ( ))}
{v.name} {v.name} {v?.description?.substring(0, v?.description?.substring(0, 80).lastIndexOf(' '))} …
)} )} {meta.filter_count === 0 && ( No results found. Try refining your search term and filters … )} {meta.filter_count > perPage && ( <> Results per page: {[12, 24, 48].map((n) => ( ))} )} ) }