Last active
September 2, 2021 20:39
-
-
Save ezemery/4030df238ecbfcf5da9c9f9077dd9710 to your computer and use it in GitHub Desktop.
React filter logic from a project I worked on.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { Fragment, useEffect, useState, useMemo } from 'react'; | |
const filterBy = { | |
disciplines: (item, selectedDisciplines) => { | |
const selectDisciplinesArr = Object.keys(selectedDisciplines).filter(key => | |
Boolean(selectedDisciplines[key]) | |
) | |
return selectDisciplinesArr.length | |
? selectDisciplinesArr.indexOf(item.discipline) > -1 | |
: true | |
}, | |
programs: (item, program) => { | |
if ( | |
(program['Matrix-insensitive'] && !item.matrixInsensitive) || | |
(program['Virtual sample'] && !item.virtualProgram) || | |
(program['Monthly'] && item.numTestEvents !== 12) || | |
(program['SARS-CoV-2'] && item.programName.indexOf('SARS-CoV-2') < 0) | |
) { | |
return false | |
} | |
return true | |
}, | |
productLines: (item, productLine) => { | |
if (!productLine || productLine === 'All products') { | |
return true | |
} else if (productLine === 'New products') { | |
return item.newProgram | |
} else if (productLine === 'Products with video descriptions') { | |
return item.videos.length > 0 | |
} else if (productLine === 'EQA programs') { | |
return item.productType === 'EQA' | |
} else if (productLine === 'Standardization programs') { | |
return item.productType === 'STANDARDIZATION' | |
} else if (productLine === 'Verification sample and kits') { | |
return item.productType === 'VERIFICATION' | |
} else if (productLine === 'Quality Controls') { | |
return item.productType === 'QUALITY_CONTROLS' | |
} | |
}, | |
keyword: (item, word) => { | |
if (!word) { | |
return true | |
} | |
const inArray = (arr, str) => | |
Boolean(arr.filter(item => item.toLowerCase().indexOf(str) > -1).length) | |
const string = word.toLowerCase() | |
return ( | |
item.discipline.toLowerCase().indexOf(string) > -1 || | |
item.programFamilyCode.toLowerCase().indexOf(string) > -1 || | |
item.programFamilyName.toLowerCase().indexOf(string) > -1 || | |
item.programCode.toLowerCase().indexOf(string) > -1 || | |
item.programName.toLowerCase().indexOf(string) > -1 || | |
item.productType.toLowerCase().indexOf(string) > -1 || | |
inArray(item.analytes, string) | |
) | |
} | |
} | |
const filteredProgramsData = useMemo(() => { | |
const { productLine, program, selectedDisciplines } = state.appliedFilters | |
const programsData = state.programsData | |
const keyword = state.keyword | |
const featuredPrograms = programsData.filter(isFeatured) | |
const data = [...(keyword ? [] : featuredPrograms), ...programsData] | |
return data.filter(item => { | |
return ( | |
filterBy.disciplines(item, selectedDisciplines) && | |
filterBy.programs(item, program) && | |
filterBy.productLines(item, productLine) && | |
filterBy.keyword(item, keyword) | |
) | |
}) | |
}, [state.appliedFilters, state.keyword, state.programsData]) | |
const displayCurrentFilters = () => { | |
const result = [] | |
const { productLine, program, selectedDisciplines } = appliedFilters | |
if (productLine) { | |
const onClear = handleSelectProductLine(null) | |
result.push({ value: productLine, onClear }) | |
} | |
if (keyword) { | |
const onClear = () => { | |
setState(s => ({ ...s, keyword: '' })) | |
} | |
result.push({ value: keyword, onClear }) | |
} | |
Object.keys(program).reduce((aggr, key) => { | |
if (program[key]) { | |
const onClear = () => handleToggleProgramFilters(key) | |
aggr.push({ value: key, onClear }) | |
} | |
return aggr | |
}, result) | |
Object.keys(selectedDisciplines).reduce((res, key) => { | |
if (selectedDisciplines[key]) { | |
const onClear = () => { | |
appliedFilters['selectedDisciplines'][key] = false | |
setState(s => ({ ...s, appliedFilters })) | |
} | |
result.push({ value: key, onClear }) | |
} | |
return res | |
}, result) | |
if (!result.length) { | |
return null | |
} | |
return ( | |
<div className='catalog-filter-results'> | |
Currently displaying result for{' '} | |
{result.map((item, index) => ( | |
<Fragment key={index}> | |
<span className='link-small' onClick={item.onClear}> | |
{item.value} <i className='fas fa-times'></i> | |
</span>{' '} | |
</Fragment> | |
))} | |
{result.length > 1 ? ( | |
<span className='link-default' onClick={handleClearAllFilters}> | |
Clear filters | |
</span> | |
) : null} | |
</div> | |
) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment