From 2453fcf37f4387c7232f53141b22a03826297837 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=EC=A4=80=EC=98=81?= Date: Wed, 1 Apr 2026 23:01:18 +0900 Subject: [PATCH 1/4] =?UTF-8?q?[=EB=B0=B0=ED=8F=AC]=20=EC=9D=B4=EB=AF=B8?= =?UTF-8?q?=EC=A7=80=20=EC=A0=84=EC=B2=98=EB=A6=AC,=20=EA=B4=91=EA=B3=A0?= =?UTF-8?q?=20=EA=B8=B0=EB=8A=A5,=20=ED=95=98=EB=8B=A8=EB=B0=94=20?= =?UTF-8?q?=EB=A6=AC=EB=94=94=EC=9E=90=EC=9D=B8,=20=EC=9D=B8=EC=95=B1=20?= =?UTF-8?q?=EC=95=8C=EB=A6=BC=20=ED=8E=98=EC=9D=B4=EC=A7=80=20=EB=B0=8F=20?= =?UTF-8?q?=ED=86=A0=EC=8A=A4=ED=8A=B8=20=ED=94=84=EB=A1=9C=EB=8D=95?= =?UTF-8?q?=EC=85=98=20=EB=B0=B0=ED=8F=AC=20(#230)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 205 feat 이미지 전처리 기능 구현 (#206) * feat: 전처리 로직 및 WebWorker 구현 * feat: 전처리 적용 및 preview 동시성 제어 로직 추가 * refactor: 리뷰 반영 * [hotfix] 하단바 너비 수정 (#208) * hotfix: 하단바 너비 수정 * chore: 불필요한 값 제거 * refactor: 고정 gap 제거 * Reapply "[feat] 광고 배너 추가 (#200)" This reverts commit c51ec851fd4f7a404fca567e383847c4c9cf6b1c. * [feat] 하단바 리디자인 (#213) * chore: asset 추가 * feat: 하단바 리디자인 반영 및 레이아웃 수정 * [refactor] 광고 카드 레이아웃 밀림 수정 (#215) * refactor: 광고 개수 측정 시기 변경 및 기본값 제거 * feat: 스켈레톤 UI 추가 * feat: 인앱 알림 페이지 및 토스트 구현 (#217) * feat: 알림 API 및 스트림 기반 추가 * feat: 인앱 알림 레이어 추가 * feat: 알림 페이지 및 헤더 진입 구현 * fix: 알림 스트림 401 재시도 조건 정리 * fix: 알림 목록 이동 차단 제거 * refactor: 알림 공용 훅 위치 정리 * fix: 알림 재연결 캐시 동기화 추가 * fix: 알림 목록 토스트 큐 누적 방지 * fix: 알림 읽음 카운트 감소 조건 보강 * [refactor] 도메인별 TanStack Query 훅 정리 (#219) * chore: pwa용 이미지 제거 * refactor: auth 도메인 쿼리와 뮤테이션 정리 * refactor: council과 schedule 조회 훅 정리 * refactor: chat과 notification 캐시 처리 정리 * refactor: club 조회와 지원 플로우 정리 * refactor: manager 도메인 캐시 처리 정리 * refactor: studyTime 도메인 쿼리와 뮤테이션 정리 * refactor: 광고와 업로드 도메인 훅 정리 * [refactor] mutaton query 및 hook 추가 수정 (#221) * refactor: auth와 user myInfo 훅 정리 * refactor: club과 schedule 조회 훅 정리 * refactor: chat과 notification 훅 구조 정리 * refactor: club 지원 뮤테이션 훅 정리 * refactor: manager 뮤테이션 훅 구조 정리 * refactor: mutation 훅 cache 정리 * refactor: 컨벤션 통일 * refactor: isRead 조건 정리 * fix: 채팅 스크롤 문제 수정 * refactor: 불필요한 코드 제거 * [fix] 모바일 환경 입력창과 키보드 간의 간격이 큰 문제 수정 (#223) * chore: 가공용 safeArea 변수 선언 * refactor: 고정 패딩 값 수정 및 safeArea 적용 변경 * feat: 키보드 활성화 감지 및 safeArea 적용 여부 기능 추가 * refactor: 매직넘버 상수화 및 가로모드 처리 * [fix] 키보드 활성화 시 화면 흔들림 문제 수정 (#225) * refactor: 채팅 viewport 훅 네이밍 정리 * refactor: viewport 높이 잠금 훅 적용 시점 조정 * [fix] 키보드 활성화 시 채팅 화면 전체가 흔들리는 문제 수정 (#227) * refactor: 채팅 viewport 훅 네이밍 정리 * refactor: viewport 높이 잠금 훅 적용 시점 조정 * fix: 채팅 화면 스크롤 잠금으로 키보드 흔들림 완화 * fix: 입력 포커스 중 viewport offset 고정 (#229) * fix: 문서 루트 스크롤 잠금으로 빈 공간 잔류 방지 (#232) * [fix] 키보드 활성화 시 채팅 화면 상단 고정이 깨지고 빈 공간이 남는 문제 수정 (#234) * fix: 채팅 화면 상단 고정 깨짐과 빈 공간 잔류 수정 * refactor: 라우트 조건 수정 * fix: 문서 스크롤 위치 감지 보강 * refactor: 입력 요소 판별 유틸과 스크롤 주석 정리 * [fix] 키보드 활성화 시 채팅 화면에서 문서 스크롤이 발생하는 문제 수정 (#236) * fix: 채팅 문서 스크롤 제스처 차단 * fix: 입력 요소 터치 동작 예외 처리 * [fix] 키보드 활성화 시 채팅방이 마지막 메시지 위치를 유지하지 못하는 문제 수정 (#238) * fix: 키보드 활성화 시 채팅 하단 정렬 유지 * refactor: 채팅 리사이즈 관찰 안정화 * fix: mypage 연계 약관 페이지 뒤로가기 수정 (#240) * refactor: alias import 경로 정리 * fix: query 설정과 suspense 분기 정리 * refactor: 관리자 화면 스타일 유틸 정리 * fix: 이미지 전처리 예외 처리 보강 * fix: 헤더와 회비 화면 동작 정리 * fix: 공통 유틸 안정성 개선 * fix: 이미지 전처리 실패 처리를 보정 * fix: 모집 공고 저장 후 설정 반영 순서 조정 * fix: 부원 직책 변경 실패 처리를 보강 * fix: 약관 링크 접근성을 개선 * fix: 공통 쿼리와 유틸 안정성을 보완 * [feat] 동적 버전 정보 표시 구현 (#211) * feat: 동적 버전 정보 표시 구현 * refactor: 버전 정보 미 존재시 v 표시 제거 * [feat] 메인화면 동아리 카드 디자인 수정 반영 (#242) * feat: 메인화면 동아리 카드 디자인 수정 * chore: 하단바 아이콘 수정 * refactor: 코드래빗 리뷰 반영 * refactor: and 연산자로 변경 * apiClient 코드 중복 제거 및 네이티브 브릿지 인증 동기화 중앙화 (#244) * refactor: apiClient 코드 중복 제거 및 네이티브 브릿지 인증 동기화 중앙화 * refactor: body 직렬화 가드를 plain object/array로 한정 * fix: body 읽기 중 AbortError가 ParseError로 오분류되는 문제 수정 * [refactor] 에러 처리 유틸 및 utils 구조 정리 (#246) * refactor: 에러 처리 유틸 및 공통 토스트 흐름 정리 * refactor: utils 폴더 구조를 역할별로 정리 * refactor: 코드래빗 리뷰 반영 * refactor: 코드래빗 리뷰 반영 * Update src/pages/Home/components/HomeClubSection.tsx * fix: 인증 세션 복구 흐름 정리 * fix: 홈 동아리 카드 레이아웃 정리 * [feat] 총동아리 페이지 리디자인 및 하단 오버레이 정리 (#249) * refactor: 하단 오버레이 처리 공통화 * feat: 총동아리 페이지와 헤더 리디자인 반영 * fix: 채팅 하단 여백과 외부 링크 속성 수정 * refactor: 총동아리 헤더 설정 정리 * fix: 총동아리 상세 접근성과 스타일 보완 * [feat] 마이페이지 관리자 카드 분리 및 채팅 미확인 배지 반영 (#251) * feat: 하단 채팅 배지 표시 및 조회 조건 보완 * refactor: 관리자 정보 카드 컴포넌트 분리 * feat: 채팅 페이지 리디자인 (#252) * feat: 채팅 페이지 리디자인 * fix:tailwind 문법 수정 * fix: 코드 수정 * fix: 폰트 색상 및 위치 수정 * fix: 채팅방 사람수 정렬 * fix: 오타 수정 * chore: conflict 해결 중 누락된 부분 수정 * [refactor] 광고 렌더링 조건 수정 (#254) * refactor: 광고 렌더링 조건 수정 * docs: 문서명 변경 --------- Co-authored-by: 박성주 <145267904+ParkSungju01@users.noreply.github.com> --- ...uest_template => PULL_REQUEST_TEMPLATE.md} | 0 public/apple-touch-icon-180x180.png | Bin 345 -> 0 bytes public/maskable-icon-512x512.png | Bin 905 -> 0 bytes public/pwa-192x192.png | Bin 1080 -> 0 bytes public/pwa-512x512.png | Bin 2951 -> 0 bytes public/pwa-64x64.png | Bin 430 -> 0 bytes src/App.tsx | 16 +- src/apis/advertisement/entity.ts | 15 + src/apis/advertisement/index.ts | 19 ++ src/apis/advertisement/mutations.ts | 15 + src/apis/advertisement/queries.ts | 17 + src/apis/auth/index.ts | 18 +- src/apis/auth/mutations.ts | 32 ++ src/apis/auth/queries.ts | 27 ++ src/apis/chat/mutations.ts | 38 +++ src/apis/chat/queries.ts | 32 ++ src/apis/client.ts | 257 +++++++-------- src/apis/club/managedMutations.ts | 112 +++++++ src/apis/club/managedQueries.ts | 159 ++++++++++ src/apis/club/mutations.ts | 15 + src/apis/club/queries.ts | 117 +++++-- src/apis/council/queries.ts | 42 +++ src/apis/inquiry/mutations.ts | 14 + src/apis/notification/cache.ts | 77 +++++ src/apis/notification/entity.ts | 31 ++ src/apis/notification/index.ts | 25 +- src/apis/notification/mutations.ts | 19 ++ src/apis/notification/queries.ts | 34 ++ src/apis/schedule/queries.ts | 22 ++ src/apis/studyTime/hooks.ts | 33 ++ src/apis/studyTime/mutations.ts | 21 ++ src/apis/studyTime/queries.ts | 55 ++++ src/apis/university/queries.ts | 15 + src/apis/upload/mutations.ts | 15 + src/assets/image/bottom-nav-home.png | Bin 0 -> 11017 bytes src/assets/image/chat-cat-header.png | Bin 7444 -> 0 bytes .../image/notification-toast-approved.png | Bin 0 -> 39638 bytes .../image/notification-toast-general.png | Bin 0 -> 99225 bytes src/assets/svg/add_circle.svg | 8 + src/assets/svg/bottom-nav-chat.svg | 6 + src/assets/svg/bottom-nav-clubs.svg | 6 + src/assets/svg/bottom-nav-mypage.svg | 6 + src/assets/svg/bottom-nav-sms.svg | 8 + src/assets/svg/bottom-nav-timer.svg | 6 + src/assets/svg/chat-icon.svg | 8 + src/assets/svg/clock.svg | 2 +- src/assets/svg/instagram.svg | 2 +- src/assets/svg/location-pin.svg | 4 +- src/assets/svg/notifications.svg | 14 + src/assets/svg/person-icon.svg | 8 + src/assets/svg/unread-notification.svg | 19 ++ src/components/common/Portal.tsx | 6 +- src/components/layout/BottomNav/index.tsx | 130 ++++++-- src/components/layout/BottomOverlaySpacer.tsx | 24 ++ .../Header/components/BackTitleHeader.tsx | 50 +++ .../layout/Header/components/ChatHeader.tsx | 9 +- .../Header/components/ChatListHeader.tsx | 25 ++ .../Header/components/CouncilHeader.tsx | 27 -- .../layout/Header/components/InfoHeader.tsx | 5 +- .../Header/components/ManagerHeader.tsx | 24 +- .../Header/components/NotificationBell.tsx | 99 ++---- .../Header/components/PlainSubpageHeader.tsx | 11 + .../Header/components/SubpageHeader.tsx | 32 ++ src/components/layout/Header/constants.ts | 2 +- src/components/layout/Header/headerConfig.ts | 20 +- src/components/layout/Header/index.tsx | 14 +- src/components/layout/Header/presentation.ts | 45 +++ src/components/layout/Header/routeTitles.ts | 8 + src/components/layout/Header/types.ts | 6 +- src/components/layout/bottomOverlay.ts | 34 ++ .../hooks/useLayoutBottomOverlayInset.ts | 44 +++ .../layout/hooks/useLayoutElements.ts | 20 ++ src/components/layout/index.tsx | 72 +++-- .../notification/InAppNotificationToast.tsx | 70 +++++ .../notification/InboxNotificationLayer.tsx | 140 +++++++++ .../hooks/useInboxNotificationMutations.ts | 37 +++ .../hooks/useInboxNotificationStream.ts | 293 ++++++++++++++++++ src/contexts/useLayoutElementsContext.tsx | 20 ++ src/global.d.ts | 1 + src/index.css | 27 +- src/main.tsx | 6 +- src/pages/Auth/SignUp/ConfirmStep.tsx | 19 +- src/pages/Auth/SignUp/FinishStep.tsx | 13 +- src/pages/Auth/SignUp/StudentIdStep.tsx | 5 +- src/pages/Auth/SignUp/TermStep.tsx | 3 + src/pages/Auth/SignUp/UniversityStep.tsx | 5 +- .../Auth/SignUp/components/AgreementArrow.tsx | 9 +- src/pages/Auth/SignUp/hooks/useInquiry.ts | 12 - src/pages/Auth/SignUp/hooks/useSignup.ts | 14 - .../Auth/SignUp/hooks/useSignupPrefill.ts | 9 - src/pages/Auth/SignUp/hooks/useUniversity.ts | 14 - src/pages/Chat/ChatRoom.tsx | 15 +- src/pages/Chat/hooks/useChat.ts | 79 +---- src/pages/Chat/hooks/useChatMutations.ts | 39 +++ src/pages/Chat/hooks/useChatRoomScroll.ts | 35 +++ src/pages/Chat/hooks/useUnreadChatCount.ts | 12 +- src/pages/Chat/index.tsx | 138 ++++++++- .../Club/Application/applyCompletePage.tsx | 5 +- src/pages/Club/Application/clubFeePage.tsx | 26 +- .../Club/Application/hooks/useApplyToClub.ts | 21 +- .../Club/Application/hooks/useClubApply.ts | 22 +- .../Club/Application/hooks/useGetClubFee.ts | 10 - .../ClubDetail/components/ClubAccount.tsx | 5 +- .../Club/ClubDetail/components/ClubMember.tsx | 11 +- .../ClubDetail/components/ClubRecruitment.tsx | 12 +- .../ClubDetail/hooks/useCouncilNotices.ts | 21 -- .../Club/ClubDetail/hooks/useGetClubDetail.ts | 10 - .../ClubDetail/hooks/useGetClubMembers.ts | 11 - .../ClubDetail/hooks/useGetClubRecruitment.ts | 12 - src/pages/Club/ClubDetail/index.tsx | 5 +- .../ClubList/components/AdvertisementCard.tsx | 52 ++++ .../Club/ClubList/components/ClubCard.tsx | 5 +- src/pages/Club/ClubList/hooks/useGetClubs.ts | 35 --- src/pages/Club/ClubList/index.tsx | 47 ++- src/pages/Club/ClubSearch/index.tsx | 8 +- .../CouncilDetail/components/CouncilIntro.tsx | 86 ++--- .../components/CouncilNotice.tsx | 50 +-- .../CouncilDetail/hooks/useGetCouncilInfo.ts | 17 - src/pages/Council/CouncilDetail/index.tsx | 100 +++--- .../hooks/useCouncilNoticeDetail.ts | 12 +- src/pages/Council/CouncilNotice/index.tsx | 8 +- .../Home/components/CouncilNoticeSection.tsx | 5 +- src/pages/Home/components/HomeClubSection.tsx | 31 +- .../Home/components/InfiniteClubCarousel.tsx | 13 +- .../Home/components/MiniSchedulePreview.tsx | 5 +- .../Home/components/RecommendedClubCard.tsx | 10 +- src/pages/Home/hooks/useGetHomeClubs.ts | 40 +-- .../Home/hooks/useGetHomeCouncilNotices.ts | 14 - .../Home/hooks/useGetNotificationToken.ts | 10 - src/pages/Home/hooks/useGetScheduleList.ts | 11 - .../Home/hooks/useGetUpComingSchedule.ts | 10 - src/pages/Manager/ManagedAccount/index.tsx | 48 ++- .../ManagedApplicationDetail/index.tsx | 40 ++- .../Manager/ManagedApplicationList/index.tsx | 36 ++- src/pages/Manager/ManagedClubDetail/index.tsx | 4 +- src/pages/Manager/ManagedClubList/index.tsx | 9 +- .../Manager/ManagedClubProfile/index.tsx | 45 +-- .../ManagedMemberApplicationDetail/index.tsx | 8 +- src/pages/Manager/ManagedMemberList/index.tsx | 136 +++++--- .../Manager/ManagedRecruitment/index.tsx | 9 +- .../Manager/ManagedRecruitmentForm/index.tsx | 31 +- .../Manager/ManagedRecruitmentWrite/index.tsx | 115 +++---- .../components/ApplicationDetailContent.tsx | 9 +- .../Manager/components/DatePicker/index.tsx | 2 +- .../hooks/useManagedApplicationMutations.ts | 31 ++ .../Manager/hooks/useManagedApplications.ts | 130 +------- .../Manager/hooks/useManagedClubMutations.ts | 74 +++++ src/pages/Manager/hooks/useManagedClubs.ts | 48 --- src/pages/Manager/hooks/useManagedFee.ts | 45 --- .../hooks/useManagedMemberApplications.ts | 23 -- .../hooks/useManagedMemberMutations.ts | 81 +++++ src/pages/Manager/hooks/useManagedMembers.ts | 135 -------- .../Manager/hooks/useManagedRecruitment.ts | 72 ----- src/pages/Manager/hooks/useManagedSettings.ts | 27 -- src/pages/Notifications/index.tsx | 162 ++++++++++ .../Schedule/components/CalendarWeekRow.tsx | 2 +- .../Schedule/components/ScheduleDetail.tsx | 18 +- src/pages/Schedule/hooks/useGetSchedules.ts | 17 - src/pages/Schedule/index.tsx | 20 +- src/pages/Timer/components/RankingItem.tsx | 2 +- src/pages/Timer/components/TimerButton.tsx | 2 +- src/pages/Timer/hooks/useStudyTime.ts | 54 +--- src/pages/Timer/hooks/useStudyTimeRanking.ts | 30 +- src/pages/Timer/hooks/useStudyTimer.ts | 6 +- .../MyPage/components/ManagerInfoCard.tsx | 114 +++++++ .../User/MyPage/components/UserInfoCard.tsx | 155 ++------- src/pages/User/MyPage/hooks/useLogout.ts | 15 +- src/pages/User/MyPage/hooks/useWithdraw.ts | 8 +- src/pages/User/MyPage/index.tsx | 16 +- src/pages/User/Profile/hooks/useMyInfo.ts | 41 --- src/pages/User/Profile/hooks/useOAuthLinks.ts | 8 +- src/pages/User/Profile/index.tsx | 5 +- src/pages/User/hooks/useAdminChatMutation.ts | 4 +- src/stores/authStore.ts | 37 +-- src/utils/hooks/error/useApiErrorToast.ts | 19 ++ src/utils/hooks/{ => image}/useUploadImage.ts | 8 +- src/utils/hooks/useAdvertisementInterval.ts | 100 ++++++ src/utils/hooks/useAdvertisements.ts | 34 ++ src/utils/hooks/useKeyboardHeight.ts | 42 --- src/utils/hooks/useSmartBack.ts | 20 +- src/utils/hooks/useViewportHeight.ts | 39 --- src/utils/hooks/useViewportHeightLock.ts | 160 ++++++++++ src/utils/ts/accessToken.ts | 26 ++ src/utils/ts/{ => datetime}/calendar.ts | 0 src/utils/ts/{ => datetime}/date.ts | 0 src/utils/ts/{ => datetime}/time.ts | 0 src/utils/ts/dom.ts | 5 + .../error.ts => utils/ts/error/apiError.ts} | 44 ++- src/utils/ts/error/apiErrorMessage.ts | 33 ++ src/utils/ts/{ => error}/errorRedirect.ts | 0 src/utils/ts/{ => image}/imagePreprocessor.ts | 53 +++- .../{ => image}/imagePreprocessor.worker.ts | 0 src/utils/ts/nativeBridge.ts | 12 + src/utils/ts/notification.ts | 93 ++++++ src/utils/ts/promise.ts | 19 +- src/utils/ts/viewport.ts | 45 ++- 196 files changed, 4429 insertions(+), 2048 deletions(-) rename .github/ISSUE_TEMPLATE/{pull_request_template => PULL_REQUEST_TEMPLATE.md} (100%) delete mode 100644 public/apple-touch-icon-180x180.png delete mode 100644 public/maskable-icon-512x512.png delete mode 100644 public/pwa-192x192.png delete mode 100644 public/pwa-512x512.png delete mode 100644 public/pwa-64x64.png create mode 100644 src/apis/advertisement/entity.ts create mode 100644 src/apis/advertisement/index.ts create mode 100644 src/apis/advertisement/mutations.ts create mode 100644 src/apis/advertisement/queries.ts create mode 100644 src/apis/auth/mutations.ts create mode 100644 src/apis/auth/queries.ts create mode 100644 src/apis/chat/mutations.ts create mode 100644 src/apis/chat/queries.ts create mode 100644 src/apis/club/managedMutations.ts create mode 100644 src/apis/club/managedQueries.ts create mode 100644 src/apis/club/mutations.ts create mode 100644 src/apis/council/queries.ts create mode 100644 src/apis/inquiry/mutations.ts create mode 100644 src/apis/notification/cache.ts create mode 100644 src/apis/notification/entity.ts create mode 100644 src/apis/notification/mutations.ts create mode 100644 src/apis/notification/queries.ts create mode 100644 src/apis/schedule/queries.ts create mode 100644 src/apis/studyTime/hooks.ts create mode 100644 src/apis/studyTime/mutations.ts create mode 100644 src/apis/studyTime/queries.ts create mode 100644 src/apis/university/queries.ts create mode 100644 src/apis/upload/mutations.ts create mode 100644 src/assets/image/bottom-nav-home.png delete mode 100644 src/assets/image/chat-cat-header.png create mode 100644 src/assets/image/notification-toast-approved.png create mode 100644 src/assets/image/notification-toast-general.png create mode 100644 src/assets/svg/add_circle.svg create mode 100644 src/assets/svg/bottom-nav-chat.svg create mode 100644 src/assets/svg/bottom-nav-clubs.svg create mode 100644 src/assets/svg/bottom-nav-mypage.svg create mode 100644 src/assets/svg/bottom-nav-sms.svg create mode 100644 src/assets/svg/bottom-nav-timer.svg create mode 100644 src/assets/svg/chat-icon.svg create mode 100644 src/assets/svg/notifications.svg create mode 100644 src/assets/svg/person-icon.svg create mode 100644 src/assets/svg/unread-notification.svg create mode 100644 src/components/layout/BottomOverlaySpacer.tsx create mode 100644 src/components/layout/Header/components/BackTitleHeader.tsx create mode 100644 src/components/layout/Header/components/ChatListHeader.tsx delete mode 100644 src/components/layout/Header/components/CouncilHeader.tsx create mode 100644 src/components/layout/Header/components/PlainSubpageHeader.tsx create mode 100644 src/components/layout/Header/components/SubpageHeader.tsx create mode 100644 src/components/layout/Header/presentation.ts create mode 100644 src/components/layout/bottomOverlay.ts create mode 100644 src/components/layout/hooks/useLayoutBottomOverlayInset.ts create mode 100644 src/components/layout/hooks/useLayoutElements.ts create mode 100644 src/components/notification/InAppNotificationToast.tsx create mode 100644 src/components/notification/InboxNotificationLayer.tsx create mode 100644 src/components/notification/hooks/useInboxNotificationMutations.ts create mode 100644 src/components/notification/hooks/useInboxNotificationStream.ts create mode 100644 src/contexts/useLayoutElementsContext.tsx delete mode 100644 src/pages/Auth/SignUp/hooks/useInquiry.ts delete mode 100644 src/pages/Auth/SignUp/hooks/useSignup.ts delete mode 100644 src/pages/Auth/SignUp/hooks/useSignupPrefill.ts delete mode 100644 src/pages/Auth/SignUp/hooks/useUniversity.ts create mode 100644 src/pages/Chat/hooks/useChatMutations.ts delete mode 100644 src/pages/Club/Application/hooks/useGetClubFee.ts delete mode 100644 src/pages/Club/ClubDetail/hooks/useCouncilNotices.ts delete mode 100644 src/pages/Club/ClubDetail/hooks/useGetClubDetail.ts delete mode 100644 src/pages/Club/ClubDetail/hooks/useGetClubMembers.ts delete mode 100644 src/pages/Club/ClubDetail/hooks/useGetClubRecruitment.ts create mode 100644 src/pages/Club/ClubList/components/AdvertisementCard.tsx delete mode 100644 src/pages/Club/ClubList/hooks/useGetClubs.ts delete mode 100644 src/pages/Council/CouncilDetail/hooks/useGetCouncilInfo.ts delete mode 100644 src/pages/Home/hooks/useGetHomeCouncilNotices.ts delete mode 100644 src/pages/Home/hooks/useGetNotificationToken.ts delete mode 100644 src/pages/Home/hooks/useGetScheduleList.ts delete mode 100644 src/pages/Home/hooks/useGetUpComingSchedule.ts create mode 100644 src/pages/Manager/hooks/useManagedApplicationMutations.ts create mode 100644 src/pages/Manager/hooks/useManagedClubMutations.ts delete mode 100644 src/pages/Manager/hooks/useManagedClubs.ts delete mode 100644 src/pages/Manager/hooks/useManagedFee.ts delete mode 100644 src/pages/Manager/hooks/useManagedMemberApplications.ts create mode 100644 src/pages/Manager/hooks/useManagedMemberMutations.ts delete mode 100644 src/pages/Manager/hooks/useManagedMembers.ts delete mode 100644 src/pages/Manager/hooks/useManagedRecruitment.ts delete mode 100644 src/pages/Manager/hooks/useManagedSettings.ts create mode 100644 src/pages/Notifications/index.tsx delete mode 100644 src/pages/Schedule/hooks/useGetSchedules.ts create mode 100644 src/pages/User/MyPage/components/ManagerInfoCard.tsx delete mode 100644 src/pages/User/Profile/hooks/useMyInfo.ts create mode 100644 src/utils/hooks/error/useApiErrorToast.ts rename src/utils/hooks/{ => image}/useUploadImage.ts (58%) create mode 100644 src/utils/hooks/useAdvertisementInterval.ts create mode 100644 src/utils/hooks/useAdvertisements.ts delete mode 100644 src/utils/hooks/useKeyboardHeight.ts delete mode 100644 src/utils/hooks/useViewportHeight.ts create mode 100644 src/utils/hooks/useViewportHeightLock.ts create mode 100644 src/utils/ts/accessToken.ts rename src/utils/ts/{ => datetime}/calendar.ts (100%) rename src/utils/ts/{ => datetime}/date.ts (100%) rename src/utils/ts/{ => datetime}/time.ts (100%) create mode 100644 src/utils/ts/dom.ts rename src/{interface/error.ts => utils/ts/error/apiError.ts} (62%) create mode 100644 src/utils/ts/error/apiErrorMessage.ts rename src/utils/ts/{ => error}/errorRedirect.ts (100%) rename src/utils/ts/{ => image}/imagePreprocessor.ts (80%) rename src/utils/ts/{ => image}/imagePreprocessor.worker.ts (100%) create mode 100644 src/utils/ts/nativeBridge.ts create mode 100644 src/utils/ts/notification.ts diff --git a/.github/ISSUE_TEMPLATE/pull_request_template b/.github/ISSUE_TEMPLATE/PULL_REQUEST_TEMPLATE.md similarity index 100% rename from .github/ISSUE_TEMPLATE/pull_request_template rename to .github/ISSUE_TEMPLATE/PULL_REQUEST_TEMPLATE.md diff --git a/public/apple-touch-icon-180x180.png b/public/apple-touch-icon-180x180.png deleted file mode 100644 index a9fb25d343c0d32d8c5ef07e39c5da39cbde5357..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 345 zcmeAS@N?(olHy`uVBq!ia0vp^TR@nD8Ax&oe*=;Xq5(c3uK)l4H!?MP`R4tXZ{J(n zTeofB78V)SRk7L%sDQJ;BeIx*f%ydpGj6R8$_5I)@^o!?*M-`tbf4Qe7|L`BjT+@a6lhgI*wQ4(`Ul$``b;>LKqTs%o zlkTf;d8^LeHUH@5v-)?=#r4mMpPuZJ^t*g2BSXT(eOKb+=XloyzleDi?7vIwZTS59 zZ>btvE_`-s_dEa3`Gn8xOl|)cD{mk6;m-Acy=8a%%xjqo@7ngXU-$;%m|b?-T@7}1 Z{vQUfTrU5Yz1K`Zd{0+Dmvv4FO#n26lGXqK diff --git a/public/maskable-icon-512x512.png b/public/maskable-icon-512x512.png deleted file mode 100644 index 0c5779f0bc3fd5e2b5a8b74e039dc6483f8da17c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 905 zcmeAS@N?(olHy`uVBq!ia0y~yU;;9k7&w@L)Zt|+CxDbtfKQ0)|NsAuOpRW>{g9QD zRaQ~9ZTq&=trJ{;vYZ7Tk;M!Q%r8Kgacgx@Hjp9f>EaktaqI0}?yN%rBCZ#|&;388 zJ8bp>eK9Y=uWL*h6nE`4H{;Z01?nFdP{Eu#&!kc`%=o&)9!dtYDteugdWuD5r> z?;q#W;{NZwH)H45`O6%<|NmLcHRHSc{LllhKJ#lOtn0H|)$sIreD;ax3)kH37pXt^ zK3&1;{{q>H&wM?Ve;qBDKi}`$*Us0l(e&cyPxE)ronXXtEa}tP8JionS-h8wOlSOR z(a`YzfDPY*w0SJ=!yFEkCm8;(yEpMdyyNZ6fCPr$i}`=b)_gFwc&bxiV^PD%!}w$_ z3)h0Qxy&|P3D5pXnrJi#+A>Ff`Sbg!^@Yj$tSqrSFD|}6u;%9VLovK1rXODD9Qey{ zRMznwN0I-6YNorQZ`LK8XRXkC@LBjn%7v#V7X;bJJpaImJ=Fi@ePDU2`(IP%zZ(OS zKm!Ad0s|w51DF}-_MB7c-;yim_PFRUay)Rhvt^tClwb&BP-9>^z;%Gdfgu7Y!oi@; zAk4s+z?#6Mz_5k^tfm3PsNe*d6xP7t12%H#F%EDEG;lUBY+y2A#Nunl2Qt`$6kW7I Z{3EM#r=GHFyUa?EoTsaw%Q~loCICX|@(cg~ diff --git a/public/pwa-192x192.png b/public/pwa-192x192.png deleted file mode 100644 index 87c7b6de3d247b1f905785897c1676a70e3b4b68..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1080 zcmeAS@N?(olHy`uVBq!ia0vp^2SAvE8Azrw%`pX1S^+*Gu0ENC|1p4(snN?f?++h2 zY-MBh@$)~a_hkn@>bDb7m zs9$y@vZdqHx~P2tD#cb-Wj8I~v8xn`us%QB{J-tQZsR5AUF%txy$vUPh?Ltd79?103J6*nZ`|K#K z1zvTZm#cPvc(r}wq{heb9CNUwXvc8S{(pXjiSN;I_Zc{~+qj6WF_p0n9(bFg9TxGnc#k9bNv!_8t&d!1yxqvd?5`3yJ9+5S#- zUMX_l^2k4i8~NhZS5BXhKTsI-=b0$D84aU;`5a#{!Y( zb9ES)6bPXQ%Wi$&n>)dqA(Z!m|J_B2X4RS*bJ~kpg4Z+8*uAB~ga0OR*BT$#!uEpa-J*Tb z%syES-ObY&;u&8s)@d#}&rp*Ybp3$tM7w&wZ?jO##rd>QA?!DfTz;O1x@cy!dBWw<3 z4mQ^ueupq`5SeuCphO1WlV=xI5*Y4S$*`SmykawteGS_zc9lj;hqubBHZUxy^pKdr ze8+AX?`pQ7&kJmH*gXta32-TF=kGpJq@a1MROu>%CfhP6%L%5+*%KKiC1n^)VqPS5 znMjpQ8OCk!v$raxxbkX2#R$Gk-5K7TOtn&<@#j~g<=BNi~IJQWfYVc%5M%k9QH zp=u&u2eaq?QyfeUUr#SlkeQ(SdJjWZ!#14|=7I-%uXgx{-q@t* zW4yN`;_{6~!`!&sEUpcQi^780MXbA6SF+u@{@YF?)tUX1o%Xu53>t4Yr`$Qk_;=Dr z`RseS|E?z7p7p(0bwVna;QVc`+dljhxuyDtyD7p#p}MtxWvkEpwT!1;ZrMDk=1e2= zqWvmCYn4h&7 diff --git a/public/pwa-512x512.png b/public/pwa-512x512.png deleted file mode 100644 index 149b71f4abbcb532a4d624647241f86ceedcd365..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2951 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 W@H^gf8V4}o7(8A5T-G@yGywox(!e+X diff --git a/src/App.tsx b/src/App.tsx index 22798bf4..124be5cb 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -42,6 +42,7 @@ const ManagedMemberList = lazy(() => import('./pages/Manager/ManagedMemberList') const ManagedRecruitment = lazy(() => import('./pages/Manager/ManagedRecruitment')); const ManagedRecruitmentForm = lazy(() => import('./pages/Manager/ManagedRecruitmentForm')); const ManagedRecruitmentWrite = lazy(() => import('./pages/Manager/ManagedRecruitmentWrite')); +const NotificationsPage = lazy(() => import('./pages/Notifications')); const Schedule = lazy(() => import('./pages/Schedule')); const Timer = lazy(() => import('./pages/Timer')); const MyPage = lazy(() => import('./pages/User/MyPage')); @@ -84,6 +85,11 @@ function App() { }> }> } /> + } /> + + } /> + } /> + } /> @@ -97,6 +103,7 @@ function App() { } /> + } /> } /> } /> @@ -113,14 +120,7 @@ function App() { } /> } /> } /> - - } /> - } /> - - - } /> - } /> - + } /> diff --git a/src/apis/advertisement/entity.ts b/src/apis/advertisement/entity.ts new file mode 100644 index 00000000..4f7f826b --- /dev/null +++ b/src/apis/advertisement/entity.ts @@ -0,0 +1,15 @@ +export interface Advertisement { + id: number; + title: string; + description: string; + imageUrl: string; + linkUrl: string; +} + +export interface AdvertisementsRequestParams { + count?: number; +} + +export interface AdvertisementsResponse { + advertisements: Advertisement[]; +} diff --git a/src/apis/advertisement/index.ts b/src/apis/advertisement/index.ts new file mode 100644 index 00000000..fa8b52bd --- /dev/null +++ b/src/apis/advertisement/index.ts @@ -0,0 +1,19 @@ +import { apiClient } from '../client'; +import type { AdvertisementsRequestParams, AdvertisementsResponse } from './entity'; + +export const getAdvertisements = async (params: AdvertisementsRequestParams = {}) => { + const response = await apiClient.get('advertisements', { + params, + requiresAuth: true, + }); + + return response; +}; + +export const postAdvertisementClick = async (advertisementId: number) => { + const response = await apiClient.post(`advertisements/${advertisementId}/clicks`, { + requiresAuth: true, + }); + + return response; +}; diff --git a/src/apis/advertisement/mutations.ts b/src/apis/advertisement/mutations.ts new file mode 100644 index 00000000..65f4f340 --- /dev/null +++ b/src/apis/advertisement/mutations.ts @@ -0,0 +1,15 @@ +import { mutationOptions } from '@tanstack/react-query'; +import { postAdvertisementClick } from '.'; + +export const advertisementMutationKeys = { + click: () => ['advertisements', 'click'] as const, +}; + +export const advertisementMutations = { + click: () => + mutationOptions({ + mutationKey: advertisementMutationKeys.click(), + mutationFn: postAdvertisementClick, + retry: false, + }), +}; diff --git a/src/apis/advertisement/queries.ts b/src/apis/advertisement/queries.ts new file mode 100644 index 00000000..b7e7df7a --- /dev/null +++ b/src/apis/advertisement/queries.ts @@ -0,0 +1,17 @@ +import { queryOptions } from '@tanstack/react-query'; +import { getAdvertisements } from '@/apis/advertisement'; + +export const advertisementQueryKeys = { + all: ['advertisements'] as const, + randomBatch: (scope: string, batchIndex: number) => + [...advertisementQueryKeys.all, scope, 'random-batch', batchIndex] as const, +}; + +export const advertisementQueries = { + randomBatch: (scope: string, batchIndex: number) => + queryOptions({ + queryKey: advertisementQueryKeys.randomBatch(scope, batchIndex), + queryFn: () => getAdvertisements({ count: 2 }), + staleTime: Infinity, + }), +}; diff --git a/src/apis/auth/index.ts b/src/apis/auth/index.ts index 44358caa..c374d6c0 100644 --- a/src/apis/auth/index.ts +++ b/src/apis/auth/index.ts @@ -1,5 +1,5 @@ -import type { ApiError } from '@/interface/error'; -import { isServerErrorStatus, redirectToServerErrorPage } from '@/utils/ts/errorRedirect'; +import type { ApiError } from '@/utils/ts/error/apiError'; +import { isServerErrorStatus, redirectToServerErrorPage } from '@/utils/ts/error/errorRedirect'; import { NORMALIZED_API_BASE_URL } from '@/utils/ts/oauth'; import { apiClient } from '../client'; import type { @@ -10,7 +10,9 @@ import type { SignupRequest, } from './entity'; -export const refreshAccessToken = async (): Promise => { +let refreshAccessTokenPromise: Promise | null = null; + +const requestAccessTokenRefresh = async (): Promise => { const url = `${NORMALIZED_API_BASE_URL}/users/refresh`; let response: Response; @@ -49,6 +51,16 @@ export const refreshAccessToken = async (): Promise => { return data.accessToken; }; +export const refreshAccessToken = async (): Promise => { + if (!refreshAccessTokenPromise) { + refreshAccessTokenPromise = requestAccessTokenRefresh().finally(() => { + refreshAccessTokenPromise = null; + }); + } + + return refreshAccessTokenPromise; +}; + export const signup = async (data: SignupRequest) => { const response = await apiClient.post('users/signup', { body: data, diff --git a/src/apis/auth/mutations.ts b/src/apis/auth/mutations.ts new file mode 100644 index 00000000..395411fd --- /dev/null +++ b/src/apis/auth/mutations.ts @@ -0,0 +1,32 @@ +import { mutationOptions } from '@tanstack/react-query'; +import { deleteMyAccount, logout, putMyInfo, signup } from '.'; + +export const authMutationKeys = { + signup: () => ['signup'] as const, + logout: () => ['logout'] as const, + withdraw: () => ['withdraw'] as const, + updateMyInfo: () => ['modifyMyInfo'] as const, +}; + +export const authMutations = { + signup: () => + mutationOptions({ + mutationKey: authMutationKeys.signup(), + mutationFn: signup, + }), + logout: () => + mutationOptions({ + mutationKey: authMutationKeys.logout(), + mutationFn: logout, + }), + withdraw: () => + mutationOptions({ + mutationKey: authMutationKeys.withdraw(), + mutationFn: deleteMyAccount, + }), + updateMyInfo: () => + mutationOptions({ + mutationKey: authMutationKeys.updateMyInfo(), + mutationFn: putMyInfo, + }), +}; diff --git a/src/apis/auth/queries.ts b/src/apis/auth/queries.ts new file mode 100644 index 00000000..fb0e2e10 --- /dev/null +++ b/src/apis/auth/queries.ts @@ -0,0 +1,27 @@ +import { queryOptions } from '@tanstack/react-query'; +import { getMyInfo, getMyOAuthLinks, getSignupPrefill } from '.'; + +export const authQueryKeys = { + all: ['user'] as const, + myInfo: () => [...authQueryKeys.all, 'myInfo'] as const, + oauthLinks: () => [...authQueryKeys.all, 'oauthLinks'] as const, + signupPrefill: () => [...authQueryKeys.all, 'prefill'] as const, +}; + +export const authQueries = { + myInfo: () => + queryOptions({ + queryKey: authQueryKeys.myInfo(), + queryFn: getMyInfo, + }), + oauthLinks: () => + queryOptions({ + queryKey: authQueryKeys.oauthLinks(), + queryFn: getMyOAuthLinks, + }), + signupPrefill: () => + queryOptions({ + queryKey: authQueryKeys.signupPrefill(), + queryFn: getSignupPrefill, + }), +}; diff --git a/src/apis/chat/mutations.ts b/src/apis/chat/mutations.ts new file mode 100644 index 00000000..055b801a --- /dev/null +++ b/src/apis/chat/mutations.ts @@ -0,0 +1,38 @@ +import { mutationOptions } from '@tanstack/react-query'; +import { postAdminChatRoom, postChatMessage, postChatMute, postChatRooms } from '@/apis/chat'; + +export const chatMutationKeys = { + createRoom: () => ['chat', 'createRoom'] as const, + createAdminRoom: () => ['chat', 'createAdminRoom'] as const, + sendMessage: () => ['chat', 'sendMessage'] as const, + toggleMute: (chatRoomId?: number) => ['chat', 'toggleMute', chatRoomId ?? 'unknown'] as const, +}; + +export const chatMutations = { + createRoom: () => + mutationOptions({ + mutationKey: chatMutationKeys.createRoom(), + mutationFn: postChatRooms, + }), + createAdminRoom: () => + mutationOptions({ + mutationKey: chatMutationKeys.createAdminRoom(), + mutationFn: postAdminChatRoom, + }), + sendMessage: () => + mutationOptions({ + mutationKey: chatMutationKeys.sendMessage(), + mutationFn: postChatMessage, + }), + toggleMute: (chatRoomId?: number) => + mutationOptions({ + mutationKey: chatMutationKeys.toggleMute(chatRoomId), + mutationFn: async () => { + if (!chatRoomId) { + throw new Error('chatRoomId is missing'); + } + + return postChatMute(chatRoomId); + }, + }), +}; diff --git a/src/apis/chat/queries.ts b/src/apis/chat/queries.ts new file mode 100644 index 00000000..2ac95de3 --- /dev/null +++ b/src/apis/chat/queries.ts @@ -0,0 +1,32 @@ +import { infiniteQueryOptions, queryOptions } from '@tanstack/react-query'; +import type { ChatMessagesResponse } from './entity'; +import { getChatMessages, getChatRooms } from '.'; + +export const chatQueryKeys = { + all: ['chat'] as const, + rooms: () => [...chatQueryKeys.all, 'rooms'] as const, + messages: (chatRoomId: number) => [...chatQueryKeys.all, 'messages', chatRoomId] as const, + disabledMessages: () => [...chatQueryKeys.all, 'messages', 'disabled'] as const, +}; + +export const chatQueries = { + rooms: () => + queryOptions({ + queryKey: chatQueryKeys.rooms(), + queryFn: getChatRooms, + }), + messages: (chatRoomId?: number, limit = 20) => + infiniteQueryOptions({ + queryKey: chatRoomId ? chatQueryKeys.messages(chatRoomId) : chatQueryKeys.disabledMessages(), + queryFn: ({ pageParam }) => + getChatMessages({ + chatRoomId: chatRoomId!, + page: pageParam, + limit, + }), + initialPageParam: 1, + getNextPageParam: (lastPage: ChatMessagesResponse) => + lastPage.currentPage < lastPage.totalPage ? lastPage.currentPage + 1 : undefined, + enabled: Boolean(chatRoomId), + }), +}; diff --git a/src/apis/client.ts b/src/apis/client.ts index fcb27348..644a5b0e 100644 --- a/src/apis/client.ts +++ b/src/apis/client.ts @@ -1,7 +1,8 @@ import { refreshAccessToken } from '@/apis/auth'; -import type { ApiError, ApiErrorResponse } from '@/interface/error'; import { useAuthStore } from '@/stores/authStore'; -import { isServerErrorStatus, redirectToServerErrorPage } from '@/utils/ts/errorRedirect'; +import type { ApiError, ApiErrorResponse } from '@/utils/ts/error/apiError'; +import { isServerErrorStatus, redirectToServerErrorPage } from '@/utils/ts/error/errorRedirect'; +import { postNativeMessage } from '@/utils/ts/nativeBridge'; const BASE_URL = import.meta.env.VITE_API_PATH; @@ -19,8 +20,6 @@ interface FetchOptions

> exten requiresAuth?: boolean; } -let refreshPromise: Promise | null = null; - export const apiClient = { get: >( endPoint: string, @@ -128,23 +127,62 @@ function buildQuery(params: Record) { return usp.toString(); } -async function sendRequest>( - endPoint: string, - options: FetchOptions

= {}, - timeout: number = 10000 -): Promise { +function buildUrl(endPoint: string, params?: Record): string { + let url = joinUrl(BASE_URL, endPoint); + if (params && Object.keys(params).length > 0) { + const query = buildQuery(params); + if (query) url += `?${query}`; + } + return url; +} + +function buildFetchOptions

( + options: FetchOptions

& { method: string }, + abortSignal: AbortSignal +): RequestInit { + // eslint-disable-next-line @typescript-eslint/no-unused-vars const { headers, body, method, params, requiresAuth, ...restOptions } = options; - if (!method) { - throw new Error('HTTP method가 설정되지 않았습니다.'); + const isPlainObjectOrArray = + body !== undefined && + body !== null && + typeof body === 'object' && + (Array.isArray(body) || body.constructor === Object); + + const h: Record = { + ...(isPlainObjectOrArray ? { 'Content-Type': 'application/json' } : {}), + ...headers, + }; + + if (requiresAuth) { + const accessToken = useAuthStore.getState().getAccessToken(); + if (accessToken) { + h['Authorization'] = `Bearer ${accessToken}`; + } } - let url = joinUrl(BASE_URL, endPoint); - if (params && Object.keys(params).length > 0) { - const query = buildQuery(params as Record); - if (query) url += `?${query}`; + const fetchOpts: RequestInit = { + headers: h, + method, + signal: abortSignal, + credentials: 'include', + ...restOptions, + }; + + if (body !== undefined && body !== null && !['GET', 'HEAD'].includes(method)) { + fetchOpts.body = isPlainObjectOrArray ? JSON.stringify(body) : (body as BodyInit); } + return fetchOpts; +} + +async function executeFetch

( + endPoint: string, + options: FetchOptions

& { method: string }, + timeout: number +): Promise<{ response: Response; timeoutId: ReturnType }> { + const url = buildUrl(endPoint, options.params as Record | undefined); + const abortController = new AbortController(); let didTimeout = false; const timeoutId = setTimeout(() => { @@ -152,44 +190,38 @@ async function sendRequest => { - const h: Record = { - ...(isJsonBody ? { 'Content-Type': 'application/json' } : {}), - ...headers, - }; + try { + const fetchOpts = buildFetchOptions(options, abortController.signal); + const response = await fetch(url, fetchOpts); + return { response, timeoutId }; + } catch (error) { + clearTimeout(timeoutId); + rethrowFetchError(error, url, didTimeout); + } +} - if (requiresAuth) { - const accessToken = useAuthStore.getState().getAccessToken(); - if (accessToken) { - h['Authorization'] = `Bearer ${accessToken}`; - } - } +async function sendRequest>( + endPoint: string, + options: FetchOptions

= {}, + timeout: number = 10000, + allowRetry: boolean = true +): Promise { + const { method } = options; - return h; - }; + if (!method) { + throw new Error('HTTP method가 설정되지 않았습니다.'); + } - try { - const fetchOptions: RequestInit = { - headers: buildHeaders(), - method, - signal: abortController.signal, - credentials: 'include', - ...restOptions, - }; - - if (body !== undefined && body !== null && !['GET', 'HEAD'].includes(method)) { - fetchOptions.body = - typeof body === 'object' && !(body instanceof Blob) && !(body instanceof FormData) - ? JSON.stringify(body) - : (body as BodyInit); - } + const { response, timeoutId } = await executeFetch

( + endPoint, + options as FetchOptions

& { method: string }, + timeout + ); - const response = await fetch(url, fetchOptions); + const url = response.url; - if (response.status === 401 && requiresAuth) { - clearTimeout(timeoutId); + try { + if (response.status === 401 && options.requiresAuth && allowRetry) { return await handleUnauthorized(endPoint, options, timeout); } @@ -197,9 +229,12 @@ async function sendRequest(response); + return await parseResponse(response); } catch (error) { - rethrowFetchError(error, url, didTimeout); + if (error instanceof Error && error.name === 'AbortError') { + rethrowFetchError(error, url, true); + } + throw error; } finally { clearTimeout(timeoutId); } @@ -210,101 +245,25 @@ async function handleUnauthorized, timeout: number ): Promise { + await refreshAuthSession(); + + return await sendRequest(endPoint, options, timeout, false); +} + +export async function refreshAuthSession(): Promise { let newAccessToken: string; try { - if (!refreshPromise) { - refreshPromise = refreshAccessToken(); - } - newAccessToken = await refreshPromise; + newAccessToken = await refreshAccessToken(); } catch { - // refresh 실패 → 인증 만료, 로그아웃 처리 useAuthStore.getState().clearAuth(); throw new Error('인증이 만료되었습니다.'); - } finally { - refreshPromise = null; } useAuthStore.getState().setAccessToken(newAccessToken); + postNativeMessage({ type: 'TOKEN_REFRESH', accessToken: newAccessToken }); - try { - if (window.ReactNativeWebView) { - window.ReactNativeWebView.postMessage(JSON.stringify({ type: 'TOKEN_REFRESH', accessToken: newAccessToken })); - } - } catch { - // 브릿지 전달 실패가 인증 흐름을 중단시키지 않도록 무시 - } - - // retry 실패는 그대로 throw (로그아웃 처리 안 함) - return await sendRequestWithoutRetry(endPoint, options, timeout); -} - -async function sendRequestWithoutRetry>( - endPoint: string, - options: FetchOptions

= {}, - timeout: number = 10000 -): Promise { - const { headers, body, method, params, requiresAuth, ...restOptions } = options; - - if (!method) { - throw new Error('HTTP method가 설정되지 않았습니다.'); - } - - let url = joinUrl(BASE_URL, endPoint); - if (params && Object.keys(params).length > 0) { - const query = buildQuery(params as Record); - if (query) url += `?${query}`; - } - - const abortController = new AbortController(); - let didTimeout = false; - const timeoutId = setTimeout(() => { - didTimeout = true; - abortController.abort(); - }, timeout); - - const isJsonBody = body !== undefined && body !== null && !(body instanceof FormData); - - try { - const h: Record = { - ...(isJsonBody ? { 'Content-Type': 'application/json' } : {}), - ...headers, - }; - - if (requiresAuth) { - const accessToken = useAuthStore.getState().getAccessToken(); - if (accessToken) { - h['Authorization'] = `Bearer ${accessToken}`; - } - } - - const fetchOptions: RequestInit = { - headers: h, - method, - signal: abortController.signal, - credentials: 'include', - ...restOptions, - }; - - if (body !== undefined && body !== null && !['GET', 'HEAD'].includes(method)) { - fetchOptions.body = - typeof body === 'object' && !(body instanceof Blob) && !(body instanceof FormData) - ? JSON.stringify(body) - : (body as BodyInit); - } - - const response = await fetch(url, fetchOptions); - - if (!response.ok) { - return await throwApiError(response); - } - - return parseResponse(response); - } catch (error) { - rethrowFetchError(error, url, didTimeout); - } finally { - clearTimeout(timeoutId); - } + return newAccessToken; } async function parseErrorResponse(response: Response): Promise { @@ -320,16 +279,34 @@ async function parseErrorResponse(response: Response): Promise(response: Response): Promise { + if (response.status === 204 || response.headers.get('Content-Length') === '0') { + return null as unknown as T; + } + const contentType = response.headers.get('Content-Type') || ''; + if (contentType.includes('application/json')) { + const responseText = await response.text(); + + if (responseText.trim() === '') { + return null as unknown as T; + } + try { - return await response.json(); + return JSON.parse(responseText) as T; } catch { - return {} as T; + const error = new Error('응답 JSON 파싱에 실패했습니다.') as ApiError; + error.name = 'ParseError'; + error.status = response.status; + error.statusText = response.statusText; + error.url = response.url; + throw error; } - } else if (contentType.includes('text')) { + } + + if (contentType.includes('text')) { return (await response.text()) as unknown as T; - } else { - return null as unknown as T; } + + return null as unknown as T; } diff --git a/src/apis/club/managedMutations.ts b/src/apis/club/managedMutations.ts new file mode 100644 index 00000000..bd6b2abb --- /dev/null +++ b/src/apis/club/managedMutations.ts @@ -0,0 +1,112 @@ +import { mutationOptions } from '@tanstack/react-query'; +import { + deleteMember, + deletePreMember, + patchClubSettings, + patchMemberPosition, + patchVicePresident, + postAddPreMember, + postClubApplicationApprove, + postClubApplicationReject, + postTransferPresident, + putClubFee, + putClubInfo, + putClubQuestions, + putClubRecruitment, +} from '@/apis/club'; +import type { + AddPreMemberRequest, + ChangeMemberPositionRequest, + ChangeVicePresidentRequest, + ClubFeeRequest, + ClubInfoRequest, + ClubQuestionsRequest, + ClubRecruitmentRequest, + ClubSettingsPatchRequest, + TransferPresidentRequest, +} from '@/apis/club/entity'; + +export const managedClubMutationKeys = { + updateInfo: (clubId: number) => ['clubs', 'managed', 'updateInfo', clubId] as const, + updateFee: (clubId: number) => ['clubs', 'managed', 'updateFee', clubId] as const, + upsertRecruitment: (clubId: number) => ['clubs', 'managed', 'upsertRecruitment', clubId] as const, + updateQuestions: (clubId: number) => ['clubs', 'managed', 'updateQuestions', clubId] as const, + patchSettings: (clubId: number) => ['clubs', 'managed', 'patchSettings', clubId] as const, + approveApplication: (clubId: number) => ['clubs', 'managed', 'approveApplication', clubId] as const, + rejectApplication: (clubId: number) => ['clubs', 'managed', 'rejectApplication', clubId] as const, + transferPresident: (clubId: number) => ['clubs', 'managed', 'transferPresident', clubId] as const, + changeVicePresident: (clubId: number) => ['clubs', 'managed', 'changeVicePresident', clubId] as const, + changeMemberPosition: (clubId: number) => ['clubs', 'managed', 'changeMemberPosition', clubId] as const, + removeMember: (clubId: number) => ['clubs', 'managed', 'removeMember', clubId] as const, + addPreMember: (clubId: number) => ['clubs', 'managed', 'addPreMember', clubId] as const, + deletePreMember: (clubId: number) => ['clubs', 'managed', 'deletePreMember', clubId] as const, +}; + +export const managedClubMutations = { + updateInfo: (clubId: number) => + mutationOptions({ + mutationKey: managedClubMutationKeys.updateInfo(clubId), + mutationFn: (data: ClubInfoRequest) => putClubInfo(clubId, data), + }), + updateFee: (clubId: number) => + mutationOptions({ + mutationKey: managedClubMutationKeys.updateFee(clubId), + mutationFn: (data: ClubFeeRequest) => putClubFee(clubId, data), + }), + upsertRecruitment: (clubId: number) => + mutationOptions({ + mutationKey: managedClubMutationKeys.upsertRecruitment(clubId), + mutationFn: (data: ClubRecruitmentRequest) => putClubRecruitment(clubId, data), + }), + updateQuestions: (clubId: number) => + mutationOptions({ + mutationKey: managedClubMutationKeys.updateQuestions(clubId), + mutationFn: (data: ClubQuestionsRequest) => putClubQuestions(clubId, data), + }), + patchSettings: (clubId: number) => + mutationOptions({ + mutationKey: managedClubMutationKeys.patchSettings(clubId), + mutationFn: (data: ClubSettingsPatchRequest) => patchClubSettings(clubId, data), + }), + approveApplication: (clubId: number) => + mutationOptions({ + mutationKey: managedClubMutationKeys.approveApplication(clubId), + mutationFn: (applicationId: number) => postClubApplicationApprove(clubId, applicationId), + }), + rejectApplication: (clubId: number) => + mutationOptions({ + mutationKey: managedClubMutationKeys.rejectApplication(clubId), + mutationFn: (applicationId: number) => postClubApplicationReject(clubId, applicationId), + }), + transferPresident: (clubId: number) => + mutationOptions({ + mutationKey: managedClubMutationKeys.transferPresident(clubId), + mutationFn: (data: TransferPresidentRequest) => postTransferPresident(clubId, data), + }), + changeVicePresident: (clubId: number) => + mutationOptions({ + mutationKey: managedClubMutationKeys.changeVicePresident(clubId), + mutationFn: (data: ChangeVicePresidentRequest) => patchVicePresident(clubId, data), + }), + changeMemberPosition: (clubId: number) => + mutationOptions({ + mutationKey: managedClubMutationKeys.changeMemberPosition(clubId), + mutationFn: ({ userId, data }: { data: ChangeMemberPositionRequest; userId: number }) => + patchMemberPosition(clubId, userId, data), + }), + removeMember: (clubId: number) => + mutationOptions({ + mutationKey: managedClubMutationKeys.removeMember(clubId), + mutationFn: (userId: number) => deleteMember(clubId, userId), + }), + addPreMember: (clubId: number) => + mutationOptions({ + mutationKey: managedClubMutationKeys.addPreMember(clubId), + mutationFn: (data: AddPreMemberRequest) => postAddPreMember(clubId, data), + }), + deletePreMember: (clubId: number) => + mutationOptions({ + mutationKey: managedClubMutationKeys.deletePreMember(clubId), + mutationFn: (preMemberId: number) => deletePreMember(clubId, preMemberId), + }), +}; diff --git a/src/apis/club/managedQueries.ts b/src/apis/club/managedQueries.ts new file mode 100644 index 00000000..01d9abcf --- /dev/null +++ b/src/apis/club/managedQueries.ts @@ -0,0 +1,159 @@ +import { infiniteQueryOptions, queryOptions } from '@tanstack/react-query'; +import { + getBanks, + getClubFee, + getClubMembers, + getClubQuestions, + getClubRecruitment, + getClubSettings, + getManagedClub, + getManagedClubApplicationDetail, + getManagedClubApplications, + getManagedClubMemberApplicationByUser, + getManagedClubMemberApplications, + getManagedClubs, + getPreMembers, +} from '@/apis/club'; +import { isApiError } from '@/utils/ts/error/apiError'; + +interface ManagedClubApplicationsParams { + clubId: number; + limit: number; +} + +interface ManagedClubMemberApplicationsParams { + clubId: number; + limit: number; + page: number; +} + +export const managedClubQueryKeys = { + all: ['clubs', 'managed'] as const, + clubs: () => [...managedClubQueryKeys.all, 'clubs'] as const, + club: (clubId: number) => [...managedClubQueryKeys.all, 'club', clubId] as const, + applications: (clubId: number) => [...managedClubQueryKeys.all, 'applications', clubId] as const, + applicationsInfinite: ({ clubId, limit }: ManagedClubApplicationsParams) => + [...managedClubQueryKeys.applications(clubId), 'infinite', limit] as const, + applicationDetail: (clubId: number, applicationId: number) => + [...managedClubQueryKeys.all, 'applicationDetail', clubId, applicationId] as const, + memberApplications: ({ clubId, page, limit }: ManagedClubMemberApplicationsParams) => + [...managedClubQueryKeys.all, 'memberApplications', clubId, page, limit] as const, + memberApplicationDetail: (clubId: number, userId: number) => + [...managedClubQueryKeys.all, 'memberApplicationDetail', clubId, userId] as const, + banks: () => [...managedClubQueryKeys.all, 'banks'] as const, + fee: (clubId: number) => [...managedClubQueryKeys.all, 'fee', clubId] as const, + recruitment: (clubId: number) => [...managedClubQueryKeys.all, 'recruitment', clubId] as const, + questions: (clubId: number) => [...managedClubQueryKeys.all, 'questions', clubId] as const, + settings: (clubId: number) => [...managedClubQueryKeys.all, 'settings', clubId] as const, + members: (clubId: number) => [...managedClubQueryKeys.all, 'members', clubId] as const, + preMembers: (clubId: number) => [...managedClubQueryKeys.all, 'preMembers', clubId] as const, +}; + +export const managedClubQueries = { + clubs: () => + queryOptions({ + queryKey: managedClubQueryKeys.clubs(), + queryFn: getManagedClubs, + }), + club: (clubId: number) => + queryOptions({ + queryKey: managedClubQueryKeys.club(clubId), + queryFn: () => getManagedClub(clubId), + }), + applications: ({ clubId, limit }: ManagedClubApplicationsParams) => + infiniteQueryOptions({ + queryKey: managedClubQueryKeys.applicationsInfinite({ clubId, limit }), + queryFn: async ({ pageParam = 1 }) => { + try { + return await getManagedClubApplications(clubId, { + page: pageParam, + limit, + sortBy: 'APPLIED_AT', + sortDirection: 'ASC', + }); + } catch (error) { + if (isApiError(error) && error.apiError?.code === 'NOT_FOUND_CLUB_RECRUITMENT') { + return null; + } + + throw error; + } + }, + initialPageParam: 1, + getNextPageParam: (lastPage) => { + if (!lastPage || lastPage.currentPage >= lastPage.totalPage) { + return undefined; + } + + return lastPage.currentPage + 1; + }, + }), + applicationDetail: (clubId: number, applicationId: number) => + queryOptions({ + queryKey: managedClubQueryKeys.applicationDetail(clubId, applicationId), + queryFn: () => getManagedClubApplicationDetail(clubId, applicationId), + }), + memberApplications: ({ clubId, page, limit }: ManagedClubMemberApplicationsParams) => + queryOptions({ + queryKey: managedClubQueryKeys.memberApplications({ clubId, page, limit }), + queryFn: () => + getManagedClubMemberApplications(clubId, { + page, + limit, + sortBy: 'APPLIED_AT', + sortDirection: 'ASC', + }), + }), + memberApplicationDetail: (clubId: number, userId: number) => + queryOptions({ + queryKey: managedClubQueryKeys.memberApplicationDetail(clubId, userId), + queryFn: async () => { + try { + return await getManagedClubMemberApplicationByUser(clubId, userId); + } catch (error) { + if (isApiError(error) && error.apiError?.code === 'NOT_FOUND_CLUB_APPLY') { + return null; + } + + throw error; + } + }, + }), + banks: () => + queryOptions({ + queryKey: managedClubQueryKeys.banks(), + queryFn: getBanks, + }), + fee: (clubId: number) => + queryOptions({ + queryKey: managedClubQueryKeys.fee(clubId), + queryFn: () => getClubFee(clubId), + }), + recruitment: (clubId: number) => + queryOptions({ + queryKey: managedClubQueryKeys.recruitment(clubId), + queryFn: () => getClubRecruitment(clubId), + retry: false, + }), + questions: (clubId: number) => + queryOptions({ + queryKey: managedClubQueryKeys.questions(clubId), + queryFn: () => getClubQuestions(clubId), + }), + settings: (clubId: number) => + queryOptions({ + queryKey: managedClubQueryKeys.settings(clubId), + queryFn: () => getClubSettings(clubId), + retry: false, + }), + members: (clubId: number) => + queryOptions({ + queryKey: managedClubQueryKeys.members(clubId), + queryFn: () => getClubMembers(clubId), + }), + preMembers: (clubId: number) => + queryOptions({ + queryKey: managedClubQueryKeys.preMembers(clubId), + queryFn: () => getPreMembers(clubId), + }), +}; diff --git a/src/apis/club/mutations.ts b/src/apis/club/mutations.ts new file mode 100644 index 00000000..0ab7ed2e --- /dev/null +++ b/src/apis/club/mutations.ts @@ -0,0 +1,15 @@ +import { mutationOptions } from '@tanstack/react-query'; +import { applyClub } from '@/apis/club'; +import type { ClubApplyRequest } from '@/apis/club/entity'; + +export const clubMutationKeys = { + apply: (clubId: number) => ['clubs', 'apply', clubId] as const, +}; + +export const clubMutations = { + apply: (clubId: number) => + mutationOptions({ + mutationKey: clubMutationKeys.apply(clubId), + mutationFn: (body: ClubApplyRequest) => applyClub(clubId, body), + }), +}; diff --git a/src/apis/club/queries.ts b/src/apis/club/queries.ts index 25539d26..94f0b2d1 100644 --- a/src/apis/club/queries.ts +++ b/src/apis/club/queries.ts @@ -1,27 +1,102 @@ +import { infiniteQueryOptions, queryOptions } from '@tanstack/react-query'; +import type { ClubRequestParams, ClubResponse, PositionType } from './entity'; +import { + getAppliedClubs, + getClubDetail, + getClubFee, + getClubMembers, + getClubQuestions, + getClubRecruitment, + getClubs, + getJoinedClubs, +} from '.'; + +interface ClubInfiniteListParams { + limit: number; + query?: string; + isRecruiting?: boolean; +} + export const clubQueryKeys = { all: ['clubs'] as const, - list: (params: { limit: number; query?: string; isRecruiting: boolean }) => [ - ...clubQueryKeys.all, - 'list', - params.limit, - params.query, - params.isRecruiting, - ], + list: (params: { limit: number; query?: string; isRecruiting: boolean }) => + [...clubQueryKeys.all, 'list', params.limit, params.query, params.isRecruiting] as const, infinite: { all: () => [...clubQueryKeys.all, 'infinite'] as const, - list: (params: { limit: number; query?: string; isRecruiting?: boolean }) => [ - ...clubQueryKeys.infinite.all(), - 'list', - params.limit, - params.query, - params.isRecruiting, - ], + list: (params: ClubInfiniteListParams) => + [...clubQueryKeys.infinite.all(), 'list', params.limit, params.query, params.isRecruiting] as const, }, - detail: (clubId: number) => [...clubQueryKeys.all, 'detail', clubId], - members: (clubId: number) => [...clubQueryKeys.all, 'members', clubId], - recruitment: (clubId: number) => [...clubQueryKeys.all, 'recruitment', clubId], - fee: (clubId: number) => [...clubQueryKeys.all, 'fee', clubId], - questions: (clubId: number) => [...clubQueryKeys.all, 'questions', clubId], - joined: () => [...clubQueryKeys.all, 'joined'], - applied: () => [...clubQueryKeys.all, 'applied'], + detail: (clubId: number) => [...clubQueryKeys.all, 'detail', clubId] as const, + members: (clubId: number, position?: PositionType) => + position + ? ([...clubQueryKeys.all, 'members', clubId, position] as const) + : ([...clubQueryKeys.all, 'members', clubId] as const), + membersDisabled: () => [...clubQueryKeys.all, 'members', 'disabled'] as const, + recruitment: (clubId: number) => [...clubQueryKeys.all, 'recruitment', clubId] as const, + fee: (clubId: number) => [...clubQueryKeys.all, 'fee', clubId] as const, + questions: (clubId: number) => [...clubQueryKeys.all, 'questions', clubId] as const, + joined: () => [...clubQueryKeys.all, 'joined'] as const, + applied: () => [...clubQueryKeys.all, 'applied'] as const, +}; + +const buildClubListRequest = ( + { limit, query, isRecruiting = false }: ClubInfiniteListParams, + page: number +): ClubRequestParams => ({ + page, + limit, + ...(query ? { query } : {}), + isRecruiting, +}); + +export const clubQueries = { + detail: (clubId: number) => + queryOptions({ + queryKey: clubQueryKeys.detail(clubId), + queryFn: () => getClubDetail(clubId), + }), + members: (clubId?: number, position?: PositionType) => + queryOptions({ + queryKey: clubId ? clubQueryKeys.members(clubId, position) : clubQueryKeys.membersDisabled(), + queryFn: () => getClubMembers(clubId!, position), + enabled: Boolean(clubId), + }), + recruitment: (clubId: number) => + queryOptions({ + queryKey: clubQueryKeys.recruitment(clubId), + queryFn: () => getClubRecruitment(clubId), + }), + fee: (clubId: number) => + queryOptions({ + queryKey: clubQueryKeys.fee(clubId), + queryFn: () => getClubFee(clubId), + }), + questions: (clubId: number) => + queryOptions({ + queryKey: clubQueryKeys.questions(clubId), + queryFn: () => getClubQuestions(clubId), + }), + joined: () => + queryOptions({ + queryKey: clubQueryKeys.joined(), + queryFn: getJoinedClubs, + }), + applied: () => + queryOptions({ + queryKey: clubQueryKeys.applied(), + queryFn: getAppliedClubs, + }), + infiniteList: (params: ClubInfiniteListParams) => + infiniteQueryOptions({ + queryKey: clubQueryKeys.infinite.list(params), + queryFn: ({ pageParam }) => getClubs(buildClubListRequest(params, pageParam)), + initialPageParam: 1, + getNextPageParam: (lastPage: ClubResponse) => { + if (lastPage.currentPage < lastPage.totalPage) { + return lastPage.currentPage + 1; + } + + return undefined; + }, + }), }; diff --git a/src/apis/council/queries.ts b/src/apis/council/queries.ts new file mode 100644 index 00000000..6e90f1a2 --- /dev/null +++ b/src/apis/council/queries.ts @@ -0,0 +1,42 @@ +import { infiniteQueryOptions, queryOptions } from '@tanstack/react-query'; +import type { NoticeResponse } from './entity'; +import { getCouncilInfo, getCouncilNotice, getCouncilNoticeDetail } from '.'; + +export const councilQueryKeys = { + all: ['council'] as const, + info: () => [...councilQueryKeys.all, 'info'] as const, + notices: (limit: number) => [...councilQueryKeys.all, 'notices', limit] as const, + noticesPreview: (limit: number) => [...councilQueryKeys.all, 'noticesPreview', limit] as const, + noticeDetail: (noticeId: number) => [...councilQueryKeys.all, 'noticeDetail', noticeId] as const, +}; + +export const councilQueries = { + info: () => + queryOptions({ + queryKey: councilQueryKeys.info(), + queryFn: getCouncilInfo, + }), + noticesPreview: (limit = 3) => + queryOptions({ + queryKey: councilQueryKeys.noticesPreview(limit), + queryFn: () => getCouncilNotice({ page: 1, limit }), + }), + noticeDetail: (noticeId: number) => + queryOptions({ + queryKey: councilQueryKeys.noticeDetail(noticeId), + queryFn: () => getCouncilNoticeDetail(noticeId), + }), + infiniteNotices: (limit = 10) => + infiniteQueryOptions({ + queryKey: councilQueryKeys.notices(limit), + queryFn: ({ pageParam }) => getCouncilNotice({ page: pageParam, limit }), + initialPageParam: 1, + getNextPageParam: (lastPage: NoticeResponse) => { + if (lastPage.currentPage >= lastPage.totalPage) { + return undefined; + } + + return lastPage.currentPage + 1; + }, + }), +}; diff --git a/src/apis/inquiry/mutations.ts b/src/apis/inquiry/mutations.ts new file mode 100644 index 00000000..6aa67a76 --- /dev/null +++ b/src/apis/inquiry/mutations.ts @@ -0,0 +1,14 @@ +import { mutationOptions } from '@tanstack/react-query'; +import { postInquiry } from '@/apis/inquiry'; + +export const inquiryMutationKeys = { + create: () => ['inquiry', 'create'] as const, +}; + +export const inquiryMutations = { + create: () => + mutationOptions({ + mutationKey: inquiryMutationKeys.create(), + mutationFn: postInquiry, + }), +}; diff --git a/src/apis/notification/cache.ts b/src/apis/notification/cache.ts new file mode 100644 index 00000000..2ddba418 --- /dev/null +++ b/src/apis/notification/cache.ts @@ -0,0 +1,77 @@ +import type { + InboxNotification, + InboxNotificationListResponse, + InboxNotificationUnreadCountResponse, +} from '@/apis/notification/entity'; +import type { InfiniteData } from '@tanstack/react-query'; + +function hasInboxNotification(previousData: InfiniteData, notificationId: number) { + return previousData.pages.some((page) => + page.notifications.some((notification) => notification.id === notificationId) + ); +} + +export function prependInboxNotification( + previousData: InfiniteData | undefined, + notification: InboxNotification +) { + if (!previousData || hasInboxNotification(previousData, notification.id)) { + return previousData; + } + + const [firstPage, ...remainingPages] = previousData.pages; + + if (!firstPage) { + return previousData; + } + + return { + ...previousData, + pages: [ + { + ...firstPage, + notifications: [notification, ...firstPage.notifications], + totalElements: firstPage.totalElements + 1, + }, + ...remainingPages.map((page) => ({ + ...page, + totalElements: page.totalElements + 1, + })), + ], + }; +} + +export function setInboxNotificationReadState( + previousData: InfiniteData | undefined, + notificationId: number +) { + if (!previousData) { + return previousData; + } + + return { + ...previousData, + pages: previousData.pages.map((page) => ({ + ...page, + notifications: page.notifications.map((notification) => + notification.id === notificationId ? { ...notification, isRead: true } : notification + ), + })), + }; +} + +export function incrementInboxUnreadCount(previousData: InboxNotificationUnreadCountResponse | undefined, count = 1) { + return { + unreadCount: Math.max((previousData?.unreadCount ?? 0) + count, 0), + }; +} + +export function decrementInboxUnreadCount(previousData: InboxNotificationUnreadCountResponse | undefined, count = 1) { + if (!previousData) { + return previousData; + } + + return { + unreadCount: Math.max(previousData.unreadCount - count, 0), + }; +} diff --git a/src/apis/notification/entity.ts b/src/apis/notification/entity.ts new file mode 100644 index 00000000..17d5ffd9 --- /dev/null +++ b/src/apis/notification/entity.ts @@ -0,0 +1,31 @@ +export type NotificationInboxType = + | 'CLUB_APPLICATION_SUBMITTED' + | 'CLUB_APPLICATION_APPROVED' + | 'CLUB_APPLICATION_REJECTED' + | 'CHAT_MESSAGE' + | 'GROUP_CHAT_MESSAGE' + | 'UNREAD_CHAT_COUNT'; + +export type InboxNotificationType = NotificationInboxType | (string & {}); + +export interface InboxNotification { + id: number; + type: InboxNotificationType; + title: string; + body: string; + path: string; + isRead: boolean; + createdAt: string; +} + +export interface InboxNotificationListResponse { + notifications: InboxNotification[]; + currentPage: number; + totalPages: number; + totalElements: number; + hasNext: boolean; +} + +export interface InboxNotificationUnreadCountResponse { + unreadCount: number; +} diff --git a/src/apis/notification/index.ts b/src/apis/notification/index.ts index d90d626d..8248c2c9 100644 --- a/src/apis/notification/index.ts +++ b/src/apis/notification/index.ts @@ -1,4 +1,5 @@ -import { apiClient } from '../client'; +import { apiClient } from '@/apis/client'; +import type { InboxNotificationListResponse, InboxNotificationUnreadCountResponse } from '@/apis/notification/entity'; export const registerPushToken = async (token: string) => { if (window.ReactNativeWebView) { @@ -21,3 +22,25 @@ export const getNotificationToken = async (): Promise<{ token: string }> => { }); return response; }; + +export const getInboxNotifications = async (page = 1): Promise => { + const response = await apiClient.get('notifications/inbox', { + params: { page }, + requiresAuth: true, + }); + return response; +}; + +export const getInboxUnreadCount = async (): Promise => { + const response = await apiClient.get('notifications/inbox/unread-count', { + requiresAuth: true, + }); + return response; +}; + +export const markInboxNotificationAsRead = async (notificationId: number) => { + const response = await apiClient.patch(`notifications/inbox/${notificationId}/read`, { + requiresAuth: true, + }); + return response; +}; diff --git a/src/apis/notification/mutations.ts b/src/apis/notification/mutations.ts new file mode 100644 index 00000000..14479719 --- /dev/null +++ b/src/apis/notification/mutations.ts @@ -0,0 +1,19 @@ +import { mutationOptions } from '@tanstack/react-query'; +import { markInboxNotificationAsRead } from '@/apis/notification'; + +export interface MarkInboxNotificationAsReadVariables { + notificationId: number; +} + +export const notificationMutationKeys = { + markInboxAsRead: () => ['notifications', 'inbox', 'mark-as-read'] as const, +}; + +export const notificationMutations = { + markInboxAsRead: () => + mutationOptions({ + mutationKey: notificationMutationKeys.markInboxAsRead(), + mutationFn: ({ notificationId }: MarkInboxNotificationAsReadVariables) => + markInboxNotificationAsRead(notificationId), + }), +}; diff --git a/src/apis/notification/queries.ts b/src/apis/notification/queries.ts new file mode 100644 index 00000000..71f6f9f6 --- /dev/null +++ b/src/apis/notification/queries.ts @@ -0,0 +1,34 @@ +import { infiniteQueryOptions, queryOptions } from '@tanstack/react-query'; +import { getInboxNotifications, getInboxUnreadCount, getNotificationToken } from '.'; + +export const notificationQueryKeys = { + all: ['notifications'] as const, + token: () => [...notificationQueryKeys.all, 'token'] as const, + inbox: { + all: () => [...notificationQueryKeys.all, 'inbox'] as const, + list: () => [...notificationQueryKeys.inbox.all(), 'list'] as const, + infinite: () => [...notificationQueryKeys.inbox.list(), 'infinite'] as const, + unreadCount: () => [...notificationQueryKeys.inbox.all(), 'unread-count'] as const, + }, +}; + +export const notificationQueries = { + token: () => + queryOptions({ + queryKey: notificationQueryKeys.token(), + queryFn: getNotificationToken, + retry: false, + }), + inboxUnreadCount: () => + queryOptions({ + queryKey: notificationQueryKeys.inbox.unreadCount(), + queryFn: getInboxUnreadCount, + }), + inboxInfinite: () => + infiniteQueryOptions({ + queryKey: notificationQueryKeys.inbox.infinite(), + queryFn: ({ pageParam = 1 }) => getInboxNotifications(pageParam), + initialPageParam: 1, + getNextPageParam: (lastPage) => (lastPage.hasNext ? lastPage.currentPage + 1 : undefined), + }), +}; diff --git a/src/apis/schedule/queries.ts b/src/apis/schedule/queries.ts new file mode 100644 index 00000000..eff138b5 --- /dev/null +++ b/src/apis/schedule/queries.ts @@ -0,0 +1,22 @@ +import { queryOptions } from '@tanstack/react-query'; +import type { ScheduleRequestParams } from './entity'; +import { getScheduleList, getUpComingScheduleList } from '.'; + +export const scheduleQueryKeys = { + all: ['schedules'] as const, + monthly: (params: ScheduleRequestParams) => [...scheduleQueryKeys.all, 'monthly', params.year, params.month] as const, + upcoming: () => [...scheduleQueryKeys.all, 'upcoming'] as const, +}; + +export const scheduleQueries = { + monthly: (params: ScheduleRequestParams) => + queryOptions({ + queryKey: scheduleQueryKeys.monthly(params), + queryFn: () => getScheduleList(params), + }), + upcoming: () => + queryOptions({ + queryKey: scheduleQueryKeys.upcoming(), + queryFn: getUpComingScheduleList, + }), +}; diff --git a/src/apis/studyTime/hooks.ts b/src/apis/studyTime/hooks.ts new file mode 100644 index 00000000..0541ddaa --- /dev/null +++ b/src/apis/studyTime/hooks.ts @@ -0,0 +1,33 @@ +import { useMutation, useQueryClient } from '@tanstack/react-query'; +import { studyTimeMutations } from '@/apis/studyTime/mutations'; +import { studyTimeQueryKeys } from '@/apis/studyTime/queries'; +import { API_ERROR_CODES, isApiError } from '@/utils/ts/error/apiError'; + +export const useStopStudyTimerMutation = () => { + const queryClient = useQueryClient(); + + return useMutation({ + ...studyTimeMutations.stopTimer(), + onSuccess: async () => { + await queryClient.invalidateQueries({ queryKey: studyTimeQueryKeys.summary() }); + }, + }); +}; + +export const useStartStudyTimerMutation = () => { + const stopMutation = useStopStudyTimerMutation(); + + return useMutation({ + ...studyTimeMutations.startTimer(), + onError: async (error) => { + if (!isApiError(error)) throw error; + + // 이미 실행 중인 타이머가 있으면 정리 후 재시도 + if (error.apiError?.code === API_ERROR_CODES.ALREADY_RUNNING_STUDY_TIMER) { + await stopMutation.mutateAsync({ totalSeconds: 0 }); + } + + throw error; + }, + }); +}; diff --git a/src/apis/studyTime/mutations.ts b/src/apis/studyTime/mutations.ts new file mode 100644 index 00000000..092ff482 --- /dev/null +++ b/src/apis/studyTime/mutations.ts @@ -0,0 +1,21 @@ +import { mutationOptions } from '@tanstack/react-query'; +import { startStudyTimer, stopStudyTimer } from '@/apis/studyTime'; +import type { StopTimerRequest } from '@/apis/studyTime/entity'; + +export const studyTimeMutationKeys = { + startTimer: () => ['studyTime', 'startTimer'] as const, + stopTimer: () => ['studyTime', 'stopTimer'] as const, +}; + +export const studyTimeMutations = { + startTimer: () => + mutationOptions({ + mutationKey: studyTimeMutationKeys.startTimer(), + mutationFn: startStudyTimer, + }), + stopTimer: () => + mutationOptions({ + mutationKey: studyTimeMutationKeys.stopTimer(), + mutationFn: (data: StopTimerRequest) => stopStudyTimer(data), + }), +}; diff --git a/src/apis/studyTime/queries.ts b/src/apis/studyTime/queries.ts new file mode 100644 index 00000000..908bfb4d --- /dev/null +++ b/src/apis/studyTime/queries.ts @@ -0,0 +1,55 @@ +import { infiniteQueryOptions, queryOptions } from '@tanstack/react-query'; +import { getMyStudyTimeRanking, getStudyTimeRanking, getStudyTimeSummary } from '@/apis/studyTime'; +import type { StudyRankingParams } from '@/apis/studyTime/entity'; + +interface StudyTimeRankingKeyParams { + limit: number; + sort: StudyRankingParams['sort']; + type: StudyRankingParams['type']; +} + +interface MyStudyTimeRankingKeyParams { + sort: StudyRankingParams['sort']; + type: StudyRankingParams['type']; +} + +export const studyTimeQueryKeys = { + all: ['studyTime'] as const, + summary: () => [...studyTimeQueryKeys.all, 'summary'] as const, + ranking: (params: StudyTimeRankingKeyParams) => + [...studyTimeQueryKeys.all, 'ranking', params.limit, params.sort, params.type] as const, + myRanking: (params: MyStudyTimeRankingKeyParams) => [...studyTimeQueryKeys.all, 'myRanking', params.sort] as const, +}; + +export const studyTimeQueries = { + summary: () => + queryOptions({ + queryKey: studyTimeQueryKeys.summary(), + queryFn: getStudyTimeSummary, + }), + ranking: ({ limit, sort, type }: StudyTimeRankingKeyParams) => + infiniteQueryOptions({ + queryKey: studyTimeQueryKeys.ranking({ limit, sort, type }), + queryFn: ({ pageParam }) => + getStudyTimeRanking({ + page: pageParam, + limit, + sort, + type, + }), + initialPageParam: 1, + getNextPageParam: (lastPage) => { + return lastPage.currentPage < lastPage.totalPage ? lastPage.currentPage + 1 : undefined; + }, + }), + myRanking: ({ sort, type }: MyStudyTimeRankingKeyParams) => + queryOptions({ + queryKey: studyTimeQueryKeys.myRanking({ sort, type }), + queryFn: () => getMyStudyTimeRanking({ sort }), + select: (data) => { + if (type === 'CLUB') return data.clubRankings; + if (type === 'STUDENT_NUMBER') return [data.studentNumberRanking]; + return [data.personalRanking]; + }, + }), +}; diff --git a/src/apis/university/queries.ts b/src/apis/university/queries.ts new file mode 100644 index 00000000..032fa060 --- /dev/null +++ b/src/apis/university/queries.ts @@ -0,0 +1,15 @@ +import { queryOptions } from '@tanstack/react-query'; +import { getUniversityList } from '.'; + +export const universityQueryKeys = { + all: ['university'] as const, + list: () => [...universityQueryKeys.all, 'list'] as const, +}; + +export const universityQueries = { + list: () => + queryOptions({ + queryKey: universityQueryKeys.list(), + queryFn: getUniversityList, + }), +}; diff --git a/src/apis/upload/mutations.ts b/src/apis/upload/mutations.ts new file mode 100644 index 00000000..d2940f0d --- /dev/null +++ b/src/apis/upload/mutations.ts @@ -0,0 +1,15 @@ +import { mutationOptions } from '@tanstack/react-query'; +import type { UploadTarget } from './entity'; +import { uploadImage } from '.'; + +export const uploadMutationKeys = { + image: (target: UploadTarget) => ['upload', 'image', target] as const, +}; + +export const uploadMutations = { + image: (target: UploadTarget) => + mutationOptions({ + mutationKey: uploadMutationKeys.image(target), + mutationFn: (file: File) => uploadImage(file, target), + }), +}; diff --git a/src/assets/image/bottom-nav-home.png b/src/assets/image/bottom-nav-home.png new file mode 100644 index 0000000000000000000000000000000000000000..8c1899e556df2858de6035ccde3f8c549984a2a1 GIT binary patch literal 11017 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 Dvv&b; literal 0 HcmV?d00001 diff --git a/src/assets/image/chat-cat-header.png b/src/assets/image/chat-cat-header.png deleted file mode 100644 index 550a566696b8942f6b822d7c0d0e105b3e8d487a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7444 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 S&Gak)0000G~GcjkD`|K9uM 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 Vv4GqQ>L7>aqTXfQ((?{6{{yY>ZDIfb literal 0 HcmV?d00001 diff --git a/src/assets/image/notification-toast-general.png b/src/assets/image/notification-toast-general.png new file mode 100644 index 0000000000000000000000000000000000000000..29e4ba0077ec0bcdf0631b606ced9341ce8a9c8a GIT binary patch literal 99225 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

bNi$ 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

t>f6&;EWxb;YHP2 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

Yf*nTj2Fs0Dg-ktoDM3l%BMEI8b)8No9CDJ2 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 w7`UWox_XC(fOvn0~KRuD$R{#J2 literal 0 HcmV?d00001 diff --git a/src/assets/svg/add_circle.svg b/src/assets/svg/add_circle.svg new file mode 100644 index 00000000..e70fca95 --- /dev/null +++ b/src/assets/svg/add_circle.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/src/assets/svg/bottom-nav-chat.svg b/src/assets/svg/bottom-nav-chat.svg new file mode 100644 index 00000000..ea888886 --- /dev/null +++ b/src/assets/svg/bottom-nav-chat.svg @@ -0,0 +1,6 @@ + + + diff --git a/src/assets/svg/bottom-nav-clubs.svg b/src/assets/svg/bottom-nav-clubs.svg new file mode 100644 index 00000000..3be29f33 --- /dev/null +++ b/src/assets/svg/bottom-nav-clubs.svg @@ -0,0 +1,6 @@ + + + diff --git a/src/assets/svg/bottom-nav-mypage.svg b/src/assets/svg/bottom-nav-mypage.svg new file mode 100644 index 00000000..8b85ae84 --- /dev/null +++ b/src/assets/svg/bottom-nav-mypage.svg @@ -0,0 +1,6 @@ + + + diff --git a/src/assets/svg/bottom-nav-sms.svg b/src/assets/svg/bottom-nav-sms.svg new file mode 100644 index 00000000..81fe72fd --- /dev/null +++ b/src/assets/svg/bottom-nav-sms.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/src/assets/svg/bottom-nav-timer.svg b/src/assets/svg/bottom-nav-timer.svg new file mode 100644 index 00000000..3dd05583 --- /dev/null +++ b/src/assets/svg/bottom-nav-timer.svg @@ -0,0 +1,6 @@ + + + diff --git a/src/assets/svg/chat-icon.svg b/src/assets/svg/chat-icon.svg new file mode 100644 index 00000000..7ebdc44f --- /dev/null +++ b/src/assets/svg/chat-icon.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/src/assets/svg/clock.svg b/src/assets/svg/clock.svg index 068bd52f..1a502a89 100644 --- a/src/assets/svg/clock.svg +++ b/src/assets/svg/clock.svg @@ -1,3 +1,3 @@ - + diff --git a/src/assets/svg/instagram.svg b/src/assets/svg/instagram.svg index 91325d78..909561d6 100644 --- a/src/assets/svg/instagram.svg +++ b/src/assets/svg/instagram.svg @@ -1,3 +1,3 @@ - + diff --git a/src/assets/svg/location-pin.svg b/src/assets/svg/location-pin.svg index 143251cc..c8f3fa16 100644 --- a/src/assets/svg/location-pin.svg +++ b/src/assets/svg/location-pin.svg @@ -1,4 +1,4 @@ - - + + diff --git a/src/assets/svg/notifications.svg b/src/assets/svg/notifications.svg new file mode 100644 index 00000000..f2b7850e --- /dev/null +++ b/src/assets/svg/notifications.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/src/assets/svg/person-icon.svg b/src/assets/svg/person-icon.svg new file mode 100644 index 00000000..9fc3dba6 --- /dev/null +++ b/src/assets/svg/person-icon.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/src/assets/svg/unread-notification.svg b/src/assets/svg/unread-notification.svg new file mode 100644 index 00000000..0c829e31 --- /dev/null +++ b/src/assets/svg/unread-notification.svg @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/src/components/common/Portal.tsx b/src/components/common/Portal.tsx index b9b2d5c7..cc3e7403 100644 --- a/src/components/common/Portal.tsx +++ b/src/components/common/Portal.tsx @@ -3,9 +3,13 @@ import { createPortal } from 'react-dom'; interface PortalProps { children: ReactNode; - container?: Element; + container?: Element | DocumentFragment | null; } export default function Portal({ children, container = document.body }: PortalProps) { + if (!container) { + return null; + } + return createPortal(children, container); } diff --git a/src/components/layout/BottomNav/index.tsx b/src/components/layout/BottomNav/index.tsx index f2733f7d..8dfa8ffa 100644 --- a/src/components/layout/BottomNav/index.tsx +++ b/src/components/layout/BottomNav/index.tsx @@ -1,45 +1,123 @@ -import { type ComponentType, type SVGProps } from 'react'; -import { NavLink } from 'react-router-dom'; -import HouseIcon from '@/assets/svg/house.svg'; -import PeopleIcon from '@/assets/svg/people.svg'; -import PersonIcon from '@/assets/svg/person.svg'; -import TimerIcon from '@/assets/svg/timer.svg'; +import { type ComponentType, type Ref, type SVGProps } from 'react'; +import { Link, useLocation } from 'react-router-dom'; +import HomeResultImage from '@/assets/image/bottom-nav-home.png'; +import ClubsIcon from '@/assets/svg/bottom-nav-clubs.svg'; +import MyPageIcon from '@/assets/svg/bottom-nav-mypage.svg'; +import ChatIcon from '@/assets/svg/bottom-nav-sms.svg'; +import TimerIcon from '@/assets/svg/bottom-nav-timer.svg'; +import useUnreadChatCount from '@/pages/Chat/hooks/useUnreadChatCount'; import { cn } from '@/utils/ts/cn'; interface BottomNavItemConfig { to: string; label: string; - Icon: ComponentType>; - end?: boolean; + Icon?: ComponentType>; + floatingImageSrc?: string; + matchesPath?: (pathname: string) => boolean; } const BOTTOM_NAV_ITEMS = [ - { to: '/home', label: '홈', Icon: HouseIcon, end: true }, - { to: '/clubs', label: '동아리', Icon: PeopleIcon }, + { to: '/clubs', label: '동아리', Icon: ClubsIcon }, { to: '/timer', label: '타이머', Icon: TimerIcon }, - { to: '/mypage', label: '내정보', Icon: PersonIcon }, + { + to: '/home', + label: '홈', + floatingImageSrc: HomeResultImage, + matchesPath: (pathname) => pathname === '/home' || pathname === '/notifications' || pathname.startsWith('/council'), + }, + { to: '/chats', label: '채팅방', Icon: ChatIcon }, + { to: '/mypage', label: '내정보', Icon: MyPageIcon }, ] satisfies BottomNavItemConfig[]; -function BottomNavItem({ to, label, Icon, end = false }: BottomNavItemConfig) { +function matchesBottomNavItemPath({ to, matchesPath }: BottomNavItemConfig, pathname: string) { + if (matchesPath) { + return matchesPath(pathname); + } + + return pathname === to || pathname.startsWith(`${to}/`); +} + +function formatUnreadChatCount(unreadCount: number) { + if (unreadCount <= 0) { + return null; + } + + return unreadCount > 99 ? '99+' : String(unreadCount); +} + +interface BottomNavItemProps { + item: BottomNavItemConfig; + isSelected: boolean; + unreadCount?: number; +} + +function BottomNavItem({ item, isSelected, unreadCount = 0 }: BottomNavItemProps) { + const { to, label, Icon, floatingImageSrc } = item; + const unreadCountLabel = formatUnreadChatCount(unreadCount); + const hasUnreadCount = unreadCountLabel !== null; + return ( - - {({ isActive }) => ( - <> - - {label} - - )} - + + {floatingImageSrc ? ( + + ) : Icon ? ( +

+ + {hasUnreadCount && ( + + )} +
+ ) : null} + + {label} + + ); } -function BottomNav() { +interface BottomNavProps { + navRef?: Ref; +} + +function BottomNav({ navRef }: BottomNavProps) { + const { pathname } = useLocation(); + const { totalUnreadCount } = useUnreadChatCount(); + return ( -