diff --git a/src/frontend/src/apis/course.ts b/src/frontend/src/apis/course.ts index 81f80d71..1cccc33c 100644 --- a/src/frontend/src/apis/course.ts +++ b/src/frontend/src/apis/course.ts @@ -1,6 +1,17 @@ import { courseResponseParams } from "@/types/course"; import { api } from "."; +export const postCourseBookmark = async (courseId: number) => { + const response = await api.post(`/course/${courseId}`); + return response.data; +}; + +// TODO: data 형식 수정 +export const uploadGpx = async (data: number) => { + const response = await api.post(`/course/uploadGpx`, { data }); + return response.data; +}; + export const getRecommendCourseData = async ({ lat, lon, @@ -10,3 +21,13 @@ export const getRecommendCourseData = async ({ }); return response.data; }; + +export const getLikesCourseData = async () => { + const response = await api.get(`/course/likes`); + return response.data; +}; + +export const getAllCourseData = async () => { + const response = await api.get(`/course/getAllCourse`); + return response.data; +}; diff --git a/src/frontend/src/apis/crew.ts b/src/frontend/src/apis/crew.ts new file mode 100644 index 00000000..b59939fc --- /dev/null +++ b/src/frontend/src/apis/crew.ts @@ -0,0 +1,117 @@ +import { + CrewGalleryDetailResponse, + CrewGalleryRequest, + CrewGalleryResponse, + CrewJoinResponse, + CrewMemberResponse, + CrewNoticeDetailResponse, + CrewNoticeRequest, + CrewNoticeResponse, + CrewResponse, +} from "@/types/crew"; +import { api } from "."; + +export const getCrewNotice = async ( + crewId: number +): Promise => { + const response = await api.get(`/crew/${crewId}/notice`); + return response.data; +}; + +export const postCrewNotice = async ({ + crewId, + data, +}: { + crewId: number; + data: CrewNoticeRequest; +}) => { + const response = await api.post(`/crew/${crewId}/notice`, { data }); + return response.data; +}; + +export const getCrewNoticeDetail = async ({ + crewId, + crewPostId, +}: { + crewId: number; + crewPostId: number; +}): Promise => { + const response = await api.get(`/crew/${crewId}/notice/${crewPostId}`); + return response.data; +}; + +export const JoinCrew = async (crewId: number): Promise => { + const response = await api.post(`/crew/${crewId}/join`); + return response.data; +}; + +export const CreateCrew = async (data: number) => { + const response = await api.post(`/crew/create`, { data }); + return response.data; +}; + +// 다른 크루 조회 api +export const getCrew = async (): Promise => { + const response = await api.get(`/crew`); + return response.data; +}; + +// 크루 멤버, 크루명, 포스팅 수 api +export const getCrewMember = async ( + crewId: number +): Promise => { + const response = await api.get(`/crew/${crewId}/member`); + return response.data; +}; + +export const getCrewGallery = async ( + crewId: number +): Promise => { + const response = await api.get(`/crew/${crewId}/gallery`); + return response.data; +}; + +export const getCrewGalleryDetail = async ( + crewId: number, + postId: number +): Promise => { + const response = await api.get(`/crew/${crewId}/gallery/${postId}`); + return response.data; +}; + +export const getCrewGalleryDetailComments = async ( + crewId: number, + postId: number +): Promise => { + const response = await api.get(`/crew/${crewId}/gallery/${postId}/comments`); + return response.data; +}; + +// 백엔드 확인 필요(multipart?) +export const postCrewGallery = async ({ + crewId, + data, +}: { + crewId: number; + data: CrewGalleryRequest; +}) => { + const response = await api.post(`/crew/${crewId}/gallery`, { data }); + return response.data; +}; + +export const postCrewGalleryComments = async ( + crewId: number, + postId: number, + content: string +) => { + const response = await api.post( + `/crew/${crewId}/gallery/${postId}/comments`, + { content } + ); + return response.data; +}; + +export const postCrewGalleryLike = async (crewId: number, postId: number) => { + const response = await api.post(`/crew/${crewId}/gallery/${postId}/like`); + return response.data; +}; diff --git a/src/frontend/src/apis/running.ts b/src/frontend/src/apis/running.ts new file mode 100644 index 00000000..270ce2c8 --- /dev/null +++ b/src/frontend/src/apis/running.ts @@ -0,0 +1,15 @@ +import { reviewRequest, runningRequest } from "@/types/running"; +import { api } from "."; + +export const postCourseReview = async ( + userCourseId: number, + data: reviewRequest +) => { + const response = await api.post(`/running/review/${userCourseId}`, { data }); + return response.data; +}; + +export const postRunningRecord = async (data: runningRequest) => { + const response = await api.post(`/running/record`, { data }); + return response.data; +}; diff --git a/src/frontend/src/components/common/KakaoMap.tsx b/src/frontend/src/components/common/KakaoMap.tsx index ac683ab5..4c581849 100644 --- a/src/frontend/src/components/common/KakaoMap.tsx +++ b/src/frontend/src/components/common/KakaoMap.tsx @@ -20,7 +20,7 @@ const KakaoMap = ({ selectedCourse, onClickCourse }: KakaoMapProps) => { lng: 127.0919, }); - // 경로 정보 상태 + // 추천 경로 정보 상태 const [state, setState] = useState({ center: { lat: 37.51265, lng: 127.0919 }, // 기본 위치 (잠실) // center: { lat: 37.5665, lng: 126.978 }, // 기본 위치 (서울 시청) @@ -37,8 +37,8 @@ const KakaoMap = ({ selectedCourse, onClickCourse }: KakaoMapProps) => { (position) => { // 현재 위치 설정 setCurrent({ - lat: 37.51265, - lng: 127.0919, + lat: 37.5665, + lng: 126.978, // lat: position.coords.latitude, // lng: position.coords.longitude, }); @@ -46,13 +46,13 @@ const KakaoMap = ({ selectedCourse, onClickCourse }: KakaoMapProps) => { setState((prev) => ({ ...prev, center: { - lat: 37.51265, - lng: 127.0919, + lat: 37.5665, + lng: 126.978, // lat: position.coords.latitude, // lng: position.coords.longitude, }, })); - fetchGpxData(position.coords.latitude, position.coords.longitude); + fetchGpxData(current.lat, current.lng); }, (err) => { setState((prev) => ({ @@ -120,6 +120,7 @@ const KakaoMap = ({ selectedCourse, onClickCourse }: KakaoMapProps) => { isLoading: false, })); } catch (err) { + console.log("실패"); // 실패시 setState((prev) => ({ ...prev, @@ -130,15 +131,10 @@ const KakaoMap = ({ selectedCourse, onClickCourse }: KakaoMapProps) => { }; getCurrentLocation(); + console.log(state); }, [state.isLoading]); const handlePolylineClick = (route: Route) => { - // 폴리라인 중심좌표 이동 - // const centerLat = - // route.path.reduce((sum, point) => sum + point.lat, 0) / route.path.length; - // const centerLng = - // route.path.reduce((sum, point) => sum + point.lng, 0) / route.path.length; - setState((prev) => ({ ...prev, // 폴리라인 시작좌표 이동 @@ -147,7 +143,12 @@ const KakaoMap = ({ selectedCourse, onClickCourse }: KakaoMapProps) => { // 선택한 폴리라인 값 업데이트 onClickCourse(route.id); + console.log("선택한 코스: ", route); + console.log("selected state: ", selectedCourse); + console.log("state: ", state); + setCourse(route.path); + // setSel }; return ( diff --git a/src/frontend/src/hooks/useCourse.ts b/src/frontend/src/hooks/useCourse.ts index a8c4b981..82420391 100644 --- a/src/frontend/src/hooks/useCourse.ts +++ b/src/frontend/src/hooks/useCourse.ts @@ -1,6 +1,36 @@ -import { getRecommendCourseData } from "@/apis/course"; +import { + getAllCourseData, + getLikesCourseData, + getRecommendCourseData, + postCourseBookmark, + uploadGpx, +} from "@/apis/course"; import { courseResponseParams } from "@/types/course"; -import { useQuery } from "@tanstack/react-query"; +import { useMutation, useQuery } from "@tanstack/react-query"; + +export const useCourseBookmarkPost = (courseId: number) => { + return useMutation({ + mutationFn: () => postCourseBookmark(courseId), + onSuccess: () => { + console.log("즐겨찾기 등록 성공"); + }, + onError: () => { + console.log("즐겨찾기 등록 실패"); + }, + }); +}; + +export const useUploadGpx = (data: number) => { + return useMutation({ + mutationFn: () => uploadGpx(data), + onSuccess: () => { + console.log("GPX 등록 성공"); + }, + onError: () => { + console.log("GPX 등록 실패"); + }, + }); +}; export const useRecommendCourseGet = ({ lat, lon }: courseResponseParams) => { return useQuery({ @@ -8,3 +38,17 @@ export const useRecommendCourseGet = ({ lat, lon }: courseResponseParams) => { queryFn: () => getRecommendCourseData({ lat, lon }), }); }; + +export const useLikesCourseGet = () => { + return useQuery({ + queryKey: ["like", "course"], + queryFn: getLikesCourseData, + }); +}; + +export const useAllCourseCourseGet = () => { + return useQuery({ + queryKey: ["all", "course"], + queryFn: getAllCourseData, + }); +}; diff --git a/src/frontend/src/hooks/useRunning.ts b/src/frontend/src/hooks/useRunning.ts new file mode 100644 index 00000000..0d63d7b5 --- /dev/null +++ b/src/frontend/src/hooks/useRunning.ts @@ -0,0 +1,30 @@ +import { postCourseReview, postRunningRecord } from "@/apis/running"; +import { reviewRequest, runningRequest } from "@/types/running"; +import { useMutation } from "@tanstack/react-query"; + +export const useCourseReviewPost = ( + userCourseId: number, + data: reviewRequest +) => { + return useMutation({ + mutationFn: () => postCourseReview(userCourseId, data), + onSuccess: () => { + console.log("리뷰 등록 성공"); + }, + onError: () => { + console.log("리뷰 등록 실패"); + }, + }); +}; + +export const useRunningRecordPost = (data: runningRequest) => { + return useMutation({ + mutationFn: () => postRunningRecord(data), + onSuccess: () => { + console.log("러닝 코스 등록 성공"); + }, + onError: () => { + console.log("러닝 코스 등록 실패"); + }, + }); +}; diff --git a/src/frontend/src/pages/Record/RecordPage.tsx b/src/frontend/src/pages/Record/RecordPage.tsx index 582d006d..b4a5d3ff 100644 --- a/src/frontend/src/pages/Record/RecordPage.tsx +++ b/src/frontend/src/pages/Record/RecordPage.tsx @@ -53,6 +53,11 @@ const RecordPage = () => { const selectedCourse = courseData.find( (course) => course.courseId === id ); + console.log("id", id); + + console.log("courseData", courseData); + + console.log("handleClick", selectedCourse); if (selectedCourse) { setSelectedCourse(selectedCourse); // 선택된 ID 업데이트 @@ -61,7 +66,11 @@ const RecordPage = () => { } }; - const { data } = useRecommendCourseGet({ lat: 37.5665, lon: 126.978 }); // 임의 좌표 + const { data } = useRecommendCourseGet({ + lat: 37.5665, + lon: 126.978, + }); // 임의 좌표 + // const { data } = useRecommendCourseGet({ lat: 37.5665, lon: 126.978 }); // 임의 좌표 useEffect(() => { // 나만의 추천코스 카테고리 diff --git a/src/frontend/src/types/crew.ts b/src/frontend/src/types/crew.ts new file mode 100644 index 00000000..c3128e7b --- /dev/null +++ b/src/frontend/src/types/crew.ts @@ -0,0 +1,96 @@ +export type CrewNoticeResponse = { + crewTitle: string; + crewProfileImage: string; + postCount: number; + memberCount: number; + noticePost: [ + { + crewPostId: number; + title: string; + author: string; + lastModified: string; + } + ]; +}; + +export type CrewNoticeRequest = { + title: string; + content: string; +}; + +export type CrewNoticeDetailResponse = { + title: string; + content: string; + author: string; + crewName: string; + createdDate: string; +}; + +export type CrewJoinResponse = { + passcode: number; +}; + +export type CrewCreateRequest = { + certificationImage: File; + profileImage: File; +}; + +export type CrewResponse = { + crewId: number; + profileImageUrl: string; + title: string; + memberCount: number; +}; + +export type Member = { + userId: number; + name: string; + profileUrl: string; + membershipDuration: string; + role: string; +}; + +export type CrewMemberResponse = { + crewTitle: string; + postCount: number; + memberCount: number; + members: Member[]; +}; + +// content 확정되면 수정 +export type Post = { + postId: number; + imageUrl: string; + content?: string; +}; + +export type CrewGalleryResponse = { + crewTitle: string; + postCount: number; + memberCount: number; + posts: Post[]; +}; + +export type CrewGalleryDetailResponse = { + postId: number; + authorNickName: string; + authorProfileUrl: string; + createdAt: string; + likeCount: number; + imageUrls: string[]; + content: string; +}; + +export type CrewGalleryDetaiCommentslResponse = { + commentId: number; + content: string; + authorName: string; + authorProfile: string; + createdAt: string; +}[]; + +// 백엔드 확인 필요(multipart) +export type CrewGalleryRequest = { + content: string; + images: File[]; +}; diff --git a/src/frontend/src/types/running.ts b/src/frontend/src/types/running.ts new file mode 100644 index 00000000..ae6fdc75 --- /dev/null +++ b/src/frontend/src/types/running.ts @@ -0,0 +1,20 @@ +export type reviewRequest = { + difficulty: string; // LOW, MEDIUM, HIGH + tagIds: number[]; // 해당하는 태그 id +}; + +export type runningRequest = { + gpxFile: File; // TODO: 수정 + distance: number; + duration: number; + pace: number; + courseId?: number; +}; + +export type runningResponse = { + userCourseId: number; + distance: number; + duration: number; + pace: number; + courseUrl: string; +};