Add AxSelect component and API call
This commit is contained in:
parent
97fb9420db
commit
1d0c242429
3 changed files with 190 additions and 0 deletions
30
components/AxSelect/index.scss
Normal file
30
components/AxSelect/index.scss
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
.AXSet {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: $unit;
|
||||
|
||||
&.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
select {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.Input {
|
||||
-webkit-font-smoothing: antialiased;
|
||||
border: none;
|
||||
background-color: $grey-90;
|
||||
border-radius: 6px;
|
||||
box-sizing: border-box;
|
||||
color: $grey-00;
|
||||
height: $unit * 6;
|
||||
display: block;
|
||||
font-size: $font-regular;
|
||||
padding: $unit;
|
||||
text-align: right;
|
||||
min-width: 100px;
|
||||
width: 100px;
|
||||
}
|
||||
|
||||
}
|
||||
159
components/AxSelect/index.tsx
Normal file
159
components/AxSelect/index.tsx
Normal file
|
|
@ -0,0 +1,159 @@
|
|||
import React, { useEffect, useState } from 'react'
|
||||
import classNames from 'classnames'
|
||||
|
||||
import { axData } from '~utils/axData'
|
||||
|
||||
import './index.scss'
|
||||
|
||||
interface Props {
|
||||
axType: number
|
||||
currentSkills?: SimpleAxSkill[],
|
||||
sendValues: (primaryAxModifier: number, primaryAxValue: number, secondaryAxModifier: number, secondaryAxValue: number) => void
|
||||
}
|
||||
|
||||
const AXSelect = (props: Props) => {
|
||||
// Refs
|
||||
const primaryAxModifierSelect = React.createRef<HTMLSelectElement>()
|
||||
const primaryAxValueInput = React.createRef<HTMLInputElement>()
|
||||
const secondaryAxModifierSelect = React.createRef<HTMLSelectElement>()
|
||||
const secondaryAxValueInput = React.createRef<HTMLInputElement>()
|
||||
|
||||
// States
|
||||
const [primaryAxModifier, setPrimaryAxModifier] = useState(-1)
|
||||
const [secondaryAxModifier, setSecondaryAxModifier] = useState(-1)
|
||||
const [primaryAxValue, setPrimaryAxValue] = useState(0.0)
|
||||
const [secondaryAxValue, setSecondaryAxValue] = useState(0.0)
|
||||
|
||||
useEffect(() => {
|
||||
if (props.currentSkills && props.currentSkills[0]) {
|
||||
if (props.currentSkills[0].modifier != null)
|
||||
setPrimaryAxModifier(props.currentSkills[0].modifier)
|
||||
|
||||
setPrimaryAxValue(props.currentSkills[0].strength)
|
||||
}
|
||||
|
||||
if (props.currentSkills && props.currentSkills[1]) {
|
||||
if (props.currentSkills[1].modifier != null)
|
||||
setSecondaryAxModifier(props.currentSkills[1].modifier)
|
||||
|
||||
setSecondaryAxValue(props.currentSkills[1].strength)
|
||||
}
|
||||
}, [props.currentSkills])
|
||||
|
||||
useEffect(() => {
|
||||
props.sendValues(primaryAxModifier, primaryAxValue, secondaryAxModifier, secondaryAxValue)
|
||||
}, [primaryAxModifier, primaryAxValue, secondaryAxModifier, secondaryAxValue])
|
||||
|
||||
// Classes
|
||||
const secondarySetClasses = classNames({
|
||||
'AXSet': true,
|
||||
'hidden': primaryAxModifier < 0
|
||||
})
|
||||
|
||||
function generateOptions(modifierSet: number) {
|
||||
const axOptions = axData[props.axType - 1]
|
||||
|
||||
let axOptionElements: React.ReactNode[] = []
|
||||
if (modifierSet == 0) {
|
||||
axOptionElements = axOptions.map((ax, i) => {
|
||||
return (
|
||||
<option key={i} value={ax.id}>{ax.name.en}</option>
|
||||
)
|
||||
})
|
||||
} else {
|
||||
// If we are loading data from the server, state doesn't set before render,
|
||||
// so our defaultValue is undefined.
|
||||
let modifier = -1;
|
||||
if (primaryAxModifier >= 0)
|
||||
modifier = primaryAxModifier
|
||||
else if (props.currentSkills)
|
||||
modifier = props.currentSkills[0].modifier
|
||||
|
||||
if (modifier >= 0 && axOptions[modifier]) {
|
||||
const primarySkill = axOptions[modifier]
|
||||
|
||||
if (primarySkill.secondary) {
|
||||
const secondaryAxOptions = primarySkill.secondary
|
||||
axOptionElements = secondaryAxOptions.map((ax, i) => {
|
||||
return (
|
||||
<option key={i} value={ax.id}>{ax.name.en}</option>
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
axOptionElements?.unshift(<option key={-1} value={-1}>No AX Skill</option>)
|
||||
return axOptionElements
|
||||
}
|
||||
|
||||
function handleSelectChange(event: React.ChangeEvent<HTMLSelectElement>) {
|
||||
const value = parseInt(event.target.value)
|
||||
|
||||
if (primaryAxModifierSelect.current == event.target) {
|
||||
setPrimaryAxModifier(value)
|
||||
|
||||
if (primaryAxValueInput.current && secondaryAxModifierSelect.current && secondaryAxValueInput.current) {
|
||||
setupInput(axData[props.axType - 1][value], primaryAxValueInput.current)
|
||||
|
||||
secondaryAxModifierSelect.current.value = "-1"
|
||||
secondaryAxValueInput.current.value = ""
|
||||
}
|
||||
} else {
|
||||
setSecondaryAxModifier(value)
|
||||
|
||||
const primaryAxSkill = axData[props.axType - 1][primaryAxModifier]
|
||||
const currentAxSkill = (primaryAxSkill.secondary) ?
|
||||
primaryAxSkill.secondary.find(skill => skill.id == value) : undefined
|
||||
|
||||
if (secondaryAxValueInput.current)
|
||||
setupInput(currentAxSkill, secondaryAxValueInput.current)
|
||||
}
|
||||
}
|
||||
|
||||
function handleInputChange(event: React.ChangeEvent<HTMLInputElement>) {
|
||||
if (primaryAxValueInput.current == event.target) {
|
||||
setPrimaryAxValue(parseFloat(event.target.value))
|
||||
} else {
|
||||
setSecondaryAxValue(parseFloat(event.target.value))
|
||||
}
|
||||
}
|
||||
|
||||
function setupInput(ax: AxSkill | undefined, element: HTMLInputElement) {
|
||||
if (ax) {
|
||||
const rangeString = `${ax.minValue}~${ax.maxValue}${ax.suffix || ''}`
|
||||
|
||||
element.disabled = false
|
||||
element.placeholder = rangeString
|
||||
element.min = `${ax.minValue}`
|
||||
element.max = `${ax.maxValue}`
|
||||
element.step = (ax.suffix) ? "0.5" : "1"
|
||||
} else {
|
||||
if (primaryAxValueInput.current && secondaryAxValueInput.current) {
|
||||
if (primaryAxValueInput.current == element) {
|
||||
primaryAxValueInput.current.disabled = true
|
||||
primaryAxValueInput.current.placeholder = ''
|
||||
}
|
||||
|
||||
secondaryAxValueInput.current.disabled = true
|
||||
secondaryAxValueInput.current.placeholder = ''
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="AXSelect">
|
||||
<div className="AXSet">
|
||||
<select key="ax1" defaultValue={ (props.currentSkills && props.currentSkills[0]) ? props.currentSkills[0].modifier : -1 } onChange={handleSelectChange} ref={primaryAxModifierSelect}>{ generateOptions(0) }</select>
|
||||
<input defaultValue={ (props.currentSkills && props.currentSkills[0]) ? props.currentSkills[0].strength : 0 } className="Input" type="number" onChange={handleInputChange} ref={primaryAxValueInput} disabled />
|
||||
</div>
|
||||
|
||||
<div className={secondarySetClasses}>
|
||||
<select key="ax2" defaultValue={ (props.currentSkills && props.currentSkills[1]) ? props.currentSkills[1].modifier : -1 } onChange={handleSelectChange} ref={secondaryAxModifierSelect}>{ generateOptions(1) }</select>
|
||||
<input defaultValue={ (props.currentSkills && props.currentSkills[1]) ? props.currentSkills[1].strength : 0 } className="Input" type="number" onChange={handleInputChange} ref={secondaryAxValueInput} disabled />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default AXSelect
|
||||
|
|
@ -103,6 +103,7 @@ class Api {
|
|||
const api: Api = new Api({ url: process.env.NEXT_PUBLIC_SIERO_API_URL || 'https://localhost:3000/api/v1'})
|
||||
api.createEntity( { name: 'users' })
|
||||
api.createEntity( { name: 'parties' })
|
||||
api.createEntity( { name: 'grid_weapons' })
|
||||
api.createEntity( { name: 'characters' })
|
||||
api.createEntity( { name: 'weapons' })
|
||||
api.createEntity( { name: 'summons' })
|
||||
|
|
|
|||
Loading…
Reference in a new issue