You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
nx-guitar-school/apps/website/components/shop-aside/shop-aside.tsx

124 lines
4.6 KiB

import {buildShopParamsGET, findQueryParamsValue, PriceRange} from "../../libs/utils";
import DropdownSection from "../dropdown-component/dropdown-section";
import ShopCategories from "../shop-categories/shop-categories";
import ShopAmountRange from "../shop-amount-range/shop-amount-range";
import ShopFilters from "../shop-filters/shop-filters";
import ShopSearch from "../shop-search/shop-search";
import {useEffect, useState} from "react";
import {useRouter} from "next/router";
import {isEqual} from "radash";
export function ShopAside({sections = [], queries = [], filters = []}) {
const [filterMap, setFilterMap] = useState(null);
const [filtersSelected, setFiltersSelected] = useState(findQueryParamsValue(queries, 'filters') || []);
const [priceRange, setPriceRange] = useState(findQueryParamsValue(queries, 'facets') as PriceRange);
const [hasFilters, setHasFilters] = useState(false);
const router = useRouter();
const validFilters = () => {
const list = [];
if (filterMap) {
Array.from(filterMap).reduce((array: number[], map: [number, Map<number, boolean>]) => {
Array.from(map[1].entries()).forEach((value: [number, boolean]) => array.push(value[0]));
return array;
}, list);
}
router.push(`${router.pathname}${buildShopParamsGET(
findQueryParamsValue(queries, 'sort'),
findQueryParamsValue(queries, 'page'),
priceRange,
findQueryParamsValue(queries, 'cat'),
list,
findQueryParamsValue(queries, 'search'),
)}`);
}
useEffect(() => {
if (!findQueryParamsValue(queries, 'filters')) {
setFilterMap(new Map());
setFiltersSelected([]);
} else {
setFiltersSelected(findQueryParamsValue(queries, 'filters') || []);
}
if (!findQueryParamsValue(queries, 'facets')) {
setPriceRange(null);
}
}, [queries]);
useEffect(() => {
setHasFilters((!isEqual(filterMap, null) && filterMap.size !== 0) || !isEqual(priceRange, null));
}, [filterMap]);
const updatePriceRange = (range: PriceRange) => {
setPriceRange(range);
}
const updateFilterMap = (map: Map<number, Map<number, boolean>>) => {
setFilterMap(map);
}
const resetFilters = () => {
router.push(`${router.pathname}${buildShopParamsGET(
findQueryParamsValue(queries, 'sort'),
findQueryParamsValue(queries, 'page'),
null,
findQueryParamsValue(queries, 'cat'),
null,
findQueryParamsValue(queries, 'search'),
)}`);
}
return (
<>
<ShopSearch queries={queries} />
<div className="rounded-lg mx-2 md:mx-0 mt-5 md:mt-0 mb-5 shadow-sm
bg-white
dark:bg-gray-800">
<DropdownSection title="Catégogies">
<ShopCategories queries={queries}
sections={sections} />
</DropdownSection>
</div>
<div className="rounded-lg mx-2 md:mx-0 mt-5 md:mt-0 mb-5 shadow-sm
bg-white
dark:bg-gray-800">
{hasFilters && (
<div className="pt-5 px-5 flex justify-end">
<button onClick={() => resetFilters()}
className="px-3 py-2 text-xs font-medium text-center rounded-lg border
text-gray-900 bg-white border-gray-200
focus:outline-none hover:bg-gray-100 hover:text-blue-700 focus:z-10 focus:ring-4 focus:ring-gray-200
dark:focus:ring-gray-700 dark:bg-gray-800 dark:text-gray-400 dark:border-gray-600 dark:hover:text-white dark:hover:bg-gray-700">Réinitialiser les filtres
</button>
</div>
)}
<DropdownSection title="Prix"
collapse={true}>
<ShopAmountRange range={priceRange}
onChange={(value: PriceRange) => updatePriceRange(value)} />
</DropdownSection>
<hr className="border-gray-100 dark:border-gray-700 w-full" />
<DropdownSection title="Filtres">
<ShopFilters filters={filters}
filtersSelected={filtersSelected}
onChange={(map: Map<number, Map<number, boolean>>) => updateFilterMap(map)} />
</DropdownSection>
<hr className="border-gray-100 dark:border-gray-700 w-full mb-5" />
<div className="px-5">
<button onClick={() => validFilters()}
className="font-medium rounded-lg text-sm px-5 py-2.5 mr-2 mb-5 w-full
text-white bg-blue-700
hover:bg-blue-800 focus:ring-4 focus:ring-blue-300
dark:bg-blue-600 dark:hover:bg-blue-700 focus:outline-none dark:focus:ring-blue-800">
Appliquer les filtres
</button>
</div>
</div>
</>
);
}
export default ShopAside;