11"use client" ;
2- import { useLikeToggle } from "@/shared/api/mutations/capsule" ;
2+ import { capsuleMutationOptions } from "@/shared/api/mutations/capsule" ;
33import { capsuleQueryOptions } from "@/shared/api/queries/capsule" ;
4+ import { capsuleQueryKeys } from "@/shared/api/queries/capsule" ;
45import { userQueryOptions } from "@/shared/api/queries/user" ;
56import MenuIcon from "@/shared/assets/icon/menu.svg" ;
67import { PATH } from "@/shared/constants/path" ;
8+ import { useOverlay } from "@/shared/hooks/use-overlay" ;
79import Dropdown from "@/shared/ui/dropdown" ;
810import InfoToast from "@/shared/ui/info-toast" ;
911import LikeButton from "@/shared/ui/like-button" ;
@@ -13,7 +15,9 @@ import NavbarDetail from "@/shared/ui/navbar/navbar-detail";
1315import PopupReport from "@/shared/ui/popup/popup-report" ;
1416import PopupWarningCapsule from "@/shared/ui/popup/popup-warning-capsule" ;
1517import { formatDateTime } from "@/shared/utils/date" ;
16- import { useQuery } from "@tanstack/react-query" ;
18+ import { oauthUtils } from "@/shared/utils/oauth" ;
19+ import { useMutation , useQuery } from "@tanstack/react-query" ;
20+ import { useQueryClient } from "@tanstack/react-query" ;
1721import {
1822 useParams ,
1923 usePathname ,
@@ -25,30 +29,26 @@ import CaptionSection from "../../_components/caption-section";
2529import InfoTitle from "../../_components/info-title" ;
2630import OpenInfoSection from "../../_components/open-info-section" ;
2731import ResponsiveFooter from "../../_components/responsive-footer" ;
28- import { useLeaveCapsule } from "@/shared/api/mutations/capsule" ;
2932import * as styles from "./page.css" ;
30- import { oauthUtils } from "@/shared/utils/oauth" ;
31- import { useOverlay } from "@/shared/hooks/use-overlay" ;
3233
3334const CapsuleDetailPage = ( ) => {
3435 const params = useParams ( ) ;
3536 const id = params . id as string ;
36- const { mutate : likeToggle } = useLikeToggle ( ) ;
37- const { data, isLoading , isError } = useQuery (
37+ const queryClient = useQueryClient ( ) ;
38+ const { data, isPending , isError } = useQuery (
3839 capsuleQueryOptions . capsuleDetail ( id ) ,
3940 ) ;
40- const { data : user } = useQuery (
41- userQueryOptions . userInfo ( )
42- ) ;
43- const { mutate : leaveCapsule } = useLeaveCapsule ( ) ;
41+ const { data : user } = useQuery ( userQueryOptions . userInfo ( ) ) ;
42+ const { mutate : likeToggle } = useMutation ( capsuleMutationOptions . like ) ;
43+ const { mutate : leaveCapsule } = useMutation ( capsuleMutationOptions . leave ) ;
4444 const router = useRouter ( ) ;
4545 const pathname = usePathname ( ) ;
4646 const searchParams = useSearchParams ( ) ;
4747 const { open } = useOverlay ( ) ;
4848
4949 const isLoggedIn = ! ! user ?. result ;
5050
51- if ( isLoading ) {
51+ if ( isPending ) {
5252 return < LoadingSpinner loading = { true } size = { 20 } /> ;
5353 }
5454
@@ -65,14 +65,32 @@ const CapsuleDetailPage = () => {
6565 router . push ( PATH . LOGIN ) ;
6666 return ;
6767 }
68- likeToggle ( { id : result . id . toString ( ) , isLiked : nextLiked } ) ;
68+ likeToggle (
69+ { id : result . id . toString ( ) , isLiked : nextLiked } ,
70+ {
71+ onSuccess : ( ) => async ( id : string ) => {
72+ await Promise . all ( [
73+ queryClient . invalidateQueries ( {
74+ queryKey : capsuleQueryKeys . detail ( id ) ,
75+ } ) ,
76+ queryClient . invalidateQueries ( { queryKey : [ "capsule" , "my" ] } ) ,
77+ ] ) ;
78+ } ,
79+ } ,
80+ ) ;
6981 } ;
7082
7183 const handleLeaveCapsule = ( close : ( ) => void ) => {
7284 close ( ) ;
7385 leaveCapsule ( result . id . toString ( ) , {
74- onSuccess : ( ) => {
86+ onSuccess : async ( ) => {
7587 router . push ( PATH . EXPLORE ) ;
88+ await Promise . all ( [
89+ queryClient . invalidateQueries ( {
90+ queryKey : capsuleQueryKeys . detail ( id ) ,
91+ } ) ,
92+ queryClient . invalidateQueries ( { queryKey : [ "capsule" , "my" ] } ) ,
93+ ] ) ;
7694 } ,
7795 } ) ;
7896 } ;
@@ -104,14 +122,14 @@ const CapsuleDetailPage = () => {
104122 < Dropdown . Item
105123 label = "캡슐 떠나기"
106124 className = { styles . textHighlight }
107- onClick = { ( ) => {
108- open ( ( { isOpen, close } ) => (
109- < PopupWarningCapsule
110- isOpen = { isOpen }
111- close = { close }
112- onConfirm = { ( ) => handleLeaveCapsule ( close ) }
113- />
114- ) ) ;
125+ onClick = { ( ) => {
126+ open ( ( { isOpen, close } ) => (
127+ < PopupWarningCapsule
128+ isOpen = { isOpen }
129+ close = { close }
130+ onConfirm = { ( ) => handleLeaveCapsule ( close ) }
131+ />
132+ ) ) ;
115133 } }
116134 />
117135 ) }
@@ -121,25 +139,25 @@ const CapsuleDetailPage = () => {
121139 ) ;
122140 } }
123141 />
124-
125- < RevealMotion >
126- < InfoTitle
127- title = { result . title }
128- participantCount = { result . participantCount }
129- joinLettersCount = { result . letterCount }
130- />
142+
143+ < RevealMotion >
144+ < InfoTitle
145+ title = { result . title }
146+ participantCount = { result . participantCount }
147+ joinLettersCount = { result . letterCount }
148+ />
149+ </ RevealMotion >
150+ < CapsuleImage imageUrl = { result . beadVideoUrl } />
151+ < div className = { styles . container } >
152+ < RevealMotion delay = { 0.8 } >
153+ { result . subtitle && < CaptionSection description = { result . subtitle } /> }
154+ </ RevealMotion >
155+ < RevealMotion delay = { 1.2 } >
156+ < OpenInfoSection openAt = { formatDateTime ( result . openAt ) } />
131157 </ RevealMotion >
132- < CapsuleImage imageUrl = { result . beadVideoUrl } />
133- < div className = { styles . container } >
134- < RevealMotion delay = { 0.8 } >
135- { result . subtitle && < CaptionSection description = { result . subtitle } /> }
136- </ RevealMotion >
137- < RevealMotion delay = { 1.2 } >
138- < OpenInfoSection openAt = { formatDateTime ( result . openAt ) } />
139- </ RevealMotion >
140- </ div >
141- < ResponsiveFooter capsuleData = { data } isLoggedIn = { isLoggedIn } />
142- { result . status !== "WRITABLE" && < InfoToast status = { result . status } /> }
158+ </ div >
159+ < ResponsiveFooter capsuleData = { data } isLoggedIn = { isLoggedIn } />
160+ { result . status !== "WRITABLE" && < InfoToast status = { result . status } /> }
143161 </ >
144162 ) ;
145163} ;
0 commit comments