From 1d0c24242918ebb215a3fbe8fe939e997a45ef48 Mon Sep 17 00:00:00 2001 From: Justin Edmund Date: Thu, 3 Mar 2022 03:10:37 -0800 Subject: [PATCH] Add AxSelect component and API call --- components/AxSelect/index.scss | 30 +++++++ components/AxSelect/index.tsx | 159 +++++++++++++++++++++++++++++++++ utils/api.tsx | 1 + 3 files changed, 190 insertions(+) create mode 100644 components/AxSelect/index.scss create mode 100644 components/AxSelect/index.tsx diff --git a/components/AxSelect/index.scss b/components/AxSelect/index.scss new file mode 100644 index 00000000..52aab9b0 --- /dev/null +++ b/components/AxSelect/index.scss @@ -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; + } + +} \ No newline at end of file diff --git a/components/AxSelect/index.tsx b/components/AxSelect/index.tsx new file mode 100644 index 00000000..b6798e74 --- /dev/null +++ b/components/AxSelect/index.tsx @@ -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() + const primaryAxValueInput = React.createRef() + const secondaryAxModifierSelect = React.createRef() + const secondaryAxValueInput = React.createRef() + + // 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 ( + + ) + }) + } 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 ( + + ) + }) + } + } + } + + axOptionElements?.unshift() + return axOptionElements + } + + function handleSelectChange(event: React.ChangeEvent) { + 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) { + 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 ( +
+
+ + +
+ +
+ + +
+
+ ) +} + +export default AXSelect \ No newline at end of file diff --git a/utils/api.tsx b/utils/api.tsx index 1e164649..3781e275 100644 --- a/utils/api.tsx +++ b/utils/api.tsx @@ -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' })