diff --git a/src/views/components/database/quest/QuestEarnings.tsx b/src/views/components/database/quest/QuestEarnings.tsx index beec9c4c..9d0eb4b5 100644 --- a/src/views/components/database/quest/QuestEarnings.tsx +++ b/src/views/components/database/quest/QuestEarnings.tsx @@ -15,6 +15,12 @@ type QuestEarningsProps = { export const QuestEarnings = ({ quest, dialogsRef, setEarningIndex }: QuestEarningsProps) => { const { projectDataValues: quests } = useProjectQuests(); const { t } = useTranslation('database_quests'); + + const editEarning = (index: number) => { + dialogsRef.current?.openDialog('earning'); + setEarningIndex(index); + }; + return ( - + ); }; diff --git a/src/views/components/database/quest/editors/QuestEarningEditor.tsx b/src/views/components/database/quest/editors/QuestEarningEditor.tsx index fa54d5f5..7a106ff9 100644 --- a/src/views/components/database/quest/editors/QuestEarningEditor.tsx +++ b/src/views/components/database/quest/editors/QuestEarningEditor.tsx @@ -1,51 +1,94 @@ -import { useRefreshUI } from '@components/editor'; import { Editor } from '@components/editor/Editor'; import { InputContainer, InputWithTopLabelContainer, Label } from '@components/inputs'; -import { SelectCustomSimple } from '@components/SelectCustom'; -import { QUEST_EARNINGS, StudioQuest, StudioQuestEarningType } from '@modelEntities/quest'; -import { createQuestEarning } from '@utils/entityCreation'; +import { QUEST_EARNINGS, StudioQuestEarningType } from '@modelEntities/quest'; import { padStr } from '@utils/PadStr'; -import React, { useMemo } from 'react'; import { useTranslation } from 'react-i18next'; import { TFunction } from 'i18next'; import { QuestEarningItem, QuestEarningMoney, QuestEarningPokemon } from './earnings'; +import { EditorHandlingClose, useEditorHandlingClose } from '@components/editor/useHandleCloseEditor'; +import { useQuestPage } from '@src/hooks/usePage'; +import { useUpdateQuest } from './useUpdateQuest'; +import { useEarningQuest } from './useEarningQuest'; +import { cloneEntity } from '@utils/cloneEntity'; +import { assertUnreachable } from '@utils/assertUnreachable'; +import { cleanNaNValue } from '@utils/cleanNaNValue'; +import { Select } from '@ds/Select'; +import React, { forwardRef, useMemo } from 'react'; const earningCategoryEntries = (t: TFunction<'database_quests'>) => QUEST_EARNINGS.map((earning) => ({ value: earning, label: t(earning) })); type QuestEarningEditorProps = { - quest: StudioQuest; earningIndex: number; }; -export const QuestEarningEditor = ({ quest, earningIndex }: QuestEarningEditorProps) => { +export const QuestEarningEditor = forwardRef(({ earningIndex }, ref) => { const { t } = useTranslation('database_quests'); - const refreshUI = useRefreshUI(); + const { quest } = useQuestPage(); + const updateQuest = useUpdateQuest(quest); + const { earning, refs, updateEarning, isValid } = useEarningQuest(quest.earnings[earningIndex]); const earningOptions = useMemo(() => earningCategoryEntries(t), [t]); - const earning = quest.earnings[earningIndex]; + const earningMethodName = earning.earningMethodName; const changeEarning = (value: StudioQuestEarningType) => { - if (value === quest.earnings[earningIndex].earningMethodName) return; - quest.earnings[earningIndex] = createQuestEarning(value); + if (value === earningMethodName) return; + + updateEarning(value); + }; + + const canClose = () => isValid; + + const onClose = () => { + if (!canClose()) return; + + const newEarning = cloneEntity(earning); + const oldEarning = quest.earnings[earningIndex]; + const isSameMethodName = newEarning.earningMethodName === oldEarning.earningMethodName; + switch (earningMethodName) { + case 'earning_money': { + if (!refs.inputRef.current) return; + + const backupValue = isSameMethodName ? (oldEarning.earningArgs[0] as number) : 100; + newEarning.earningArgs[0] = cleanNaNValue(refs.inputRef.current.valueAsNumber, backupValue); + break; + } + case 'earning_item': { + if (!refs.entityRef.current || !refs.inputRef.current) return; + + const backupValue = isSameMethodName ? (oldEarning.earningArgs[1] as number) : 1; + newEarning.earningArgs[0] = refs.entityRef.current; + newEarning.earningArgs[1] = cleanNaNValue(refs.inputRef.current.valueAsNumber, backupValue); + break; + } + case 'earning_pokemon': + case 'earning_egg': { + if (!refs.entityRef.current) return; + + newEarning.earningArgs[0] = refs.entityRef.current; + break; + } + default: + assertUnreachable(earningMethodName); + } + const updatedEarnings = cloneEntity(quest.earnings); + updatedEarnings[earningIndex] = cloneEntity(newEarning); + updateQuest({ earnings: updatedEarnings }); }; + useEditorHandlingClose(ref, onClose, canClose); + return ( - - refreshUI(changeEarning(value as StudioQuestEarningType))} - noTooltip - /> + + + +