feat: 버튼 로그 추가

This commit is contained in:
“hyeonggkim”
2025-10-20 17:02:10 +09:00
parent f1bb39a5d0
commit 9f6056ef77
9 changed files with 129 additions and 33 deletions

View File

@@ -18,7 +18,7 @@ const props = withDefaults(defineProps<Props>(), {
pagination: true,
})
const emit = defineEmits(['mounted', 'move', 'moved'])
const emit = defineEmits(['mounted', 'move', 'moved', 'arrowClick'])
const isMultipleItems = computed(() => {
return props.slideItemLength > 1
@@ -82,6 +82,11 @@ const style = computed(() => {
const handleSplideMounted = (splide: SplideType) => {
emit('mounted', splide)
splide.refresh()
// 화살표 버튼 클릭 이벤트 리스너 추가
nextTick(() => {
addArrowClickListeners(splide)
})
}
const handleMove = (
@@ -101,6 +106,37 @@ const handleMoved = (
) => {
emit('moved', splide, newIndex, oldIndex, destIndex)
}
const handleArrowClick = (direction: 'prev' | 'next', splide: SplideType) => {
const currentIndex = splide.index
const totalSlides = splide.length
// 이동할 슬라이드 인덱스 계산
let targetIndex: number
if (direction === 'next') {
targetIndex = currentIndex + 1 >= totalSlides ? 0 : currentIndex + 1
} else {
targetIndex = currentIndex - 1 < 0 ? totalSlides - 1 : currentIndex - 1
}
emit('arrowClick', direction, targetIndex)
}
// 화살표 버튼에 클릭 이벤트 리스너 추가
const addArrowClickListeners = (splide: SplideType) => {
const prevArrow = splide.root.querySelector('.arrow-prev')
const nextArrow = splide.root.querySelector('.arrow-next')
if (prevArrow) {
prevArrow.addEventListener('click', () => handleArrowClick('prev', splide))
}
if (nextArrow) {
nextArrow.addEventListener('click', () => handleArrowClick('next', splide))
}
}
</script>
<template>

View File

@@ -21,7 +21,12 @@ interface Props {
style?: Record<string, string>
}
const {locale} = useI18n()
const props = defineProps<Props>()
const { sendLog, useAnalyticsLogDataDirect } = useAnalytics()
const emit = defineEmits(['arrowClick'])
let mainInst: SplideType | null = null
let thumbsInst: SplideType | null = null
@@ -86,12 +91,51 @@ const isPassVideo = (item: PageDataTemplateComponentSet, index: number) => {
const handleVideoClick = (index: number) => {
playingSlideIndex.value = index
// tracking 데이터 수정
const modifiedTracking = {
...props.videoPlay.tracking,
click_item: props.videoPlay.tracking.click_item + `_${index}`
}
const trackingData = {
tracking: modifiedTracking
};
sendLog(locale.value, useAnalyticsLogDataDirect(trackingData, 1))
}
const stopVideo = () => {
playingSlideIndex.value = null
}
const handleArrowClick = (direction: 'prev' | 'next', splide: SplideType) => {
const currentIndex = splide.index
const totalSlides = splide.length
// 이동할 슬라이드 인덱스 계산
let targetIndex: number
if (direction === 'next') {
targetIndex = currentIndex + 1 >= totalSlides ? 0 : currentIndex + 1
} else {
targetIndex = currentIndex - 1 < 0 ? totalSlides - 1 : currentIndex - 1
}
emit('arrowClick', direction, targetIndex)
}
// 화살표 버튼에 클릭 이벤트 리스너 추가
const addArrowClickListeners = (splide: SplideType) => {
const prevArrow = splide.root.querySelector('.arrow-prev')
const nextArrow = splide.root.querySelector('.arrow-next')
if (prevArrow) {
prevArrow.addEventListener('click', () => handleArrowClick('prev', splide))
}
if (nextArrow) {
nextArrow.addEventListener('click', () => handleArrowClick('next', splide))
}
}
onMounted(() => {
mainInst = mainRef.value?.splide ?? null
thumbsInst = thumbsRef.value?.splide ?? null
@@ -99,6 +143,11 @@ onMounted(() => {
if (mainInst && thumbsInst) {
mainInst.sync(thumbsInst)
mainInst.on('moved', stopVideo)
// 썸네일 슬라이드의 화살표 버튼에 이벤트 리스너 추가
nextTick(() => {
addArrowClickListeners(thumbsInst)
})
}
})
@@ -117,6 +166,7 @@ onBeforeUnmount(() => {
:key="item.set_order || index"
class="main-slide"
>
{{ item }}
<img
:src="getMediaImgSrcFromItem(item)"
alt="main image"

View File

@@ -2,7 +2,6 @@
import type {
PageDataResourceGroup,
PageDataResourceGroupBtnInfo,
PageDataTracking,
} from '#layers/types/api/pageData'
import type { ButtonType } from '#layers/types/components/button'
@@ -12,11 +11,8 @@ interface ButtonListProps {
}
const props = defineProps<ButtonListProps>()
const { sendLog, useAnalyticsLogDataDirect } = useAnalytics()
const {locale} = useI18n()
const { gameData } = useGameDataStore()
const BUTTON_TYPE_MAP = {
URL: {
_self: 'internal' as const,
@@ -58,18 +54,18 @@ const getButtonBackgroundImage = (
return ''
}
const handleButtonClick = (btnInfo: PageDataResourceGroupBtnInfo) => {
const { locale } = useI18n()
const { sendLog, useAnalyticsLogDataDirect } = useAnalytics()
const handleButtonClick = (btnInfo: PageDataResourceGroupBtnInfo, index: any) => {
sendLog(locale.value, useAnalyticsLogDataDirect(props.resourcesData[index], props.pageVerTmplSeq))
const marketType = btnInfo?.detail?.market_type
if (marketType) {
const url = gameData?.market[marketType]?.url
window.open(url, '_blank')
return
}
// sendLog(locale.value, useAnalyticsLogDataDirect(btnInfo, props.pageVerTmplSeq))
// v-analytics="useAnalyticsLogDataDirect(props.resourcesData[0].tracking, props.pageVerTmplSeq)"
}
</script>
@@ -81,7 +77,6 @@ const handleButtonClick = (btnInfo: PageDataResourceGroupBtnInfo) => {
<AtomsButton
v-for="(button, index) in props.resourcesData"
:key="index"
v-analytics="useAnalyticsLogDataDirect(props.resourcesData[index].tracking, props.pageVerTmplSeq)"
:type="getButtonType(button.btn_info)"
:target="button.btn_info?.detail?.action?.link_target"
:href="button.btn_info?.detail?.action?.url"
@@ -103,7 +98,7 @@ const handleButtonClick = (btnInfo: PageDataResourceGroupBtnInfo) => {
:style="{
backgroundImage: `url(${getButtonBackgroundImage(button.btn_info)})`,
}"
@click="handleButtonClick(button.btn_info)"
@click="handleButtonClick(button.btn_info, index)"
>
{{ button.btn_info?.txt_btn_name }}
</AtomsButton>

View File

@@ -6,7 +6,7 @@ const props = defineProps<{
pageVerTmplSeq: number
}>()
const { useAnalyticsLogDataDirect } = useAnalytics()
const logData = useAnalyticsLogDataDirect(props.resourcesData.tracking, props.pageVerTmplSeq)
const logData = useAnalyticsLogDataDirect(props.resourcesData, props.pageVerTmplSeq)
// YouTube 모달 스토어 사용
const modalStore = useModalStore()

View File

@@ -1,7 +1,6 @@
import * as amplitude from '@amplitude/analytics-browser'
import type {
AnalyticsDetailType,
AnalyticsLogDataTracking,
} from '../types/AnalyticsType'
import type { PageDataResourceGroup } from '#layers/types/api/pageData'
import type { IdentityInfo, ActionInfo, MarketingInfo } from '../types/Stove'
@@ -27,7 +26,8 @@ export const useAnalyticsLogData = (
return ref({} as AnalyticsDetailType)
}
const pageDataTrack = (typeof resourcesData.tracking === 'object' ? resourcesData.tracking : {}) as AnalyticsLogDataTracking
// const pageDataTrack = (typeof resourcesData.tracking === 'object' ? resourcesData.tracking : {}) as AnalyticsLogDataTracking
const pageDataTrack = resourcesData.tracking
const logData = ref({
actionType: pageDataTrack?.action_type,
@@ -64,8 +64,8 @@ export const useAnalyticsLogDataDirect = (
if (!pageData) {
return {} as AnalyticsDetailType
}
const pageDataTrack = (typeof resourcesData === 'object' ? resourcesData : {}) as AnalyticsLogDataTracking
// const pageDataTrack = (typeof resourcesData.tracking === 'object' ? resourcesData.tracking : {}) as AnalyticsLogDataTracking
const pageDataTrack = resourcesData.tracking
const logData = {
actionType: pageDataTrack?.action_type,

View File

@@ -24,13 +24,20 @@ const slideData = computed(() => {
const videoPlayData = computed(() =>
getComponentGroup(props.components, 'videoPlay')
)
const {locale} = useI18n()
const { sendLog, useAnalyticsLogDataDirect } = useAnalytics()
const onArrowClick = (direction, targetIndex) => {
const logTraking = direction == 'prev' ? props.components.arrow.groups[0] : props.components.arrow.groups[1];
sendLog(locale.value, useAnalyticsLogDataDirect(logTraking, 1))
}
</script>
<template>
<section class="section-container">
<WidgetsBackground v-if="backgroundData" :resources-data="backgroundData" />
<div class="section-content">
<WidgetsMainTitle
<WidgetsMainTitle
v-if="mainTitleData"
:resources-data="mainTitleData"
class="title-sm"
@@ -39,6 +46,7 @@ const videoPlayData = computed(() =>
:slide-data="slideData"
:video-play="videoPlayData"
class="mt-[24px] md:mt-[32px]"
@arrow-click="onArrowClick"
/>
</div>
</section>

View File

@@ -54,6 +54,12 @@ const handleChange = (
'buttonList'
)
}
const {locale} = useI18n()
const { sendLog, useAnalyticsLogDataDirect } = useAnalytics()
const onArrowClick = (direction, targetIndex) => {
const logTraking = direction == 'prev' ? props.components.arrow.groups[0] : props.components.arrow.groups[1];
sendLog(locale.value, useAnalyticsLogDataDirect(logTraking, 1))
}
</script>
<template>
@@ -72,11 +78,13 @@ const handleChange = (
:pagination="false"
class="mt-[24px] md:mt-[48px]"
@move="handleChange"
@arrow-click="onArrowClick"
>
<SplideSlide v-for="(item, index) in slideData" :key="index">
<div class="slide-inner border-line mt-auto">
<BlocksVisualContent
:resources-data="getComponentGroup(item, 'imgList')"
:page-ver-tmpl-seq="Number(props.pageVerTmplSeq)"
object-fit="cover"
:alt="getComponentGroup(item, 'subTitle')?.display?.text"
/>

View File

@@ -18,15 +18,8 @@ const props = defineProps<Props>()
const { sendLog, useAnalyticsLogDataDirect } = useAnalytics()
const onArrowClick = (direction, targetIndex) => {
// tracking 데이터 복사 및 click_item 수정
const modifiedTracking = {
...props.components.arrow.groups[targetIndex].tracking,
click_item: props.components.arrow.groups[targetIndex].tracking.click_item + `_slide${targetIndex}`
}
sendLog(locale.value, useAnalyticsLogDataDirect(new Proxy(modifiedTracking, {}), Number(props.pageVerTmplSeq)))
const logTraking = direction == 'prev' ? props.components.arrow.groups[0] : props.components.arrow.groups[1];
sendLog(locale.value, useAnalyticsLogDataDirect(logTraking, 1))
}
</script>

View File

@@ -98,7 +98,7 @@ export interface PageDataResourceGroup {
color_code?: string
color_name?: string
}
tracking: string
tracking: PageDataTracking
}
export type PageDataResourceGroups = PageDataResourceGroup[]
@@ -118,11 +118,11 @@ export type PageDataTemplateComponentSet = PageDataTemplateComponent & {
set_order?: number
}
// 템플릿 컴포넌트 타입 - 가지 패턴
// 템플릿 컴포넌트 타입 - 가지 패턴
export type PageDataTemplateComponents =
| PageDataTemplateComponent // 단일 컴포넌트 패턴
| { group_sets: PageDataTemplateComponentSet[] } // 그룹 세트 패턴
| { group_sets: PageDataTemplateComponentSet[], arrow: PageDataArrowComponent } // 그룹 세트 패턴
// 템플릿 타입
export interface PageDataTemplate {
page_ver_tmpl_seq: number
@@ -170,4 +170,10 @@ export interface PageDataTracking {
click_item: string
action_type: string
click_sarea: string
}
}
// Arrow 컴포넌트 타입
export type PageDataArrowComponent = PageDataTemplateComponent & {
groups: PageDataResourceGroups
}