feat. 공통 로그 변경, 고정 템플릿 로그 추가
This commit is contained in:
@@ -7,11 +7,11 @@ import type {
|
||||
|
||||
const { locale } = useI18n()
|
||||
const gameDomain = useGetGameDomain()
|
||||
const { sendLog, useAnalyticsData } = useAnalytics()
|
||||
const { sendLog } = useAnalytics()
|
||||
|
||||
const analytics = {
|
||||
action_type: 'click',
|
||||
click_sarea: 'eventNavigation',
|
||||
click_sarea: 'EventNavigation',
|
||||
}
|
||||
|
||||
const isEventNavigationOpen = ref(true)
|
||||
@@ -48,7 +48,7 @@ const toggleEventNavigation = () => {
|
||||
...analytics,
|
||||
click_item: isEventNavigationOpen.value ? '열기' : '닫기',
|
||||
} as TrackingObject
|
||||
sendLog(locale.value, useAnalyticsData(navigationAnalytics))
|
||||
sendLog(locale.value, navigationAnalytics)
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
@@ -77,15 +77,13 @@ onMounted(async () => {
|
||||
<AtomsLocaleLink
|
||||
:to="item.page_url"
|
||||
:target="item.link_type === 2 ? '_blank' : '_self'"
|
||||
:rel="item.link_type === 2 ? 'noopener noreferrer' : undefined"
|
||||
class="item-link"
|
||||
@click="
|
||||
sendLog(
|
||||
locale,
|
||||
useAnalyticsData({
|
||||
...analytics,
|
||||
click_item: item.banner_title || item.promotion_name,
|
||||
})
|
||||
)
|
||||
sendLog(locale, {
|
||||
...analytics,
|
||||
click_item: item.banner_title || item.promotion_name,
|
||||
})
|
||||
"
|
||||
>
|
||||
<div class="item-thumbnail">
|
||||
|
||||
@@ -1,3 +1,184 @@
|
||||
<script setup lang="ts">
|
||||
import type {
|
||||
FooterMenuItem,
|
||||
FooterData,
|
||||
DevCiConfig,
|
||||
} from '#layers/types/components/footer'
|
||||
|
||||
// Configuration
|
||||
const runtimeConfig = useRuntimeConfig()
|
||||
const dataResourcesUrl = runtimeConfig.public.dataResourcesUrl as string
|
||||
const multilingualFileName = 'STOVE_PUBTEMPLATE_homepage_brand_footer.json'
|
||||
|
||||
// Multilingual
|
||||
const resultGetMultilingual = await useGetMultilingual({
|
||||
baseApiUrl: dataResourcesUrl,
|
||||
fileName: multilingualFileName,
|
||||
})
|
||||
const { tm, locale }: any = useI18n({
|
||||
useScope: 'local',
|
||||
messages: Object(resultGetMultilingual?.value?.multilingual),
|
||||
})
|
||||
|
||||
// Footer_caution 값이 있고 빈 객체가 아닌지 체크
|
||||
const hasCautionText = computed(() => {
|
||||
const value = tm('Footer_caution')
|
||||
|
||||
// null, undefined 체크
|
||||
if (value === null || value === undefined) {
|
||||
return false
|
||||
}
|
||||
|
||||
// 빈 객체 체크
|
||||
if (
|
||||
typeof value === 'object' &&
|
||||
!Array.isArray(value) &&
|
||||
Object.keys(value).length === 0
|
||||
) {
|
||||
return false
|
||||
}
|
||||
|
||||
// 문자열로 변환하여 빈 문자열 또는 '{}' 문자열 체크
|
||||
const stringValue = String(value).trim()
|
||||
if (stringValue === '' || stringValue === '{}') {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
})
|
||||
|
||||
const gameDataStore = useGameDataStore()
|
||||
const { gameData } = storeToRefs(gameDataStore)
|
||||
// const path = ref<string>(`${staticUrl}/local/template/${gameData.value.s3_folder_name}`)
|
||||
|
||||
// 공통다국어 data
|
||||
const footerLinks = computed((): FooterMenuItem[] => {
|
||||
const menu = (tm as any)('Footer_Menu')
|
||||
const menuItems = Array.isArray(menu) ? (menu as FooterMenuItem[]) : []
|
||||
|
||||
// ja일 때 fund_display_yn에 따라 id가 footerFund인 항목 처리
|
||||
if (locale.value === 'ja') {
|
||||
const fundDisplayYn = footerData.value?.fund_display_yn
|
||||
const fundDisplayUrl = footerData.value?.fund_display_url
|
||||
|
||||
// id가 footerFund인 항목의 인덱스 찾기
|
||||
const fundIndex = menuItems.findIndex(
|
||||
(item: any) => item.id === 'footerFund'
|
||||
)
|
||||
|
||||
// fund_display_yn이 'y'가 아니면 id가 footerFund인 항목 제거
|
||||
if (!fundDisplayYn) {
|
||||
return menuItems.filter((item: any) => item.id !== 'footerFund')
|
||||
}
|
||||
|
||||
// fund_display_yn이 'y'이면 id가 footerFund인 항목의 url 설정
|
||||
if (fundDisplayYn && fundIndex !== -1) {
|
||||
const updatedMenuItems = [...menuItems]
|
||||
updatedMenuItems[fundIndex] = {
|
||||
...updatedMenuItems[fundIndex],
|
||||
url: fundDisplayUrl || updatedMenuItems[fundIndex].url,
|
||||
}
|
||||
return updatedMenuItems
|
||||
}
|
||||
}
|
||||
|
||||
return menuItems
|
||||
})
|
||||
const footerData = ref(gameData.value?.footer_json as unknown as FooterData)
|
||||
const setDevCi = ref<DevCiConfig>({
|
||||
dev_ci_yn: gameData.value?.footer_dev_ci_img_yn as boolean,
|
||||
dev_ci_img_path: gameData.value?.footer_dev_ci_img_path as string,
|
||||
})
|
||||
|
||||
const useGameRating = computed<boolean>(() => {
|
||||
return footerData.value.use_game_rating
|
||||
})
|
||||
|
||||
///local/template/common/grades_age
|
||||
const getGameRatingImage = computed((): { type: string; image: string } => {
|
||||
// 안전하게 rating_type 값 확인
|
||||
if (
|
||||
!footerData.value?.game_rating_info?.rating_type ||
|
||||
typeof footerData.value.game_rating_info.rating_type !== 'string'
|
||||
) {
|
||||
return { type: '', image: '' }
|
||||
}
|
||||
|
||||
const contentInfo = footerData.value.game_rating_info.rating_type
|
||||
const ratingType = contentInfo.trim()
|
||||
|
||||
// 빈 문자열인 경우 처리
|
||||
if (!ratingType) {
|
||||
return { type: '', image: '' }
|
||||
}
|
||||
|
||||
const ageTypeMap: Record<string, string> = {
|
||||
'6': 'Type6',
|
||||
'12': 'Type12',
|
||||
'15': 'Type15',
|
||||
'18': 'Type18',
|
||||
'19': 'Type19',
|
||||
all: 'TypeAll',
|
||||
e: 'TypeExempt',
|
||||
}
|
||||
|
||||
const type = ageTypeMap[ratingType as keyof typeof ageTypeMap] || 'TypeTest'
|
||||
return {
|
||||
type,
|
||||
image: formatPathHost(
|
||||
`/images/common/grades_age/${locale.value}/${type}.svg`,
|
||||
{
|
||||
imageType: 'common',
|
||||
}
|
||||
),
|
||||
}
|
||||
})
|
||||
|
||||
const getContentInfoImage = computed((): string[] => {
|
||||
// 안전하게 content_info 값 확인
|
||||
if (
|
||||
!footerData.value?.game_rating_info?.content_info ||
|
||||
typeof footerData.value.game_rating_info.content_info !== 'string'
|
||||
) {
|
||||
return []
|
||||
}
|
||||
|
||||
const contentInfo = footerData.value.game_rating_info.content_info.split(',')
|
||||
contentInfo.pop()
|
||||
|
||||
const contentTypeMap: Record<string, string> = {
|
||||
'1': 'Type-sexual',
|
||||
'2': 'Type-violence',
|
||||
'3': 'Type-fear',
|
||||
'4': 'Type-inapposite',
|
||||
'5': 'Type-drug',
|
||||
'6': 'Type-crime',
|
||||
'7': 'Type-speculation',
|
||||
}
|
||||
|
||||
return contentInfo
|
||||
.map(item => {
|
||||
const type = contentTypeMap[item]
|
||||
return type
|
||||
? formatPathHost(`/images/common/grades_use/${type}.svg`, {
|
||||
imageType: 'common',
|
||||
})
|
||||
: ''
|
||||
})
|
||||
.filter(Boolean)
|
||||
})
|
||||
|
||||
const showAgeRating = ref<boolean>(false)
|
||||
const toggleAgeRating = (): void => {
|
||||
showAgeRating.value = !showAgeRating.value
|
||||
}
|
||||
|
||||
const footerAgeRatingInfo = computed((): string[] => {
|
||||
const info = (tm as any)('Footer_AgeRating_Info')
|
||||
return Array.isArray(info) ? info : []
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<footer id="footer" ref="footerRef" class="relative bg-blac">
|
||||
<div
|
||||
@@ -91,13 +272,22 @@
|
||||
</div>
|
||||
|
||||
<!-- 정보 테이블 -->
|
||||
<div v-if="locale === 'zh-tw'" class="px-6 py-6 rounded-b-lg bg-[#292929]">
|
||||
<div
|
||||
v-if="locale === 'zh-tw'"
|
||||
class="px-6 py-6 rounded-b-lg bg-[#292929]"
|
||||
>
|
||||
<div class="space-y-2">
|
||||
<div v-dompurify-html="tm('Footer_AgeRating_Caution')"></div>
|
||||
<div
|
||||
v-dompurify-html="tm('Footer_AgeRating_Caution')"
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-else class="px-6 py-6 rounded-b-lg bg-[#A31639]" :class="`bg-${getGameRatingImage.type}`">
|
||||
<div
|
||||
v-else
|
||||
class="px-6 py-6 rounded-b-lg bg-[#A31639]"
|
||||
:class="`bg-${getGameRatingImage.type}`"
|
||||
>
|
||||
<div class="space-y-2">
|
||||
<div class="flex flex-start border-b border-white/10 pb-2">
|
||||
<span class="text-white text-sm flex-1">
|
||||
@@ -159,13 +349,12 @@
|
||||
<div
|
||||
class="language-area static md:absolute bottom-7 right-10 text-white mt-5 md:mt-0 md:bottom-5.5 md:right-4"
|
||||
>
|
||||
<BlocksLanguageSwitcher :language-order="tm('Footer_Language_Order')" />
|
||||
<BlocksLanguageSwitcher
|
||||
:language-order="tm('Footer_Language_Order')"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="hasCautionText"
|
||||
class="mt-6 md:mt-6 hidden sm:block"
|
||||
>
|
||||
<div v-if="hasCautionText" class="mt-6 md:mt-6 hidden sm:block">
|
||||
<div
|
||||
v-dompurify-html="tm('Footer_caution')"
|
||||
class="text-xs text-white/30"
|
||||
@@ -178,7 +367,11 @@
|
||||
|
||||
<div class="logo-area flex items-center gap-7 mt-6 md:mt-6">
|
||||
<span>
|
||||
<a :href="tm('Footer_Smilegate_Link')" target="_blank" class="smilegate">
|
||||
<a
|
||||
:href="tm('Footer_Smilegate_Link')"
|
||||
target="_blank"
|
||||
class="smilegate"
|
||||
>
|
||||
<img
|
||||
:src="
|
||||
formatPathHost(`/images/common/logo_smilegate.png`, {
|
||||
@@ -225,183 +418,6 @@
|
||||
</footer>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type {
|
||||
FooterMenuItem,
|
||||
FooterData,
|
||||
DevCiConfig,
|
||||
} from '#layers/types/Common'
|
||||
|
||||
// Configuration
|
||||
const runtimeConfig = useRuntimeConfig()
|
||||
const dataResourcesUrl = runtimeConfig.public.dataResourcesUrl as string
|
||||
const multilingualFileName = 'STOVE_PUBTEMPLATE_homepage_brand_footer.json'
|
||||
|
||||
// Multilingual
|
||||
const resultGetMultilingual = await useGetMultilingual({
|
||||
baseApiUrl: dataResourcesUrl,
|
||||
fileName: multilingualFileName,
|
||||
})
|
||||
const { tm, locale }: any = useI18n({
|
||||
useScope: 'local',
|
||||
messages: Object(resultGetMultilingual?.value?.multilingual),
|
||||
})
|
||||
|
||||
|
||||
// Footer_caution 값이 있고 빈 객체가 아닌지 체크
|
||||
const hasCautionText = computed(() => {
|
||||
const value = tm('Footer_caution')
|
||||
|
||||
// null, undefined 체크
|
||||
if (value === null || value === undefined) {
|
||||
return false
|
||||
}
|
||||
|
||||
// 빈 객체 체크
|
||||
if (typeof value === 'object' && !Array.isArray(value) && Object.keys(value).length === 0) {
|
||||
return false
|
||||
}
|
||||
|
||||
// 문자열로 변환하여 빈 문자열 또는 '{}' 문자열 체크
|
||||
const stringValue = String(value).trim()
|
||||
if (stringValue === '' || stringValue === '{}') {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
})
|
||||
|
||||
const gameDataStore = useGameDataStore()
|
||||
const { gameData } = storeToRefs(gameDataStore)
|
||||
// const path = ref<string>(`${staticUrl}/local/template/${gameData.value.s3_folder_name}`)
|
||||
|
||||
// 공통다국어 data
|
||||
const footerLinks = computed((): FooterMenuItem[] => {
|
||||
const menu = (tm as any)('Footer_Menu')
|
||||
const menuItems = Array.isArray(menu) ? (menu as FooterMenuItem[]) : []
|
||||
|
||||
// ja일 때 fund_display_yn에 따라 id가 footerFund인 항목 처리
|
||||
if (locale.value === 'ja') {
|
||||
const fundDisplayYn = footerData.value?.fund_display_yn
|
||||
const fundDisplayUrl = footerData.value?.fund_display_url
|
||||
|
||||
// id가 footerFund인 항목의 인덱스 찾기
|
||||
const fundIndex = menuItems.findIndex((item: any) => item.id === 'footerFund')
|
||||
|
||||
// fund_display_yn이 'y'가 아니면 id가 footerFund인 항목 제거
|
||||
if (!fundDisplayYn) {
|
||||
return menuItems.filter((item: any) => item.id !== 'footerFund')
|
||||
}
|
||||
|
||||
// fund_display_yn이 'y'이면 id가 footerFund인 항목의 url 설정
|
||||
if (fundDisplayYn && fundIndex !== -1) {
|
||||
const updatedMenuItems = [...menuItems]
|
||||
updatedMenuItems[fundIndex] = {
|
||||
...updatedMenuItems[fundIndex],
|
||||
url: fundDisplayUrl || updatedMenuItems[fundIndex].url
|
||||
}
|
||||
return updatedMenuItems
|
||||
}
|
||||
}
|
||||
|
||||
return menuItems
|
||||
})
|
||||
const footerData = ref(gameData.value?.footer_json as unknown as FooterData)
|
||||
const setDevCi = ref<DevCiConfig>({
|
||||
dev_ci_yn: gameData.value?.footer_dev_ci_img_yn as boolean,
|
||||
dev_ci_img_path: gameData.value?.footer_dev_ci_img_path as string,
|
||||
})
|
||||
|
||||
const useGameRating = computed<boolean>(() => {
|
||||
return footerData.value.use_game_rating
|
||||
})
|
||||
|
||||
///local/template/common/grades_age
|
||||
const getGameRatingImage = computed((): { type: string, image: string } => {
|
||||
// 안전하게 rating_type 값 확인
|
||||
if (
|
||||
!footerData.value?.game_rating_info?.rating_type ||
|
||||
typeof footerData.value.game_rating_info.rating_type !== 'string'
|
||||
) {
|
||||
return { type: '', image: '' }
|
||||
}
|
||||
|
||||
const contentInfo = footerData.value.game_rating_info.rating_type
|
||||
const ratingType = contentInfo.trim()
|
||||
|
||||
// 빈 문자열인 경우 처리
|
||||
if (!ratingType) {
|
||||
return { type: '', image: '' }
|
||||
}
|
||||
|
||||
const ageTypeMap: Record<string, string> = {
|
||||
'6': 'Type6',
|
||||
'12': 'Type12',
|
||||
'15': 'Type15',
|
||||
'18': 'Type18',
|
||||
'19': 'Type19',
|
||||
all: 'TypeAll',
|
||||
e: 'TypeExempt',
|
||||
}
|
||||
|
||||
const type = ageTypeMap[ratingType as keyof typeof ageTypeMap] || 'TypeTest'
|
||||
return {
|
||||
type,
|
||||
image: formatPathHost(
|
||||
`/images/common/grades_age/${locale.value}/${type}.svg`,
|
||||
{
|
||||
imageType: 'common',
|
||||
}
|
||||
),
|
||||
}
|
||||
})
|
||||
|
||||
const getContentInfoImage = computed((): string[] => {
|
||||
// 안전하게 content_info 값 확인
|
||||
if (
|
||||
!footerData.value?.game_rating_info?.content_info ||
|
||||
typeof footerData.value.game_rating_info.content_info !== 'string'
|
||||
) {
|
||||
return []
|
||||
}
|
||||
|
||||
const contentInfo = footerData.value.game_rating_info.content_info.split(',')
|
||||
contentInfo.pop()
|
||||
|
||||
const contentTypeMap: Record<string, string> = {
|
||||
'1': 'Type-sexual',
|
||||
'2': 'Type-violence',
|
||||
'3': 'Type-fear',
|
||||
'4': 'Type-inapposite',
|
||||
'5': 'Type-drug',
|
||||
'6': 'Type-crime',
|
||||
'7': 'Type-speculation',
|
||||
}
|
||||
|
||||
return contentInfo
|
||||
.map(item => {
|
||||
const type = contentTypeMap[item]
|
||||
return type
|
||||
? formatPathHost(`/images/common/grades_use/${type}.svg`, {
|
||||
imageType: 'common',
|
||||
})
|
||||
: ''
|
||||
})
|
||||
.filter(Boolean)
|
||||
})
|
||||
|
||||
const showAgeRating = ref<boolean>(false)
|
||||
const toggleAgeRating = (): void => {
|
||||
showAgeRating.value = !showAgeRating.value
|
||||
}
|
||||
|
||||
const footerAgeRatingInfo = computed((): string[] => {
|
||||
const info = (tm as any)('Footer_AgeRating_Info')
|
||||
return Array.isArray(info) ? info : []
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
em {
|
||||
font-style: normal;
|
||||
@@ -412,11 +428,11 @@ em {
|
||||
}
|
||||
|
||||
.bg-Type12 {
|
||||
background-color: #4369B1;
|
||||
background-color: #4369b1;
|
||||
}
|
||||
|
||||
.bg-Type15 {
|
||||
background-color: #F9B846;
|
||||
background-color: #f9b846;
|
||||
}
|
||||
|
||||
.bg-Type18 {
|
||||
@@ -424,11 +440,11 @@ em {
|
||||
}
|
||||
|
||||
.bg-Type19 {
|
||||
background-color: #A31639;
|
||||
background-color: #a31639;
|
||||
}
|
||||
|
||||
.bg-TypeAll {
|
||||
background-color: #44A342;
|
||||
background-color: #44a342;
|
||||
}
|
||||
|
||||
.bg-TypeExempt {
|
||||
|
||||
@@ -18,7 +18,7 @@ const gameDataStore = useGameDataStore()
|
||||
const pageDataStore = usePageDataStore()
|
||||
const scrollStore = useScrollStore()
|
||||
const breakpoints = useResponsiveBreakpoints()
|
||||
const { sendLog, useAnalyticsData } = useAnalytics()
|
||||
const { sendLog } = useAnalytics()
|
||||
|
||||
const { gameData } = storeToRefs(gameDataStore)
|
||||
const { pageLayoutType } = storeToRefs(pageDataStore)
|
||||
@@ -145,14 +145,14 @@ const handleSendLog = (item: string) => {
|
||||
click_item: item,
|
||||
click_sarea: 'GNB',
|
||||
}
|
||||
sendLog(locale.value, useAnalyticsData(analytics))
|
||||
sendLog(locale.value, analytics)
|
||||
}
|
||||
|
||||
const handleGnbItemClick = (gnbItem: GameDataMenu) => {
|
||||
if (isNotClickable(gnbItem)) return
|
||||
|
||||
handleMenuClose()
|
||||
sendLog(locale.value, useAnalyticsData(gnbItem.tracking_json))
|
||||
sendLog(locale.value, gnbItem.tracking_json)
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
@@ -389,9 +389,7 @@ onMounted(() => {
|
||||
:text-color="
|
||||
getColorCodeFromData(start1depthData?.btn_info, 'txt')
|
||||
"
|
||||
@click="
|
||||
sendLog(locale, useAnalyticsData(start1depthData.tracking))
|
||||
"
|
||||
@click="sendLog(locale, start1depthData.tracking)"
|
||||
>
|
||||
{{ start1depthData?.btn_info?.txt_btn_name }}
|
||||
</BlocksButtonLauncher>
|
||||
@@ -404,9 +402,7 @@ onMounted(() => {
|
||||
<BlocksButtonLauncher
|
||||
type="custom"
|
||||
:platform="key"
|
||||
@click="
|
||||
sendLog(locale, useAnalyticsData(item.tracking))
|
||||
"
|
||||
@click="sendLog(locale, item.tracking)"
|
||||
>
|
||||
{{ item.btn_info?.txt_btn_name }}
|
||||
</BlocksButtonLauncher>
|
||||
|
||||
@@ -75,7 +75,7 @@ watch(isPAssApiLoading, newVal => {
|
||||
|
||||
onMounted(() => {
|
||||
const { sendLog } = useAnalytics()
|
||||
sendLog(locale.value, useAnalyticsData('view'))
|
||||
sendLog(locale.value, 'view')
|
||||
|
||||
if (!hasApiCallStarted.value) {
|
||||
loadingStore.stopFullLoading()
|
||||
|
||||
Reference in New Issue
Block a user