From 1a1cefcfbe57712c509b15fcbf8b4f9b340d2b6f Mon Sep 17 00:00:00 2001 From: choihooo Date: Thu, 31 Oct 2024 05:01:40 +0900 Subject: [PATCH 1/2] =?UTF-8?q?[feat]=20#40=20=ED=95=91=20=EC=97=85?= =?UTF-8?q?=EB=8D=B0=EC=9D=B4=ED=8B=B0=EB=A5=BC=20=EC=A0=9C=EC=99=B8?= =?UTF-8?q?=ED=95=9C=20=ED=8E=98=EC=9D=B4=EC=A7=80=20=EC=97=B0=EA=B2=B0=20?= =?UTF-8?q?=EB=B0=8F=20api=20=EC=97=B0=EB=8F=99=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/PincheckInput.tsx | 182 ++++++++++++++++++ .../load-mappin-edit/components/Form.tsx | 0 .../load-mappin-edit/components/LinkField.tsx | 0 .../[nonMemberId]}/load-mappin-edit/page.tsx | 5 +- .../[id]/[nonMemberId]}/page.tsx | 2 +- .../[id]/components/BottomDrawer.tsx | 12 +- .../[id]/load-mappin/components/Form.tsx | 14 +- .../app/event-maps/[id]/load-mappin/page.tsx | 3 +- fe/src/app/event-maps/[id]/page.tsx | 19 +- fe/src/app/eventcreate-page/page.tsx | 2 +- .../components/PincheckInput.tsx | 114 ----------- 11 files changed, 223 insertions(+), 130 deletions(-) create mode 100644 fe/src/app/event-maps/[id]/[nonMemberId]/components/PincheckInput.tsx rename fe/src/app/{ => event-maps/[id]/[nonMemberId]}/load-mappin-edit/components/Form.tsx (100%) rename fe/src/app/{ => event-maps/[id]/[nonMemberId]}/load-mappin-edit/components/LinkField.tsx (100%) rename fe/src/app/{ => event-maps/[id]/[nonMemberId]}/load-mappin-edit/page.tsx (92%) rename fe/src/app/{pincheck-page => event-maps/[id]/[nonMemberId]}/page.tsx (89%) delete mode 100644 fe/src/app/pincheck-page/components/PincheckInput.tsx diff --git a/fe/src/app/event-maps/[id]/[nonMemberId]/components/PincheckInput.tsx b/fe/src/app/event-maps/[id]/[nonMemberId]/components/PincheckInput.tsx new file mode 100644 index 0000000..d3683c6 --- /dev/null +++ b/fe/src/app/event-maps/[id]/[nonMemberId]/components/PincheckInput.tsx @@ -0,0 +1,182 @@ +"use client"; + +import React, { useRef, useState, useEffect } from "react"; +import { useRouter, useParams } from "next/navigation"; + +export default function PasswordInput() { + const [password, setPassword] = useState(["", "", "", ""]); + const [currentIndex, setCurrentIndex] = useState(0); + const [error, setError] = useState(false); + const inputRefs = useRef<(HTMLInputElement | null)[]>([]); + const router = useRouter(); + const { id, nonMemberId } = useParams(); + + const submitPassword = async () => { + const fullPassword = password.join(""); + console.log(password); + console.log("Password submitted:", fullPassword); + + try { + const response = await fetch( + "http://110.165.17.236:8081/api/v1/nonmembers/login", + { + method: "PUT", + headers: { + "Content-Type": "application/json", + Accept: "application/json", + }, + body: JSON.stringify({ + nonMemberId, + password: fullPassword, + }), + } + ); + + if (response.ok) { + router.push(`/event-maps/${id}/${nonMemberId}/load-mappin-edit`); + } else { + setError(true); + setPassword(["", "", "", ""]); + setCurrentIndex(0); + } + } catch (error) { + console.error("서버 오류:", error); + setError(true); + } + }; + + const handleInputChange = ( + e: React.ChangeEvent, + index: number + ) => { + const inputValue = e.target.value; + + if (/^\d$/.test(inputValue)) { + const newPass = [...password]; + newPass[index] = inputValue; + setPassword(newPass); + + if (index < password.length - 1) { + setCurrentIndex(index + 1); + } + } + }; + + const handleKeyDown = ( + e: React.KeyboardEvent, + index: number + ) => { + if (e.key === "Backspace") { + const newPass = [...password]; + newPass[index] = ""; + + if (index > 0) { + setCurrentIndex(index - 1); + } + + setPassword(newPass); + setError(false); + } + }; + + useEffect(() => { + inputRefs.current[currentIndex]?.focus(); + }, [currentIndex]); + + return ( +
+
+
+ { + inputRefs.current[0] = el; + }} + type="text" + inputMode="numeric" + pattern="[0-9]*" + className="grow text-center w-full h-full bg-transparent outline-none text-2xl" + maxLength={1} + value={password[0]} + onChange={(e) => handleInputChange(e, 0)} + onKeyDown={(e) => handleKeyDown(e, 0)} + /> +
+
+ { + inputRefs.current[1] = el; + }} + type="text" + inputMode="numeric" + pattern="[0-9]*" + className="grow text-center w-full h-full bg-transparent outline-none text-2xl" + maxLength={1} + value={password[1]} + onChange={(e) => handleInputChange(e, 1)} + onKeyDown={(e) => handleKeyDown(e, 1)} + /> +
+
+ { + inputRefs.current[2] = el; + }} + type="text" + inputMode="numeric" + pattern="[0-9]*" + className="grow text-center w-full h-full bg-transparent outline-none text-2xl" + maxLength={1} + value={password[2]} + onChange={(e) => handleInputChange(e, 2)} + onKeyDown={(e) => handleKeyDown(e, 2)} + /> +
+
+ { + inputRefs.current[3] = el; + }} + type="text" + inputMode="numeric" + pattern="[0-9]*" + className="grow text-center w-full h-full bg-transparent outline-none text-2xl" + maxLength={1} + value={password[3]} + onChange={(e) => handleInputChange(e, 3)} + onKeyDown={(e) => handleKeyDown(e, 3)} + /> +
+
+ + {error && ( +

+ 비밀번호가 일치하지 않아요 +

+ )} + + +
+ ); +} diff --git a/fe/src/app/load-mappin-edit/components/Form.tsx b/fe/src/app/event-maps/[id]/[nonMemberId]/load-mappin-edit/components/Form.tsx similarity index 100% rename from fe/src/app/load-mappin-edit/components/Form.tsx rename to fe/src/app/event-maps/[id]/[nonMemberId]/load-mappin-edit/components/Form.tsx diff --git a/fe/src/app/load-mappin-edit/components/LinkField.tsx b/fe/src/app/event-maps/[id]/[nonMemberId]/load-mappin-edit/components/LinkField.tsx similarity index 100% rename from fe/src/app/load-mappin-edit/components/LinkField.tsx rename to fe/src/app/event-maps/[id]/[nonMemberId]/load-mappin-edit/components/LinkField.tsx diff --git a/fe/src/app/load-mappin-edit/page.tsx b/fe/src/app/event-maps/[id]/[nonMemberId]/load-mappin-edit/page.tsx similarity index 92% rename from fe/src/app/load-mappin-edit/page.tsx rename to fe/src/app/event-maps/[id]/[nonMemberId]/load-mappin-edit/page.tsx index daf4ba4..7e8a052 100644 --- a/fe/src/app/load-mappin-edit/page.tsx +++ b/fe/src/app/event-maps/[id]/[nonMemberId]/load-mappin-edit/page.tsx @@ -2,7 +2,7 @@ import React, { useState } from "react"; import Image from "next/image"; -import { useRouter } from "next/navigation"; +import { useRouter, useParams } from "next/navigation"; import ExitModal from "@/app/components/common/ExitModal"; import Form from "./components/Form"; @@ -10,6 +10,7 @@ export default function Page() { const [userName] = useState("규리"); const [isModalOpen, setIsModalOpen] = useState(false); const router = useRouter(); + const { id } = useParams(); const handleBackClick = () => { setIsModalOpen(true); @@ -20,7 +21,7 @@ export default function Page() { }; const handleExit = () => { - router.push("/map-page"); + router.push(`/event-maps/${id}`); }; return ( diff --git a/fe/src/app/pincheck-page/page.tsx b/fe/src/app/event-maps/[id]/[nonMemberId]/page.tsx similarity index 89% rename from fe/src/app/pincheck-page/page.tsx rename to fe/src/app/event-maps/[id]/[nonMemberId]/page.tsx index 30b1127..6d309a3 100644 --- a/fe/src/app/pincheck-page/page.tsx +++ b/fe/src/app/event-maps/[id]/[nonMemberId]/page.tsx @@ -1,7 +1,7 @@ "use client"; import Image from "next/image"; -import PasswordInput from "@/app/pincheck-page/components/PincheckInput"; +import PasswordInput from "./components/PincheckInput"; import NavBar from "@/app/components/common/Navigation"; export default function PasswordPage() { diff --git a/fe/src/app/event-maps/[id]/components/BottomDrawer.tsx b/fe/src/app/event-maps/[id]/components/BottomDrawer.tsx index 9478857..cea2095 100644 --- a/fe/src/app/event-maps/[id]/components/BottomDrawer.tsx +++ b/fe/src/app/event-maps/[id]/components/BottomDrawer.tsx @@ -127,6 +127,12 @@ export default function BottomDrawer({ router.push(`/event-maps/${id}/load-mappin`); }; + const handleEditBtn = () => { + if (selectedButton !== null) { + router.push(`/event-maps/${id}/${selectedButton}`); + } + }; + const handleShare = () => { if (navigator.share) { navigator.share({ url: window.location.href }).then().catch(); @@ -170,7 +176,11 @@ export default function BottomDrawer({
{eventName}
-
diff --git a/fe/src/app/eventcreate-page/page.tsx b/fe/src/app/eventcreate-page/page.tsx index 9b3f80b..7e3ad06 100644 --- a/fe/src/app/eventcreate-page/page.tsx +++ b/fe/src/app/eventcreate-page/page.tsx @@ -71,7 +71,7 @@ function EventCreatePage() { useEffect(() => { if (uuid && !isRedirecting) { setIsRedirecting(true); // 이동 시작 시 상태 설정 - router.push(`/map-page?uuid=${uuid}`); + router.push(`/event-maps/${uuid}`); } }, [uuid, isRedirecting, router]); diff --git a/fe/src/app/pincheck-page/components/PincheckInput.tsx b/fe/src/app/pincheck-page/components/PincheckInput.tsx deleted file mode 100644 index 423e649..0000000 --- a/fe/src/app/pincheck-page/components/PincheckInput.tsx +++ /dev/null @@ -1,114 +0,0 @@ -"use client"; - -import React, { - useRef, - useState, - useEffect, - useCallback, - useMemo, -} from "react"; -import { useRouter } from "next/navigation"; -import { v4 as uuidv4 } from "uuid"; - -export default function PasswordInput() { - const [password, setPassword] = useState(["", "", "", ""]); - const [currentIndex, setCurrentIndex] = useState(0); - const [error, setError] = useState(false); - const inputRefs = useRef<(HTMLInputElement | null)[]>([]); - const router = useRouter(); - - const correctPassword = useMemo(() => ["1", "2", "3", "4"], []); - - const checkPassword = useCallback( - (inputPassword: string[]) => { - if (inputPassword.every((char) => char !== "")) { - if (JSON.stringify(inputPassword) === JSON.stringify(correctPassword)) { - setError(false); - router.push("/editmappin-page"); - } else { - setError(true); - } - } - }, - [correctPassword, router] - ); - - const handleInputChange = ( - e: React.ChangeEvent, - index: number - ) => { - const inputValue = e.target.value; - - // 숫자만 허용 - if (/^\d$/.test(inputValue)) { - const newPass = [...password]; - newPass[index] = inputValue; - setPassword(newPass); - - if (index < password.length - 1) { - setCurrentIndex(index + 1); - } - - checkPassword(newPass); - } - }; - - const handleKeyDown = ( - e: React.KeyboardEvent, - index: number - ) => { - if (e.key === "Backspace") { - const newPass = [...password]; - newPass[index] = ""; - - if (index > 0) { - setCurrentIndex(index - 1); - } - - setPassword(newPass); - setError(false); - } - }; - - // 현재 인덱스의 입력 칸에 포커스 설정 - useEffect(() => { - inputRefs.current[currentIndex]?.focus(); - }, [currentIndex]); - - const inputKeys = useMemo(() => password.map(() => uuidv4()), [password]); - - return ( -
-
- {password.map((char, index) => ( -
- { - inputRefs.current[index] = el; - }} - type="text" - inputMode="numeric" - pattern="[0-9]*" - className="grow shrink basis-0 text-center w-full h-full bg-transparent outline-none text-2xl text-text-default" - maxLength={1} - value={char} - onChange={(e) => handleInputChange(e, index)} - onKeyDown={(e) => handleKeyDown(e, index)} - /> -
- ))} -
- - {error && ( -

- 비밀번호가 일치하지 않아요 -

- )} -
- ); -} From ab33840359f6388553588b3f317b7a484d98e4fa Mon Sep 17 00:00:00 2001 From: choihooo Date: Thu, 31 Oct 2024 05:04:40 +0900 Subject: [PATCH 2/2] =?UTF-8?q?[feat]=20#40=20eslint=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../[nonMemberId]/components/PincheckInput.tsx | 18 +++++++++--------- .../app/event-maps/[id]/[nonMemberId]/page.tsx | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/fe/src/app/event-maps/[id]/[nonMemberId]/components/PincheckInput.tsx b/fe/src/app/event-maps/[id]/[nonMemberId]/components/PincheckInput.tsx index d3683c6..27029d9 100644 --- a/fe/src/app/event-maps/[id]/[nonMemberId]/components/PincheckInput.tsx +++ b/fe/src/app/event-maps/[id]/[nonMemberId]/components/PincheckInput.tsx @@ -6,7 +6,7 @@ import { useRouter, useParams } from "next/navigation"; export default function PasswordInput() { const [password, setPassword] = useState(["", "", "", ""]); const [currentIndex, setCurrentIndex] = useState(0); - const [error, setError] = useState(false); + const [hasError, setHasError] = useState(false); // 변수명 변경 const inputRefs = useRef<(HTMLInputElement | null)[]>([]); const router = useRouter(); const { id, nonMemberId } = useParams(); @@ -35,13 +35,13 @@ export default function PasswordInput() { if (response.ok) { router.push(`/event-maps/${id}/${nonMemberId}/load-mappin-edit`); } else { - setError(true); + setHasError(true); // hasError로 변경 setPassword(["", "", "", ""]); setCurrentIndex(0); } } catch (error) { console.error("서버 오류:", error); - setError(true); + setHasError(true); // hasError로 변경 } }; @@ -75,7 +75,7 @@ export default function PasswordInput() { } setPassword(newPass); - setError(false); + setHasError(false); // hasError로 변경 } }; @@ -88,7 +88,7 @@ export default function PasswordInput() {
- {error && ( + {hasError && (

비밀번호가 일치하지 않아요

diff --git a/fe/src/app/event-maps/[id]/[nonMemberId]/page.tsx b/fe/src/app/event-maps/[id]/[nonMemberId]/page.tsx index 6d309a3..f6ac537 100644 --- a/fe/src/app/event-maps/[id]/[nonMemberId]/page.tsx +++ b/fe/src/app/event-maps/[id]/[nonMemberId]/page.tsx @@ -1,8 +1,8 @@ "use client"; import Image from "next/image"; -import PasswordInput from "./components/PincheckInput"; import NavBar from "@/app/components/common/Navigation"; +import PasswordInput from "./components/PincheckInput"; export default function PasswordPage() { return (