diff --git a/frontend/src/Pages/hobbytestresultpage/hobbytestresultpage.tsx b/frontend/src/Pages/hobbytestresultpage/hobbytestresultpage.tsx index ad0e4c3a..2c44e10e 100644 --- a/frontend/src/Pages/hobbytestresultpage/hobbytestresultpage.tsx +++ b/frontend/src/Pages/hobbytestresultpage/hobbytestresultpage.tsx @@ -2,7 +2,11 @@ import * as S from "./style"; import Header from "../../components/normal_header/nh"; import { useLocation, useNavigate } from "react-router-dom"; import Arrow from "../../assets/images/blackarrow.svg"; -import type { HobbyTestResponse, HobbyScoreResponse } from "../../types/hobby"; +import type { HobbyTestResponse, HobbyScoreResponse, ReviewAnswerResponse } from "../../types/hobby"; +import { useState } from "react"; +import { toast, ToastContainer } from "react-toastify"; +import { hobbyApi } from "../../api/hobby"; +import { authApi } from "../../api/auth"; const normalizeToRange = (value: number) => { return ((value + 1) / 4) * 4 - 2; @@ -14,6 +18,25 @@ export default function TestResult() { const { finalAverage, result } = location.state || {}; const testResult = result as HobbyTestResponse; + // 모달 상태 + const [isModalOpen, setIsModalOpen] = useState(false); + const [selectedHobby, setSelectedHobby] = useState(null); + const [reviewQuestion, setReviewQuestion] = useState(""); + const [activityReviewId, setActivityReviewId] = useState(null); + const [isLoading, setIsLoading] = useState(false); + + // 5개 카테고리 답변 + const [answers, setAnswers] = useState({ + socialAnswer: "", + learningAnswer: "", + planningAnswer: "", + focusAnswer: "", + creativityAnswer: "", + }); + + // 새로 추천된 취미 + const [newRecommendations, setNewRecommendations] = useState(null); + if (!finalAverage) return null; const categories = [ @@ -70,33 +93,74 @@ export default function TestResult() { - {testResult?.hobbyScores - ?.slice(0, 3) - .map((hobby: HobbyScoreResponse) => ( + {(newRecommendations ? [ + { hobbyName: newRecommendations.hobby1, hobbyId: undefined, distance: 0 }, + { hobbyName: newRecommendations.hobby2, hobbyId: undefined, distance: 0 }, + { hobbyName: newRecommendations.hobby3, hobbyId: undefined, distance: 0 }, + ] : testResult?.hobbyScores?.slice(0, 3))?.map((hobby: HobbyScoreResponse) => ( {hobby.hobbyName} { - // hobbyId가 없으면 임시 ID 사용 - const newActivity = { - activityId: hobby.hobbyId ?? Date.now(), - activityName: hobby.hobbyName, - activityStart: new Date().toISOString().slice(0, 10), - activityRecent: new Date().toISOString().slice(0, 10), - linkedHobbyId: hobby.hobbyId ?? Date.now(), - linkedHobbyName: hobby.hobbyName, - top: "480px", // 좌표값 예시 - left: "45%", - }; - - navigate("/mypage", { - state: { - newActivities: [newActivity], - }, - }); + onClick={async () => { + try { + setIsLoading(true); + // 1. 사용자 정보 가져오기 + const userRes = await authApi.findCurrentUser(); + if (!userRes.success) { + toast.error("로그인이 필요합니다."); + navigate("/login", { state: { from: "hobby-test" } }); + return; + } + + // 2. 취미 ID 찾기 (이름으로 전체 목록에서 검색) + const allHobbiesRes = await hobbyApi.findAllHobbies(); + if (!allHobbiesRes.success) { + toast.error("취미 정보를 가져오는데 실패했습니다."); + return; + } + + const foundHobby = allHobbiesRes.data.hobbies.find( + (h) => h.hobbyName === hobby.hobbyName + ); + + if (!foundHobby) { + toast.error("해당 취미를 찾을 수 없습니다."); + return; + } + + // 3. 활동 추가 API 호출 + const addRes = await hobbyApi.addActivity({ + hobbyId: foundHobby.hobbyId, + userEmail: userRes.data.userEmail, + }); + + if (addRes.success) { + toast.success(`${hobby.hobbyName} 활동이 나무에 추가되었습니다!`); + + // 4. 활동 리뷰 질문 생성 API 호출 + const reviewRes = await hobbyApi.createReviewQuestion({ + hobbyId: foundHobby.hobbyId, + }); + + if (reviewRes.success) { + setSelectedHobby({ ...hobby, hobbyId: foundHobby.hobbyId }); + setReviewQuestion(reviewRes.data.reviewQuestion); + setActivityReviewId(foundHobby.hobbyId); // hobbyId를 activityReviewId로 사용 + setIsModalOpen(true); + } + } else { + toast.error("활동 추가에 실패했습니다."); + } + } catch (error) { + console.error(error); + toast.error("오류가 발생했습니다."); + } finally { + setIsLoading(false); + } }} + disabled={isLoading} > - 나무에 추가 + {isLoading ? "처리중..." : "나무에 추가"} ))} @@ -108,6 +172,130 @@ export default function TestResult() { + + {/* 활동 리뷰 모달 */} + {isModalOpen && selectedHobby && ( + setIsModalOpen(false)}> + e.stopPropagation()}> + {selectedHobby.hobbyName} 활동 리뷰 + {reviewQuestion} + + + + + setAnswers({ ...answers, socialAnswer: e.target.value })} + /> + + + + + setAnswers({ ...answers, learningAnswer: e.target.value })} + /> + + + + + setAnswers({ ...answers, planningAnswer: e.target.value })} + /> + + + + + setAnswers({ ...answers, focusAnswer: e.target.value })} + /> + + + + + setAnswers({ ...answers, creativityAnswer: e.target.value })} + /> + + + + + setIsModalOpen(false)}>취소 + { + if (!selectedHobby.hobbyId || !activityReviewId) { + toast.error("리뷰 정보가 올바르지 않습니다."); + return; + } + + // 모든 답변이 입력되었는지 확인 + if (!answers.socialAnswer || !answers.learningAnswer || + !answers.planningAnswer || !answers.focusAnswer || + !answers.creativityAnswer) { + toast.error("모든 항목을 입력해주세요."); + return; + } + + try { + setIsLoading(true); + const userRes = await authApi.findCurrentUser(); + if (!userRes.success) { + toast.error("로그인이 필요합니다."); + return; + } + + const reviewRes = await hobbyApi.answerReview({ + activityReviewId: activityReviewId, + userEmail: userRes.data.userEmail, + hobbyId: selectedHobby.hobbyId, + socialAnswer: answers.socialAnswer, + learningAnswer: answers.learningAnswer, + planningAnswer: answers.planningAnswer, + focusAnswer: answers.focusAnswer, + creativityAnswer: answers.creativityAnswer, + }); + + if (reviewRes.success) { + toast.success("리뷰가 제출되었습니다! 새로운 취미를 추천합니다."); + setNewRecommendations(reviewRes.data); + setIsModalOpen(false); + // 답변 초기화 + setAnswers({ + socialAnswer: "", + learningAnswer: "", + planningAnswer: "", + focusAnswer: "", + creativityAnswer: "", + }); + } else { + toast.error("리뷰 제출에 실패했습니다."); + } + } catch (error) { + console.error(error); + toast.error("오류가 발생했습니다."); + } finally { + setIsLoading(false); + } + }} + > + {isLoading ? "제출중..." : "리뷰 제출"} + + + + + )} + + ); }