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
+ );
+}