diff --git a/frontend/src/constants/enhance/rebirth.ts b/frontend/src/constants/enhance/rebirth.ts new file mode 100644 index 0000000..71b9e2d --- /dev/null +++ b/frontend/src/constants/enhance/rebirth.ts @@ -0,0 +1 @@ +export const MAX_REBIRTHS = 6; diff --git a/frontend/src/pages/crystal/1-character/characterButton.tsx b/frontend/src/pages/crystal/1-character/characterButton.tsx index 659a3fa..d6d5405 100644 --- a/frontend/src/pages/crystal/1-character/characterButton.tsx +++ b/frontend/src/pages/crystal/1-character/characterButton.tsx @@ -63,6 +63,7 @@ export default function CharacterButton({ h="fit-content" justifyContent="space-between" variant={selected == index ? undefined : "ghost"} + borderWidth={1} opacity={isDragging ? 0.4 : undefined} transform={transform ? transformToString(transform) : undefined} transition={transition ?? "transform 0ms linear"} diff --git a/frontend/src/pages/enhance/7-execute/common/itemSlot.tsx b/frontend/src/pages/enhance/7-execute/common/itemSlot.tsx new file mode 100644 index 0000000..92ffc3c --- /dev/null +++ b/frontend/src/pages/enhance/7-execute/common/itemSlot.tsx @@ -0,0 +1,28 @@ +import { Flex, Image, useColorMode } from "@chakra-ui/react"; + +export default function ItemSlot({ image }: { image?: string }) { + const dark = useColorMode().colorMode == "dark"; + + return ( + + + + + + ); +} diff --git a/frontend/src/pages/enhance/7-execute/potential/optionButton.tsx b/frontend/src/pages/enhance/7-execute/common/optionButton.tsx similarity index 72% rename from frontend/src/pages/enhance/7-execute/potential/optionButton.tsx rename to frontend/src/pages/enhance/7-execute/common/optionButton.tsx index 7cb34e5..0288bcc 100644 --- a/frontend/src/pages/enhance/7-execute/potential/optionButton.tsx +++ b/frontend/src/pages/enhance/7-execute/common/optionButton.tsx @@ -1,5 +1,6 @@ import { Badge, + Box, Button, Flex, Heading, @@ -10,7 +11,6 @@ import { useColorMode, } from "@chakra-ui/react"; import { - MAX_POTENTIALS, POTENTIAL_GRADE, POTENTIAL_INFOS, } from "../../../../constants/enhance/potential"; @@ -19,13 +19,17 @@ export default function OptionsButton({ title, grade, options, + borderColor, + maxOptionCount, isDisabled, onClick, }: { title: string; grade?: POTENTIAL_GRADE; options: string[]; - isDisabled: boolean; + borderColor?: string; + maxOptionCount: number; + isDisabled?: boolean; onClick?: () => void; }) { const dark = useColorMode().colorMode == "dark"; @@ -46,7 +50,7 @@ export default function OptionsButton({ alignItems="stretch" textAlign="start" borderWidth={1} - borderColor={grade ? POTENTIAL_INFOS[grade].borderColor : undefined} + borderColor={borderColor} isDisabled={isDisabled} cursor={onClick ? undefined : "default"} onClick={onClick} @@ -72,19 +76,21 @@ export default function OptionsButton({ borderRadius={4} backgroundColor={dark ? "gray.800" : "gray.300"} > - - {grade && } - {grade && POTENTIAL_INFOS[grade].name} - - {new Array(MAX_POTENTIALS).fill(0).map((_, i) => ( + {borderColor == undefined || ( + + {grade && } + {grade && POTENTIAL_INFOS[grade].name} + + )} + + {new Array(maxOptionCount).fill(0).map((_, i) => ( ))} diff --git a/frontend/src/pages/enhance/7-execute/execute.tsx b/frontend/src/pages/enhance/7-execute/execute.tsx index ae325c9..219ac3f 100644 --- a/frontend/src/pages/enhance/7-execute/execute.tsx +++ b/frontend/src/pages/enhance/7-execute/execute.tsx @@ -2,6 +2,7 @@ import RequiredText from "../../../components/content/requiredText"; import { MATERIAL_TYPE } from "../../../constants/enhance/material"; import GrindStone from "./grindStone/grindStone"; import Potential from "./potential/potential"; +import Rebirth from "./rebirth/rebirth"; export default function Execute({ inventoryIndex, @@ -20,6 +21,21 @@ export default function Execute({ return {message}; } + if ( + [ + MATERIAL_TYPE.POWERFUL, + MATERIAL_TYPE.ETERNAL, + MATERIAL_TYPE.BLACK_REBIRTH, + MATERIAL_TYPE.ABYSS, + ].includes(materialType) + ) + return ( + + ); + + if (materialType == MATERIAL_TYPE.GRINDSTONE) + return ; + if ( [ MATERIAL_TYPE.STRANGE, @@ -38,8 +54,5 @@ export default function Execute({ ); - if (materialType == MATERIAL_TYPE.GRINDSTONE) - return ; - return 개발중인 기능입니다.; } diff --git a/frontend/src/pages/enhance/7-execute/grindStone/grindStone.tsx b/frontend/src/pages/enhance/7-execute/grindStone/grindStone.tsx index f301c51..45e2845 100644 --- a/frontend/src/pages/enhance/7-execute/grindStone/grindStone.tsx +++ b/frontend/src/pages/enhance/7-execute/grindStone/grindStone.tsx @@ -55,6 +55,7 @@ export default function GrindStone({ } > @@ -67,6 +68,7 @@ export default function GrindStone({ /> 1 / 5}> @@ -86,6 +88,7 @@ export default function GrindStone({ } > diff --git a/frontend/src/pages/enhance/7-execute/potential/potential.tsx b/frontend/src/pages/enhance/7-execute/potential/potential.tsx index 48d2e10..a457ae0 100644 --- a/frontend/src/pages/enhance/7-execute/potential/potential.tsx +++ b/frontend/src/pages/enhance/7-execute/potential/potential.tsx @@ -14,9 +14,10 @@ import { MATERIAL_TYPE, } from "../../../../constants/enhance/material"; import { useAppDispatch, useAppSelector } from "../../../../stores/hooks"; -import OptionsButton from "./optionButton"; +import OptionsButton from "../common/optionButton"; import { useEffect, useRef, useState } from "react"; import { + MAX_POTENTIALS, POTENTIAL_CRITERIA, POTENTIAL_GRADE, POTENTIAL_INFOS, @@ -48,6 +49,7 @@ import AutoModal from "./autoModal"; import PotentialCondition from "../../../../types/character/itemEquipment/potential/potentialCondition"; import { FaPlay, FaStop } from "react-icons/fa6"; import { isFitConditions } from "../../../../services/enhance/potentialCondition"; +import ItemSlot from "../common/itemSlot"; const AUTO_DELAY = 100; @@ -96,7 +98,11 @@ export default function Potential({ level, }); - useEffect(() => () => clearInterval(intervalId), []); + useEffect( + () => () => clearInterval(intervalId), + // eslint-disable-next-line react-hooks/exhaustive-deps + [] + ); useEffect(() => { optionsRef.current = options; }, [options]); @@ -120,6 +126,8 @@ export default function Potential({ setIntervalId(undefined); clearInterval(intervalId); } + + // eslint-disable-next-line react-hooks/exhaustive-deps }, [inventoryIndex, materialType]); const clearNewOptions = () => { @@ -236,31 +244,20 @@ export default function Potential({ return ( - - - - - + + + + 아이템의 잠재능력을 재설정합니다. + + + @@ -270,6 +267,8 @@ export default function Potential({ grade={newGrade} options={formatOptions(newOptions)} isDisabled={!newOptions[0]} + borderColor={grade ? POTENTIAL_INFOS[grade].borderColor : ""} + maxOptionCount={MAX_POTENTIALS} onClick={ selectable ? () => applyOptions(newOptions, newGrade) : undefined } diff --git a/frontend/src/pages/enhance/7-execute/rebirth/rebirth.tsx b/frontend/src/pages/enhance/7-execute/rebirth/rebirth.tsx new file mode 100644 index 0000000..653fa29 --- /dev/null +++ b/frontend/src/pages/enhance/7-execute/rebirth/rebirth.tsx @@ -0,0 +1,56 @@ +import { Flex, Image, Stack, Tag, Text, useColorMode } from "@chakra-ui/react"; +import { + MATERIAL_INFOS, + MATERIAL_TYPE, +} from "../../../../constants/enhance/material"; +import { useAppSelector } from "../../../../stores/hooks"; +import ItemSlot from "../common/itemSlot"; +import OptionsButton from "../common/optionButton"; +import { MAX_REBIRTHS } from "../../../../constants/enhance/rebirth"; +import { isSelectable } from "../../../../services/enhance/rebirth"; + +export default function Rebirth({ + inventoryIndex, + materialType, +}: { + inventoryIndex: number; + materialType: MATERIAL_TYPE; +}) { + const inventory = useAppSelector((state) => state.user.inventory); + + const item = inventory[inventoryIndex].after; + const selectable = isSelectable(materialType); + + return ( + + + + + 아이템의 추가옵션을 재설정합니다. + + + + {} : undefined} + /> + {selectable && ( + {}} + /> + )} + + ); +} diff --git a/frontend/src/pages/home/2-character/characterButton.tsx b/frontend/src/pages/home/2-character/characterButton.tsx index fb3121c..993e809 100644 --- a/frontend/src/pages/home/2-character/characterButton.tsx +++ b/frontend/src/pages/home/2-character/characterButton.tsx @@ -80,6 +80,7 @@ export default function CharacterButton({ flexDir="column" variant={name && selected ? undefined : "ghost"} opacity={isDragging ? 0.4 : undefined} + borderWidth={1} transform={transform ? transformToString(transform) : undefined} transition={transition ?? "transform 0ms linear"} onClick={onClick} diff --git a/frontend/src/services/enhance/rebirth.ts b/frontend/src/services/enhance/rebirth.ts new file mode 100644 index 0000000..3c07883 --- /dev/null +++ b/frontend/src/services/enhance/rebirth.ts @@ -0,0 +1,7 @@ +import { MATERIAL_TYPE } from "../../constants/enhance/material"; + +export function isSelectable(materialType: MATERIAL_TYPE) { + return [MATERIAL_TYPE.BLACK_REBIRTH, MATERIAL_TYPE.ABYSS].includes( + materialType + ); +}