feat: support global state

This commit is contained in:
jinhojang6 2024-10-04 02:28:07 +09:00
parent 7dab5f70f9
commit 8c45beb11b
5 changed files with 4565 additions and 4530 deletions

File diff suppressed because it is too large Load Diff

View File

@ -57,7 +57,7 @@ const OperatorDetails: React.FC<OperatorDetailsProps> = ({
const handleShare = () => { const handleShare = () => {
const text = encodeURIComponent( const text = encodeURIComponent(
`I am a/an ${operator?.name}, an Operator forging Parallel Societies with Logos.\n\nEnter the portal and explore the collection at https://dashboard.logos.co`, `${operator?.name} has chosen to EXIT.\n\nJoin me and explore the collection at https://dashboard.logos.co`,
) )
const twitterUrl = `https://x.com/intent/post?text=${text}` const twitterUrl = `https://x.com/intent/post?text=${text}`
@ -118,7 +118,7 @@ const OperatorDetails: React.FC<OperatorDetailsProps> = ({
<AttributesFullGrid> <AttributesFullGrid>
<AttributeItem> <AttributeItem>
<AttributeLabel>Skin</AttributeLabel> <AttributeLabel>Skin</AttributeLabel>
<AttributeValue>None</AttributeValue> <AttributeValue>{operator?.skin}</AttributeValue>
</AttributeItem> </AttributeItem>
</AttributesFullGrid> </AttributesFullGrid>

View File

@ -1,7 +1,9 @@
import { Dropdown } from '@/components/Dropdown' import { Dropdown } from '@/components/Dropdown'
import { OperatorGrid } from '@/components/Explore/OperatorGrid' import { OperatorGrid } from '@/components/Explore/OperatorGrid'
import { defaultFilterState } from '@/states/filterState'
import styled from '@emotion/styled' import styled from '@emotion/styled'
import React, { useState } from 'react' import { hookstate, useHookstate } from '@hookstate/core'
import React from 'react'
import useGetOperators from '../../../apis/operators/useGetOperators' import useGetOperators from '../../../apis/operators/useGetOperators'
import { import {
ARCHETYPE, ARCHETYPE,
@ -11,31 +13,22 @@ import {
JACKET, JACKET,
SKIN, SKIN,
} from '../../../constants/operators' } from '../../../constants/operators'
import { Archetype } from '../../../types/operators'
import { processOperators, shuffleOperators } from '../../../utils/operators' import { processOperators, shuffleOperators } from '../../../utils/operators'
interface ExploreSectionProps {} interface ExploreSectionProps {}
const globalState = hookstate(defaultFilterState)
const ExploreSection: React.FC<ExploreSectionProps> = () => { const ExploreSection: React.FC<ExploreSectionProps> = () => {
const { data, isLoading } = useGetOperators() const { data, isLoading } = useGetOperators()
const [filter, setFilter] = useState<{ const state = useHookstate(globalState)
archetype: Archetype[] const filter = state.get()
comp: string[]
skin: string[]
helmet: string[]
jacket: string[]
background: string[]
}>({
archetype: [],
comp: [],
skin: [],
helmet: [],
jacket: [],
background: [],
})
const processedOperators = processOperators(data as any, filter.archetype) const processedOperators = processOperators(
data as any,
filter.archetype.slice(),
)
const selectedOperators = processedOperators?.filter((operator) => { const selectedOperators = processedOperators?.filter((operator) => {
// filter by comp, skin, helmet, jacket, background // filter by comp, skin, helmet, jacket, background
@ -59,10 +52,7 @@ const ExploreSection: React.FC<ExploreSectionProps> = () => {
selectedOptions: string[], selectedOptions: string[],
filterType: string, filterType: string,
) => { ) => {
setFilter((prevFilter) => ({ ;(state[filterType as keyof typeof filter] as any).set(selectedOptions)
...prevFilter,
[filterType]: selectedOptions,
}))
} }
return ( return (
@ -74,42 +64,42 @@ const ExploreSection: React.FC<ExploreSectionProps> = () => {
options={ARCHETYPE} options={ARCHETYPE}
onSelectionChange={handleFilterChange} onSelectionChange={handleFilterChange}
filterType="archetype" filterType="archetype"
prefill={ARCHETYPE} prefill={filter.archetype.slice()}
/> />
<Dropdown <Dropdown
title="Comp" title="Comp"
options={COMP} options={COMP}
onSelectionChange={handleFilterChange} onSelectionChange={handleFilterChange}
filterType="comp" filterType="comp"
prefill={COMP} prefill={filter.comp.slice()}
/> />
<Dropdown <Dropdown
title="Skin" title="Skin"
options={SKIN} options={SKIN}
onSelectionChange={handleFilterChange} onSelectionChange={handleFilterChange}
filterType="skin" filterType="skin"
prefill={SKIN} prefill={filter.skin.slice()}
/> />
<Dropdown <Dropdown
title="Helmet" title="Helmet"
options={HELMET} options={HELMET}
onSelectionChange={handleFilterChange} onSelectionChange={handleFilterChange}
filterType="helmet" filterType="helmet"
prefill={HELMET} prefill={filter.helmet.slice()}
/> />
<Dropdown <Dropdown
title="Jacket" title="Jacket"
options={JACKET} options={JACKET}
onSelectionChange={handleFilterChange} onSelectionChange={handleFilterChange}
filterType="jacket" filterType="jacket"
prefill={JACKET} prefill={filter.jacket.slice()}
/> />
<Dropdown <Dropdown
title="Background" title="Background"
options={BACKGROUND} options={BACKGROUND}
onSelectionChange={handleFilterChange} onSelectionChange={handleFilterChange}
filterType="background" filterType="background"
prefill={BACKGROUND} prefill={filter.background.slice()}
/> />
</DropdownContainer> </DropdownContainer>
<OperatorGrid <OperatorGrid

View File

@ -0,0 +1,44 @@
import { hookstate, State, useHookstate } from '@hookstate/core'
import { localstored } from '@hookstate/localstored'
import {
ARCHETYPE,
BACKGROUND,
COMP,
HELMET,
JACKET,
SKIN,
} from '../../../constants/operators'
import { Archetype } from '../../../types/operators'
export type FilterState = {
archetype: Archetype[]
comp: string[]
skin: string[]
helmet: string[]
jacket: string[]
background: string[]
}
export const defaultFilterState: FilterState = {
archetype: ARCHETYPE,
comp: COMP,
skin: SKIN,
helmet: HELMET,
jacket: JACKET,
background: BACKGROUND,
}
const filterState =
typeof window === 'undefined'
? hookstate(defaultFilterState)
: hookstate<FilterState>(defaultFilterState, localstored({ key: 'filter' }))
const wrapFilterState = (state: State<FilterState>) => ({
filter: { ...state.value },
get: () => state.value,
setFilter: (value: FilterState) => state.set(value),
})
export const useFilterState = () => wrapFilterState(useHookstate(filterState))
export default useFilterState

View File

@ -0,0 +1 @@
export * from './filter.state'