Update object modals
We needed to update CharacterModal and WeaponModal to display awakenings from the new data format. However, the component used (`SelectWithInput`) was tied to AX Skills in a way that would take exponentially more time to resolve. Instead, we forked `SelectWithInput` into `AwakeningSelectWithInput` and did our work there. `AwakeningSelect` was found to be redundant, so it was removed.
This commit is contained in:
parent
a998413870
commit
35e3ce7b08
5 changed files with 274 additions and 163 deletions
|
|
@ -1,13 +1,7 @@
|
||||||
// Core dependencies
|
// Core dependencies
|
||||||
import React, {
|
import React, { PropsWithChildren, useEffect, useState } from 'react'
|
||||||
PropsWithChildren,
|
|
||||||
useCallback,
|
|
||||||
useEffect,
|
|
||||||
useState,
|
|
||||||
} from 'react'
|
|
||||||
import { useRouter } from 'next/router'
|
import { useRouter } from 'next/router'
|
||||||
import { useTranslation } from 'next-i18next'
|
import { useTranslation } from 'next-i18next'
|
||||||
import { AxiosResponse } from 'axios'
|
|
||||||
import classNames from 'classnames'
|
import classNames from 'classnames'
|
||||||
|
|
||||||
// UI dependencies
|
// UI dependencies
|
||||||
|
|
@ -20,14 +14,10 @@ import {
|
||||||
import DialogContent from '~components/common/DialogContent'
|
import DialogContent from '~components/common/DialogContent'
|
||||||
import Button from '~components/common/Button'
|
import Button from '~components/common/Button'
|
||||||
import SelectWithInput from '~components/common/SelectWithInput'
|
import SelectWithInput from '~components/common/SelectWithInput'
|
||||||
import AwakeningSelect from '~components/mastery/AwakeningSelect'
|
|
||||||
import RingSelect from '~components/mastery/RingSelect'
|
import RingSelect from '~components/mastery/RingSelect'
|
||||||
import Switch from '~components/common/Switch'
|
import Switch from '~components/common/Switch'
|
||||||
|
|
||||||
// Utilities
|
// Utilities
|
||||||
import api from '~utils/api'
|
|
||||||
import { appState } from '~utils/appState'
|
|
||||||
import { retrieveCookies } from '~utils/retrieveCookies'
|
|
||||||
import elementalizeAetherialMastery from '~utils/elementalizeAetherialMastery'
|
import elementalizeAetherialMastery from '~utils/elementalizeAetherialMastery'
|
||||||
|
|
||||||
// Data
|
// Data
|
||||||
|
|
@ -36,6 +26,8 @@ const emptyExtendedMastery: ExtendedMastery = {
|
||||||
strength: 0,
|
strength: 0,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const MAX_AWAKENING_LEVEL = 9
|
||||||
|
|
||||||
// Styles and icons
|
// Styles and icons
|
||||||
import CrossIcon from '~public/icons/Cross.svg'
|
import CrossIcon from '~public/icons/Cross.svg'
|
||||||
import './index.scss'
|
import './index.scss'
|
||||||
|
|
@ -46,6 +38,7 @@ import {
|
||||||
ExtendedMastery,
|
ExtendedMastery,
|
||||||
GridCharacterObject,
|
GridCharacterObject,
|
||||||
} from '~types'
|
} from '~types'
|
||||||
|
import AwakeningSelectWithInput from '~components/mastery/AwakeningSelectWithInput'
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
gridCharacter: GridCharacter
|
gridCharacter: GridCharacter
|
||||||
|
|
@ -66,9 +59,6 @@ const CharacterModal = ({
|
||||||
router.locale && ['en', 'ja'].includes(router.locale) ? router.locale : 'en'
|
router.locale && ['en', 'ja'].includes(router.locale) ? router.locale : 'en'
|
||||||
const { t } = useTranslation('common')
|
const { t } = useTranslation('common')
|
||||||
|
|
||||||
// Cookies
|
|
||||||
const cookies = retrieveCookies()
|
|
||||||
|
|
||||||
// UI state
|
// UI state
|
||||||
const [open, setOpen] = useState(false)
|
const [open, setOpen] = useState(false)
|
||||||
const [formValid, setFormValid] = useState(false)
|
const [formValid, setFormValid] = useState(false)
|
||||||
|
|
@ -103,8 +93,8 @@ const CharacterModal = ({
|
||||||
const [earring, setEarring] = useState<ExtendedMastery>(emptyExtendedMastery)
|
const [earring, setEarring] = useState<ExtendedMastery>(emptyExtendedMastery)
|
||||||
|
|
||||||
// Character properties: Awakening
|
// Character properties: Awakening
|
||||||
const [awakeningType, setAwakeningType] = useState(0)
|
const [awakening, setAwakening] = useState<Awakening>()
|
||||||
const [awakeningLevel, setAwakeningLevel] = useState(0)
|
const [awakeningLevel, setAwakeningLevel] = useState(1)
|
||||||
|
|
||||||
// Character properties: Transcendence
|
// Character properties: Transcendence
|
||||||
const [transcendenceStep, setTranscendenceStep] = useState(0)
|
const [transcendenceStep, setTranscendenceStep] = useState(0)
|
||||||
|
|
@ -118,7 +108,7 @@ const CharacterModal = ({
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
setAwakeningType(gridCharacter.awakening.type)
|
setAwakening(gridCharacter.awakening.type)
|
||||||
setAwakeningLevel(gridCharacter.awakening.level)
|
setAwakeningLevel(gridCharacter.awakening.level)
|
||||||
setPerpetuity(gridCharacter.perpetuity)
|
setPerpetuity(gridCharacter.perpetuity)
|
||||||
}, [gridCharacter])
|
}, [gridCharacter])
|
||||||
|
|
@ -147,15 +137,16 @@ const CharacterModal = ({
|
||||||
modifier: earring.modifier,
|
modifier: earring.modifier,
|
||||||
strength: earring.strength,
|
strength: earring.strength,
|
||||||
},
|
},
|
||||||
awakening: {
|
|
||||||
type: awakeningType,
|
|
||||||
level: awakeningLevel,
|
|
||||||
},
|
|
||||||
transcendence_step: transcendenceStep,
|
transcendence_step: transcendenceStep,
|
||||||
perpetuity: perpetuity,
|
perpetuity: perpetuity,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (awakening) {
|
||||||
|
object.character.awakening_id = awakening.id
|
||||||
|
object.character.awakening_level = awakeningLevel
|
||||||
|
}
|
||||||
|
|
||||||
return object
|
return object
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -191,8 +182,8 @@ const CharacterModal = ({
|
||||||
if (onOpenChange) onOpenChange(false)
|
if (onOpenChange) onOpenChange(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
function receiveAwakeningValues(type: number, level: number) {
|
function receiveAwakeningValues(id: string, level: number) {
|
||||||
setAwakeningType(type)
|
setAwakening(gridCharacter.object.awakenings.find((a) => a.id === id))
|
||||||
setAwakeningLevel(level)
|
setAwakeningLevel(level)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -234,10 +225,16 @@ const CharacterModal = ({
|
||||||
return (
|
return (
|
||||||
<section>
|
<section>
|
||||||
<h3>{t('modals.characters.subtitles.awakening')}</h3>
|
<h3>{t('modals.characters.subtitles.awakening')}</h3>
|
||||||
<AwakeningSelect
|
<AwakeningSelectWithInput
|
||||||
object="character"
|
dataSet={gridCharacter.object.awakenings}
|
||||||
type={awakeningType}
|
awakening={gridCharacter.awakening.type}
|
||||||
level={awakeningLevel}
|
level={gridCharacter.awakening.level}
|
||||||
|
defaultAwakening={
|
||||||
|
gridCharacter.object.awakenings.find(
|
||||||
|
(a) => a.slug === 'character-balanced'
|
||||||
|
)!
|
||||||
|
}
|
||||||
|
maxLevel={MAX_AWAKENING_LEVEL}
|
||||||
sendValidity={receiveValidity}
|
sendValidity={receiveValidity}
|
||||||
sendValues={receiveAwakeningValues}
|
sendValues={receiveAwakeningValues}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -1,97 +0,0 @@
|
||||||
import React, { useEffect, useState } from 'react'
|
|
||||||
import cloneDeep from 'lodash.clonedeep'
|
|
||||||
|
|
||||||
import SelectWithInput from '~components/common/SelectWithInput'
|
|
||||||
import { weaponAwakening, characterAwakening } from '~data/awakening'
|
|
||||||
|
|
||||||
import './index.scss'
|
|
||||||
|
|
||||||
interface Props {
|
|
||||||
object: 'character' | 'weapon'
|
|
||||||
type?: number
|
|
||||||
level?: number
|
|
||||||
onOpenChange?: (open: boolean) => void
|
|
||||||
sendValidity: (isValid: boolean) => void
|
|
||||||
sendValues: (type: number, level: number) => void
|
|
||||||
}
|
|
||||||
|
|
||||||
const AwakeningSelect = (props: Props) => {
|
|
||||||
// Data states
|
|
||||||
const [awakeningType, setAwakeningType] = useState(
|
|
||||||
props.object === 'weapon' ? 0 : 1
|
|
||||||
)
|
|
||||||
const [awakeningLevel, setAwakeningLevel] = useState(1)
|
|
||||||
|
|
||||||
// Data
|
|
||||||
const chooseDataset = () => {
|
|
||||||
let list: ItemSkill[] = []
|
|
||||||
|
|
||||||
switch (props.object) {
|
|
||||||
case 'character':
|
|
||||||
list = characterAwakening
|
|
||||||
break
|
|
||||||
case 'weapon':
|
|
||||||
// WARNING: Clonedeep is masking a deeper error
|
|
||||||
// which is running this method every time this component is rerendered
|
|
||||||
// causing multiple "No awakening" items to be added
|
|
||||||
const awakening = cloneDeep(weaponAwakening)
|
|
||||||
awakening.unshift({
|
|
||||||
id: 0,
|
|
||||||
name: {
|
|
||||||
en: 'No awakening',
|
|
||||||
ja: '覚醒なし',
|
|
||||||
},
|
|
||||||
granblue_id: '',
|
|
||||||
slug: 'no-awakening',
|
|
||||||
minValue: 0,
|
|
||||||
maxValue: 0,
|
|
||||||
fractional: false,
|
|
||||||
})
|
|
||||||
list = awakening
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
return list
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set default awakening and level based on object type
|
|
||||||
useEffect(() => {
|
|
||||||
const defaultAwakening = props.object === 'weapon' ? 0 : 1
|
|
||||||
const type = props.type != undefined ? props.type : defaultAwakening
|
|
||||||
|
|
||||||
setAwakeningType(type)
|
|
||||||
setAwakeningLevel(props.level ? props.level : 1)
|
|
||||||
}, [props.object, props.type, props.level])
|
|
||||||
|
|
||||||
// Send validity of form when awakening level changes
|
|
||||||
useEffect(() => {
|
|
||||||
props.sendValidity(awakeningLevel > 0)
|
|
||||||
}, [props.sendValidity, awakeningLevel])
|
|
||||||
|
|
||||||
// Classes
|
|
||||||
function changeOpen(open: boolean) {
|
|
||||||
if (props.onOpenChange) props.onOpenChange(open)
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleValueChange(type: number, level: number) {
|
|
||||||
setAwakeningType(type)
|
|
||||||
setAwakeningLevel(level)
|
|
||||||
props.sendValues(type, level)
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="Awakening">
|
|
||||||
<SelectWithInput
|
|
||||||
object={`${props.object}_awakening`}
|
|
||||||
dataSet={chooseDataset()}
|
|
||||||
selectValue={awakeningType}
|
|
||||||
inputValue={awakeningLevel}
|
|
||||||
onOpenChange={changeOpen}
|
|
||||||
sendValidity={props.sendValidity}
|
|
||||||
sendValues={handleValueChange}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default AwakeningSelect
|
|
||||||
|
|
@ -1,4 +1,22 @@
|
||||||
.AwakeningSelect .AwakeningSet {
|
.SelectWithItem {
|
||||||
|
.InputSet {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
gap: $unit;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
.SelectTrigger {
|
||||||
|
flex-grow: 1;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Input {
|
||||||
|
flex-grow: 0;
|
||||||
|
text-align: right;
|
||||||
|
width: 13rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.errors {
|
.errors {
|
||||||
color: $error;
|
color: $error;
|
||||||
display: none;
|
display: none;
|
||||||
|
|
@ -8,30 +26,4 @@
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.fields {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
gap: $unit;
|
|
||||||
width: 100%;
|
|
||||||
|
|
||||||
.SelectTrigger {
|
|
||||||
flex-grow: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.Label {
|
|
||||||
display: none;
|
|
||||||
flex-grow: 0;
|
|
||||||
|
|
||||||
&.Visible {
|
|
||||||
display: block;
|
|
||||||
width: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.Input {
|
|
||||||
min-width: $unit * 12;
|
|
||||||
width: inherit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
215
components/mastery/AwakeningSelectWithInput/index.tsx
Normal file
215
components/mastery/AwakeningSelectWithInput/index.tsx
Normal file
|
|
@ -0,0 +1,215 @@
|
||||||
|
// Core dependencies
|
||||||
|
import React, { useEffect, useState } from 'react'
|
||||||
|
import { useRouter } from 'next/router'
|
||||||
|
import { useTranslation } from 'next-i18next'
|
||||||
|
import classNames from 'classnames'
|
||||||
|
|
||||||
|
// UI Dependencies
|
||||||
|
import Input from '~components/common/Input'
|
||||||
|
import Select from '~components/common/Select'
|
||||||
|
import SelectItem from '~components/common/SelectItem'
|
||||||
|
|
||||||
|
// Styles and icons
|
||||||
|
import './index.scss'
|
||||||
|
|
||||||
|
// Types
|
||||||
|
interface Props {
|
||||||
|
dataSet: Awakening[]
|
||||||
|
defaultAwakening: Awakening
|
||||||
|
awakening?: Awakening
|
||||||
|
level?: number
|
||||||
|
maxLevel: number
|
||||||
|
selectDisabled: boolean
|
||||||
|
onOpenChange?: (open: boolean) => void
|
||||||
|
sendValidity: (isValid: boolean) => void
|
||||||
|
sendValues: (type: string, level: number) => void
|
||||||
|
}
|
||||||
|
|
||||||
|
const defaultProps = {
|
||||||
|
selectDisabled: false,
|
||||||
|
}
|
||||||
|
|
||||||
|
const AwakeningSelectWithInput = ({
|
||||||
|
dataSet,
|
||||||
|
defaultAwakening,
|
||||||
|
awakening,
|
||||||
|
level,
|
||||||
|
maxLevel,
|
||||||
|
selectDisabled,
|
||||||
|
onOpenChange,
|
||||||
|
sendValidity,
|
||||||
|
sendValues,
|
||||||
|
}: Props) => {
|
||||||
|
// Set up translations
|
||||||
|
const router = useRouter()
|
||||||
|
const locale =
|
||||||
|
router.locale && ['en', 'ja'].includes(router.locale) ? router.locale : 'en'
|
||||||
|
const { t } = useTranslation('common')
|
||||||
|
|
||||||
|
// State: Component
|
||||||
|
const [open, setOpen] = useState(false)
|
||||||
|
const [error, setError] = useState('')
|
||||||
|
|
||||||
|
// State: Data
|
||||||
|
const [currentAwakening, setCurrentAwakening] = useState<Awakening>()
|
||||||
|
const [currentLevel, setCurrentLevel] = useState(1)
|
||||||
|
|
||||||
|
// Refs
|
||||||
|
const inputRef = React.createRef<HTMLInputElement>()
|
||||||
|
|
||||||
|
// Classes
|
||||||
|
const inputClasses = classNames({
|
||||||
|
Bound: true,
|
||||||
|
Hidden: currentAwakening === undefined || currentAwakening.id === '0',
|
||||||
|
})
|
||||||
|
|
||||||
|
const errorClasses = classNames({
|
||||||
|
errors: true,
|
||||||
|
visible: error !== '',
|
||||||
|
})
|
||||||
|
|
||||||
|
// Hooks
|
||||||
|
useEffect(() => {
|
||||||
|
setCurrentAwakening(awakening)
|
||||||
|
setCurrentLevel(level ? level : 1)
|
||||||
|
|
||||||
|
if (awakening) sendValidity(true)
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
// Methods: UI state management
|
||||||
|
function changeOpen() {
|
||||||
|
if (!selectDisabled) {
|
||||||
|
setOpen(!open)
|
||||||
|
if (onOpenChange) onOpenChange(!open)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function onClose() {
|
||||||
|
if (onOpenChange) onOpenChange(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Methods: Rendering
|
||||||
|
function generateOptions() {
|
||||||
|
const sortedDataSet = [...dataSet].sort((a, b) => {
|
||||||
|
return a.order - b.order
|
||||||
|
})
|
||||||
|
|
||||||
|
let options: React.ReactNode[] = sortedDataSet.map((awakening, i) => {
|
||||||
|
return generateItem(awakening)
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!dataSet.includes(defaultAwakening))
|
||||||
|
options.unshift(generateItem(defaultAwakening))
|
||||||
|
|
||||||
|
return options
|
||||||
|
}
|
||||||
|
|
||||||
|
function generateItem(awakening: Awakening) {
|
||||||
|
return (
|
||||||
|
<SelectItem key={awakening.slug} value={awakening.id}>
|
||||||
|
{awakening.name[locale]}
|
||||||
|
</SelectItem>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Methods: User input detection
|
||||||
|
function handleSelectChange(id: string) {
|
||||||
|
const input = inputRef.current
|
||||||
|
if (input && !handleInputError(parseFloat(input.value))) return
|
||||||
|
|
||||||
|
setCurrentAwakening(dataSet.find((awakening) => awakening.id === id))
|
||||||
|
sendValues(id, currentLevel)
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleInputChange(event: React.ChangeEvent<HTMLInputElement>) {
|
||||||
|
const input = inputRef.current
|
||||||
|
if (input && !handleInputError(parseFloat(input.value))) return
|
||||||
|
|
||||||
|
setCurrentLevel(parseInt(event.target.value))
|
||||||
|
sendValues(
|
||||||
|
currentAwakening ? currentAwakening.id : '0',
|
||||||
|
parseInt(event.target.value)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Methods: Handle error
|
||||||
|
|
||||||
|
function handleInputError(value: number) {
|
||||||
|
let error = ''
|
||||||
|
|
||||||
|
if (currentAwakening) {
|
||||||
|
if (value < 1) {
|
||||||
|
error = t(`awakening.errors.value_too_low`, {
|
||||||
|
minValue: 1,
|
||||||
|
})
|
||||||
|
} else if (value > maxLevel) {
|
||||||
|
error = t(`awakening.errors.value_too_high`, {
|
||||||
|
maxValue: maxLevel,
|
||||||
|
})
|
||||||
|
} else if (value % 1 != 0) {
|
||||||
|
error = t(`awakening.errors.value_not_whole`)
|
||||||
|
} else if (!value || value <= 0) {
|
||||||
|
error = t(`awakening.errors.value_empty`)
|
||||||
|
} else {
|
||||||
|
error = ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setError(error)
|
||||||
|
|
||||||
|
if (error.length > 0) {
|
||||||
|
sendValidity(false)
|
||||||
|
return false
|
||||||
|
} else return true
|
||||||
|
}
|
||||||
|
|
||||||
|
const rangeString = () => {
|
||||||
|
let placeholder = ''
|
||||||
|
|
||||||
|
if (awakening) {
|
||||||
|
const minValue = 1
|
||||||
|
const maxValue = maxLevel
|
||||||
|
placeholder = `${minValue}~${maxValue}`
|
||||||
|
}
|
||||||
|
|
||||||
|
return placeholder
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="SelectWithItem">
|
||||||
|
<div className="InputSet">
|
||||||
|
<Select
|
||||||
|
key="awakening-type"
|
||||||
|
value={`${awakening ? awakening.id : defaultAwakening.id}`}
|
||||||
|
open={open}
|
||||||
|
disabled={selectDisabled}
|
||||||
|
onValueChange={handleSelectChange}
|
||||||
|
onOpenChange={changeOpen}
|
||||||
|
onClose={onClose}
|
||||||
|
triggerClass="modal"
|
||||||
|
overlayVisible={false}
|
||||||
|
>
|
||||||
|
{generateOptions()}
|
||||||
|
</Select>
|
||||||
|
|
||||||
|
<Input
|
||||||
|
value={level ? level : 1}
|
||||||
|
className={inputClasses}
|
||||||
|
type="number"
|
||||||
|
placeholder={rangeString()}
|
||||||
|
min={1}
|
||||||
|
max={maxLevel}
|
||||||
|
step="1"
|
||||||
|
onChange={handleInputChange}
|
||||||
|
visible={awakening ? 'true' : 'false'}
|
||||||
|
ref={inputRef}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<p className={errorClasses}>{error}</p>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
AwakeningSelectWithInput.defaultProps = defaultProps
|
||||||
|
|
||||||
|
export default AwakeningSelectWithInput
|
||||||
|
|
@ -11,14 +11,15 @@ import {
|
||||||
DialogTrigger,
|
DialogTrigger,
|
||||||
} from '~components/common/Dialog'
|
} from '~components/common/Dialog'
|
||||||
import DialogContent from '~components/common/DialogContent'
|
import DialogContent from '~components/common/DialogContent'
|
||||||
|
import AwakeningSelectWithInput from '~components/mastery/AwakeningSelectWithInput'
|
||||||
import AXSelect from '~components/mastery/AxSelect'
|
import AXSelect from '~components/mastery/AxSelect'
|
||||||
import AwakeningSelect from '~components/mastery/AwakeningSelect'
|
|
||||||
import ElementToggle from '~components/ElementToggle'
|
import ElementToggle from '~components/ElementToggle'
|
||||||
import WeaponKeySelect from '~components/weapon/WeaponKeySelect'
|
import WeaponKeySelect from '~components/weapon/WeaponKeySelect'
|
||||||
import Button from '~components/common/Button'
|
import Button from '~components/common/Button'
|
||||||
|
|
||||||
import api from '~utils/api'
|
import api from '~utils/api'
|
||||||
import { appState } from '~utils/appState'
|
import { appState } from '~utils/appState'
|
||||||
|
import { NO_AWAKENING } from '~data/awakening'
|
||||||
|
|
||||||
import CrossIcon from '~public/icons/Cross.svg'
|
import CrossIcon from '~public/icons/Cross.svg'
|
||||||
import './index.scss'
|
import './index.scss'
|
||||||
|
|
@ -33,7 +34,7 @@ interface GridWeaponObject {
|
||||||
ax_modifier2?: number
|
ax_modifier2?: number
|
||||||
ax_strength1?: number
|
ax_strength1?: number
|
||||||
ax_strength2?: number
|
ax_strength2?: number
|
||||||
awakening_type?: number
|
awakening_id?: string
|
||||||
awakening_level?: Number
|
awakening_level?: Number
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -70,7 +71,7 @@ const WeaponModal = ({
|
||||||
|
|
||||||
const [element, setElement] = useState(-1)
|
const [element, setElement] = useState(-1)
|
||||||
|
|
||||||
const [awakeningType, setAwakeningType] = useState(0)
|
const [awakening, setAwakening] = useState<Awakening>()
|
||||||
const [awakeningLevel, setAwakeningLevel] = useState(1)
|
const [awakeningLevel, setAwakeningLevel] = useState(1)
|
||||||
|
|
||||||
const [primaryAxModifier, setPrimaryAxModifier] = useState(-1)
|
const [primaryAxModifier, setPrimaryAxModifier] = useState(-1)
|
||||||
|
|
@ -136,9 +137,10 @@ const WeaponModal = ({
|
||||||
setFormValid(isValid)
|
setFormValid(isValid)
|
||||||
}
|
}
|
||||||
|
|
||||||
function receiveAwakeningValues(type: number, level: number) {
|
function receiveAwakeningValues(id: string, level: number) {
|
||||||
setAwakeningType(type)
|
setAwakening(gridWeapon.object.awakenings.find((a) => a.id === id))
|
||||||
setAwakeningLevel(level)
|
setAwakeningLevel(level)
|
||||||
|
setFormValid(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
function receiveElementValue(element: string) {
|
function receiveElementValue(element: string) {
|
||||||
|
|
@ -167,8 +169,8 @@ const WeaponModal = ({
|
||||||
object.weapon.ax_strength2 = secondaryAxValue
|
object.weapon.ax_strength2 = secondaryAxValue
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gridWeapon.object.awakening) {
|
if (gridWeapon.object.awakenings) {
|
||||||
object.weapon.awakening_type = awakeningType
|
object.weapon.awakening_id = awakening?.id
|
||||||
object.weapon.awakening_level = awakeningLevel
|
object.weapon.awakening_level = awakeningLevel
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -313,10 +315,12 @@ const WeaponModal = ({
|
||||||
return (
|
return (
|
||||||
<section>
|
<section>
|
||||||
<h3>{t('modals.weapon.subtitles.awakening')}</h3>
|
<h3>{t('modals.weapon.subtitles.awakening')}</h3>
|
||||||
<AwakeningSelect
|
<AwakeningSelectWithInput
|
||||||
object="weapon"
|
dataSet={gridWeapon.object.awakenings}
|
||||||
type={gridWeapon.awakening?.type}
|
awakening={gridWeapon.awakening?.type}
|
||||||
level={gridWeapon.awakening?.level}
|
level={gridWeapon.awakening?.level}
|
||||||
|
defaultAwakening={NO_AWAKENING}
|
||||||
|
maxLevel={gridWeapon.object.max_awakening_level}
|
||||||
onOpenChange={receiveAwakeningOpen}
|
onOpenChange={receiveAwakeningOpen}
|
||||||
sendValidity={receiveValidity}
|
sendValidity={receiveValidity}
|
||||||
sendValues={receiveAwakeningValues}
|
sendValues={receiveAwakeningValues}
|
||||||
|
|
@ -326,7 +330,7 @@ const WeaponModal = ({
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleOpenChange(open: boolean) {
|
function handleOpenChange(open: boolean) {
|
||||||
if (gridWeapon.object.ax || gridWeapon.object.awakening) {
|
if (gridWeapon.object.ax || gridWeapon.object.awakenings) {
|
||||||
setFormValid(false)
|
setFormValid(false)
|
||||||
} else {
|
} else {
|
||||||
setFormValid(true)
|
setFormValid(true)
|
||||||
|
|
@ -387,7 +391,7 @@ const WeaponModal = ({
|
||||||
{gridWeapon.object.element == 0 ? elementSelect() : ''}
|
{gridWeapon.object.element == 0 ? elementSelect() : ''}
|
||||||
{[2, 3, 17, 24].includes(gridWeapon.object.series) ? keySelect() : ''}
|
{[2, 3, 17, 24].includes(gridWeapon.object.series) ? keySelect() : ''}
|
||||||
{gridWeapon.object.ax ? axSelect() : ''}
|
{gridWeapon.object.ax ? axSelect() : ''}
|
||||||
{gridWeapon.awakening ? awakeningSelect() : ''}
|
{gridWeapon.object.awakenings ? awakeningSelect() : ''}
|
||||||
</div>
|
</div>
|
||||||
<div className="DialogFooter" ref={footerRef}>
|
<div className="DialogFooter" ref={footerRef}>
|
||||||
<Button
|
<Button
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue