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'})
|
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: 'users' })
|
||||||
api.createEntity( { name: 'parties' })
|
api.createEntity( { name: 'parties' })
|
||||||
|
api.createEntity( { name: 'grid_weapons' })
|
||||||
api.createEntity( { name: 'characters' })
|
api.createEntity( { name: 'characters' })
|
||||||
api.createEntity( { name: 'weapons' })
|
api.createEntity( { name: 'weapons' })
|
||||||
api.createEntity( { name: 'summons' })
|
api.createEntity( { name: 'summons' })
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue