Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
antono91 committed Aug 9, 2023
1 parent 3cc10e9 commit 3f2f1bb
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 16 deletions.
37 changes: 33 additions & 4 deletions src/Components/ProductFilters.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Disclosure, Menu, Transition } from '@headlessui/react'
import { ChevronDownIcon, FilterIcon } from '@heroicons/react/solid'
import React, { Fragment } from 'react'
import React, { Fragment, useEffect, useState } from 'react'

function classNames(...classes) {
return classes.filter(Boolean).join(' ')
Expand All @@ -11,7 +11,32 @@ export default function ProductFilters({
setFilterOptions,
sortOptions,
setSortOptions,
handleClear,
}) {
function handleFilterChange(event) {
const filter = event.target.value

if (event.target.name.startsWith('color')) {
// Color filter changed
const newColorArray = filterOptions.color.map((c) =>
c.value === filter ? { ...c, checked: !c.checked } : c
)
setFilterOptions({ ...filterOptions, color: newColorArray })
} else {
// Price filter changed
const newPriceArray = filterOptions.price.map((p) =>
p.minValue === Number(filter) ? { ...p, checked: !p.checked } : p
)
setFilterOptions({ ...filterOptions, price: newPriceArray })
}
}
function countFilter() {
return (
filterOptions.price.reduce((s, p) => Number(p.checked) + s, 0) +
filterOptions.color.reduce((s, c) => Number(c.checked) + s, 0)
)
}

return (
<Disclosure
as="section"
Expand All @@ -32,13 +57,14 @@ export default function ProductFilters({
className="flex-none w-5 h-5 mr-2 text-gray-400 group-hover:text-gray-500"
aria-hidden="true"
/>
0 Filters
{countFilter()} Filters
</Disclosure.Button>
</div>
<div className="pl-6">
<button
type="button"
className="text-gray-500"
onClick={handleClear}
>
Clear all
</button>
Expand All @@ -62,7 +88,8 @@ export default function ProductFilters({
defaultValue={option.minValue}
type="checkbox"
className="flex-shrink-0 h-4 w-4 border-gray-300 rounded text-black focus:ring-black"
defaultChecked={option.checked}
checked={option.checked}
onChange={handleFilterChange}
/>
<label
htmlFor={`price-${optionIdx}`}
Expand All @@ -88,8 +115,10 @@ export default function ProductFilters({
defaultValue={option.value}
type="checkbox"
className="flex-shrink-0 h-4 w-4 border-gray-300 rounded text-black focus:ring-black"
defaultChecked={option.checked}
checked={option.checked}
onChange={handleFilterChange}
/>

<label
htmlFor={`color-${optionIdx}`}
className="ml-3 min-w-0 flex-1 text-gray-600"
Expand Down
65 changes: 53 additions & 12 deletions src/Components/ProductTable.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,29 +43,70 @@ export default function ProductTable({ cart, updateCart }) {
console.info('Fetching Products...')
let res = await fetch('http://localhost:3001/products')
let body = await res.json()
let sortedProducts = []
if (sortOptions[0].current) {
sortedProducts = body.sort((a, b) => a.price - b.price)
} else if (sortOptions[1].current) {
sortedProducts = body.sort((a, b) => a.releaseDate - b.releaseDate)
} else {
sortedProducts = body
}
setProducts(sortedProducts)

setProducts(body)
}
fetchProducts()
}, [sortOptions])
}, [])

// Filter products
const filterProducts = () => {
let filteredProducts = products
const colorFilter = filterOptions.color
.filter((c) => c.checked)
.map((c) => c.value)
const priceFilter = filterOptions.price
.filter((p) => p.checked)
.map((p) => {
return { minF: p.minValue, maxF: p.maxValue }
})

if (colorFilter.length > 0)
filteredProducts = filteredProducts.filter((p) =>
colorFilter.includes(p.color)
)
if (priceFilter.length > 0) {
filteredProducts = filteredProducts.filter((p) =>
priceFilter.some(({ minF, maxF }) => p.price >= minF && p.price <= maxF)
)
}
return filteredProducts
}

// Sort products
const sortProducts = (p) => {
if (sortOptions[0].current) {
return p.sort((a, b) => a.price - b.price)
} else if (sortOptions[1].current) {
return p.sort((a, b) => a.releaseDate - b.releaseDate)
} else {
return p
}
}

function handleClear(event) {
setFilterOptions(getDefaultFilterOptions())
}

const filteredProducts = filterProducts()
const productsToShow = sortProducts(filteredProducts)

return (
<div className="bg-white">
<div className="max-w-2xl mx-auto px-4 sm:px-6 lg:max-w-7xl lg:px-8">
<h2 className="sr-only">Products</h2>
<ProductFilters
{...{ filterOptions, setFilterOptions, sortOptions, setSortOptions }}
{...{
filterOptions,
setFilterOptions,
sortOptions,
setSortOptions,
handleClear,
}}
/>

<div className="grid grid-cols-1 gap-y-10 sm:grid-cols-2 gap-x-6 lg:grid-cols-3 xl:grid-cols-4 xl:gap-x-8">
{products.map((product) => (
{productsToShow.map((product) => (
<a
key={product.id}
className="group"
Expand Down

0 comments on commit 3f2f1bb

Please sign in to comment.