feat. FX_PREREGIST_01 템플릿 제작
@@ -36,7 +36,7 @@
|
|||||||
@apply line-clamp-2 text-[16px] font-[500] leading-[24px] drop-shadow-[0_2px_2px_rgba(0,0,0,0.6)] md:line-clamp-1 md:text-[24px] md:leading-[34px];
|
@apply line-clamp-2 text-[16px] font-[500] leading-[24px] drop-shadow-[0_2px_2px_rgba(0,0,0,0.6)] md:line-clamp-1 md:text-[24px] md:leading-[34px];
|
||||||
}
|
}
|
||||||
.title-sm {
|
.title-sm {
|
||||||
@apply text-[15px] font-[500] leading-[24px] tracking-[-0.45px] md:text-[20px] md:leading-[30px] md:tracking-[-0.6px];
|
@apply text-[15px] font-[500] leading-[24px] tracking-[-0.45px] drop-shadow-[0_2px_2px_rgba(0,0,0,0.6)] md:text-[20px] md:leading-[30px] md:tracking-[-0.6px];
|
||||||
}
|
}
|
||||||
.title-xs {
|
.title-xs {
|
||||||
@apply text-[14px] font-[500] leading-[20px] tracking-[-0.42px] md:text-[18px] md:leading-[26px] md:tracking-[-0.54px];
|
@apply text-[14px] font-[500] leading-[20px] tracking-[-0.42px] md:text-[18px] md:leading-[26px] md:tracking-[-0.54px];
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ interface Props {
|
|||||||
arrows?: boolean
|
arrows?: boolean
|
||||||
pagination?: boolean
|
pagination?: boolean
|
||||||
paginationData?: PageDataResourceGroups
|
paginationData?: PageDataResourceGroups
|
||||||
|
destroy?: boolean
|
||||||
breakpoints?: ResponsiveOptions['breakpoints']
|
breakpoints?: ResponsiveOptions['breakpoints']
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -23,6 +24,7 @@ const props = withDefaults(defineProps<Props>(), {
|
|||||||
drag: true,
|
drag: true,
|
||||||
arrows: true,
|
arrows: true,
|
||||||
pagination: true,
|
pagination: true,
|
||||||
|
destroy: false,
|
||||||
})
|
})
|
||||||
|
|
||||||
const emit = defineEmits(['mounted', 'move', 'arrowClick'])
|
const emit = defineEmits(['mounted', 'move', 'arrowClick'])
|
||||||
@@ -50,6 +52,7 @@ const options = computed((): ResponsiveOptions => {
|
|||||||
trimSpace: false,
|
trimSpace: false,
|
||||||
arrows: props.arrows,
|
arrows: props.arrows,
|
||||||
pagination: props.pagination,
|
pagination: props.pagination,
|
||||||
|
destroy: props.destroy,
|
||||||
classes: {
|
classes: {
|
||||||
arrows: 'splide-arrows',
|
arrows: 'splide-arrows',
|
||||||
arrow: 'splide-arrow',
|
arrow: 'splide-arrow',
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import GrBoard01 from '#layers/templates/GrBoard01/index.vue'
|
|||||||
import GrContents01 from '#layers/templates/GrContents01/index.vue'
|
import GrContents01 from '#layers/templates/GrContents01/index.vue'
|
||||||
import FxVideo01 from '#layers/templates/FxVideo01/index.vue'
|
import FxVideo01 from '#layers/templates/FxVideo01/index.vue'
|
||||||
import FxDownload01 from '#layers/templates/FxDownload01/index.vue'
|
import FxDownload01 from '#layers/templates/FxDownload01/index.vue'
|
||||||
|
import FxPreregist01 from '#layers/templates/FxPreregist01/index.vue'
|
||||||
|
|
||||||
const templateRegistry = {
|
const templateRegistry = {
|
||||||
GR_VISUAL_01: { component: GrVisual01 },
|
GR_VISUAL_01: { component: GrVisual01 },
|
||||||
@@ -26,6 +27,7 @@ const templateRegistry = {
|
|||||||
GR_CONTENTS_01: { component: GrContents01 },
|
GR_CONTENTS_01: { component: GrContents01 },
|
||||||
FX_VIDEO_01: { component: FxVideo01 },
|
FX_VIDEO_01: { component: FxVideo01 },
|
||||||
FX_DOWNLOAD_01: { component: FxDownload01 },
|
FX_DOWNLOAD_01: { component: FxDownload01 },
|
||||||
|
FX_PREREGIST_01: { component: FxPreregist01 },
|
||||||
} as const
|
} as const
|
||||||
|
|
||||||
type TemplateKey = keyof typeof templateRegistry
|
type TemplateKey = keyof typeof templateRegistry
|
||||||
|
|||||||
@@ -1,15 +1,7 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts"></script>
|
||||||
console.log('🚀 ~ promotion')
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="promotion-wrap">
|
<LayoutsHeader />
|
||||||
<slot />
|
<slot />
|
||||||
</div>
|
<LayoutsFooter />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.promo-wrap {
|
|
||||||
background-color: tan;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|||||||
627
layers/templates/FxPreregist01/index.vue
Normal file
@@ -0,0 +1,627 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { SplideSlide } from '@splidejs/vue-splide'
|
||||||
|
import { getComponentGroup, getComponentGroupAry } from '#layers/utils/dataUtil'
|
||||||
|
import type { PageDataTemplateComponents } from '#layers/types/api/pageData'
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
components: PageDataTemplateComponents
|
||||||
|
pageVerTmplSeq: number
|
||||||
|
}
|
||||||
|
|
||||||
|
const props = defineProps<Props>()
|
||||||
|
|
||||||
|
const { tm } = useI18n()
|
||||||
|
|
||||||
|
const test = {
|
||||||
|
subTitle: {
|
||||||
|
groups: [
|
||||||
|
{
|
||||||
|
display: {
|
||||||
|
text: '사전 등록 기간 + 2024.06.04 ~ 정식 오픈 전까지',
|
||||||
|
color_code: '',
|
||||||
|
color_name: 'primary',
|
||||||
|
},
|
||||||
|
resource_type: 'TXT',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
mainTitle: {
|
||||||
|
groups: [
|
||||||
|
{
|
||||||
|
display: {
|
||||||
|
text: '로드나인 사전 등록',
|
||||||
|
color_code: '',
|
||||||
|
color_name: 'primary',
|
||||||
|
},
|
||||||
|
resource_type: 'TXT',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
background: {
|
||||||
|
groups: [
|
||||||
|
{
|
||||||
|
res_path: {
|
||||||
|
path_mo: '/local/template/l9/16/1/1/FX_PREREGIST_01/common/bg_m.jpg',
|
||||||
|
path_pc: '/local/template/l9/16/1/1/FX_PREREGIST_01/common/bg.jpg',
|
||||||
|
},
|
||||||
|
resource_type: 'IMG_COMM',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
txtSnsLink: {
|
||||||
|
groups: [
|
||||||
|
{
|
||||||
|
display: {
|
||||||
|
text: 'https://pf.kakao.com/_xmyxjpG',
|
||||||
|
},
|
||||||
|
resource_type: 'TXT',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
display: {
|
||||||
|
text: 'https://www.youtube.com/@LORDNINE_KR',
|
||||||
|
},
|
||||||
|
resource_type: 'TXT',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
description: {
|
||||||
|
groups: [
|
||||||
|
{
|
||||||
|
display: {
|
||||||
|
text: '로드나인은 PC, GooglePlay, AppStore에서 즐기실 수 있습니다',
|
||||||
|
color_code: '',
|
||||||
|
color_name: 'text-primary',
|
||||||
|
},
|
||||||
|
resource_type: 'TXT',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
imgAccReward: {
|
||||||
|
groups: [
|
||||||
|
{
|
||||||
|
display: {
|
||||||
|
text: '골드 100,000',
|
||||||
|
},
|
||||||
|
res_path: {
|
||||||
|
path_mo:
|
||||||
|
'/local/template/l9/16/1/1/FX_PREREGIST_01/ko/img_acc_reward01_m.png',
|
||||||
|
path_pc:
|
||||||
|
'/local/template/l9/16/1/1/FX_PREREGIST_01/ko/img_acc_reward01.png',
|
||||||
|
},
|
||||||
|
resource_type: 'IMG_LANG',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
display: {
|
||||||
|
text: '중급 물약 x100',
|
||||||
|
},
|
||||||
|
res_path: {
|
||||||
|
path_mo:
|
||||||
|
'/local/template/l9/16/1/1/FX_PREREGIST_01/ko/img_acc_reward02_m.png',
|
||||||
|
path_pc:
|
||||||
|
'/local/template/l9/16/1/1/FX_PREREGIST_01/ko/img_acc_reward02.png',
|
||||||
|
},
|
||||||
|
resource_type: 'IMG_LANG',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
display: {
|
||||||
|
text: '방어구 강화석 x3',
|
||||||
|
},
|
||||||
|
res_path: {
|
||||||
|
path_mo:
|
||||||
|
'/local/template/l9/16/1/1/FX_PREREGIST_01/ko/img_acc_reward03_m.png',
|
||||||
|
path_pc:
|
||||||
|
'/local/template/l9/16/1/1/FX_PREREGIST_01/ko/img_acc_reward03.png',
|
||||||
|
},
|
||||||
|
resource_type: 'IMG_LANG',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
display: {
|
||||||
|
text: '무기 강화석 x3',
|
||||||
|
},
|
||||||
|
res_path: {
|
||||||
|
path_mo:
|
||||||
|
'/local/template/l9/16/1/1/FX_PREREGIST_01/ko/img_acc_reward04_m.png',
|
||||||
|
path_pc:
|
||||||
|
'/local/template/l9/16/1/1/FX_PREREGIST_01/ko/img_acc_reward04.png',
|
||||||
|
},
|
||||||
|
resource_type: 'IMG_LANG',
|
||||||
|
},
|
||||||
|
// {
|
||||||
|
// display: {
|
||||||
|
// text: '순수한 무기 강화석 x1',
|
||||||
|
// },
|
||||||
|
// res_path: {
|
||||||
|
// path_mo:
|
||||||
|
// '/local/template/l9/16/1/1/FX_PREREGIST_01/ko/img_acc_reward05_m.png',
|
||||||
|
// path_pc:
|
||||||
|
// '/local/template/l9/16/1/1/FX_PREREGIST_01/ko/img_acc_reward05.png',
|
||||||
|
// },
|
||||||
|
// resource_type: 'IMG_LANG',
|
||||||
|
// },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
imgSnsButton: {
|
||||||
|
groups: [
|
||||||
|
{
|
||||||
|
res_path: {
|
||||||
|
path_mo:
|
||||||
|
'/local/template/l9/16/1/1/FX_PREREGIST_01/ko/sns_button01_m.jpg',
|
||||||
|
path_pc:
|
||||||
|
'/local/template/l9/16/1/1/FX_PREREGIST_01/ko/sns_button01.jpg',
|
||||||
|
},
|
||||||
|
tracking: {
|
||||||
|
click_item: 'imgSnsButton_7. 사전등록-SNS버튼이미지(1)',
|
||||||
|
action_type: 'click',
|
||||||
|
click_sarea: 'promotionPreregist_tmpl_01__imgSnsButton',
|
||||||
|
},
|
||||||
|
resource_type: 'IMG_LANG',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
res_path: {
|
||||||
|
path_mo:
|
||||||
|
'/local/template/l9/16/1/1/FX_PREREGIST_01/ko/sns_button02_m.jpg',
|
||||||
|
path_pc:
|
||||||
|
'/local/template/l9/16/1/1/FX_PREREGIST_01/ko/sns_button02.jpg',
|
||||||
|
},
|
||||||
|
tracking: {
|
||||||
|
click_item: 'imgSnsButton_7. 사전등록-SNS버튼이미지(2)',
|
||||||
|
action_type: 'click',
|
||||||
|
click_sarea: 'promotionPreregist_tmpl_01__imgSnsButton',
|
||||||
|
},
|
||||||
|
resource_type: 'IMG_LANG',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
imgSnsReward: {
|
||||||
|
groups: [
|
||||||
|
{
|
||||||
|
res_path: {
|
||||||
|
path_mo:
|
||||||
|
'/local/template/l9/16/1/1/FX_PREREGIST_01/ko/img_preregist_reward_sns_m.png',
|
||||||
|
path_pc:
|
||||||
|
'/local/template/l9/16/1/1/FX_PREREGIST_01/ko/img_preregist_reward_sns.png',
|
||||||
|
},
|
||||||
|
resource_type: 'IMG_LANG',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
subTitleAccReward: {
|
||||||
|
groups: [
|
||||||
|
{
|
||||||
|
display: {
|
||||||
|
text: '이벤트 기간 + 2024.06.04 ~ 정식 오픈 전까지',
|
||||||
|
color_code: '#c5902f',
|
||||||
|
color_name: '',
|
||||||
|
},
|
||||||
|
resource_type: 'TXT',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
imgPreregistReward: {
|
||||||
|
groups: [
|
||||||
|
{
|
||||||
|
res_path: {
|
||||||
|
path_mo:
|
||||||
|
'/local/template/l9/16/1/1/FX_PREREGIST_01/ko/img_preregist_reward_m.png',
|
||||||
|
path_pc:
|
||||||
|
'/local/template/l9/16/1/1/FX_PREREGIST_01/ko/img_preregist_reward.png',
|
||||||
|
},
|
||||||
|
resource_type: 'IMG_LANG',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
mainTitleAccReward: {
|
||||||
|
groups: [
|
||||||
|
{
|
||||||
|
display: {
|
||||||
|
text: '카카오톡 공식 채널 구독 이벤트',
|
||||||
|
color_code: '#c5902f',
|
||||||
|
color_name: '',
|
||||||
|
},
|
||||||
|
resource_type: 'TXT',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
backgroundAccReward: {
|
||||||
|
groups: [
|
||||||
|
{
|
||||||
|
res_path: {
|
||||||
|
path_mo:
|
||||||
|
'/local/template/l9/16/1/1/FX_PREREGIST_01/common/bg_acc_reward_m.jpg',
|
||||||
|
path_pc:
|
||||||
|
'/local/template/l9/16/1/1/FX_PREREGIST_01/common/bg_acc_reward.jpg',
|
||||||
|
},
|
||||||
|
resource_type: 'IMG_COMM',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
descriptionAccReward: {
|
||||||
|
groups: [
|
||||||
|
{
|
||||||
|
display: {
|
||||||
|
text: '※ 달성 여부는 실시간으로 반영되지 않을 수 있습니다.',
|
||||||
|
color_code: '#737474',
|
||||||
|
color_name: '',
|
||||||
|
},
|
||||||
|
resource_type: 'TXT',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
isAccRewardCompleted: {},
|
||||||
|
preregistButtonColor: {
|
||||||
|
groups: [
|
||||||
|
{
|
||||||
|
display: {
|
||||||
|
color_code: '#cc0000',
|
||||||
|
color_name: '',
|
||||||
|
},
|
||||||
|
resource_type: 'COLOR',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
display: {
|
||||||
|
color_code: '#ccff00',
|
||||||
|
color_name: '',
|
||||||
|
},
|
||||||
|
resource_type: 'COLOR',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
rewardTitleAccReward: {
|
||||||
|
groups: [
|
||||||
|
{
|
||||||
|
display: {
|
||||||
|
text: '누적 목표를 달성할수록 더 많은 보상을 드립니다!',
|
||||||
|
color_code: '#33312e',
|
||||||
|
color_name: '',
|
||||||
|
},
|
||||||
|
resource_type: 'TXT',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
imgAccRewardIncomplete: {
|
||||||
|
groups: [
|
||||||
|
{
|
||||||
|
display: {
|
||||||
|
text: '골드 100,000',
|
||||||
|
},
|
||||||
|
res_path: {
|
||||||
|
path_mo:
|
||||||
|
'/local/template/l9/16/1/1/FX_PREREGIST_01/ko/img_acc_reward_incomplete01_m.png',
|
||||||
|
path_pc:
|
||||||
|
'/local/template/l9/16/1/1/FX_PREREGIST_01/ko/img_acc_reward_incomplete01.png',
|
||||||
|
},
|
||||||
|
resource_type: 'IMG_LANG',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
display: {
|
||||||
|
text: '중급 물약 x100',
|
||||||
|
},
|
||||||
|
res_path: {
|
||||||
|
path_mo:
|
||||||
|
'/local/template/l9/16/1/1/FX_PREREGIST_01/ko/img_acc_reward_incomplete02_m.png',
|
||||||
|
path_pc:
|
||||||
|
'/local/template/l9/16/1/1/FX_PREREGIST_01/ko/img_acc_reward_incomplete02.png',
|
||||||
|
},
|
||||||
|
resource_type: 'IMG_LANG',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
display: {
|
||||||
|
text: '방어구 강화석 x3',
|
||||||
|
},
|
||||||
|
res_path: {
|
||||||
|
path_mo:
|
||||||
|
'/local/template/l9/16/1/1/FX_PREREGIST_01/ko/img_acc_reward_incomplete03_m.png',
|
||||||
|
path_pc:
|
||||||
|
'/local/template/l9/16/1/1/FX_PREREGIST_01/ko/img_acc_reward_incomplete03.png',
|
||||||
|
},
|
||||||
|
resource_type: 'IMG_LANG',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
display: {
|
||||||
|
text: '무기 강화석 x3',
|
||||||
|
},
|
||||||
|
res_path: {
|
||||||
|
path_mo:
|
||||||
|
'/local/template/l9/16/1/1/FX_PREREGIST_01/ko/img_acc_reward_incomplete04_m.png',
|
||||||
|
path_pc:
|
||||||
|
'/local/template/l9/16/1/1/FX_PREREGIST_01/ko/img_acc_reward_incomplete04.png',
|
||||||
|
},
|
||||||
|
resource_type: 'IMG_LANG',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
display: {
|
||||||
|
text: '순수한 무기 강화석 x1',
|
||||||
|
},
|
||||||
|
res_path: {
|
||||||
|
path_mo:
|
||||||
|
'/local/template/l9/16/1/1/FX_PREREGIST_01/ko/img_acc_reward_incomplete05_m.png',
|
||||||
|
path_pc:
|
||||||
|
'/local/template/l9/16/1/1/FX_PREREGIST_01/ko/img_acc_reward_incomplete05.png',
|
||||||
|
},
|
||||||
|
resource_type: 'IMG_LANG',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
} as any
|
||||||
|
|
||||||
|
// Constants
|
||||||
|
const PREREGIST_PLATFORMS = [
|
||||||
|
{ platform: 'stove', label: '사전 등록 하기' },
|
||||||
|
{ platform: 'google_play', label: '사전 등록 하기' },
|
||||||
|
{ platform: 'app_store', label: '사전 등록 하기' },
|
||||||
|
] as const
|
||||||
|
|
||||||
|
const COLOR_INDEX = {
|
||||||
|
BACKGROUND: 0,
|
||||||
|
TEXT: 1,
|
||||||
|
} as const
|
||||||
|
|
||||||
|
// Preregist Section
|
||||||
|
const backgroundData = computed(() =>
|
||||||
|
getComponentGroup(props.components, 'background')
|
||||||
|
)
|
||||||
|
const mainTitleData = computed(() =>
|
||||||
|
getComponentGroup(props.components, 'mainTitle')
|
||||||
|
)
|
||||||
|
const subTitleData = computed(() =>
|
||||||
|
getComponentGroup(props.components, 'subTitle')
|
||||||
|
)
|
||||||
|
const imgPreregistRewardData = computed(() =>
|
||||||
|
getComponentGroup(props.components, 'imgPreregistReward')
|
||||||
|
)
|
||||||
|
const imgSnsRewardData = computed(() =>
|
||||||
|
getComponentGroup(props.components, 'imgSnsReward')
|
||||||
|
)
|
||||||
|
const preregistButtonColorData = computed(() =>
|
||||||
|
getComponentGroupAry(props.components, 'preregistButtonColor')
|
||||||
|
)
|
||||||
|
const imgSnsButtonData = computed(() =>
|
||||||
|
getComponentGroupAry(props.components, 'imgSnsButton')
|
||||||
|
)
|
||||||
|
const txtSnsLinkData = computed(() =>
|
||||||
|
getComponentGroupAry(props.components, 'txtSnsLink')
|
||||||
|
)
|
||||||
|
const descriptionData = computed(() =>
|
||||||
|
getComponentGroup(props.components, 'description')
|
||||||
|
)
|
||||||
|
const snsButtons = computed(() => {
|
||||||
|
const buttons = imgSnsButtonData.value
|
||||||
|
const links = txtSnsLinkData.value
|
||||||
|
|
||||||
|
if (!buttons?.length) return []
|
||||||
|
|
||||||
|
return buttons.map((button, index) => ({
|
||||||
|
image: button,
|
||||||
|
link: links?.[index]?.display?.text ?? '',
|
||||||
|
}))
|
||||||
|
})
|
||||||
|
const buttonColors = computed(() => {
|
||||||
|
const colorData = preregistButtonColorData.value
|
||||||
|
|
||||||
|
if (!colorData?.length) {
|
||||||
|
return { background: undefined, text: undefined }
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
background: getColorCode({
|
||||||
|
colorName: colorData[COLOR_INDEX.BACKGROUND]?.display?.color_name,
|
||||||
|
colorCode: colorData[COLOR_INDEX.BACKGROUND]?.display?.color_code,
|
||||||
|
}),
|
||||||
|
text: getColorCode({
|
||||||
|
colorName: colorData[COLOR_INDEX.TEXT]?.display?.color_name,
|
||||||
|
colorCode: colorData[COLOR_INDEX.TEXT]?.display?.color_code,
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// Reward Section
|
||||||
|
const backgroundAccRewardData = computed(() =>
|
||||||
|
getComponentGroup(props.components, 'backgroundAccReward')
|
||||||
|
)
|
||||||
|
const mainTitleAccRewardData = computed(() =>
|
||||||
|
getComponentGroup(props.components, 'mainTitleAccReward')
|
||||||
|
)
|
||||||
|
const subTitleAccRewardData = computed(() =>
|
||||||
|
getComponentGroup(props.components, 'subTitleAccReward')
|
||||||
|
)
|
||||||
|
const rewardTitleAccRewardData = computed(() =>
|
||||||
|
getComponentGroup(props.components, 'rewardTitleAccReward')
|
||||||
|
)
|
||||||
|
const imgAccRewardData = computed(() =>
|
||||||
|
getComponentGroupAry(test, 'imgAccReward')
|
||||||
|
)
|
||||||
|
const imgAccRewardLength = computed(() => imgAccRewardData.value?.length ?? 0)
|
||||||
|
const descriptionAccRewardData = computed(() =>
|
||||||
|
getComponentGroup(props.components, 'descriptionAccReward')
|
||||||
|
)
|
||||||
|
|
||||||
|
const splideOptions = computed(() => {
|
||||||
|
return {
|
||||||
|
type: 'slide',
|
||||||
|
gap: 16,
|
||||||
|
arrows: false,
|
||||||
|
pagination: false,
|
||||||
|
destroy: true,
|
||||||
|
breakpoints: {
|
||||||
|
[BREAKPOINTS.md - 1]: {
|
||||||
|
destroy: imgAccRewardLength.value <= 3,
|
||||||
|
perPage: 'auto',
|
||||||
|
focus: 'center',
|
||||||
|
drag: imgAccRewardLength.value > 3,
|
||||||
|
padding: {
|
||||||
|
left: 40,
|
||||||
|
right: 40,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
[BREAKPOINTS.sm - 1]: {
|
||||||
|
destroy: false,
|
||||||
|
gap: 12,
|
||||||
|
drag: true,
|
||||||
|
padding: {
|
||||||
|
left: 20,
|
||||||
|
right: 20,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<section class="relative py-[80px] md:py-[120px]">
|
||||||
|
<WidgetsBackground v-if="backgroundData" :resources-data="backgroundData" />
|
||||||
|
<div class="content-standard">
|
||||||
|
<WidgetsMainTitle
|
||||||
|
v-if="mainTitleData"
|
||||||
|
:resources-data="mainTitleData"
|
||||||
|
class="title-xlg"
|
||||||
|
/>
|
||||||
|
<WidgetsSubTitle
|
||||||
|
v-if="subTitleData"
|
||||||
|
:resources-data="subTitleData"
|
||||||
|
class="title-sm mt-2"
|
||||||
|
/>
|
||||||
|
<div class="flex flex-col gap-4 mt-8 md:flex-row">
|
||||||
|
<div v-if="imgPreregistRewardData" class="w-full max-w-[446px]">
|
||||||
|
<AtomsImg
|
||||||
|
:src="getImagePaths(imgPreregistRewardData)"
|
||||||
|
loading="lazy"
|
||||||
|
decoding="async"
|
||||||
|
class="w-full h-full object-contain"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div v-if="imgSnsRewardData" class="relative w-full max-w-[446px]">
|
||||||
|
<AtomsImg
|
||||||
|
:src="getImagePaths(imgSnsRewardData)"
|
||||||
|
loading="lazy"
|
||||||
|
decoding="async"
|
||||||
|
class="w-full h-full object-contain"
|
||||||
|
/>
|
||||||
|
<ul
|
||||||
|
v-if="snsButtons.length"
|
||||||
|
class="absolute bottom-[20px] left-0 w-full flex items-center justify-center gap-2 md:bottom-[24px] md:gap-3"
|
||||||
|
>
|
||||||
|
<li
|
||||||
|
v-for="(snsButton, index) in snsButtons"
|
||||||
|
:key="`sns-${snsButton.link}-${index}`"
|
||||||
|
>
|
||||||
|
<a
|
||||||
|
:href="snsButton.link"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
>
|
||||||
|
<AtomsImg :src="getImagePaths(snsButton.image)" />
|
||||||
|
<span class="sr-only">
|
||||||
|
{{ snsButton.link }}
|
||||||
|
</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-if="PREREGIST_PLATFORMS.length"
|
||||||
|
class="flex gap-3 justify-center flex-wrap mt-8 md:gap-2.5"
|
||||||
|
>
|
||||||
|
<AtomsButtonLauncher
|
||||||
|
v-for="item in PREREGIST_PLATFORMS"
|
||||||
|
:key="`preregist-${item.platform}`"
|
||||||
|
type="duplication"
|
||||||
|
:platform="item.platform"
|
||||||
|
:background-color="buttonColors.background"
|
||||||
|
:text-color="buttonColors.text"
|
||||||
|
>
|
||||||
|
{{ item.label }}
|
||||||
|
</AtomsButtonLauncher>
|
||||||
|
</div>
|
||||||
|
<WidgetsDescription
|
||||||
|
v-if="descriptionData"
|
||||||
|
:resources-data="descriptionData"
|
||||||
|
class="mt-8"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<section class="relative py-[80px] md:py-[120px]">
|
||||||
|
<WidgetsBackground
|
||||||
|
v-if="backgroundAccRewardData"
|
||||||
|
:resources-data="backgroundAccRewardData"
|
||||||
|
/>
|
||||||
|
<div class="content-standard">
|
||||||
|
<WidgetsMainTitle
|
||||||
|
v-if="mainTitleAccRewardData"
|
||||||
|
:resources-data="mainTitleAccRewardData"
|
||||||
|
class="title-xlg"
|
||||||
|
/>
|
||||||
|
<WidgetsSubTitle
|
||||||
|
v-if="subTitleAccRewardData"
|
||||||
|
:resources-data="subTitleAccRewardData"
|
||||||
|
class="title-sm mt-2"
|
||||||
|
/>
|
||||||
|
<WidgetsSubTitle
|
||||||
|
v-if="rewardTitleAccRewardData"
|
||||||
|
tag="h4"
|
||||||
|
:resources-data="rewardTitleAccRewardData"
|
||||||
|
class="mt-[48px] text-[18px] font-[700] leading-[26px] tracking-[-0.54px] drop-shadow-[0_2px_2px_rgba(0,0,0,0.6)] md:mt-[72px] md:text-[24px] md:leading-[34px] md:tracking-[0.72px]"
|
||||||
|
/>
|
||||||
|
<div v-if="imgAccRewardLength" class="mt-6 md:mt-8">
|
||||||
|
<ul class="hidden md:flex justify-center md:mb-[20px]">
|
||||||
|
<li
|
||||||
|
v-for="index in imgAccRewardLength"
|
||||||
|
:key="index"
|
||||||
|
class="flex items-center"
|
||||||
|
>
|
||||||
|
<span class="progress-bullet"></span>
|
||||||
|
<div v-if="index !== imgAccRewardLength" class="progress-bar">
|
||||||
|
<span class="progress-fill"></span>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<BlocksSlideDefault
|
||||||
|
v-bind="splideOptions"
|
||||||
|
class="w-[100vw] mx-[-20px] sm:mx-[-40px] md:w-auto md:mx-auto"
|
||||||
|
>
|
||||||
|
<SplideSlide
|
||||||
|
v-for="(item, index) in imgAccRewardData"
|
||||||
|
:key="`reward-${item.id ?? index}`"
|
||||||
|
class="w-[162px] h-[228px] md:w-[176px] md:h-[249px]"
|
||||||
|
>
|
||||||
|
<AtomsImg
|
||||||
|
:src="getImagePaths(item)"
|
||||||
|
:alt="item?.display?.text ?? `Reward ${index + 1}`"
|
||||||
|
loading="lazy"
|
||||||
|
decoding="async"
|
||||||
|
class="w-full h-full object-contain"
|
||||||
|
/>
|
||||||
|
</SplideSlide>
|
||||||
|
</BlocksSlideDefault>
|
||||||
|
</div>
|
||||||
|
<WidgetsDescription
|
||||||
|
v-if="descriptionAccRewardData"
|
||||||
|
:resources-data="descriptionAccRewardData"
|
||||||
|
class="mt-6 md:mt-8"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
/* destroy되었을 때 (슬라이드 비활성화) 중앙 정렬 */
|
||||||
|
.splide:not(.is-active):deep(.splide__list) {
|
||||||
|
@apply flex justify-center gap-3 md:gap-4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.progress-bullet {
|
||||||
|
@apply block w-3 h-3 rounded-full transition-all duration-300;
|
||||||
|
background-color: red;
|
||||||
|
/* background-color: var(--pagination-disabled); */
|
||||||
|
}
|
||||||
|
.progress-bar {
|
||||||
|
@apply relative w-[180px] h-0.5 overflow-hidden;
|
||||||
|
/* background-color: var(--pagination-disabled); */
|
||||||
|
background-color: red;
|
||||||
|
}
|
||||||
|
.progress-fill {
|
||||||
|
@apply absolute inset-y-0 left-0 w-[0];
|
||||||
|
background-color: var(--pagination-active);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -58,33 +58,42 @@ const { data: slideData } = await useAsyncData(
|
|||||||
server: false,
|
server: false,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
const slideLength = computed(() => slideData.value.length)
|
const slideLength = computed(() => slideData.value.length ?? 0)
|
||||||
const slideClass = computed(() => ({
|
const splideOptions = computed(() => {
|
||||||
'is-one-item': slideLength.value === 1,
|
return {
|
||||||
'is-two-items': slideLength.value === 2,
|
gap: 20,
|
||||||
'is-three-items': slideLength.value === 3,
|
perPage: 4,
|
||||||
'is-four-items': slideLength.value === 4,
|
drag: false,
|
||||||
}))
|
arrows: slideLength.value > 4,
|
||||||
const splideOptions = computed(() => ({
|
pagination: slideLength.value > 4,
|
||||||
gap: 20,
|
destroy: slideLength.value <= 4,
|
||||||
perPage: 4,
|
breakpoints: {
|
||||||
drag: false,
|
[BREAKPOINTS.lg - 1]: {
|
||||||
arrows: slideLength.value > 4,
|
perPage: 2,
|
||||||
pagination: slideLength.value > 4,
|
arrows: slideLength.value > 2,
|
||||||
breakpoints: {
|
pagination: slideLength.value > 2,
|
||||||
[BREAKPOINTS.lg - 1]: {
|
destroy: slideLength.value < 3,
|
||||||
perPage: 2,
|
},
|
||||||
arrows: slideLength.value > 2,
|
[BREAKPOINTS.md - 1]: {
|
||||||
pagination: slideLength.value > 2,
|
drag: true,
|
||||||
|
perPage: 1,
|
||||||
|
arrows: false,
|
||||||
|
pagination: false,
|
||||||
|
destroy: slideLength.value < 2,
|
||||||
|
padding: {
|
||||||
|
left: 40,
|
||||||
|
right: 40,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
[BREAKPOINTS.sm - 1]: {
|
||||||
|
padding: {
|
||||||
|
left: 20,
|
||||||
|
right: 20,
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
[BREAKPOINTS.md - 1]: {
|
}
|
||||||
drag: true,
|
})
|
||||||
perPage: 1,
|
|
||||||
arrows: false,
|
|
||||||
pagination: false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}))
|
|
||||||
|
|
||||||
const getArticleUrl = (articleId: string) => {
|
const getArticleUrl = (articleId: string) => {
|
||||||
const communityUrl = gameData.value?.url_json?.community
|
const communityUrl = gameData.value?.url_json?.community
|
||||||
@@ -118,7 +127,7 @@ const onArrowClick = (direction, targetIndex) => {
|
|||||||
v-if="slideLength > 0"
|
v-if="slideLength > 0"
|
||||||
:slide-item-length="slideLength"
|
:slide-item-length="slideLength"
|
||||||
v-bind="splideOptions"
|
v-bind="splideOptions"
|
||||||
:class="`${slideClass} w-full`"
|
class="w-full"
|
||||||
@arrow-click="onArrowClick"
|
@arrow-click="onArrowClick"
|
||||||
>
|
>
|
||||||
<SplideSlide
|
<SplideSlide
|
||||||
@@ -158,9 +167,6 @@ const onArrowClick = (direction, targetIndex) => {
|
|||||||
.splide {
|
.splide {
|
||||||
@apply mt-[24px] md:max-w-[776px] md:mt-[48px] md:mx-auto md:px-[72px] lg:max-w-[1428px];
|
@apply mt-[24px] md:max-w-[776px] md:mt-[48px] md:mx-auto md:px-[72px] lg:max-w-[1428px];
|
||||||
}
|
}
|
||||||
.splide:deep(.splide__track) {
|
|
||||||
@apply !px-[20px] md:max-w-[632px] lg:max-w-[1284px] md:mx-auto md:!px-[0] sm:!px-[40px];
|
|
||||||
}
|
|
||||||
.splide:deep(.arrow-prev) {
|
.splide:deep(.arrow-prev) {
|
||||||
@apply top-[calc(50%-28px)] left-[0];
|
@apply top-[calc(50%-28px)] left-[0];
|
||||||
}
|
}
|
||||||
@@ -168,23 +174,11 @@ const onArrowClick = (direction, targetIndex) => {
|
|||||||
@apply top-[calc(50%-28px)] right-[0];
|
@apply top-[calc(50%-28px)] right-[0];
|
||||||
}
|
}
|
||||||
.slide-inner {
|
.slide-inner {
|
||||||
@apply w-[275px] aspect-[1/1] md:w-[306px] md:box-border;
|
@apply w-[275px] aspect-[1/1] md:w-[306px];
|
||||||
}
|
}
|
||||||
|
|
||||||
.splide.is-one-item:deep(.splide__track) {
|
/* destroy되었을 때 (슬라이드 비활성화) 중앙 정렬 */
|
||||||
@apply max-w-[315px] sm:max-w-[355px] mx-auto md:max-w-[306px];
|
.splide:not(.is-active):deep(.splide__list) {
|
||||||
}
|
@apply flex justify-center gap-5;
|
||||||
.splide.is-two-items:deep(.splide__track) {
|
|
||||||
@apply lg:max-w-[632px];
|
|
||||||
}
|
|
||||||
.splide.is-two-items:deep(.splide__list) {
|
|
||||||
@apply md:!translate-x-0;
|
|
||||||
}
|
|
||||||
.splide.is-three-items:deep(.splide__track) {
|
|
||||||
@apply lg:max-w-[958px];
|
|
||||||
}
|
|
||||||
.splide.is-three-items:deep(.splide__list),
|
|
||||||
.splide.is-four-items:deep(.splide__list) {
|
|
||||||
@apply lg:!translate-x-0;
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ const buttonListData = computed(() => {
|
|||||||
v-if="getImagePaths(item)"
|
v-if="getImagePaths(item)"
|
||||||
:src="getImagePaths(item)"
|
:src="getImagePaths(item)"
|
||||||
:alt="item?.group_label"
|
:alt="item?.group_label"
|
||||||
|
class="w-full object-contain"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
BIN
public/images/sample/FX_PREREGIST_01/common/bg_acc_reward.jpg
Normal file
|
After Width: | Height: | Size: 1.5 MiB |
BIN
public/images/sample/FX_PREREGIST_01/common/bg_acc_reward_m.jpg
Normal file
|
After Width: | Height: | Size: 887 KiB |
BIN
public/images/sample/FX_PREREGIST_01/ko/img_acc_reward01.png
Normal file
|
After Width: | Height: | Size: 74 KiB |
BIN
public/images/sample/FX_PREREGIST_01/ko/img_acc_reward01_m.png
Normal file
|
After Width: | Height: | Size: 209 KiB |
BIN
public/images/sample/FX_PREREGIST_01/ko/img_acc_reward02.png
Normal file
|
After Width: | Height: | Size: 236 KiB |
BIN
public/images/sample/FX_PREREGIST_01/ko/img_acc_reward02_m.png
Normal file
|
After Width: | Height: | Size: 204 KiB |
BIN
public/images/sample/FX_PREREGIST_01/ko/img_acc_reward03.png
Normal file
|
After Width: | Height: | Size: 234 KiB |
BIN
public/images/sample/FX_PREREGIST_01/ko/img_acc_reward03_m.png
Normal file
|
After Width: | Height: | Size: 206 KiB |
BIN
public/images/sample/FX_PREREGIST_01/ko/img_acc_reward04.png
Normal file
|
After Width: | Height: | Size: 218 KiB |
BIN
public/images/sample/FX_PREREGIST_01/ko/img_acc_reward04_m.png
Normal file
|
After Width: | Height: | Size: 190 KiB |
BIN
public/images/sample/FX_PREREGIST_01/ko/img_acc_reward05.png
Normal file
|
After Width: | Height: | Size: 239 KiB |
BIN
public/images/sample/FX_PREREGIST_01/ko/img_acc_reward05_m.png
Normal file
|
After Width: | Height: | Size: 211 KiB |
|
After Width: | Height: | Size: 248 KiB |
|
After Width: | Height: | Size: 222 KiB |
|
After Width: | Height: | Size: 248 KiB |
|
After Width: | Height: | Size: 222 KiB |
|
After Width: | Height: | Size: 248 KiB |
|
After Width: | Height: | Size: 222 KiB |
|
After Width: | Height: | Size: 248 KiB |
|
After Width: | Height: | Size: 222 KiB |
|
After Width: | Height: | Size: 248 KiB |
|
After Width: | Height: | Size: 222 KiB |
|
Before Width: | Height: | Size: 351 KiB After Width: | Height: | Size: 351 KiB |
|
Before Width: | Height: | Size: 638 KiB After Width: | Height: | Size: 638 KiB |
|
Before Width: | Height: | Size: 315 KiB After Width: | Height: | Size: 315 KiB |
|
Before Width: | Height: | Size: 570 KiB After Width: | Height: | Size: 570 KiB |
|
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 3.6 KiB |
|
Before Width: | Height: | Size: 5.8 KiB After Width: | Height: | Size: 5.8 KiB |
|
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 3.5 KiB |
|
Before Width: | Height: | Size: 5.5 KiB After Width: | Height: | Size: 5.5 KiB |