110 lines
2.9 KiB
Vue
110 lines
2.9 KiB
Vue
<script setup lang="ts">
|
|
import { useTemplateRegistry } from '#layers/composables/useTemplateRegistry'
|
|
import type {
|
|
PageDataValue,
|
|
PageDataTemplate,
|
|
PageDataMetaTag,
|
|
} from '#layers/types/api/pageData'
|
|
|
|
interface Props {
|
|
pageData: PageDataValue
|
|
}
|
|
|
|
const props = defineProps<Props>()
|
|
|
|
const { locale } = useI18n()
|
|
const { getTemplateComponent } = useTemplateRegistry()
|
|
|
|
const pinToMain = inject('pinToMain')
|
|
|
|
// 개별 메타 태그 표시 여부 확인
|
|
const shouldShowMetaTag = computed(() => props.pageData?.meta_tag_type === 2)
|
|
|
|
// 템플릿 표시 여부 확인
|
|
const isTemplateVisible = (template: PageDataTemplate): boolean => {
|
|
return Boolean(
|
|
template?.page_ver_tmpl_json &&
|
|
Object.keys(template?.page_ver_tmpl_json).length > 0
|
|
)
|
|
}
|
|
|
|
// 템플릿 목록 계산
|
|
const visibleTemplates = computed(() =>
|
|
Object.values(props.pageData?.templates).filter(isTemplateVisible)
|
|
)
|
|
const isShowTopBtn = computed(() => props.pageData?.use_top_btn ?? false)
|
|
const isShowSnsBtn = computed(() => props.pageData?.use_sns_btn ?? false)
|
|
const isShowLnb = computed(() => props.pageData?.use_lnb ?? false)
|
|
|
|
// SEO 메타 태그 설정
|
|
const setupSeoMeta = (metaTag: PageDataMetaTag) => {
|
|
useSeoMeta({
|
|
title: metaTag?.page_title ?? '',
|
|
description: metaTag?.page_desc ?? '',
|
|
ogTitle: metaTag?.og_title ?? '',
|
|
ogDescription: metaTag?.og_desc ?? '',
|
|
ogImage: metaTag?.og_image ?? '',
|
|
twitterTitle: metaTag?.x_title ?? '',
|
|
twitterImage: metaTag?.x_image ?? '',
|
|
twitterDescription: metaTag?.x_desc ?? '',
|
|
})
|
|
}
|
|
|
|
onMounted(() => {
|
|
const { sendLog } = useAnalytics()
|
|
sendLog(locale.value, useAnalyticsLogDataDirect('view', 1))
|
|
})
|
|
|
|
// 메타 태그 설정 감시
|
|
watchEffect(() => {
|
|
if (shouldShowMetaTag.value && props.pageData?.meta_tag_json) {
|
|
setupSeoMeta(props.pageData?.meta_tag_json)
|
|
}
|
|
})
|
|
</script>
|
|
|
|
<template>
|
|
<div class="main-content">
|
|
<template
|
|
v-for="(template, index) in visibleTemplates"
|
|
:key="template.template_code ?? index"
|
|
>
|
|
<component
|
|
:is="getTemplateComponent(template.template_code)"
|
|
:id="template.page_ver_tmpl_name_en"
|
|
:components="template.page_ver_tmpl_json"
|
|
:page-ver-tmpl-seq="template.page_ver_tmpl_seq"
|
|
/>
|
|
</template>
|
|
<ClientOnly>
|
|
<BlocksLnb v-if="isShowLnb" />
|
|
<div
|
|
v-if="isShowTopBtn || isShowSnsBtn"
|
|
:class="['utile-wrap', { 'is-stop': pinToMain }]"
|
|
>
|
|
<AtomsButtonScrollTop v-if="isShowTopBtn" />
|
|
<AtomsButtonSns v-if="isShowSnsBtn" />
|
|
</div>
|
|
</ClientOnly>
|
|
</div>
|
|
</template>
|
|
|
|
<style scoped>
|
|
.main-content {
|
|
@apply relative min-h-[200px] pt-[48px] md:min-h-[800px] md:pt-[64px];
|
|
}
|
|
.utile-wrap {
|
|
@apply fixed flex flex-col z-[100]
|
|
bottom-[12px] right-[12px] gap-2 md:bottom-[40px] md:right-[40px] md:gap-3;
|
|
}
|
|
.utile-wrap.is-stop {
|
|
@apply absolute;
|
|
}
|
|
|
|
[data-theme='light'] {
|
|
.main-content {
|
|
@apply bg-theme-foreground;
|
|
}
|
|
}
|
|
</style>
|