536 lines
20 KiB
Vue
536 lines
20 KiB
Vue
<script setup lang="ts">
|
|
import { getComponentGroup, getComponentGroupAry } from '#layers/utils/dataUtil'
|
|
import type { PageDataTemplateComponents } from '#layers/types/api/pageData'
|
|
import type { Platform } from '#layers/types/components/button'
|
|
|
|
// Props
|
|
interface Props {
|
|
id?: string
|
|
components: PageDataTemplateComponents
|
|
pageVerTmplSeq: number
|
|
pageVerTmplNameEn: string
|
|
}
|
|
const props = defineProps<Props>()
|
|
|
|
// Configuration
|
|
const runtimeConfig = useRuntimeConfig()
|
|
const device = useDevice()
|
|
const gameDataStore = useGameDataStore()
|
|
const breakpoints = useResponsiveBreakpoints()
|
|
|
|
const { gameData } = storeToRefs(gameDataStore)
|
|
const { sendLog } = useAnalytics()
|
|
|
|
const dataResourcesUrl = runtimeConfig.public.dataResourcesUrl as string
|
|
const multilingualFileName = 'STOVE_PUBTEMPLATE_homepage_brand_download.json'
|
|
const stoveClientDownloadUrl = runtimeConfig.public
|
|
.stoveClientDownloadUrl as string
|
|
|
|
// Multilingual
|
|
const resultGetMultilingual = await useGetMultilingual({
|
|
baseApiUrl: dataResourcesUrl,
|
|
fileName: multilingualFileName,
|
|
})
|
|
const { t, tm, locale }: any = useI18n({
|
|
useScope: 'local',
|
|
messages: Object(resultGetMultilingual?.value?.multilingual),
|
|
})
|
|
|
|
// Composables
|
|
const { checkPCSpec } = useCheckPCSpec(tm)
|
|
|
|
const specPCRef = ref<HTMLElement | null>(null)
|
|
const specMobileRef = ref<HTMLElement | null>(null)
|
|
const driverArray = ref<Array<string>>([
|
|
'DirectX',
|
|
'NVIDIA',
|
|
'AMD',
|
|
'intel',
|
|
'Visual',
|
|
])
|
|
const pcSpecArray = ref<Array<string>>([
|
|
'Os',
|
|
'Cpu',
|
|
'Vga',
|
|
'Ram',
|
|
'Directx',
|
|
'Hdd',
|
|
])
|
|
const mobileSpecArray = ref<Array<string>>(['Android', 'Ios'])
|
|
const mobileOSArray = ref<Array<string>>(['AOS', 'iOS'])
|
|
|
|
// Data
|
|
const backgroundData = computed(() =>
|
|
getComponentGroup(props.components, 'background')
|
|
)
|
|
const specCheckData = computed(() =>
|
|
getComponentGroupAry(props.components, 'tablePcSpecTool')
|
|
)
|
|
const schemeFormatData = computed(
|
|
() => specCheckData.value[0]?.display?.text || ''
|
|
)
|
|
const setupUrlData = computed(() => specCheckData.value[1]?.display?.text || '')
|
|
|
|
const driverList = computed(() =>
|
|
driverArray.value.map(driver => ({
|
|
id: `DRIVER_${driver}`,
|
|
driverCode: driver,
|
|
driverText: tm(`Download_Driver_${driver}`),
|
|
}))
|
|
)
|
|
const pcSpecList = computed(() =>
|
|
pcSpecArray.value.map(data => ({
|
|
id: `PC_TABLE_ITEM_${data}`,
|
|
itemCode: data,
|
|
itemText: tm(`Download_Table_${data}`),
|
|
itemData: getComponentGroupAry(props.components, `tablePcSpec${data}`),
|
|
}))
|
|
)
|
|
const mobileSpecList = computed(() =>
|
|
mobileSpecArray.value.map(data => ({
|
|
id: `MO_TABLE_ITEM_${data}`,
|
|
itemCode: data,
|
|
itemText: tm(`Download_Table_${data}`),
|
|
itemData: getComponentGroupAry(props.components, `tableMoSpec${data}`),
|
|
}))
|
|
)
|
|
const mobileOSList = computed(() =>
|
|
mobileOSArray.value.map(os => ({
|
|
id: `MO_OS_${os}`,
|
|
osType: tm(`Download_${os}_Type`),
|
|
osCode: os,
|
|
osText: tm(`Download_${os}_OS`),
|
|
platformCode: tm(`Download_${os}_Platform`),
|
|
platformText: tm(`Download_${os}_Name`),
|
|
isValue: device[tm(`Download_${os}_IsValue`) as keyof typeof device],
|
|
}))
|
|
)
|
|
|
|
// Functions
|
|
const handleSendLog = (item: string) => {
|
|
const analytics = {
|
|
action_type: 'click',
|
|
click_item: item,
|
|
click_sarea: props.pageVerTmplNameEn,
|
|
}
|
|
|
|
sendLog(locale.value, analytics)
|
|
}
|
|
/**
|
|
* 입력한 pc, mobile 인자값에 따라 해당 최소사양&권장사양 테이블로 포커스 스크롤 이동합니다.
|
|
* @param target<string> 'pc' | 'mobile'
|
|
*/
|
|
const handleMoveFocus = (target: 'pc' | 'mobile') => {
|
|
const refs: Record<string, HTMLElement | null> = {
|
|
pc: specPCRef.value,
|
|
mobile: specMobileRef.value,
|
|
}
|
|
|
|
const adjustedOffset: number = breakpoints.value.isMobile ? 80 : 100
|
|
const adjustedOffsetTop: number =
|
|
refs[target]?.getBoundingClientRect().top + window.scrollY - adjustedOffset
|
|
|
|
window.scrollTo({ top: adjustedOffsetTop, behavior: 'smooth' })
|
|
handleSendLog(`${target === 'pc' ? 'PC' : '모바일'} 버전 사양 확인하기`)
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<WidgetsFixMainTitle
|
|
:title="tm('Download_Page_Title')"
|
|
:resources-data="backgroundData"
|
|
/>
|
|
|
|
<div class="section-container static">
|
|
<section class="section-static">
|
|
<WidgetsFixSubTitle :title="tm('Download_Section_Platform_Title')" />
|
|
|
|
<div
|
|
class="relative flex flex-col-reverse items-stretch justify-center sm:flex-row-reverse gap-[12px] w-full md:gap-[24px] md:grid md:grid-cols-12 md:grid-rows-1 lg:gap-[20px]"
|
|
>
|
|
<div
|
|
v-if="gameData?.platform_type !== '2'"
|
|
class="relative flex flex-col items-start justify-start w-full h-[270px] py-[20px] rounded-[12px] bg-white sm:w-[calc(50%-6px)] sm:h-auto md:flex-none md:w-auto md:pt-[24px] md:pb-0 lg:pt-[32px]"
|
|
:class="
|
|
gameData?.platform_type === '1' ? 'md:col-span-12' : 'md:col-span-8'
|
|
"
|
|
>
|
|
<div
|
|
class="relative flex flex-col items-start justify-start gap-[20px] w-full max-w-[880px] h-full px-[20px] mx-auto md:gap-[24px] md:h-auto md:px-[28px] md:pr-[262px] lg:px-[40px]"
|
|
>
|
|
<span
|
|
v-if="!breakpoints.isMobile"
|
|
class="absolute top-0 right-[28px] w-[212px] h-[212px] lg:right-[40px]"
|
|
>
|
|
<img
|
|
:src="
|
|
formatPathHost('/images/common/img_desktop.png', {
|
|
imageType: 'public',
|
|
})
|
|
"
|
|
:alt="tm('Download_Box_PC_Title')"
|
|
loading="lazy"
|
|
draggable="false"
|
|
class="w-full h-full object-contain"
|
|
/>
|
|
</span>
|
|
|
|
<div
|
|
class="relative flex flex-col items-start justify-start w-full h-auto min-h-[108px] gap-[8px] md:gap-[12px] lg:min-h-[134px]"
|
|
>
|
|
<h4
|
|
class="relative flex justify-left items-center w-full gap-[4px] text-left text-[#1F1F1F] text-[18px] font-bold leading-[26px] tracking-[-0.54px] md:text-[24px] md:leading-[34px] md:tracking-[-0.72px]"
|
|
>
|
|
<span>{{ tm('Download_Box_PC_Title') }}</span>
|
|
|
|
<AtomsTooltip
|
|
position="top"
|
|
:offset="8"
|
|
background-color="#666666"
|
|
text-color="#FFFFFF"
|
|
:arrow="true"
|
|
:content="tm('Download_Box_PC_Tooltip')"
|
|
/>
|
|
</h4>
|
|
|
|
<template
|
|
v-for="(description, dIndex) in tm(
|
|
'Download_Box_PC_Description_List'
|
|
)"
|
|
:key="dIndex"
|
|
>
|
|
<p
|
|
v-dompurify-html="tm(description as string)"
|
|
class="relative flex items-center justify-start w-full text-left text-[#999999] text-[14px] font-[400] leading-[24px] tracking-[-0.42px] md:text-[15px] md:tracking-[-0.45px]"
|
|
></p>
|
|
</template>
|
|
|
|
<button
|
|
class="relative flex gap-1 text-[14px] font-[500] text-[#1F1F1F] leading-[20px] tracking-[-0.42px] md:text-[16px] md:leading-[24px] md:tracking-[-0.48px] before:content-[''] before:absolute before:z-[2] before:top-p before:left-0 before:w-full before:h-full before:bg-[#FFFFFF] before:transition-opacity before:duration-300 before:ease-in-out before:opacity-0 hover:before:opacity-20"
|
|
@click="handleMoveFocus('pc')"
|
|
>
|
|
<span>{{ tm('Download_Box_PC_SpecCheck') }}</span>
|
|
<AtomsIconsLongArrowRightLine
|
|
:size="20"
|
|
color="#1F1F1F"
|
|
class="relative rotate-90"
|
|
/>
|
|
</button>
|
|
</div>
|
|
|
|
<div
|
|
v-if="breakpoints.isMobile"
|
|
class="relative flex items-center justify-center w-full h-auto min-h-[48px] py-[14px] px-[40px] mt-auto border border-solid border-[rgba(0,0,0,0.1)] rounded-[8px] bg-[#EBEBEB] text-center text-[#999999] text-[14px] font-[500] leading-[20px] tracking-[-0.42px]"
|
|
>
|
|
<span>{{ tm('Download_Button_PC_Mobile') }}</span>
|
|
</div>
|
|
|
|
<BlocksButtonLauncher
|
|
v-else-if="breakpoints.isMd || breakpoints.isDesktop"
|
|
platform="pc"
|
|
class="w-[300px]"
|
|
@click="
|
|
handleSendLog(
|
|
t('Download_Button_PC_Download', {}, { locale: 'ko' })
|
|
)
|
|
"
|
|
>
|
|
<span>{{ tm('Download_Button_PC') }}</span>
|
|
</BlocksButtonLauncher>
|
|
</div>
|
|
|
|
<div
|
|
v-if="!breakpoints.isMobile"
|
|
class="relative flex items-center justify-center w-full p-[25px] mt-[24px] rounded-b-[12px] bg-[#FAFAFA] lg:mt-[32px]"
|
|
>
|
|
<p
|
|
class="relative flex items-center justify-center w-full gap-[8px] text-[#999999] text-[16px] font-[400] leading-[26px] tracking-[-0.48px]"
|
|
>
|
|
<span>{{ tm('Download_Text_Not_STOVE_Client') }}</span>
|
|
<a
|
|
:href="stoveClientDownloadUrl"
|
|
target="_self"
|
|
rel="noopener noreferrer"
|
|
class="inline-flex items-center justify-start gap-[4px] text-[#3C75FF] text-[16px] font-[500] reading-[24px] tracking-[-0.48px]"
|
|
@click="
|
|
handleSendLog(
|
|
t('Download_Button_STOVE', {}, { locale: 'ko' })
|
|
)
|
|
"
|
|
>
|
|
<span>{{ tm('Download_Button_STOVE') }}</span>
|
|
<AtomsIconsDownloadLine color="#3C75FF" />
|
|
</a>
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div
|
|
v-if="gameData?.platform_type !== '1'"
|
|
class="relative flex flex-col items-start justify-start w-full h-[270px] p-[20px] rounded-[12px] bg-white sm:w-[calc(50%-6px)] sm:h-auto md:flex-none md:w-auto md:py-[24px] md:px-[28px] lg:py-[32px] lg:px-[40px]"
|
|
:class="
|
|
gameData?.platform_type === '2' ? 'md:col-span-12' : 'md:col-span-4'
|
|
"
|
|
>
|
|
<div
|
|
class="relative flex flex-col items-start justify-start gap-[20px] w-full h-full max-w-[880px] mx-auto md:gap-[24px]"
|
|
>
|
|
<div
|
|
class="relative flex flex-col items-start justify-start w-full gap-[8px] md:gap-[12px]"
|
|
>
|
|
<h4
|
|
class="relative flex justify-left items-center w-full text-left text-[#1F1F1F] text-[18px] font-bold leading-[26px] tracking-[-0.54px] md:text-[24px] md:leading-[34px] md:tracking-[-0.72px]"
|
|
>
|
|
<span>{{ tm('Download_Box_MOBILE_Title') }}</span>
|
|
</h4>
|
|
|
|
<button
|
|
class="relative flex gap-1 text-[14px] font-[500] text-[#1F1F1F] leading-[20px] tracking-[-0.42px] md:text-[16px] md:leading-[24px] md:tracking-[-0.48px] before:content-[''] before:absolute before:z-[2] before:top-p before:left-0 before:w-full before:h-full before:bg-[#FFFFFF] before:transition-opacity before:duration-300 before:ease-in-out before:opacity-0 hover:before:opacity-20"
|
|
@click="handleMoveFocus('mobile')"
|
|
>
|
|
<span>{{ tm('Download_Box_MOBILE_SpecCheck') }}</span>
|
|
<AtomsIconsLongArrowRightLine
|
|
:size="20"
|
|
color="#1F1F1F"
|
|
class="relative rotate-90"
|
|
/>
|
|
</button>
|
|
</div>
|
|
|
|
<div
|
|
class="relative flex flex-col items-start justify-start w-full gap-[8px] mt-auto md:gap-[12px]"
|
|
>
|
|
<template v-for="os in mobileOSList" :key="os.id">
|
|
<BlocksButtonLauncher
|
|
v-if="
|
|
device.isMobile
|
|
? os.isValue
|
|
: gameData?.os_type !== '3'
|
|
? gameData?.os_type === os.osType
|
|
: true
|
|
"
|
|
:platform="`${os.platformCode as Platform}`"
|
|
class="w-full"
|
|
@click="handleSendLog(formatSnakeToTitle(os.platformCode))"
|
|
>
|
|
<span>{{ os.platformText }}</span>
|
|
</BlocksButtonLauncher>
|
|
</template>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<section ref="specPCRef" class="section-static">
|
|
<WidgetsFixSubTitle :title="tm('Download_Section_PC_Title')" />
|
|
|
|
<div
|
|
class="relative w-full border border-solid border-[#D9D9D9] rounded-[12px] overflow-hidden md:rounded-[16px]"
|
|
>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th class="w-[80px] md:w-[172px] !border-l-[0]">
|
|
{{ tm('Download_Table_Item') }}
|
|
</th>
|
|
<th>{{ tm('Download_Table_Min_Spec') }}</th>
|
|
<th>{{ tm('Download_Table_Rec_Spec') }}</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<template v-for="(tr, trIdx) in pcSpecList" :key="tr.id">
|
|
<tr>
|
|
<th
|
|
:class="[
|
|
'w-[80px] md:w-[172px] !border-l-[0]',
|
|
trIdx === pcSpecList.length - 1 ? '!border-b-[0]' : '',
|
|
]"
|
|
>
|
|
{{ tr.itemText }}
|
|
</th>
|
|
<template v-for="td in tr.itemData" :key="td.display.text">
|
|
<td
|
|
:class="
|
|
trIdx === pcSpecList.length - 1 ? '!border-b-[0]' : ''
|
|
"
|
|
>
|
|
{{ td.display.text }}
|
|
</td>
|
|
</template>
|
|
</tr>
|
|
</template>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
<div
|
|
v-if="!breakpoints.isMobile"
|
|
class="relative flex items-end justify-between w-full mt-[24px] gap-[24px]"
|
|
>
|
|
<ul
|
|
v-if="tm('Download_Section_PC_Notice_List').length > 0"
|
|
class="relative flex flex-col items-center justify-start w-full"
|
|
>
|
|
<template
|
|
v-for="notice in tm('Download_Section_PC_Notice_List')"
|
|
:key="notice"
|
|
>
|
|
<li
|
|
v-dompurify-html="tm(notice)"
|
|
class="relative w-full pl-[26px] text-left text-[#666666] text-[16px] font-[400] leading-[26px] tracking-[-0.48px] before:content-[''] before:absolute before:top-[11px] before:left-[10px] before:w-[4px] before:h-[4px] before:bg-[#666666] before:rounded-full"
|
|
></li>
|
|
</template>
|
|
</ul>
|
|
<AtomsButton
|
|
type="action"
|
|
size="size-small"
|
|
background-color="#383838"
|
|
text-color="#FFFFFF"
|
|
class="shrink-0 w-[206px] px-0 text-[16px]"
|
|
@click="[
|
|
checkPCSpec({
|
|
schemeFormat: schemeFormatData,
|
|
setupUrl: setupUrlData,
|
|
gameNo: gameData?.game_code?.toString(),
|
|
locale: locale as string,
|
|
}),
|
|
handleSendLog(t('Download_Button_SpecCheck', {}, { locale: 'ko' })),
|
|
]"
|
|
>
|
|
<em
|
|
class="inline-flex items-center justify-center gap-[8px] not-italic"
|
|
>
|
|
<span
|
|
class="relative inline-flex items-center justify-center w-[20px] h-[20px]"
|
|
>
|
|
<AtomsIconsDesktopLine :size="16" color="#FFFFFF" />
|
|
</span>
|
|
<span>{{ tm('Download_Button_SpecCheck') }}</span>
|
|
</em>
|
|
</AtomsButton>
|
|
</div>
|
|
</section>
|
|
|
|
<section v-if="!breakpoints.isMobile" class="section-static">
|
|
<WidgetsFixSubTitle :title="tm('Download_Section_Driver_Title')" />
|
|
<ul class="flex items-center justify-between gap-[20px] w-full">
|
|
<template v-for="driver in driverList" :key="driver.id">
|
|
<li class="w-full h-[250px]">
|
|
<div
|
|
class="flex flex-col items-center justify-between gap-[16px] h-[250px] rounded-[16px] p-[20px] bg-[#FFFFFF]"
|
|
>
|
|
<div class="flex items-center justify-center w-full">
|
|
<img
|
|
:src="
|
|
formatPathHost(
|
|
`/images/common/download_driver/Type-${driver.driverCode}.svg`,
|
|
{ imageType: 'public' }
|
|
)
|
|
"
|
|
:alt="driver.driverText"
|
|
loading="lazy"
|
|
draggable="false"
|
|
/>
|
|
</div>
|
|
|
|
<div
|
|
class="flex flex-col items-start justify-end gap-[16px] w-full"
|
|
>
|
|
<p
|
|
class="text-left text-[#666666] text-[16px] font-[400] leading-[26px] tracking-[-0.48px]"
|
|
>
|
|
{{ driver.driverText }}
|
|
</p>
|
|
|
|
<AtomsButton
|
|
type="external"
|
|
size="size-small"
|
|
background-color="#383838"
|
|
text-color="#FFFFFF"
|
|
class="btn-download"
|
|
rel="noopener noreferrer"
|
|
:href="tm(`Download_Driver_${driver.driverCode}_Url`)"
|
|
@click="handleSendLog(`다운로드_${driver.driverText}`)"
|
|
>
|
|
<span>{{ tm('Download_Button_Download') }}</span>
|
|
</AtomsButton>
|
|
</div>
|
|
</div>
|
|
</li>
|
|
</template>
|
|
</ul>
|
|
</section>
|
|
|
|
<section ref="specMobileRef" class="section-static">
|
|
<WidgetsFixSubTitle :title="tm('Download_Section_MOBILE_Title')" />
|
|
<div
|
|
class="relative w-full border border-solid border-[#D9D9D9] rounded-[12px] overflow-hidden md:rounded-[16px]"
|
|
>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th rowspan="2" class="w-[80px] md:w-[172px] !border-l-[0]">
|
|
{{ tm('Download_Table_Item') }}
|
|
</th>
|
|
<th colspan="2">{{ tm('Download_Table_Min_Spec') }}</th>
|
|
<th colspan="2">{{ tm('Download_Table_Rec_Spec') }}</th>
|
|
</tr>
|
|
<tr>
|
|
<th>{{ tm('Download_Table_Device') }}</th>
|
|
<th>{{ tm('Download_Table_Os') }}</th>
|
|
<th>{{ tm('Download_Table_Device') }}</th>
|
|
<th>{{ tm('Download_Table_Os') }}</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<template v-for="(tr, trIdx) in mobileSpecList" :key="tr.id">
|
|
<tr>
|
|
<th
|
|
:class="[
|
|
'w-[80px] md:w-[172px] !border-l-[0]',
|
|
trIdx === mobileSpecList.length - 1 ? '!border-b-[0]' : '',
|
|
]"
|
|
>
|
|
{{ tr.itemText }}
|
|
</th>
|
|
<template v-for="td in tr.itemData" :key="td.display.text">
|
|
<td
|
|
:class="
|
|
trIdx === mobileSpecList.length - 1 ? '!border-b-[0]' : ''
|
|
"
|
|
>
|
|
{{ td.display.text }}
|
|
</td>
|
|
</template>
|
|
</tr>
|
|
</template>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</section>
|
|
</div>
|
|
</template>
|
|
|
|
<style scoped>
|
|
/* 고정형 페이지 Table Style */
|
|
table {
|
|
@apply w-full h-auto border-collapse border-spacing-0 table-fixed;
|
|
}
|
|
table th {
|
|
@apply py-[8px] px-[12px] border-l border-b border-solid border-[#D9D9D9] bg-[#FAFAFA] text-center text-[#1F1F1F] text-[14px] font-bold leading-[24px] tracking-[-0.42px]
|
|
md:py-[11px] md:px-[20px] md:text-[16px] md:leading-[26px] md:tracking-[-0.48px];
|
|
}
|
|
table td {
|
|
@apply h-[64px] py-[8px] px-[12px] border-l border-b border-[#D9D9D9] bg-[#FFFFFF] text-center text-[#666666] text-[14px] font-[400] leading-[24px] tracking-[-0.42px]
|
|
md:h-[80px] md:py-[14px] md:px-[20px] md:text-[16px] md:leading-[26px] md:tracking-[-0.48px];
|
|
}
|
|
|
|
.btn-download {
|
|
@apply w-full px-0;
|
|
}
|
|
.btn-download:deep(.icon-external) {
|
|
@apply hidden;
|
|
}
|
|
</style>
|