Refactor RaidDropdown

Generally cleaned it up. Moved `raidGroups` out into a utils file and restructured it so we can localized names.
This commit is contained in:
Justin Edmund 2022-03-06 15:20:34 -08:00
parent 7ea3907e7f
commit 79b5960cea
2 changed files with 169 additions and 47 deletions

View file

@ -1,35 +1,43 @@
import React, { useCallback, useEffect, useState } from 'react'
import { useRouter } from 'next/router'
import { useTranslation } from 'next-i18next'
import { appState } from '~utils/appState'
import api from '~utils/api'
import { appState } from '~utils/appState'
import { raidGroups } from '~utils/raidGroups'
import './index.scss'
// Props
interface Props {
allOption: boolean
selected?: string
showAllRaidsOption: boolean
currentRaidId?: string
onChange?: (event: React.ChangeEvent<HTMLSelectElement>) => void
onBlur?: (event: React.ChangeEvent<HTMLSelectElement>) => void
}
const RaidDropdown = React.forwardRef<HTMLSelectElement, Props>(function useFieldSet(props, ref) {
// Set up router for locale
const router = useRouter()
const { t } = useTranslation('common')
const locale = (router.locale && ['en', 'ja'].includes(router.locale)) ? router.locale : 'en'
const locale = router.locale || 'en'
const [raids, setRaids] = useState<Raid[][]>()
// Set up local states for storing lists of raids
const [raids, setRaids] = useState<Raid[]>()
const [sortedRaids, setSortedRaids] = useState<Raid[][]>()
const raidGroups = [
'Assorted', 'Guild Wars', 'Omega', 'T1 Summons', 'T2 Summons',
'Primarchs', 'Nightmare', 'Omega (Impossible)', 'Omega II',
'Tier 1 Summons (Impossible)', 'Tier 3 Summons', 'Ennead', 'Malice',
'6-Star Raids', 'Six-Dragons', 'Nightmare (Impossible)', 'Arcarum: Replicard Sandbox',
'Astral', 'Super Ultimate'
]
// Set up empty raid for "All raids"
const all = {
id: '0',
name: {
en: 'All raids',
ja: '全て'
},
slug: 'all',
level: 0,
group: 0,
element: 0
}
// Organize raids into groups on mount
const organizeRaids = useCallback((raids: Raid[]) => {
const numGroups = Math.max.apply(Math, raids.map(raid => raid.group))
let groupedRaids = []
@ -38,55 +46,45 @@ const RaidDropdown = React.forwardRef<HTMLSelectElement, Props>(function useFiel
groupedRaids[i] = raids.filter(raid => raid.group == i)
}
if (props.allOption)
groupedRaids[0].unshift({
id: '0',
name: {
en: 'All raids',
ja: '全てのマルチ'
},
level: 0,
group: 0,
element: 0
})
setRaids(groupedRaids)
}, [props.allOption])
useEffect(() => {
function fetchRaids() {
api.endpoints.raids.getAll()
.then((response) => {
const raids = response.data.map((r: any) => r.raid)
appState.raids = raids
organizeRaids(raids)
})
if (props.showAllRaidsOption) {
raids.unshift(all)
groupedRaids[0].unshift(all)
}
fetchRaids()
setRaids(raids)
setSortedRaids(groupedRaids)
}, [props.showAllRaidsOption])
// Fetch all raids on mount
useEffect(() => {
api.endpoints.raids.getAll()
.then(response => organizeRaids(response.data.map((r: any) => r.raid)))
}, [organizeRaids])
function raidGroup(index: number) {
const options = raids && raids.length > 0 && raids[index].length > 0 &&
raids[index].sort((a, b) => a.element - b.element).map((item, i) => {
// Render JSX for each raid option, sorted into optgroups
function renderRaidGroup(index: number) {
const options = sortedRaids && sortedRaids.length > 0 && sortedRaids[index].length > 0 &&
sortedRaids[index].sort((a, b) => a.element - b.element).map((item, i) => {
return (
<option key={i} value={item.id}>{item.name[locale]}</option>
)
})
return (
<optgroup key={index} label={raidGroups[index]}>
<optgroup key={index} label={raidGroups[index].name[locale]}>
{options}
</optgroup>
)
}
return (
<select key={props.selected} defaultValue={props.selected} onBlur={props.onBlur} onChange={props.onChange} ref={ref}>
{ Array.from(Array(raids?.length)).map((x, i) => {
return raidGroup(i)
})}
<select
key={props.currentRaidId}
defaultValue={props.currentRaidId}
onBlur={props.onBlur}
onChange={props.onChange}
ref={ref}>
{ Array.from(Array(sortedRaids?.length)).map((x, i) => renderRaidGroup(i)) }
</select>
)
})

124
utils/raidGroups.tsx Normal file
View file

@ -0,0 +1,124 @@
interface RaidGroup {
name: {
[key: string]: string
en: string
ja: string
}
}
export const raidGroups: RaidGroup[] = [
{
name: {
en: 'Assorted',
ja: 'その他'
}
},
{
name: {
en: 'Guild Wars',
ja: '星の古戦場'
}
},
{
name: {
en: 'Omega',
ja: 'マグナ'
}
},
{
name: {
en: 'T1 Summons',
ja: '召喚石マルチ1'
}
},
{
name: {
en: 'T2 Summons',
ja: '召喚石マルチ2'
}
},
{
name: {
en: 'Primarchs',
ja: '四大天使'
}
},
{
name: {
en: 'Nightmare',
ja: 'HELL'
}
},
{
name: {
en: 'Omega (Impossible)',
ja: 'マグナHL'
}
},
{
name: {
en: 'Omega II',
ja: 'マグナII'
}
},
{
name: {
en: 'Tier 1 Summons (Impossible)',
ja: '旧召喚石HL'
}
},
{
name: {
en: 'Tier 3 Summons',
ja: 'エピックHL'
}
},
{
name: {
en: 'Ennead',
ja: 'エニアド'
}
},
{
name: {
en: 'Malice',
ja: 'マリス'
}
},
{
name: {
en: '6-Star Raids',
ja: '★★★★★★'
}
},
{
name: {
en: 'Six-Dragons',
ja: '六竜HL'
}
},
{
name: {
en: 'Nightmare (Impossible)',
ja: '高級HELL'
}
},
{
name: {
en: 'Arcarum: Replicard Sandbox',
ja: 'アーカルム レプリカルド・サンドボックス'
}
},
{
name: {
en: 'Astrals',
ja: '星の民'
}
},
{
name: {
en: 'Super Ultimate',
ja: 'スーパーアルティメット'
}
}
]