Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[feat] 버전1 기능 API 연동 및 페이지 연결(업데이트 제외) #41

Merged
merged 2 commits into from
Oct 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
182 changes: 182 additions & 0 deletions fe/src/app/event-maps/[id]/[nonMemberId]/components/PincheckInput.tsx
Original file line number Diff line number Diff line change
@@ -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 [hasError, setHasError] = 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 {
setHasError(true); // hasError로 변경
setPassword(["", "", "", ""]);
setCurrentIndex(0);
}
} catch (error) {
console.error("서버 오류:", error);
setHasError(true); // hasError로 변경
}
};

const handleInputChange = (
e: React.ChangeEvent<HTMLInputElement>,
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<HTMLInputElement>,
index: number
) => {
if (e.key === "Backspace") {
const newPass = [...password];
newPass[index] = "";

if (index > 0) {
setCurrentIndex(index - 1);
}

setPassword(newPass);
setHasError(false); // hasError로 변경
}
};

useEffect(() => {
inputRefs.current[currentIndex]?.focus();
}, [currentIndex]);

return (
<div className="flex flex-col items-center">
<div className="inline-flex items-center justify-start gap-4 mb-4">
<div
className={`w-14 h-14 p-4 bg-[#f7f7f7] rounded-lg inline-flex items-center ${
hasError ? "border-2 border-primary-50" : ""
} ${currentIndex === 0 ? "border-2 border-gray-950" : ""}`}
>
<input
ref={(el) => {
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)}
/>
</div>
<div
className={`w-14 h-14 p-4 bg-[#f7f7f7] rounded-lg inline-flex items-center ${
hasError ? "border-2 border-primary-50" : ""
} ${currentIndex === 1 ? "border-2 border-gray-950" : ""}`}
>
<input
ref={(el) => {
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)}
/>
</div>
<div
className={`w-14 h-14 p-4 bg-[#f7f7f7] rounded-lg inline-flex items-center ${
hasError ? "border-2 border-primary-50" : ""
} ${currentIndex === 2 ? "border-2 border-gray-950" : ""}`}
>
<input
ref={(el) => {
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)}
/>
</div>
<div
className={`w-14 h-14 p-4 bg-[#f7f7f7] rounded-lg inline-flex items-center ${
hasError ? "border-2 border-primary-50" : ""
} ${currentIndex === 3 ? "border-2 border-gray-950" : ""}`}
>
<input
ref={(el) => {
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)}
/>
</div>
</div>

{hasError && (
<p className="text-primary-50 text-left w-full max-w-sm">
비밀번호가 일치하지 않아요
</p>
)}

<button
type="button"
onClick={submitPassword}
className="mt-4 px-6 py-2 bg-primary-50 text-white rounded-lg"
>
제출
</button>
</div>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@

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";

export default function Page() {
const [userName] = useState("규리");
const [isModalOpen, setIsModalOpen] = useState(false);
const router = useRouter();
const { id } = useParams();

const handleBackClick = () => {
setIsModalOpen(true);
Expand All @@ -20,7 +21,7 @@ export default function Page() {
};

const handleExit = () => {
router.push("/map-page");
router.push(`/event-maps/${id}`);
};

return (
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
"use client";

import Image from "next/image";
import PasswordInput from "@/app/pincheck-page/components/PincheckInput";
import NavBar from "@/app/components/common/Navigation";
import PasswordInput from "./components/PincheckInput";

export default function PasswordPage() {
return (
Expand Down
12 changes: 11 additions & 1 deletion fe/src/app/event-maps/[id]/components/BottomDrawer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -170,7 +176,11 @@ export default function BottomDrawer({
<div className="h-[62px] w-full pt-[16px] pb-[14px] pl-[20px] pr-[16px] flex justify-between text-lg text-grayscale-0 font-300">
<div className="truncate max-w-[210px]">{eventName}</div>
<div>
<button type="button" className="w-[32px] h-[32px]">
<button
type="button"
className="w-[32px] h-[32px]"
onClick={selectedButton !== null ? handleEditBtn : undefined}
>
<Image
src={
selectedButton !== null ? "/svg/edit.svg" : "/svg/refresh.svg"
Expand Down
14 changes: 10 additions & 4 deletions fe/src/app/event-maps/[id]/load-mappin/components/Form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,25 @@ interface FormProps {
export default function Form({ uuid }: FormProps) {
const [name, setName] = useState("");
const [pin, setPin] = useState(["", "", "", ""]);
const [mapLinks, setMapLinks] = useState<string[]>([]); // 빈 배열로 초기화
const [storeLinks, setStoreLinks] = useState<string[]>([]); // 빈 배열로 초기화
const [mapLinks, setMapLinks] = useState<string[]>([]);
const [storeLinks, setStoreLinks] = useState<string[]>([]);
const [isFormComplete, setIsFormComplete] = useState(false);
const [isTooltipVisible, setIsTooltipVisible] = useState(true);
const router = useRouter();

const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();

// 빈 문자열을 제거한 배열을 생성
const filteredMapLinks = mapLinks.filter((link) => link.trim() !== "");
const filteredStoreLinks = storeLinks.filter((link) => link.trim() !== "");

const requestBody = {
uuid,
name,
password: pin.join(""),
bookmarkUrls: mapLinks,
storeUrls: storeLinks,
bookmarkUrls: filteredMapLinks,
storeUrls: filteredStoreLinks,
};

try {
Expand All @@ -43,9 +47,11 @@ export default function Form({ uuid }: FormProps) {
);

if (response.ok) {
console.log(requestBody);
console.log("성공적으로 처리되었습니다.");
router.push(`/event-maps/${uuid}`);
} else {
console.log(requestBody);
console.log("요청에 실패했습니다. 상태 코드:", response.status);
}
} catch (error) {
Expand Down
3 changes: 2 additions & 1 deletion fe/src/app/event-maps/[id]/load-mappin/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,15 @@ export default function Page() {
const { id } = useParams();
const uuid = Array.isArray(id) ? id[0] : id;
const router = useRouter();

return (
<div className="w-full h-screen flex justify-center items-center">
<div className="max-w-[360px] w-full h-screen overflow-y-auto hide-scrollbar">
<div className="w-full h-[56px] p-[16px]">
<button
type="button"
className="w-[24px] h-[24px]"
onClick={() => router.push(`/event-maps/${uuid}`)}
onClick={() => router.back()} // 뒤로 가기 기능
>
<Image
src="/images/ArrowBack.svg"
Expand Down
19 changes: 13 additions & 6 deletions fe/src/app/event-maps/[id]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
"use client";

import React, { useEffect, useState } from "react";
import { useParams } from "next/navigation";
import { useParams, useRouter } from "next/navigation";
import Image from "next/image"; // 외부 라이브러리
import { a } from "@react-spring/web"; // 외부 라이브러리
import { useDrag } from "@use-gesture/react"; // 외부 라이브러리

import MapComponent from "./components/MapComponent"; // 내부 모듈
import BottomDrawer from "./components/BottomDrawer"; // 내부 모듈
import MapComponent from "./components/MapComponent";
import BottomDrawer from "./components/BottomDrawer";
import useDrawer from "./hooks/useDrawer"; // 내부 모듈
import { useLocationStore } from "./stores/useLocationStore"; // 내부 모듈
import { useMarkerStore } from "./load-mappin/stores/useMarkerStore"; // 내부 모듈
import { useMarkerStore } from "./load-mappin/stores/useMarkerStore";

interface NonMember {
nonMemberId: number;
Expand Down Expand Up @@ -41,6 +40,7 @@ export default function Page() {
const [data, setData] = useState<Data | null>(null);
const moveToLocation = useLocationStore((state) => state.moveToLocation);
const setCustomMarkers = useMarkerStore((state) => state.setCustomMarkers);
const router = useRouter();

useEffect(() => {
const fetchData = async () => {
Expand Down Expand Up @@ -82,6 +82,9 @@ export default function Page() {
}
}, [id, data, moveToLocation, setCustomMarkers]);

const handleBackbtn = () => {
router.push(`eventcreate-page`);
};
const bind = useDrag(
({ last, movement: [, my], memo = y.get() }) => {
if (last) {
Expand All @@ -104,7 +107,11 @@ export default function Page() {
return (
<div>
<div className="w-[100%] h-[56px] px-[16px] py-[8px] fixed z-10">
<button type="button" className="w-[40px] h-[40px]">
<button
type="button"
className="w-[40px] h-[40px]"
onClick={handleBackbtn}
>
<Image src="/svg/arrow-back.svg" alt="icon" width={40} height={40} />
</button>
</div>
Expand Down
2 changes: 1 addition & 1 deletion fe/src/app/eventcreate-page/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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]);

Expand Down
Loading
Loading