feat: support filtering

This commit is contained in:
jinhojang6 2024-10-01 23:22:26 +09:00
parent b75923a9c2
commit 082843a0e8
4 changed files with 169 additions and 27 deletions

71
constants/operators.ts Normal file
View File

@ -0,0 +1,71 @@
import { Archetype } from '../types/operators'
export const ARCHETYPE: Archetype[] = [
'Alchemist',
'Artisan',
'Explorer',
'Illuminator',
'Magician',
'Memetic',
'Oracle',
'Outlaw',
'Philosopher',
'Polymath',
]
export const COMP = [
'Ascii',
'Ascii_RGB',
'RetroScreen',
'RetroVHS',
'SketchStar',
]
export const BACKGROUND = [
'[CAMOED]',
'Rust',
'[REDACTED]',
'[CYPHERED]',
'Mariana',
'Marooned',
'Void',
'Cypress',
'LimeWire',
'Sanguine',
'Nightfall',
'Sulphur',
'Phantom',
]
export const SKIN = [
'[CAMOED]',
'IC1',
'[REDACTED]',
'[CYPHERED]',
'IC4',
'IC2',
'IC6',
'IC3',
]
export const HELMET = [
'[CAMOED]',
'Verdant crested helm',
'[REDACTED]',
'[CYPHERED]',
'Ethereal crested helm',
'Celestial crested helm',
'Aurora crested helm',
'Regal crested helm',
]
export const JACKET = [
'[CAMOED]',
'Cobalt frock coat',
'Amethyst frock coat',
'[REDACTED]',
'[CYPHERED]',
'Sulphur frock coat',
'Carmine frock coat',
'Emerald frock coat',
]

View File

@ -5,12 +5,14 @@ import Checkbox from './Checkbox' // Import the CustomCheckbox
interface DropdownProps {
title: string
options: string[]
onSelectionChange: (selectedOptions: any) => void
filterType: string
onSelectionChange: (selectedOptions: string[], filterType: string) => void
}
const Dropdown: React.FC<DropdownProps> = ({
title,
options,
filterType,
onSelectionChange,
}) => {
const [selectedOptions, setSelectedOptions] = useState<string[]>([])
@ -25,17 +27,17 @@ const Dropdown: React.FC<DropdownProps> = ({
newSelectedOptions = [...selectedOptions, option]
}
setSelectedOptions(newSelectedOptions)
onSelectionChange(newSelectedOptions)
onSelectionChange(newSelectedOptions, filterType)
}
const selectAll = () => {
setSelectedOptions(options)
onSelectionChange(options)
onSelectionChange(options, filterType)
}
const clearAll = () => {
setSelectedOptions([])
onSelectionChange([])
onSelectionChange([], filterType)
}
const toggleDropdown = () => {
@ -104,9 +106,11 @@ const DropdownHeader = styled.div<{ isExpanded: boolean }>`
align-items: center;
padding: 10px;
cursor: pointer;
border: 1px solid white;
background-color: ${({ isExpanded }) => (isExpanded ? 'white' : 'black')};
color: ${({ isExpanded }) => (isExpanded ? 'black' : 'white')};
border: 1px solid white;
border-left: none;
`
const Chevron = styled.span<{ isExpanded: boolean }>`

View File

@ -14,6 +14,7 @@ const OFFSET = 18
const OperatorGrid: React.FC<OperatorGridProps> = ({ data, isLoading }) => {
const [itemsCount, setItemsCount] = useState(18)
const observerRef = useRef<IntersectionObserver | null>(null)
const lastElementRef = useRef<HTMLDivElement | null>(null)

View File

@ -3,33 +3,64 @@ import { OperatorGrid } from '@/components/Explore/OperatorGrid'
import styled from '@emotion/styled'
import React, { useState } from 'react'
import useGetOperators from '../../../apis/operators/useGetOperators'
import {
ARCHETYPE,
BACKGROUND,
COMP,
HELMET,
JACKET,
SKIN,
} from '../../../constants/operators'
import { Archetype } from '../../../types/operators'
import { processOperators } from '../../../utils/operators'
interface ExploreSectionProps {}
// one of Archetype
const archetypes: Archetype[] = [
'Alchemist',
'Artisan',
'Explorer',
'Illuminator',
'Magician',
'Memetic',
'Oracle',
'Outlaw',
'Philosopher',
'Polymath',
]
const ExploreSection: React.FC<ExploreSectionProps> = () => {
const { data, isLoading } = useGetOperators()
const [selectedArchetypes, setSelectedArchetypes] = useState<Archetype[]>([])
const processedOperators = processOperators(data as any, selectedArchetypes)
const [filter, setFilter] = useState<{
archetype: Archetype[]
comp: string[]
skin: string[]
helmet: string[]
jacket: string[]
background: string[]
}>({
archetype: [],
comp: [],
skin: [],
helmet: [],
jacket: [],
background: [],
})
const handleSelectionChange = (selectedOptions: Archetype[]) => {
setSelectedArchetypes(selectedOptions)
const processedOperators = processOperators(data as any, filter.archetype)
const selectedOperators = processedOperators?.filter((operator) => {
// filter by comp, skin, helmet, jacket, background
return (
(filter.comp.length === 0 ||
filter.comp.includes(operator.comp as string)) &&
(filter.skin.length === 0 ||
filter.skin.includes(operator.skin as string)) &&
(filter.helmet.length === 0 ||
filter.helmet.includes(operator.helmet as string)) &&
(filter.jacket.length === 0 ||
filter.jacket.includes(operator.jacket as string)) &&
(filter.background.length === 0 ||
filter.background.includes(operator.background as string))
)
})
const handleFilterChange = (
selectedOptions: string[],
filterType: string,
) => {
setFilter((prevFilter) => ({
...prevFilter,
[filterType]: selectedOptions,
}))
}
return (
@ -38,13 +69,44 @@ const ExploreSection: React.FC<ExploreSectionProps> = () => {
<DropdownContainer>
<Dropdown
title="Archetype"
options={archetypes}
onSelectionChange={handleSelectionChange}
options={ARCHETYPE}
onSelectionChange={handleFilterChange}
filterType="archetype"
/>
<Dropdown
title="Comp"
options={COMP}
onSelectionChange={handleFilterChange}
filterType="comp"
/>
<Dropdown
title="Skin"
options={SKIN}
onSelectionChange={handleFilterChange}
filterType="skin"
/>
<Dropdown
title="Helmet"
options={HELMET}
onSelectionChange={handleFilterChange}
filterType="helmet"
/>
<Dropdown
title="Jacket"
options={JACKET}
onSelectionChange={handleFilterChange}
filterType="jacket"
/>
<Dropdown
title="Background"
options={BACKGROUND}
onSelectionChange={handleFilterChange}
filterType="background"
/>
</DropdownContainer>
<OperatorGrid
key={selectedArchetypes.join(',')}
data={processedOperators as any}
key={selectedOperators?.join(',')}
data={selectedOperators as any}
isLoading={isLoading}
/>
</Container>
@ -70,6 +132,10 @@ const DropdownContainer = styled.div`
justify-content: center;
align-items: center;
margin-top: 70px;
& > div:first-of-type {
border-left: 1px solid white;
}
`
export default ExploreSection