mirror of
https://github.com/acid-info/logos-ordinals-dashboard.git
synced 2025-01-27 13:45:01 +00:00
feat: support filtering
This commit is contained in:
parent
b75923a9c2
commit
082843a0e8
71
constants/operators.ts
Normal file
71
constants/operators.ts
Normal 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',
|
||||
]
|
@ -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 }>`
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user