Skip to content

Commit

Permalink
FE: [feat] 리뷰 작성 기능 추가 #148
Browse files Browse the repository at this point in the history
  • Loading branch information
hyeona01 committed Dec 3, 2024
1 parent 6ecf0c6 commit c964f09
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 32 deletions.
10 changes: 5 additions & 5 deletions src/frontend/src/components/record/CourseSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -130,25 +130,25 @@ const CourseSection = ({
key={index}
className="flex items-center justify-between gap-2"
>
<div className="p-4 w-[70%] h-full bg-courseGradient rounded-[10px] overflow-hidden flex flex-col justify-center items-center">
<div className="p-4 w-[50%] h-full bg-courseGradient rounded-[10px] overflow-hidden flex flex-col justify-center items-center">
<div className="text-[#444] font-semibold">
{couseData.name}
</div>
<div className="text-[#444] text-sm">
<div className="text-[#444] text-sm text-center">
"{couseData.description}"
</div>
</div>

<div className="flex flex-col gap-4">
<div className="flex justify-end items-center gap-3">
<div className="w-[50%] flex flex-col gap-4">
<div className="flex justify-end items-center gap-3 text-3xl font-bold">
{couseData.distance}km
<CourseCTA
onClick={() => handleCourseClick(couseData.courseId)}
/>
</div>
<div className="flex flex-wrap justify-end gap-2">
{couseData.tags.map((tag) => (
<div className="bg-[#B1FF8C] p-1 rounded text-[14px] font-extralight">
<div className="bg-[#B1FF8C] px-2 rounded text-[14px] font-extralight">
#{tag}
</div>
))}
Expand Down
11 changes: 11 additions & 0 deletions src/frontend/src/hooks/useRunning.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { postCourseReview, postRunningRecord } from "@/apis/running";
import useUserCourseIdStore from "@/store/useCourseId";
import useSelectedCourseStore from "@/store/useSelectedCourseStore";
import {
reviewRequest,
runningRequest,
Expand All @@ -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("리뷰 등록 실패");
Expand All @@ -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}`);
Expand Down
6 changes: 0 additions & 6 deletions src/frontend/src/pages/Review/ReviewPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,6 @@ const ReviewPage = () => {
};

const handleComplete = () => {
alert(`완료!
난이도: ${difficulty}
선택된 키워드: ${selectedKeywords
.map((index) => keywords[index])
.join(", ")}
`);
console.log(difficulty, selectedKeywords);
mutate();
};
Expand Down
42 changes: 22 additions & 20 deletions src/frontend/src/pages/Running/RunningPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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 파일로 변환
Expand All @@ -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",
});
Expand All @@ -86,8 +83,6 @@ const convertToGPX = (path: LatLng[]): File => {
};

const RunningPage = () => {
const navigate = useNavigate();

const { runningCourse } = useRunningCourseStore(); // 선택된 코스
const [state, setState] = useState<LatLng[]>([]); // 실시간 경로 리스트
const stateRef = useRef<LatLng[]>([]); // 최신 state를 참조하기 위한 ref
Expand All @@ -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)
);
Expand All @@ -115,12 +115,14 @@ const RunningPage = () => {
};
const handleDone = () => {
setIsPaused(true);
alert(`
console.log(
`
러닝 기록
거리: ${distance.toFixed(2)} km
시간: ${formatTime(duration)}
평균 페이스: ${pace} 분/km
`);
`
);

mutate();
};
Expand Down
2 changes: 1 addition & 1 deletion src/frontend/src/store/useSelectedCourseStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<SelectedCourseStore>()((set) => ({
Expand Down

0 comments on commit c964f09

Please sign in to comment.