From 824242b696e495addeeaf64a7c849d2221d2ff2a Mon Sep 17 00:00:00 2001
From: happppi <102276917+hhbb0081@users.noreply.github.com>
Date: Thu, 8 Aug 2024 23:04:44 +0900
Subject: [PATCH 3/7] =?UTF-8?q?Feat:=20=EB=A9=A4=EB=B2=84=20=EC=B4=88?=
=?UTF-8?q?=EA=B8=B0=20=ED=94=84=EB=A1=9C=ED=95=84=20=EC=84=A4=EC=A0=95=20?=
=?UTF-8?q?=EC=98=88=EC=99=B8=20=EC=B2=98=EB=A6=AC=20=EC=B6=94=EA=B0=80?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/components/molecules/headerInfo/HeaderInfo.tsx | 6 +++++-
src/features/home/SetHome.tsx | 2 +-
.../info/manage/join/components/ManageJoinHeader.tsx | 2 --
src/hook/info/useMyCommentQuery.ts | 2 +-
src/hook/member/useMemberAuthQuery.ts | 6 +++---
5 files changed, 10 insertions(+), 8 deletions(-)
diff --git a/src/components/molecules/headerInfo/HeaderInfo.tsx b/src/components/molecules/headerInfo/HeaderInfo.tsx
index 0271756..bf5dcc5 100644
--- a/src/components/molecules/headerInfo/HeaderInfo.tsx
+++ b/src/components/molecules/headerInfo/HeaderInfo.tsx
@@ -45,7 +45,11 @@ export function HeaderInfo({
}: isHeaderInfo) {
const router = useRouter();
const saveData = useSelector((state: RootState) => state.club.children);
- const { data: loadData } = useMemberAuthQuery();
+ const { data: loadData, isError, error } = useMemberAuthQuery();
+ if (isError) {
+ console.log(error.response?.status);
+ if (error.response?.status) router.push('/user/onboarding');
+ }
if (loadData === undefined) return;
const clubInfo = saveData.memberId === -1 ? loadData.data : saveData;
return (
diff --git a/src/features/home/SetHome.tsx b/src/features/home/SetHome.tsx
index fce3fd9..83d58a2 100644
--- a/src/features/home/SetHome.tsx
+++ b/src/features/home/SetHome.tsx
@@ -38,7 +38,7 @@ const SetHome = () => {
return (
-
+
diff --git a/src/features/info/manage/join/components/ManageJoinHeader.tsx b/src/features/info/manage/join/components/ManageJoinHeader.tsx
index 285668e..2ba65b6 100644
--- a/src/features/info/manage/join/components/ManageJoinHeader.tsx
+++ b/src/features/info/manage/join/components/ManageJoinHeader.tsx
@@ -20,10 +20,8 @@ export default function ManageJoinHeader({
const mutationJoin = (type: boolean) => {
console.log(type, selectJoins);
if (type) {
- console.log("Calling acceptMutate");
acceptMutate(selectJoins);
} else {
- console.log("Calling denyMutate");
denyMutate(selectJoins);
}
}
diff --git a/src/hook/info/useMyCommentQuery.ts b/src/hook/info/useMyCommentQuery.ts
index 2a1d048..e7ec6b4 100644
--- a/src/hook/info/useMyCommentQuery.ts
+++ b/src/hook/info/useMyCommentQuery.ts
@@ -12,7 +12,7 @@ export const useMyCommentQuery = ({
sort="",
}: MyPostProps) => {
const clubId = FormatClubId();
- const myPostUrl = `/clubs/${clubId}/comment/my?page=${page}&size=${size}`;
+ const myPostUrl = `/clubs/${clubId}/posts/my-comment-list?page=${page}&size=${size}`;
return useQuery
>({
queryKey: ["postMyComment", { clubId, size, page, sort }],
queryFn: async () =>
diff --git a/src/hook/member/useMemberAuthQuery.ts b/src/hook/member/useMemberAuthQuery.ts
index 6b5aca7..4f85ceb 100644
--- a/src/hook/member/useMemberAuthQuery.ts
+++ b/src/hook/member/useMemberAuthQuery.ts
@@ -1,15 +1,15 @@
import { http } from "@/apis/http";
-import { CommonNoPageRes } from "@/types";
import { MemberAuthInfo } from "@/types/member";
import { FormatClubId } from "@/utils/extractPathElements";
import { useQuery } from "@tanstack/react-query";
+import { AxiosError, AxiosResponse } from "axios";
// 클럽 auth 조회
export const useMemberAuthQuery = () => {
const clubId = FormatClubId();
- return useQuery>({
+ return useQuery, AxiosError>({
queryKey: ["myClubAuth", [clubId]],
queryFn: async () => {
- const response = await http.get>(
+ const response = await http.get>(
`/clubs/${clubId}/member/my/auth`
);
return response;
From 247e47ee7ea7a8f315ce8cacb04dbfebc1e36007 Mon Sep 17 00:00:00 2001
From: KKangHHee
Date: Fri, 9 Aug 2024 21:58:23 +0900
Subject: [PATCH 4/7] =?UTF-8?q?Feat:=20=EB=AC=B4=ED=95=9C=20=EC=8A=A4?=
=?UTF-8?q?=ED=81=AC=EB=A1=A4=20=EA=B5=AC=ED=98=84?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/types/types.ts | 18 ++++-----
src/utils/useCustomInfiniteQuery.ts | 21 ++++++++++
src/utils/useScrollHandler.ts | 61 +++++++++++++++++++++++++++++
3 files changed, 91 insertions(+), 9 deletions(-)
create mode 100644 src/utils/useCustomInfiniteQuery.ts
create mode 100644 src/utils/useScrollHandler.ts
diff --git a/src/types/types.ts b/src/types/types.ts
index 8635a1e..7369776 100644
--- a/src/types/types.ts
+++ b/src/types/types.ts
@@ -1,10 +1,10 @@
export interface Pageable {
- pageNumber: number;
+ pageNumber: number; //현재 페이지 번호
pageSize: number;
sort: {
- empty: boolean;
- sorted: boolean;
- unsorted: boolean;
+ empty: boolean;
+ sorted: boolean;
+ unsorted: boolean;
};
offset: number;
paged: boolean;
@@ -16,14 +16,14 @@ export interface CommonPage {
content: T[];
pageable: Pageable;
last: boolean;
- totalPages: number;
+ totalPages: number; // 전체 페이지 번호
totalElements: number;
size: number;
number: number;
sort: {
- empty: boolean;
- sorted: boolean;
- unsorted: boolean;
+ empty: boolean;
+ sorted: boolean;
+ unsorted: boolean;
};
first: boolean;
numberOfElements: number;
@@ -31,7 +31,7 @@ export interface CommonPage {
}
export interface CommonRes {
- data: CommonPage
+ data: CommonPage;
}
export interface CommonNoPageRes {
diff --git a/src/utils/useCustomInfiniteQuery.ts b/src/utils/useCustomInfiniteQuery.ts
new file mode 100644
index 0000000..3465a55
--- /dev/null
+++ b/src/utils/useCustomInfiniteQuery.ts
@@ -0,0 +1,21 @@
+import { CommonPage } from "@/types";
+import { useInfiniteQuery } from "@tanstack/react-query";
+
+export function useCustomInfiniteQuery({
+ queryKey,
+ customQueryFn,
+}: {
+ queryKey: any;
+ customQueryFn: (pageParam: number) => Promise>;
+}) {
+ return useInfiniteQuery, Error>({
+ queryKey: queryKey,
+ queryFn: async ({ pageParam = 0 }) => customQueryFn(pageParam as number),
+ getNextPageParam: (lastPage) => {
+ return lastPage.last ? undefined : lastPage.pageable.pageNumber + 1;
+ },
+ retry: 3,
+ refetchOnWindowFocus: false,
+ initialPageParam: undefined,
+ });
+}
diff --git a/src/utils/useScrollHandler.ts b/src/utils/useScrollHandler.ts
new file mode 100644
index 0000000..c98d196
--- /dev/null
+++ b/src/utils/useScrollHandler.ts
@@ -0,0 +1,61 @@
+import { useEffect, useRef, useState } from "react";
+
+// export function useScrollHandler(onScrollEnd: () => void) {
+// return useCallback(
+// (e: React.UIEvent) => {
+// const target = e.currentTarget;
+// const isBottom =
+// target.scrollHeight - target.scrollTop <= target.clientHeight;
+// if (isBottom) {
+// console.log("끝");
+// onScrollEnd();
+// }
+// },
+// [onScrollEnd]
+// );
+// }
+
+export function useScrollHandler(onScrollEnd: () => void) {
+ const [isEnd, setIsEnd] = useState(false);
+ const observer = useRef(null);
+ const targetRef = useRef(null);
+
+ useEffect(() => {
+ if (!("IntersectionObserver" in window)) return; // IntersectionObserver 지원 확인용
+
+ const handleIntersect = ([entry]: IntersectionObserverEntry[]) => {
+ if (entry.isIntersecting) {
+ setIsEnd(true);
+ }
+ };
+
+ // IntersectionObserver를 초기화하고 handleIntersect 콜백 연결
+ observer.current = new IntersectionObserver(handleIntersect, {
+ root: null, // viewport를 root로 설정
+ rootMargin: "0px", // root와 대상 요소 사이의 여백 설정
+ threshold: 1.0, // 요소의 100%가 보일 때 트리거
+ });
+
+ const currentObserver = observer.current;
+ const targetElement = targetRef.current;
+
+ if (currentObserver && targetElement) {
+ currentObserver.observe(targetElement);
+ }
+
+ return () => {
+ if (currentObserver && targetElement) {
+ currentObserver.unobserve(targetElement);
+ }
+ };
+ }, []);
+
+ useEffect(() => {
+ if (isEnd) {
+ onScrollEnd();
+ setIsEnd(false);
+ }
+ }, [isEnd, onScrollEnd]);
+
+ return targetRef;
+}
From 604194987a2a66f6089aef40ffd232d9b45085f2 Mon Sep 17 00:00:00 2001
From: KKangHHee
Date: Fri, 9 Aug 2024 21:59:07 +0900
Subject: [PATCH 5/7] =?UTF-8?q?Docs:=20=EB=AC=B4=ED=95=9C=20=EC=8A=A4?=
=?UTF-8?q?=ED=81=AC=EB=A1=A4=20=EC=A0=81=EC=9A=A9(=EB=8C=93=EA=B8=80,=20?=
=?UTF-8?q?=EA=B2=8C=EC=8B=9C=EA=B8=80)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../molecules/commentList/CommentList.tsx | 39 ++++++++++-----
src/features/board/components/Board.css | 2 +-
src/features/board/components/Board.tsx | 48 +++++++++++--------
src/features/board/components/BoardDetail.css | 3 +-
src/features/board/components/BoardList.tsx | 6 +--
src/hook/comment/useCommentsQuery.ts | 33 ++++++-------
src/hook/post/usePostListQuery.ts | 31 ++++++------
7 files changed, 90 insertions(+), 72 deletions(-)
diff --git a/src/components/molecules/commentList/CommentList.tsx b/src/components/molecules/commentList/CommentList.tsx
index fde9bbb..93d084b 100644
--- a/src/components/molecules/commentList/CommentList.tsx
+++ b/src/components/molecules/commentList/CommentList.tsx
@@ -4,14 +4,17 @@ import { Text } from "@/components/atoms/text";
import useCommentsQuery from "@/hook/comment/useCommentsQuery";
import { CommentsListProps } from "@/types/comment";
import { FormatClubId, FormatPostId } from "@/utils/extractPathElements";
+import { useScrollHandler } from "@/utils/useScrollHandler";
import React, { useImperativeHandle, useState } from "react";
export const CommentList = React.forwardRef(
({ commentCount }: CommentsListProps, ref) => {
- const { data: commentList } = useCommentsQuery({
+ const {
+ data: commentList,
+ fetchNextPage,
+ hasNextPage,
+ } = useCommentsQuery({
clubId: FormatClubId(),
postId: FormatPostId(),
- size: 100,
- page: 0,
});
const [targetComment, setTargetComment] = useState(
undefined
@@ -22,9 +25,14 @@ export const CommentList = React.forwardRef(
const handleOffTargetComment = () => {
setTargetComment(undefined);
};
+ const handleMoreNextComment = () => {
+ if (hasNextPage) fetchNextPage();
+ };
+ const targetRef = useScrollHandler(handleMoreNextComment);
useImperativeHandle(ref, () => ({
handleOffTargetComment: () => handleOffTargetComment(),
})); //부모 컴포넌트로 토스
+
return (
<>
@@ -35,16 +43,21 @@ export const CommentList = React.forwardRef(
- {commentList?.data.content &&
- commentList.data.content.slice().map((comment, index: number) => (
-
-
-
- ))}
+ {commentList?.pages.flatMap((page) => page.content) &&
+ commentList?.pages
+ .flatMap((page) => page.content)
+ .slice()
+ .map((comment, index: number) => (
+
+
+
+ ))}
+
+ {/* 해당을 통해 끝라인 확인 */}
-
+
- {data?.data.content.map((item, index) => (
-
- ))}
+ {data?.pages
+ .flatMap((page) => page.content)
+ .map((item, index) => (
+
+ ))}
+
+ {/* 해당을 통해 끝라인 확인 */}
{
const { data: noticeList } = usePostListQuery({
category: "NOTICE",
- page: 0,
size: 7,
});
const { data: freeList } = usePostListQuery({
category: "FREE",
- page: 0,
size: 7,
});
return (
@@ -21,12 +19,12 @@ const BoardList = () => {
page.content)}
/>
page.content)}
/>
);
diff --git a/src/hook/comment/useCommentsQuery.ts b/src/hook/comment/useCommentsQuery.ts
index 5140d17..98a20c5 100644
--- a/src/hook/comment/useCommentsQuery.ts
+++ b/src/hook/comment/useCommentsQuery.ts
@@ -1,28 +1,23 @@
import { http } from "@/apis/http";
import { commentKeys } from "@/constants/keys/postKey";
-import { CommonRes } from "@/types";
+import { CommonPage, CommonRes } from "@/types";
import { Comment } from "@/types/comment";
import { PostDetailProps } from "@/types/post";
-import { useQuery } from "@tanstack/react-query";
+import { useCustomInfiniteQuery } from "@/utils/useCustomInfiniteQuery";
-interface commentListProps extends PostDetailProps {
- size: number;
- page: number;
-}
+export const useCommentsQuery = ({ clubId, postId }: PostDetailProps) => {
+ const size = 10;
-export const useCommentsQuery = ({
- clubId,
- postId,
- size,
- page,
-}: commentListProps) => {
- return useQuery
>({
+ const getCommentList = async (page: number): Promise> => {
+ const response = await http.get>(
+ `/clubs/${clubId}/comment/${postId}?size=${size}&page=${page}`
+ );
+ const data = await response;
+ return data.data;
+ };
+ return useCustomInfiniteQuery({
queryKey: [commentKeys.comment({ clubId, postId })],
- queryFn: async () =>
- await http.get>(
- `/clubs/${clubId}/comment/${postId}?size=${size}&page=${page}`
- ),
+ customQueryFn: getCommentList,
});
};
-
-export default useCommentsQuery;
+export default useCommentsQuery;
\ No newline at end of file
diff --git a/src/hook/post/usePostListQuery.ts b/src/hook/post/usePostListQuery.ts
index e988376..de37018 100644
--- a/src/hook/post/usePostListQuery.ts
+++ b/src/hook/post/usePostListQuery.ts
@@ -1,39 +1,40 @@
"use client";
-
import { http } from "@/apis/http";
-import { CommonRes } from "@/types";
+import { CommonPage, CommonRes } from "@/types";
import { PostList } from "@/types/post";
import { FormatClubId } from "@/utils/extractPathElements";
-import { useQuery } from "@tanstack/react-query";
+import { useCustomInfiniteQuery } from "@/utils/useCustomInfiniteQuery";
interface props {
keyword?: string;
category: "NOTICE" | "FREE";
startData?: string;
endData?: string;
- page: number;
- size: number;
+ size?: number;
sort?: string;
}
+
export const usePostListQuery = ({
keyword = "",
category,
startData,
endData,
- page,
- size,
+ size = 10,
sort = "string",
}: props) => {
const clubId = FormatClubId();
- const keywordUrl = `/clubs/${clubId}/posts?keyword=${keyword}&sortBy=createAt&category=${category}&page=${page}&size=${size}`;
- const datePullUrl = `/clubs/${clubId}/posts?keyword=${keyword}&startDate=${startData}&endData=${endData}&sortBy=createAt&page=${page}&size=${size}`;
- return useQuery>({
- queryKey: ["postList", { clubId, category, size, page, sort }],
- queryFn: async () =>
- await http.get>(keywordUrl, {
- headers: { accept: "*/*" },
- }),
+ const getPostList = async (page: number): Promise> => {
+ const response = await http.get>(
+ `/clubs/${clubId}/posts?keyword=${keyword}&sortBy=createAt&category=${category}&page=${page}&size=${size}`
+ );
+ const data = await response;
+ return data.data;
+ };
+ return useCustomInfiniteQuery({
+ queryKey: ["postList", { clubId, category, size, sort }],
+ customQueryFn: getPostList,
});
};
+
export default usePostListQuery;
From 298f4d17f3bf275b550f3a37622b8636a0a9d52b Mon Sep 17 00:00:00 2001
From: happppi <102276917+hhbb0081@users.noreply.github.com>
Date: Fri, 9 Aug 2024 23:11:19 +0900
Subject: [PATCH 6/7] =?UTF-8?q?Feat:=20=EB=82=B4=EA=B0=80=20=EC=93=B4=20?=
=?UTF-8?q?=EB=8C=93=EA=B8=80=20api=20=EC=97=B0=EB=8F=99?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../info/board/comment/InfoBoardComment.tsx | 35 +++++++++-------
.../components/RealnameOnboarding.tsx | 37 +++++++++++++----
src/hook/info/useMyCommentQuery.ts | 9 ++--
src/hook/member/useMemberProfileMutation.ts | 35 ++++++++++++++++
src/types/info/types.ts | 41 +++++++++++++++++++
5 files changed, 128 insertions(+), 29 deletions(-)
create mode 100644 src/hook/member/useMemberProfileMutation.ts
diff --git a/src/features/info/board/comment/InfoBoardComment.tsx b/src/features/info/board/comment/InfoBoardComment.tsx
index 9f7918d..054cfce 100644
--- a/src/features/info/board/comment/InfoBoardComment.tsx
+++ b/src/features/info/board/comment/InfoBoardComment.tsx
@@ -25,21 +25,26 @@ export const InfoBoardComment = () => {
Loading...
:
(
- {commentInfo?.data?.content?.map((item: any) => (
-
- ))}
+ {commentInfo
+ ?.data
+ ?.myCommentList
+ ?.content
+ ?.map((item: any) => (
+
+ ))
+ }
)
}
diff --git a/src/features/user/onboarding/components/RealnameOnboarding.tsx b/src/features/user/onboarding/components/RealnameOnboarding.tsx
index bceb363..f57a315 100644
--- a/src/features/user/onboarding/components/RealnameOnboarding.tsx
+++ b/src/features/user/onboarding/components/RealnameOnboarding.tsx
@@ -3,27 +3,46 @@ import { FileUpload } from "@/components/atoms/fileUpload";
import { Text } from "@/components/atoms/text";
import { InputBox } from "@/components/molecules/inputBox";
import { Wrapper } from "@/components/organisms/Wrapper";
+import { useMemberProfileMutation } from "@/hook/member/useMemberProfileMutation";
import { COLORS } from "@/styles";
-import React from "react";
+import React, { useState } from "react";
import { useForm } from "react-hook-form";
import { ONBOARDING_BTN, ONBOARDING_INPUT_ARR } from "../constants/const";
interface FormData {
- name: string;
- introduce: string;
- emailPublic: boolean;
- mobilePublic: boolean;
+ memberName: string;
+ memberIntro: string;
+ profileImage: string | File;
+ isEmailPublic: boolean;
+ isPhonePublic: boolean;
}
const RealnameOnboarding = () => {
- const methods = useForm({
- mode: 'onChange'
+ const { control, handleSubmit, setValue } =
+ useForm({
+ mode: "onChange",
+ defaultValues: {
+ memberName: '',
+ memberIntro: '',
+ profileImage: '',
+ isEmailPublic: false,
+ isPhonePublic: false,
+ }
});
+ const [imageUrl, setImageUrl] = useState();
+ const handleChangeImage = (e: React.ChangeEvent) => {
+ const files = e.target.files;
+ if (!files || files.length === 0) return;
+ const selectedFile = files[0];
+ const newImageUrl = URL.createObjectURL(selectedFile);
+ setImageUrl(newImageUrl);
+ setValue("profileImage", selectedFile);
+ };
- const { handleSubmit, control } = methods;
-
+ const { mutate } = useMemberProfileMutation()
const submitOnboarding = (data: FormData) => {
console.log(data);
+ // mutate(data);
}
return (