feat(category): check if user defined already exists, remove duplicates

This commit is contained in:
enes 2024-12-11 14:36:07 +01:00
parent f7f8778707
commit b9d6820405
2 changed files with 55 additions and 34 deletions

View File

@ -1,10 +1,11 @@
import React, { useEffect, useState } from 'react'
import React, { useEffect, useMemo, useState } from 'react'
import { createPortal } from 'react-dom'
import { Category } from 'types'
import {
addToUserCategories,
capitalizeEachWord,
deleteFromUserCategories
deleteFromUserCategories,
flattenCategories
} from 'utils'
import { useLocalStorage } from 'hooks'
import styles from './CategoryFilterPopup.module.scss'
@ -35,6 +36,21 @@ export const CategoryFilterPopup = ({
setHierarchies(filterHierarchies)
}
const [inputValue, setInputValue] = useState<string>('')
const userHierarchiesMatching = useMemo(
() =>
flattenCategories(userHierarchies, []).some((h) =>
h.hierarchy.includes(inputValue.toLowerCase())
),
[inputValue, userHierarchies]
)
const hierarchiesMatching = useMemo(
() =>
flattenCategories(categoriesData, []).some((h) =>
h.hierarchy.includes(inputValue.toLowerCase())
),
[inputValue]
)
const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setInputValue(e.target.value)
}
@ -75,13 +91,14 @@ export const CategoryFilterPopup = ({
const path = values.join(':')
// Add new hierarchy to current selection and active selection
// Convert through set to remove duplicates
setFilterHierarchies((prev) => {
prev.push(path)
return [...prev]
return Array.from(new Set([...prev]))
})
setHierarchies((prev) => {
prev.push(path)
return [...prev]
return Array.from(new Set([...prev]))
})
setInputValue('')
}
@ -149,6 +166,7 @@ export const CategoryFilterPopup = ({
overflow: 'auto'
}}
>
{!userHierarchiesMatching && <div>No results.</div>}
{userHierarchies
.filter((c) => typeof c !== 'string')
.map((c, i) => (
@ -187,6 +205,15 @@ export const CategoryFilterPopup = ({
</>
)}
<div className='inputLabelWrapperMain'>
<div className='inputLabelWrapperMain'>
<label
className='form-label labelMain'
style={{ fontWeight: 'bold' }}
>
Categories
</label>
<p className='labelDescriptionMain'>Maybe</p>
</div>
<div
className='inputMain'
style={{
@ -199,27 +226,31 @@ export const CategoryFilterPopup = ({
<div className={`${styles.noResult}`}>
<div>No results.</div>
<br />
<div
className='dropdown-item dropdownMainMenuItem'
onClick={handleAddNew}
>
Add and search for "{inputValue}" category
<button
type='button'
className='btn btnMain btnMainInsideField btnMainAdd'
title='Add'
{userHierarchiesMatching ? (
<div>Already defined in your categories</div>
) : (
<div
className='dropdown-item dropdownMainMenuItem'
onClick={handleAddNew}
>
<svg
xmlns='http://www.w3.org/2000/svg'
viewBox='-32 0 512 512'
width='1em'
height='1em'
fill='currentColor'
Add and search for "{inputValue}" category
<button
type='button'
className='btn btnMain btnMainInsideField btnMainAdd'
title='Add'
>
<path d='M432 256c0 17.69-14.33 32.01-32 32.01H256v144c0 17.69-14.33 31.99-32 31.99s-32-14.3-32-31.99v-144H48c-17.67 0-32-14.32-32-32.01s14.33-31.99 32-31.99H192v-144c0-17.69 14.33-32.01 32-32.01s32 14.32 32 32.01v144h144C417.7 224 432 238.3 432 256z'></path>
</svg>
</button>
</div>
<svg
xmlns='http://www.w3.org/2000/svg'
viewBox='-32 0 512 512'
width='1em'
height='1em'
fill='currentColor'
>
<path d='M432 256c0 17.69-14.33 32.01-32 32.01H256v144c0 17.69-14.33 31.99-32 31.99s-32-14.3-32-31.99v-144H48c-17.67 0-32-14.32-32-32.01s14.33-31.99 32-31.99H192v-144c0-17.69 14.33-32.01 32-32.01s32 14.32 32 32.01v144h144C417.7 224 432 238.3 432 256z'></path>
</svg>
</button>
</div>
)}
</div>
{(categoriesData as Category[]).map((category, i) => (
<CategoryCheckbox

View File

@ -1,7 +1,7 @@
import { Categories, Category } from 'types/category'
import categoriesData from './../assets/categories/categories.json'
const flattenCategories = (
export const flattenCategories = (
categories: (Category | string)[],
parentPath: string[] = []
): Categories[] => {
@ -26,16 +26,6 @@ export const getCategories = () => {
return flattenCategories(categoriesData)
}
export const buildCategories = (input: string[]) => {
const categories: (string | Category)[] = []
input.forEach((cat) => {
addToUserCategories(categories, cat)
})
return categories
}
export const addToUserCategories = (
categories: (string | Category)[],
input: string