From c964f0989bd115dbb80a901fc595fe1dfc3e41d9 Mon Sep 17 00:00:00 2001 From: Hyeona01 Date: Wed, 4 Dec 2024 00:56:36 +0900 Subject: [PATCH] =?UTF-8?q?FE:=20[feat]=20=EB=A6=AC=EB=B7=B0=20=EC=9E=91?= =?UTF-8?q?=EC=84=B1=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80=20#148?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/record/CourseSection.tsx | 10 ++--- src/frontend/src/hooks/useRunning.ts | 11 +++++ src/frontend/src/pages/Review/ReviewPage.tsx | 6 --- .../src/pages/Running/RunningPage.tsx | 42 ++++++++++--------- .../src/store/useSelectedCourseStore.ts | 2 +- 5 files changed, 39 insertions(+), 32 deletions(-) diff --git a/src/frontend/src/components/record/CourseSection.tsx b/src/frontend/src/components/record/CourseSection.tsx index 2e5efb0..d1acc20 100644 --- a/src/frontend/src/components/record/CourseSection.tsx +++ b/src/frontend/src/components/record/CourseSection.tsx @@ -130,17 +130,17 @@ const CourseSection = ({ key={index} className="flex items-center justify-between gap-2" > -
+
{couseData.name}
-
+
"{couseData.description}"
-
-
+
+
{couseData.distance}km handleCourseClick(couseData.courseId)} @@ -148,7 +148,7 @@ const CourseSection = ({
{couseData.tags.map((tag) => ( -
+
#{tag}
))} diff --git a/src/frontend/src/hooks/useRunning.ts b/src/frontend/src/hooks/useRunning.ts index e36e636..e9a2220 100644 --- a/src/frontend/src/hooks/useRunning.ts +++ b/src/frontend/src/hooks/useRunning.ts @@ -1,5 +1,6 @@ import { postCourseReview, postRunningRecord } from "@/apis/running"; import useUserCourseIdStore from "@/store/useCourseId"; +import useSelectedCourseStore from "@/store/useSelectedCourseStore"; import { reviewRequest, runningRequest, @@ -12,10 +13,19 @@ export const useCourseReviewPost = ( userCourseId: number, data: reviewRequest ) => { + const navigate = useNavigate(); + const { setSelectedCourse } = useSelectedCourseStore(); + return useMutation({ mutationFn: () => postCourseReview(userCourseId, data), onSuccess: () => { + // 선택된 코스 초기화 + setSelectedCourse(null); + + // 후기 등록 성공 이후 동작 console.log("리뷰 등록 성공"); + alert("후기가 반영되었습니다!"); + navigate("/"); }, onError: () => { console.log("리뷰 등록 실패"); @@ -36,6 +46,7 @@ export const useRunningRecordPost = ( onSuccess: (data: runningResponse) => { console.log("러닝 코스 등록 성공"); console.log("userCourseId", data.userCourseId); + alert("러닝이 종료되었습니다! 오늘 러닝은 어떠셨나요?"); setUserCourseId(data.userCourseId); navigate(`/record/${id}/review/${data.userCourseId}`); diff --git a/src/frontend/src/pages/Review/ReviewPage.tsx b/src/frontend/src/pages/Review/ReviewPage.tsx index 19309b2..ea997f4 100644 --- a/src/frontend/src/pages/Review/ReviewPage.tsx +++ b/src/frontend/src/pages/Review/ReviewPage.tsx @@ -44,12 +44,6 @@ const ReviewPage = () => { }; const handleComplete = () => { - alert(`완료! - 난이도: ${difficulty} - 선택된 키워드: ${selectedKeywords - .map((index) => keywords[index]) - .join(", ")} - `); console.log(difficulty, selectedKeywords); mutate(); }; diff --git a/src/frontend/src/pages/Running/RunningPage.tsx b/src/frontend/src/pages/Running/RunningPage.tsx index a65b27f..21a2010 100644 --- a/src/frontend/src/pages/Running/RunningPage.tsx +++ b/src/frontend/src/pages/Running/RunningPage.tsx @@ -8,7 +8,8 @@ import { ReactComponent as EndIcon } from "@/assets/icons/EndIcon.svg"; import { ReactComponent as StopIcon } from "@/assets/icons/StopIcon.svg"; import { ReactComponent as RestartIcon } from "@/assets/icons/RestartIcon.svg"; import { useRunningRecordPost } from "@/hooks/useRunning"; -import { useNavigate, useParams } from "react-router-dom"; +import { useParams } from "react-router-dom"; +import { runningRequest } from "@/types/running"; const calculateDistance = (path: LatLng[]) => { if (path.length < 2) return 0; @@ -43,12 +44,10 @@ const formatTime = (seconds: number) => { return `${minutes}분 ${remainingSeconds}초`; }; -// 페이스를 숫자형태로 포맷 -const formatPace = (pace: string): number => { - const [minutes, seconds] = pace - .split("'") - .map((part) => parseInt(part.replace('"', "").trim())); - return minutes + seconds / 60; +const formatPace = (paceString: string): number => { + const [minutes, seconds] = paceString.split(/['"]/); + + return parseFloat(`${minutes}.${seconds}`); }; // gpx 파일로 변환 @@ -74,10 +73,8 @@ const convertToGPX = (path: LatLng[]): File => { const gpxXML = `${gpxHeader}${gpxData}${gpxFooter}`; - // Convert the GPX XML string to a Blob const blob = new Blob([gpxXML], { type: "application/gpx+xml" }); - // Create a File object from the Blob const gpxFile = new File([blob], "track.gpx", { type: "application/gpx+xml", }); @@ -86,8 +83,6 @@ const convertToGPX = (path: LatLng[]): File => { }; const RunningPage = () => { - const navigate = useNavigate(); - const { runningCourse } = useRunningCourseStore(); // 선택된 코스 const [state, setState] = useState([]); // 실시간 경로 리스트 const stateRef = useRef([]); // 최신 state를 참조하기 위한 ref @@ -98,14 +93,19 @@ const RunningPage = () => { const { id } = useParams(); + const formattedData: runningRequest = { + distance: distance, + duration: duration, + pace: formatPace(pace), // 포맷팅된 pace 값 + }; + + // 코스를 선택하고 뛰었다면 courseId 추가 + if (Number(id) !== 0) { + formattedData.courseId = Number(id); + } + const { mutate } = useRunningRecordPost( - { - distance: distance, - duration: duration, - pace: 1, // 포맷팅된 pace 값 - // pace: formatPace(pace), // 포맷팅된 pace 값 - courseId: Number(id), - }, + formattedData, convertToGPX(state), Number(id) ); @@ -115,12 +115,14 @@ const RunningPage = () => { }; const handleDone = () => { setIsPaused(true); - alert(` + console.log( + ` 러닝 기록 거리: ${distance.toFixed(2)} km 시간: ${formatTime(duration)} 평균 페이스: ${pace} 분/km - `); + ` + ); mutate(); }; diff --git a/src/frontend/src/store/useSelectedCourseStore.ts b/src/frontend/src/store/useSelectedCourseStore.ts index 056ac49..4e144a7 100644 --- a/src/frontend/src/store/useSelectedCourseStore.ts +++ b/src/frontend/src/store/useSelectedCourseStore.ts @@ -4,7 +4,7 @@ import { create } from "zustand"; // 코스 기록 화면의 추천코스/인기코스 등의 특정 코스 선택 정보(RouteResponse 타입) 저장소 type SelectedCourseStore = { selectedCourse: RouteResponse | null; - setSelectedCourse: (newSelectedCourse: RouteResponse) => void; // 코스 업데이트 + setSelectedCourse: (newSelectedCourse: RouteResponse | null) => void; // 코스 업데이트 }; const useSelectedCourseStore = create()((set) => ({