import { useState, useEffect } from 'react' import { ServiceContent } from '../types/ServiceContent' import { Tag, FilterMatchRequirement } from '../types/content/' const useServiceFilter = (services: ServiceContent[], filter: any) => { const defaultFilters: any = { type: [], status: [], } const [activeTagFilters, setActiveTagFilters] = useState(defaultFilters) const [filteredServices, setFilteredServices] = useState(services) useEffect(() => { // filter param change, update filter and filter servicves if (filter) { setActiveTagFilters(paramsToFilter(filter)) } else { setActiveTagFilters(defaultFilters) } filterServices() }, [filter]) const filterToParams = () => { const ressources = [] Object.keys(activeTagFilters).forEach(filter => { if (activeTagFilters[filter].length > 0) { activeTagFilters[filter].forEach(activeFilter => ressources.push(activeFilter)) } }) return [...new Set(ressources)].join('&') } const paramsToFilter = (choosenFiltersAsString: String | String[]) => { if (!choosenFiltersAsString) { return defaultFilters } else if (Array.isArray(choosenFiltersAsString)) { choosenFiltersAsString = choosenFiltersAsString[0] } const filters = choosenFiltersAsString.split('&') filters.forEach(filterAsString => { const filter = filterAsString.split(':')[0] if (activeTagFilters[filter].indexOf(filterAsString) < 0) { activeTagFilters[filter].push(filterAsString) } }) return activeTagFilters } const filterServices = () => { const servicesFilteredByTags = services.filter((service: ServiceContent) => { const activeTypeFilterTags = activeTagFilters.type const activeStatusFilterTags = activeTagFilters.status return filterServiceByTags(service, activeTypeFilterTags, FilterMatchRequirement.ALL) && filterServiceByTags(service, activeStatusFilterTags, FilterMatchRequirement.SOME) }) servicesFilteredByTags.sort((sortableServiceContantA: ServiceContent, sortableServiceContantB: ServiceContent) => { return sortableServiceContantA.name.localeCompare(sortableServiceContantB.name) }) setFilteredServices(servicesFilteredByTags) } return { filteredServices, activeTagFilters, filterToParams } } function filterServiceByTags(service: ServiceContent, filterTags: any, matchingRequirement: FilterMatchRequirement) { if (!filterTags.length) { return true } const filteredArray = service.tags.filter((tag: Tag) => filterTags.includes(`${tag.name}:${tag.value}`)) if (matchingRequirement == FilterMatchRequirement.ALL) { return filteredArray?.length == filterTags.length } else if (matchingRequirement == FilterMatchRequirement.SOME) { return filteredArray?.length > 0 } } export default useServiceFilter