@@ -11,6 +11,8 @@ import { axiosClient } from "@/apis/axiosClient";
1111import { isAuthError } from "@/apis/errors" ;
1212// import { useToastStore } from "@/states/useToastStore";
1313import SenifitDialog from "@/components/SenifitDialog" ;
14+ import { getGtmClassType , pushGtmEvent } from "@/utils/gtm" ;
15+ import { WorkoutKind } from "@/types/IRoutine" ;
1416
1517export interface IWorkoutVideo {
1618 id : number ;
@@ -34,6 +36,7 @@ export interface IWorkoutVideoPlaylistProps {
3436 /** 인덱스 변경 콜백(옵션) */
3537 onIndexChange ?: ( index : number , video : IWorkoutVideo ) => void ;
3638 duration : number ;
39+ type : "customized" | "popular" | [ "thematic" , WorkoutKind ] | null ;
3740}
3841
3942/** DOM 요소의 실시간 높이를 구하는 훅 */
@@ -68,6 +71,7 @@ export default function WorkoutVideoPlaylist({
6871 assetBaseUrl,
6972 onIndexChange,
7073 duration,
74+ type,
7175} : IWorkoutVideoPlaylistProps ) {
7276 const { isPhone } = useMedia ( ) ;
7377 const router = useRouter ( ) ;
@@ -160,6 +164,15 @@ export default function WorkoutVideoPlaylist({
160164 } ;
161165 } , [ recordId ] ) ;
162166
167+ const progressFired = useRef ( false ) ;
168+ useEffect ( ( ) => {
169+ const halfDuration = Math . floor ( duration * 30 ) ;
170+ if ( ! progressFired . current && seconds >= halfDuration && halfDuration > 0 ) {
171+ pushGtmEvent ( "click_Progress" , getGtmClassType ( type ) ) ;
172+ progressFired . current = true ;
173+ }
174+ } , [ seconds , duration , type ] ) ;
175+
163176 // 이탈 방지 bypass 플래그 (앱 내부 이동 시 사용)
164177 const shouldBypassUnload = useRef ( false ) ;
165178
@@ -281,6 +294,7 @@ export default function WorkoutVideoPlaylist({
281294 isEnd = { index === videos . length - 1 }
282295 onEnd = { notifyDone }
283296 seconds = { seconds }
297+ type = { type }
284298 />
285299 </ Box >
286300
0 commit comments