11'use client' ;
2- import React , { useState } from 'react' ;
2+ import React , { useEffect , useRef , useState } from 'react' ;
33import ExerciseInfo from '../components/ExerciseInfo' ;
44import SelectToggle from '../components/SelectToggle' ;
55import Comment from '../components/Comment' ;
66import Record from '../components/Record' ;
7- import { usePathname , useSearchParams } from 'next/navigation' ;
7+ import { usePathname , useRouter , useSearchParams } from 'next/navigation' ;
88import { useDetailsInfo } from '@/app/api/exercise-details/query' ;
9- import { useSession } from 'next-auth/react' ;
109import Header from '@/components/layouts/Header' ;
1110import Link from 'next/link' ;
1211import Back from '@/components/common/Back' ;
1312import Image from 'next/image' ;
14- import { useDetailLikeRegister } from '@/app/api/exercise/query' ;
13+ import { useDeleteCustomExerciseMutation , useDetailLikeRegister } from '@/app/api/exercise/query' ;
1514
1615const ExerciseDetails = ( ) => {
16+ const router = useRouter ( ) ;
1717 const searchParams = useSearchParams ( ) ;
1818 const type = searchParams . get ( 'type' ) ;
1919 const [ selected , setSelected ] = useState < 'explain' | 'record' > (
2020 type === 'default' ? 'explain' : 'record'
2121 ) ;
22-
22+ const [ isActiveMenu , setIsActiveMenu ] = useState < boolean > ( false ) ;
2323 const pathname = usePathname ( ) ;
2424
2525 const pathSegments = pathname . split ( '/' ) ;
2626 const lastSegment = pathSegments [ pathSegments . length - 1 ] ;
2727
28- const { data : session } = useSession ( ) ;
28+ const { deleteCustomExerciseMutation } = useDeleteCustomExerciseMutation ( ) ;
2929 const { postDetailLikeRegisterMutation } = useDetailLikeRegister ( ) ;
3030
3131 const { data } = useDetailsInfo ( { id : lastSegment , source : 'default' } ) ;
@@ -36,14 +36,29 @@ const ExerciseDetails = () => {
3636 source : type as 'custom' | 'default' ,
3737 } ) ;
3838 } ;
39+
40+ const menuRef = useRef < HTMLDivElement | null > ( null ) ;
41+
42+ const handleClickOutside = ( e : Event ) => {
43+ if ( menuRef . current && ! menuRef . current . contains ( e . target as Node ) ) {
44+ setIsActiveMenu ( false ) ;
45+ }
46+ } ;
47+
48+ useEffect ( ( ) => {
49+ document . addEventListener ( 'mousedown' , handleClickOutside ) ;
50+ return ( ) => {
51+ document . removeEventListener ( 'mousedown' , handleClickOutside ) ;
52+ } ;
53+ } , [ ] ) ;
3954 console . log ( data ) ;
4055 return (
4156 < div >
4257 { lastSegment !== 'edit' && (
4358 < Header
4459 className = { 'bg-backgrounds-default' }
4560 left = {
46- < Link href = "/" >
61+ < Link href = "/exercise-list/search " >
4762 < Back />
4863 </ Link >
4964 }
@@ -59,21 +74,50 @@ const ExerciseDetails = () => {
5974 height = { 24 }
6075 />
6176 { type === 'custom' && (
62- < Image
63- onClick = { handleHeartChange }
64- priority
65- src = { '/assets/menu.svg' }
66- alt = { '찜하기' }
67- width = { 28 }
68- height = { 28 }
69- className = "ml-4 rotate-90"
70- />
77+ < div className = "relative" >
78+ < Image
79+ priority
80+ src = { '/assets/menu.svg' }
81+ alt = { '메뉴' }
82+ width = { 28 }
83+ height = { 28 }
84+ className = "ml-4 rotate-90"
85+ onClick = { ( ) => setIsActiveMenu ( ( pre ) => ! pre ) }
86+ />
87+ { isActiveMenu && (
88+ < div
89+ ref = { menuRef }
90+ className = "absolute top-0 z-20 right-0 shadow-main bg-backgrounds-light text-md"
91+ >
92+ < div
93+ onClick = { ( ) => {
94+ router . push (
95+ `/custom-exercise?status=edit&exerciseId=${ data ?. data ?. exerciseId } `
96+ ) ;
97+ } }
98+ className = "cursor-pointer w-[152px] h-[46px] text-text-main p-3 border-b border-borders-sub"
99+ >
100+ 수정
101+ </ div >
102+ < div
103+ onClick = { ( ) =>
104+ deleteCustomExerciseMutation . mutate ( {
105+ id : String ( data ?. data ?. exerciseId ) ,
106+ } )
107+ }
108+ className = "w-[152px] h-[46px] text-text-accent p-3 cursor-pointer"
109+ >
110+ 삭제
111+ </ div >
112+ </ div >
113+ ) }
114+ </ div >
71115 ) }
72116 </ div >
73117 }
74118 />
75119 ) }
76- < ExerciseInfo id = { lastSegment } type = { type } info = { data ?. data } />
120+ < ExerciseInfo info = { data ?. data } />
77121 < SelectToggle type = { type } selected = { selected } setSelected = { setSelected } />
78122 { type === 'default' && selected === 'explain' && (
79123 < div className = "w-full px-5 mt-4 mb-10" >
@@ -87,7 +131,14 @@ const ExerciseDetails = () => {
87131 } ) }
88132 < div className = "w-[320px] h-[40px] rounded-6 border border-backgrounds-light text-s flex justify-between items-center px-4 mb-10 mt-5" >
89133 < div className = "leading-[18px] text-text-main " > 더 자세한 동작을 알고싶다면?</ div >
90- < div className = "leading-[18px] text-blue" > 동영상 보러 가기 </ div >
134+ < Link
135+ href = { `https://www.youtube.com/results?search_query=${ data ?. data ?. exerciseName } ` }
136+ className = "cursor-pointer leading-[18px] text-blue"
137+ target = "_blank"
138+ rel = "noopener noreferrer"
139+ >
140+ 동영상 보러 가기
141+ </ Link >
91142 </ div >
92143 < Comment />
93144 </ div >
0 commit comments