Skip to content

Commit 1fff012

Browse files
authored
[fix] 약속/주제 확정 관련 버그 수정 및 기능 연결 (#79)
* fix: 약속/주제 확정 관련 버그 수정 및 기능 연결 (#78) - confirmedTopicExpand 필드명을 confirmedTopic으로 수정 - 약속 승인 후 모임 약속 리스트 캐시 무효화 추가 - 주제 확정 후 약속 상세 쿼리 캐시 무효화 추가 - 약속 수정 완료 후 약속 상세 페이지로 이동하도록 수정 - 약속 수정 버튼(CAN_EDIT) 클릭 시 수정 페이지로 이동 연결 - 수정 모드에서 도서 선택 유효성 검사 예외 처리 - 주제 확정 시 좋아요/삭제 버튼 비활성화 처리 - 주제 확정 API 메서드 POST → PATCH로 수정 * fix: confirmedTopic필드명 변경(#78) * style: 디버깅코드 제거(#78)
1 parent b17aa47 commit 1fff012

13 files changed

Lines changed: 53 additions & 31 deletions

src/features/meetings/components/MeetingApprovalItem.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ export default function MeetingApprovalItem({ item, gatheringId }: MeetingApprov
3030
const { meetingName, bookName, nickname, startDateTime, endDateTime, meetingStatus, meetingId } =
3131
item
3232

33-
const confirmMutation = useConfirmMeeting()
33+
const confirmMutation = useConfirmMeeting(gatheringId)
3434
const rejectMutation = useRejectMeeting(gatheringId)
3535
const deleteMutation = useDeleteMeeting(gatheringId)
3636
const isPending =

src/features/meetings/components/MeetingDetailButton.tsx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,27 @@
1+
import { useNavigate } from 'react-router-dom'
2+
13
import { useCancelJoinMeeting, useJoinMeeting } from '@/features/meetings/hooks'
24
import type { MeetingDetailActionStateType } from '@/features/meetings/meetings.types'
5+
import { ROUTES } from '@/shared/constants/routes'
36
import { Button } from '@/shared/ui'
47
import { useGlobalModalStore } from '@/store'
58

69
interface MeetingDetailButtonProps {
710
buttonLabel: string
811
isEnabled: boolean
912
type: MeetingDetailActionStateType
13+
gatheringId: number
1014
meetingId: number
1115
}
1216

1317
export default function MeetingDetailButton({
1418
buttonLabel,
1519
isEnabled,
1620
type,
21+
gatheringId,
1722
meetingId,
1823
}: MeetingDetailButtonProps) {
24+
const navigate = useNavigate()
1925
const joinMutation = useJoinMeeting()
2026
const cancelJoinMutation = useCancelJoinMeeting()
2127
const { openError, openConfirm } = useGlobalModalStore()
@@ -25,9 +31,9 @@ export default function MeetingDetailButton({
2531
const handleClick = async () => {
2632
if (!isEnabled || isPending) return
2733

28-
// 약속 수정 - 페이지 이동 예정 (TODO)
34+
// 약속 수정
2935
if (type === 'CAN_EDIT') {
30-
// 페이지 이동 로직 추가 예정
36+
navigate(ROUTES.MEETING_UPDATE(gatheringId, meetingId))
3137
return
3238
}
3339

src/features/meetings/components/MeetingDetailInfo.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,11 @@ export function MeetingDetailInfo({ meeting }: MeetingDetailInfoProps) {
3636
{/* 도서 */}
3737
<dl className="flex gap-base">
3838
<dt className={DT_VARIANTS}>도서</dt>
39-
<dd className="flex flex-col gap-xtiny">
40-
<p className="text-black typo-body3">{meeting.book.bookName}</p>
39+
<dd className="flex flex-col gap-tiny">
40+
<div className="flex flex-col gap-xtiny">
41+
<p className="text-black typo-body3">{meeting.book.bookName}</p>
42+
<p className="typo-caption1 text-grey-700">{meeting.book.authors}</p>
43+
</div>
4144
<div className="w-[120px] h-[170px] overflow-hidden rounded">
4245
<img
4346
src={meeting.book.thumbnail}

src/features/meetings/hooks/useConfirmMeeting.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55

66
import { useMutation, useQueryClient } from '@tanstack/react-query'
77

8-
import { ApiError } from '@/api/errors'
9-
import type { ApiResponse } from '@/api/types'
8+
import type { ApiError, ApiResponse } from '@/api'
9+
import { gatheringQueryKeys } from '@/features/gatherings'
1010
import { confirmMeeting, type ConfirmMeetingResponse } from '@/features/meetings'
1111

1212
import { meetingQueryKeys } from './meetingQueryKeys'
@@ -18,12 +18,13 @@ import { meetingQueryKeys } from './meetingQueryKeys'
1818
* 약속을 승인하고 관련 쿼리 캐시를 무효화합니다.
1919
* - 약속 승인 리스트 캐시 무효화
2020
* - 약속 승인 카운트 캐시 무효화
21+
* - 모임 약속 리스트 캐시 무효화
2122
*
2223
* @example
23-
* const confirmMutation = useConfirmMeeting()
24+
* const confirmMutation = useConfirmMeeting(gatheringId)
2425
* confirmMutation.mutate(meetingId)
2526
*/
26-
export const useConfirmMeeting = () => {
27+
export const useConfirmMeeting = (gatheringId: number) => {
2728
const queryClient = useQueryClient()
2829

2930
return useMutation<ApiResponse<ConfirmMeetingResponse>, ApiError, number>({
@@ -33,6 +34,8 @@ export const useConfirmMeeting = () => {
3334
queryClient.invalidateQueries({
3435
queryKey: meetingQueryKeys.approvals(),
3536
})
37+
// 모임 약속 리스트 캐시 무효화
38+
queryClient.invalidateQueries({ queryKey: gatheringQueryKeys.meetings(gatheringId) })
3639
},
3740
})
3841
}

src/features/meetings/hooks/useMeetingForm.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -123,11 +123,12 @@ export const useMeetingForm = ({ gatheringMaxCount, initialData }: UseMeetingFor
123123
const newError: ValidationErrors = {}
124124

125125
if (
126-
!formData.bookId ||
127-
!formData.bookName ||
128-
!formData.bookThumbnail ||
129-
!formData.bookAuthors ||
130-
!formData.bookPublisher
126+
!isEditMode &&
127+
(!formData.bookId ||
128+
!formData.bookName ||
129+
!formData.bookThumbnail ||
130+
!formData.bookAuthors ||
131+
!formData.bookPublisher)
131132
) {
132133
newError.bookId = '* 도서를 선택해주세요.'
133134
}

src/features/meetings/meetings.mock.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -261,15 +261,15 @@ const mockMeetingDetails: Record<number, GetMeetingDetailResponse> = {
261261
buttonLabel: '약속이 끝났어요',
262262
enabled: false,
263263
},
264-
confirmedTopicExpand: true,
264+
confirmedTopic: true,
265265
confirmedTopicDate: '2026-01-20T14:00:00',
266266
},
267267
11: {
268268
meetingId: 11,
269269
progressStatus: 'PRE',
270270
meetingName: '킥오프 모임',
271271
meetingStatus: 'CONFIRMED',
272-
confirmedTopicExpand: false,
272+
confirmedTopic: false,
273273
confirmedTopicDate: null,
274274
gathering: {
275275
gatheringId: 102,

src/features/meetings/meetings.types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ export type GetMeetingDetailResponse = {
215215
/** 약속 진행 상태 */
216216
progressStatus: MeetingProgressStatus
217217
/** 주제 확정 여부 */
218-
confirmedTopicExpand: boolean
218+
confirmedTopic: boolean
219219
/** 주제 확정 일시 */
220220
confirmedTopicDate: string | null
221221
/** 모임 정보 */

src/features/topics/components/ProposedTopicList.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ type ProposedTopicListProps = {
1212
onLoadMore: () => void
1313
gatheringId: number
1414
meetingId: number
15+
confirmedTopic: boolean
1516
}
1617

1718
export default function ProposedTopicList({
@@ -21,6 +22,7 @@ export default function ProposedTopicList({
2122
onLoadMore,
2223
gatheringId,
2324
meetingId,
25+
confirmedTopic,
2426
}: ProposedTopicListProps) {
2527
// 무한 스크롤: IntersectionObserver로 다음 페이지 로드
2628
const observerRef = useInfiniteScroll(onLoadMore, {
@@ -44,11 +46,12 @@ export default function ProposedTopicList({
4446
description={topic.description}
4547
createdByNickname={topic.createdByInfo.nickname}
4648
likeCount={topic.likeCount}
47-
isLiked={topic.isLiked}
48-
canDelete={topic.canDelete}
49+
isLiked={confirmedTopic ? false : topic.isLiked}
50+
canDelete={confirmedTopic ? false : topic.canDelete}
4951
gatheringId={gatheringId}
5052
meetingId={meetingId}
5153
topicId={topic.topicId}
54+
isLikeDisabled={confirmedTopic}
5255
/>
5356
</li>
5457
))}

src/features/topics/components/TopicHeader.tsx

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -64,13 +64,12 @@ export default function TopicHeader(props: TopicHeaderProps) {
6464
</Button>
6565
)}
6666

67-
{props.actions.canSuggest && (
68-
<Button
69-
onClick={() => navigate(ROUTES.TOPICS_CREATE(props.gatheringId, props.meetingId))}
70-
>
71-
제안하기
72-
</Button>
73-
)}
67+
<Button
68+
onClick={() => navigate(ROUTES.TOPICS_CREATE(props.gatheringId, props.meetingId))}
69+
disabled={!props.actions.canSuggest}
70+
>
71+
제안하기
72+
</Button>
7473
</div>
7574
</div>
7675
)}

src/features/topics/hooks/useConfirmTopics.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import { useMutation, useQueryClient } from '@tanstack/react-query'
77

88
import { ApiError } from '@/api/errors'
9+
import { meetingQueryKeys } from '@/features/meetings/hooks/meetingQueryKeys'
910

1011
import { confirmTopics } from '../topics.api'
1112
import type { ConfirmTopicsParams, ConfirmTopicsResponse } from '../topics.types'
@@ -55,6 +56,10 @@ export const useConfirmTopics = () => {
5556
meetingId: variables.meetingId,
5657
}),
5758
})
59+
// 약속 상세 무효화
60+
queryClient.invalidateQueries({
61+
queryKey: meetingQueryKeys.detail(variables.meetingId),
62+
})
5863
},
5964
})
6065
}

0 commit comments

Comments
 (0)