From 9a9a0397e976fac284d0c49e4b19a1bc63ad1f6c Mon Sep 17 00:00:00 2001 From: Justin Edmund Date: Tue, 20 Dec 2022 19:14:14 -0800 Subject: [PATCH 01/46] Refactor AxSelect because it was awful/broken I think this works. * Shows "No AX Skill" if no AX skill has been set * Inputs appear after AX skill has been selected * Second AX skill select shows up after first one has been selected --- components/AxSelect/index.tsx | 193 ++++++++++++++++++++++------------ 1 file changed, 127 insertions(+), 66 deletions(-) diff --git a/components/AxSelect/index.tsx b/components/AxSelect/index.tsx index 44da8fed..0b19a891 100644 --- a/components/AxSelect/index.tsx +++ b/components/AxSelect/index.tsx @@ -1,7 +1,10 @@ -import React, { useEffect, useState } from 'react' +import React, { ForwardedRef, useEffect, useState } from 'react' import { useRouter } from 'next/router' import { useTranslation } from 'next-i18next' +import Select from '~components/Select' +import SelectItem from '~components/SelectItem' + import classNames from 'classnames' import { axData } from '~utils/axData' @@ -32,6 +35,9 @@ const AXSelect = (props: Props) => { router.locale && ['en', 'ja'].includes(router.locale) ? router.locale : 'en' const { t } = useTranslation('common') + const [openAX1, setOpenAX1] = useState(false) + const [openAX2, setOpenAX2] = useState(false) + // Set up form states and error handling const [errors, setErrors] = useState({ axValue1: '', @@ -49,9 +55,9 @@ const AXSelect = (props: Props) => { }) // Refs - const primaryAxModifierSelect = React.createRef() + const primaryAxModifierSelect = React.createRef() const primaryAxValueInput = React.createRef() - const secondaryAxModifierSelect = React.createRef() + const secondaryAxModifierSelect = React.createRef() const secondaryAxValueInput = React.createRef() // States @@ -61,19 +67,8 @@ const AXSelect = (props: Props) => { 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) - } + setupAx1() + setupAx2() }, [props.currentSkills]) useEffect(() => { @@ -103,6 +98,62 @@ const AXSelect = (props: Props) => { hidden: primaryAxModifier < 0, }) + function setupAx1() { + if ( + props.currentSkills && + props.currentSkills[0] && + // Should this be > -1 or != null + props.currentSkills[0].modifier != null + ) { + setPrimaryAxModifier(props.currentSkills[0].modifier) + setPrimaryAxValue(props.currentSkills[0].strength) + + if (props.currentSkills[0].modifier > -1 && primaryAxValueInput.current) { + const modifier = props.currentSkills[0].modifier + const axSkill = axData[props.axType - 1][modifier] + setupInput(axSkill, primaryAxValueInput.current) + } + } + } + + function setupAx2() { + if ( + props.currentSkills && + props.currentSkills[1] && + // Should this be > -1 or != null + props.currentSkills[1].modifier != null + ) { + const firstSkill = props.currentSkills[0] + const primaryAxSkill = axData[props.axType - 1][firstSkill.modifier] + const secondaryAxSkill = findSecondaryAxSkill( + primaryAxSkill, + props.currentSkills[1] + ) + + if ( + props.currentSkills[1].modifier > -1 && + secondaryAxValueInput.current + ) { + setupInput(secondaryAxSkill, secondaryAxValueInput.current) + } + } + } + + function findSecondaryAxSkill( + axSkill: AxSkill | undefined, + skillAtIndex: SimpleAxSkill + ) { + if (axSkill) + return axSkill.secondary + ? axSkill.secondary.find((skill) => skill.id === skillAtIndex.modifier) + : undefined + } + + function openSelect(ref: ForwardedRef) { + if (ref === primaryAxModifierSelect) setOpenAX1(!openAX1) + if (ref === secondaryAxModifierSelect) setOpenAX2(!openAX2) + } + function generateOptions(modifierSet: number) { const axOptions = axData[props.axType - 1] @@ -110,9 +161,9 @@ const AXSelect = (props: Props) => { if (modifierSet == 0) { axOptionElements = axOptions.map((ax, i) => { return ( - + ) }) } else { @@ -129,9 +180,9 @@ const AXSelect = (props: Props) => { const secondaryAxOptions = primarySkill.secondary axOptionElements = secondaryAxOptions.map((ax, i) => { return ( - + ) }) } @@ -139,42 +190,42 @@ const AXSelect = (props: Props) => { } axOptionElements?.unshift( - + ) return axOptionElements } - function handleSelectChange(event: React.ChangeEvent) { - const value = parseInt(event.target.value) + function handleAX1SelectChange(rawValue: string) { + const value = parseInt(rawValue) + setPrimaryAxModifier(value) - if (primaryAxModifierSelect.current == event.target) { - setPrimaryAxModifier(value) + if ( + primaryAxValueInput.current && + secondaryAxModifierSelect.current && + secondaryAxValueInput.current + ) { + setupInput(axData[props.axType - 1][value], primaryAxValueInput.current) - 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) + secondaryAxModifierSelect.current.value = '-1' + secondaryAxValueInput.current.value = '' } } + function handleAX2SelectChange(rawValue: string) { + const value = parseInt(rawValue) + 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) { const value = parseFloat(event.target.value) let newErrors = { ...errors } @@ -260,6 +311,7 @@ const AXSelect = (props: Props) => { if (ax) { const rangeString = `${ax.minValue}~${ax.maxValue}${ax.suffix || ''}` + element.className = 'Input Visible' element.disabled = false element.placeholder = rangeString element.min = `${ax.minValue}` @@ -268,43 +320,56 @@ const AXSelect = (props: Props) => { } else { if (primaryAxValueInput.current && secondaryAxValueInput.current) { if (primaryAxValueInput.current == element) { + primaryAxValueInput.current.className = 'Input' primaryAxValueInput.current.disabled = true primaryAxValueInput.current.placeholder = '' } + secondaryAxValueInput.current.className = 'Input' secondaryAxValueInput.current.disabled = true secondaryAxValueInput.current.placeholder = '' } } } + const ax1DefaultValue = () => { + return props.currentSkills && + props.currentSkills[0].modifier != null && + props.currentSkills[0].modifier >= 0 + ? props.currentSkills[0].modifier + : -1 + } + + const ax2DefaultValue = () => { + return props.currentSkills && props.currentSkills[1].modifier + ? props.currentSkills[1].modifier + : -1 + } + return (
- + +

{errors.axValue1}

@@ -312,29 +377,25 @@ const AXSelect = (props: Props) => {
- +

{errors.axValue2}

From 85fd5df516e6b8ebbbc41b892e8040e4b2aa84a0 Mon Sep 17 00:00:00 2001 From: Justin Edmund Date: Tue, 20 Dec 2022 23:06:27 -0800 Subject: [PATCH 02/46] Refactored WeaponKeySelect and updated styles --- components/AxSelect/index.tsx | 8 +- components/Input/index.scss | 8 ++ components/Input/index.tsx | 23 ++++-- components/Select/index.scss | 13 +++ components/Select/index.tsx | 6 +- components/SelectItem/index.scss | 2 +- .../index.scss | 0 .../index.tsx | 49 ++++++------ components/WeaponModal/index.tsx | 79 +++++++++++-------- 9 files changed, 120 insertions(+), 68 deletions(-) rename components/{WeaponKeyDropdown => WeaponKeySelect}/index.scss (100%) rename components/{WeaponKeyDropdown => WeaponKeySelect}/index.tsx (77%) diff --git a/components/AxSelect/index.tsx b/components/AxSelect/index.tsx index 0b19a891..832cf1c7 100644 --- a/components/AxSelect/index.tsx +++ b/components/AxSelect/index.tsx @@ -311,7 +311,7 @@ const AXSelect = (props: Props) => { if (ax) { const rangeString = `${ax.minValue}~${ax.maxValue}${ax.suffix || ''}` - element.className = 'Input Visible' + element.className = 'Input Contained Visible' element.disabled = false element.placeholder = rangeString element.min = `${ax.minValue}` @@ -320,12 +320,12 @@ const AXSelect = (props: Props) => { } else { if (primaryAxValueInput.current && secondaryAxValueInput.current) { if (primaryAxValueInput.current == element) { - primaryAxValueInput.current.className = 'Input' + primaryAxValueInput.current.className = 'Input Contained' primaryAxValueInput.current.disabled = true primaryAxValueInput.current.placeholder = '' } - secondaryAxValueInput.current.className = 'Input' + secondaryAxValueInput.current.className = 'Input Contained' secondaryAxValueInput.current.disabled = true secondaryAxValueInput.current.placeholder = '' } @@ -356,6 +356,7 @@ const AXSelect = (props: Props) => { open={openAX1} onChange={handleAX1SelectChange} onClick={() => openSelect(primaryAxModifierSelect)} + triggerClass="modal" ref={primaryAxModifierSelect} > {generateOptions(0)} @@ -383,6 +384,7 @@ const AXSelect = (props: Props) => { open={openAX2} onChange={handleAX2SelectChange} onClick={() => openSelect(secondaryAxModifierSelect)} + triggerClass="modal" ref={secondaryAxModifierSelect} > {generateOptions(1)} diff --git a/components/Input/index.scss b/components/Input/index.scss index 013f4a74..5614baa7 100644 --- a/components/Input/index.scss +++ b/components/Input/index.scss @@ -7,6 +7,14 @@ display: block; padding: $unit-2x; width: 100%; + + &.Contained { + background-color: var(--input-bound-bg); + + &:hover { + background-color: var(--input-bound-bg-hover); + } + } } .InputError { diff --git a/components/Input/index.tsx b/components/Input/index.tsx index 27d21315..2d093b28 100644 --- a/components/Input/index.tsx +++ b/components/Input/index.tsx @@ -7,15 +7,26 @@ interface Props React.InputHTMLAttributes, HTMLInputElement > { + contained?: boolean error?: string label?: string } +const defaultProps = { + contained: false, +} + const Input = React.forwardRef(function input( - props: Props, + { contained, error, label, ...props }, forwardedRef ) { - const classes = classNames({ Input: true }, props.className) + const classes = classNames( + { + Input: true, + Contained: contained, + }, + props.className + ) return ( ) }) +Input.defaultProps = defaultProps + export default Input diff --git a/components/Select/index.scss b/components/Select/index.scss index c7b01b68..55589029 100644 --- a/components/Select/index.scss +++ b/components/Select/index.scss @@ -6,9 +6,22 @@ display: flex; padding: $unit-2x $unit-2x; + &.modal { + background-color: var(--select-modal-bg); + + &:hover { + background-color: var(--select-modal-bg-hover); + } + } + &:hover { background-color: var(--input-bg-hover); + color: var(--text-primary); cursor: pointer; + + &[data-placeholder] > span:not(.SelectIcon) { + color: var(--text-primary); + } } &[data-placeholder] > span:not(.SelectIcon) { diff --git a/components/Select/index.tsx b/components/Select/index.tsx index 8a0dd7f4..d5d7c239 100644 --- a/components/Select/index.tsx +++ b/components/Select/index.tsx @@ -11,25 +11,27 @@ interface Props { open: boolean defaultValue?: string | number placeholder?: string - trigger?: React.ReactNode + name?: string children?: React.ReactNode onClick?: () => void onChange?: (value: string) => void triggerClass?: string } -const Select = React.forwardRef(function useFieldSet( +const Select = React.forwardRef(function useFieldSet( props, ref ) { return ( diff --git a/components/SelectItem/index.scss b/components/SelectItem/index.scss index 2f1ca4f3..11cface5 100644 --- a/components/SelectItem/index.scss +++ b/components/SelectItem/index.scss @@ -1,7 +1,7 @@ .SelectItem { border-radius: $item-corner; border: 2px solid transparent; - color: var(--text-secondary); + color: var(--text-tertiary); font-size: $font-regular; padding: ($unit * 1.5) $unit-2x; diff --git a/components/WeaponKeyDropdown/index.scss b/components/WeaponKeySelect/index.scss similarity index 100% rename from components/WeaponKeyDropdown/index.scss rename to components/WeaponKeySelect/index.scss diff --git a/components/WeaponKeyDropdown/index.tsx b/components/WeaponKeySelect/index.tsx similarity index 77% rename from components/WeaponKeyDropdown/index.tsx rename to components/WeaponKeySelect/index.tsx index 327eb65e..7200b74b 100644 --- a/components/WeaponKeyDropdown/index.tsx +++ b/components/WeaponKeySelect/index.tsx @@ -1,5 +1,8 @@ import React, { useEffect, useState } from 'react' +import Select from '~components/Select' +import SelectGroup from '~components/SelectGroup' +import SelectItem from '~components/SelectItem' import api from '~utils/api' import './index.scss' @@ -9,14 +12,13 @@ interface Props { currentValue?: WeaponKey series: number slot: number - onChange?: (event: React.ChangeEvent) => void - onBlur?: (event: React.ChangeEvent) => void + onChange?: (value: string, slot: number) => void } -const WeaponKeyDropdown = React.forwardRef( +const WeaponKeySelect = React.forwardRef( function useFieldSet(props, ref) { + const [open, setOpen] = useState(false) const [keys, setKeys] = useState([]) - const [currentKey, setCurrentKey] = useState('') const pendulumNames = [ { en: 'Pendulum', jp: '' }, @@ -31,10 +33,6 @@ const WeaponKeyDropdown = React.forwardRef( { en: 'Gate of Omnipotence', jp: '' }, ] - useEffect(() => { - if (props.currentValue) setCurrentKey(props.currentValue.id) - }, [props.currentValue]) - useEffect(() => { const filterParams = { params: { @@ -66,6 +64,10 @@ const WeaponKeyDropdown = React.forwardRef( fetchWeaponKeys() }, [props.series, props.slot]) + function openSelect() { + setOpen(!open) + } + function weaponKeyGroup(index: number) { ;['α', 'β', 'γ', 'Δ'].sort((a, b) => a.localeCompare(b, 'el')) @@ -78,9 +80,9 @@ const WeaponKeyDropdown = React.forwardRef( keys[index].length > 0 && keys[index].sort(sortByOrder).map((item, i) => { return ( - + ) }) @@ -93,21 +95,20 @@ const WeaponKeyDropdown = React.forwardRef( else if (props.series == 22) name = emblemNames[index] return ( - {options} - + ) } - function handleChange(event: React.ChangeEvent) { - if (props.onChange) props.onChange(event) - - setCurrentKey(event.currentTarget.value) + function handleChange(value: string) { + if (props.onChange) props.onChange(value, props.slot) } const emptyOption = () => { @@ -121,22 +122,24 @@ const WeaponKeyDropdown = React.forwardRef( } return ( - + ) } ) -export default WeaponKeyDropdown +export default WeaponKeySelect diff --git a/components/WeaponModal/index.tsx b/components/WeaponModal/index.tsx index 559300cc..3c2e333b 100644 --- a/components/WeaponModal/index.tsx +++ b/components/WeaponModal/index.tsx @@ -1,4 +1,4 @@ -import React, { useState } from 'react' +import React, { useEffect, useState } from 'react' import { getCookie } from 'cookies-next' import { useRouter } from 'next/router' import { useTranslation } from 'next-i18next' @@ -8,7 +8,7 @@ import * as Dialog from '@radix-ui/react-dialog' import AXSelect from '~components/AxSelect' import ElementToggle from '~components/ElementToggle' -import WeaponKeyDropdown from '~components/WeaponKeyDropdown' +import WeaponKeySelect from '~components/WeaponKeySelect' import Button from '~components/Button' import api from '~utils/api' @@ -50,21 +50,38 @@ const WeaponModal = (props: Props) => { ? { Authorization: `Bearer ${accountData.token}` } : {} - // Refs - const weaponKey1Select = React.createRef() - const weaponKey2Select = React.createRef() - const weaponKey3Select = React.createRef() - // State const [open, setOpen] = useState(false) const [formValid, setFormValid] = useState(false) const [element, setElement] = useState(-1) + const [primaryAxModifier, setPrimaryAxModifier] = useState(-1) const [secondaryAxModifier, setSecondaryAxModifier] = useState(-1) const [primaryAxValue, setPrimaryAxValue] = useState(0.0) const [secondaryAxValue, setSecondaryAxValue] = useState(0.0) + const [weaponKey1, setWeaponKey1] = useState() + const [weaponKey2, setWeaponKey2] = useState() + const [weaponKey3, setWeaponKey3] = useState() + const [weaponKey1Id, setWeaponKey1Id] = useState('') + const [weaponKey2Id, setWeaponKey2Id] = useState('') + const [weaponKey3Id, setWeaponKey3Id] = useState('') + + useEffect(() => { + setElement(props.gridWeapon.element) + + if (props.gridWeapon.weapon_keys) { + if (props.gridWeapon.weapon_keys[0]) { + setWeaponKey1(props.gridWeapon.weapon_keys[0]) + } + if (props.gridWeapon.weapon_keys[1]) + setWeaponKey2(props.gridWeapon.weapon_keys[1]) + if (props.gridWeapon.weapon_keys[2]) + setWeaponKey3(props.gridWeapon.weapon_keys[2]) + } + }, [props]) + function receiveAxValues( primaryAxModifier: number, primaryAxValue: number, @@ -91,14 +108,15 @@ const WeaponModal = (props: Props) => { if (props.gridWeapon.object.element == 0) object.weapon.element = element - if ([2, 3, 17, 24].includes(props.gridWeapon.object.series)) - object.weapon.weapon_key1_id = weaponKey1Select.current?.value + if ([2, 3, 17, 24].includes(props.gridWeapon.object.series)) { + object.weapon.weapon_key1_id = weaponKey1Id + } if ([2, 3, 17].includes(props.gridWeapon.object.series)) - object.weapon.weapon_key2_id = weaponKey2Select.current?.value + object.weapon.weapon_key2_id = weaponKey2Id if (props.gridWeapon.object.series == 17) - object.weapon.weapon_key3_id = weaponKey3Select.current?.value + object.weapon.weapon_key3_id = weaponKey3Id if (props.gridWeapon.object.ax > 0) { object.weapon.ax_modifier1 = primaryAxModifier @@ -131,12 +149,18 @@ const WeaponModal = (props: Props) => { console.error(error) } + function receiveWeaponKey(value: string, slot: number) { + if (slot === 0) setWeaponKey1Id(value) + if (slot === 1) setWeaponKey2Id(value) + if (slot === 2) setWeaponKey3Id(value) + } + const elementSelect = () => { return (

{t('modals.weapon.subtitles.element')}

@@ -148,45 +172,33 @@ const WeaponModal = (props: Props) => {

{t('modals.weapon.subtitles.weapon_keys')}

{[2, 3, 17, 22].includes(props.gridWeapon.object.series) ? ( - ) : ( '' )} {[2, 3, 17].includes(props.gridWeapon.object.series) ? ( - ) : ( '' )} {props.gridWeapon.object.series == 17 ? ( - ) : ( '' @@ -245,6 +257,7 @@ const WeaponModal = (props: Props) => { : ''} {props.gridWeapon.object.ax > 0 ? axSelect() : ''}
+

{error}

+
+
+ ) +} + +export default AwakeningSelect diff --git a/components/Input/index.scss b/components/Input/index.scss index 9ec5d332..a55cef8b 100644 --- a/components/Input/index.scss +++ b/components/Input/index.scss @@ -5,7 +5,7 @@ border-radius: 6px; box-sizing: border-box; display: block; - padding: ($unit * 1.5) $unit-2x; + padding: $unit-2x; width: 100%; &.Bound { @@ -15,6 +15,10 @@ background-color: var(--input-bound-bg-hover); } } + + &.Hidden { + display: none; + } } .InputError { diff --git a/components/Select/index.tsx b/components/Select/index.tsx index 17867ee1..cf6e244a 100644 --- a/components/Select/index.tsx +++ b/components/Select/index.tsx @@ -33,7 +33,6 @@ const Select = (props: Props) => { if (props.onValueChange) props.onValueChange(newValue) } - console.log(value) return ( { const [element, setElement] = useState(-1) + const [awakeningType, setAwakeningType] = useState(-1) + const [awakeningLevel, setAwakeningLevel] = useState(1) + const [primaryAxModifier, setPrimaryAxModifier] = useState(-1) const [secondaryAxModifier, setSecondaryAxModifier] = useState(-1) const [primaryAxValue, setPrimaryAxValue] = useState(0.0) @@ -99,6 +105,11 @@ const WeaponModal = (props: Props) => { setFormValid(isValid) } + function receiveAwakeningValues(type: number, level: number) { + setAwakeningType(type) + setAwakeningLevel(level) + } + function receiveElementValue(element: string) { setElement(parseInt(element)) } @@ -125,6 +136,11 @@ const WeaponModal = (props: Props) => { object.weapon.ax_strength2 = secondaryAxValue } + if (props.gridWeapon.object.awakening) { + object.weapon.awakening_type = awakeningType + object.weapon.awakening_level = awakeningLevel + } + return object } @@ -137,7 +153,8 @@ const WeaponModal = (props: Props) => { } function processResult(response: AxiosResponse) { - const gridWeapon: GridWeapon = response.data.grid_weapon + console.log(response) + const gridWeapon: GridWeapon = response.data if (gridWeapon.mainhand) appState.grid.weapons.mainWeapon = gridWeapon else appState.grid.weapons.allWeapons[gridWeapon.position] = gridWeapon @@ -221,6 +238,20 @@ const WeaponModal = (props: Props) => { ) } + const awakeningSelect = () => { + return ( +
+

{t('modals.weapon.subtitles.awakening')}

+ +
+ ) + } + function openChange(open: boolean) { setFormValid(false) setOpen(open) @@ -256,6 +287,7 @@ const WeaponModal = (props: Props) => { ? keySelect() : ''} {props.gridWeapon.object.ax > 0 ? axSelect() : ''} + {props.gridWeapon.awakening ? awakeningSelect() : ''}