fix. 코드 리팩토링
This commit is contained in:
@@ -80,7 +80,7 @@ const createMetaTags = (metaTag: Partial<GameDataMetaTag> = {}) => {
|
||||
}
|
||||
|
||||
// CSS 변수 생성 헬퍼
|
||||
const createCssVariable = (keyColorJson: GameDataKeyColors) => {
|
||||
const createStyleCss = (keyColorJson: GameDataKeyColors) => {
|
||||
const colorVariables = Object.entries(keyColorJson)
|
||||
.filter(([key, value]) => key && value != null)
|
||||
.map(([key, value]) => `--${key}: ${value};`)
|
||||
@@ -95,9 +95,10 @@ const setupGameHead = (data: GameDataValue) => {
|
||||
const metaTag: Partial<GameDataMetaTag> = data.meta_tag_json ?? {}
|
||||
const designTheme = data.design_theme === 1 ? 'light' : 'dark'
|
||||
const styleLinks = createStyleLinks(
|
||||
data.favicon_json
|
||||
// data?.game_font?.font_path
|
||||
data.favicon_json,
|
||||
data?.game_font?.font_path
|
||||
)
|
||||
const styleCss = createStyleCss(data.key_color_json)
|
||||
|
||||
useHead({
|
||||
title: metaTag.page_title ?? '',
|
||||
@@ -110,7 +111,7 @@ const setupGameHead = (data: GameDataValue) => {
|
||||
link: styleLinks,
|
||||
style: [
|
||||
{
|
||||
innerHTML: createCssVariable(data.key_color_json),
|
||||
innerHTML: styleCss,
|
||||
id: 'game-css-variables',
|
||||
},
|
||||
],
|
||||
|
||||
@@ -56,80 +56,24 @@
|
||||
></span>
|
||||
</h3>
|
||||
<div class="button-group justify-center">
|
||||
<!-- <a
|
||||
:href="communityUrl"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="inspection-btn inspection-btn-outline inspection-btn-community"
|
||||
:class="{ 'bg-[var(--primary)]' : !launchingStatus }"
|
||||
>
|
||||
<span>{{ tm('Inspection_Community_Btn') || '공식 커뮤니티' }}</span>
|
||||
<AtomsIconsLongArrowRightLine :size="16" color="#1F1F1F" />
|
||||
</a> -->
|
||||
|
||||
<AtomsButtonVariant
|
||||
type="custom"
|
||||
class="inspection-btn inspection-btn-community color-black text-sm px-4 md:text-base"
|
||||
:class="{ 'inspection-btn-outline flex-1': launchingStatus }"
|
||||
<AtomsButton
|
||||
variant="outlined"
|
||||
class="flex-1 size-extra-small md:size-small"
|
||||
@click="handleCommunityClick"
|
||||
>
|
||||
<span>{{ tm('Inspection_Community_Btn') }}</span>
|
||||
<span class="text">{{ tm('Inspection_Community_Btn') }}</span>
|
||||
<AtomsIconsLongArrowRightLine :size="16" color="#1F1F1F" />
|
||||
</AtomsButtonVariant>
|
||||
|
||||
<div v-if="launchingStatus" class="flex flex-1">
|
||||
<BlocksButtonLauncher
|
||||
v-if="
|
||||
(Number(gameData?.platform_type) !== 2 &&
|
||||
device.isDesktop) ||
|
||||
Number(gameData?.platform_type) === 1
|
||||
"
|
||||
type="custom"
|
||||
platform="pc"
|
||||
class="inspection-btn inspection-btn-primary w-full color-black text-sm md:text-base flex-1"
|
||||
>
|
||||
<span>{{ tm('Txt_Game_Start') }}</span>
|
||||
|
||||
<svg
|
||||
width="16"
|
||||
height="16"
|
||||
viewBox="0 0 16 16"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
d="M10.3098 1.49172C8.86574 1.28049 7.15098 1.28055 5.70176 1.49167C3.50821 1.81315 1.81986 3.50786 1.49213 5.69168L1.4918 5.69391C1.38564 6.41904 1.33331 7.19181 1.33331 7.99998C1.33331 8.80815 1.3857 9.58136 1.49187 10.3065C1.81362 12.4934 3.50335 14.1805 5.69381 14.5079L5.69577 14.5082C6.42109 14.6143 7.19417 14.6666 7.99717 14.6666C8.80032 14.6666 9.57311 14.6143 10.3035 14.5083L10.3046 14.5082C12.4928 14.1865 14.1802 12.4917 14.5078 10.3083L14.5082 10.3061C14.6143 9.58092 14.6666 8.80815 14.6666 7.99998C14.6666 7.19527 14.6203 6.42148 14.5137 5.69347C14.1921 3.50726 12.4966 1.81316 10.3098 1.49172ZM6.38756 8.95267C6.39301 9.15365 6.40004 9.35195 6.40866 9.54742L6.40968 9.57054C6.41945 9.78867 6.43118 10.0033 6.44489 10.2141C6.45959 10.4433 6.68743 10.5836 6.88293 10.4823C7.22837 10.3029 7.58116 10.1096 7.9413 9.90379C8.20002 9.7541 8.46167 9.6013 8.72479 9.43914C8.98791 9.27854 9.24516 9.11482 9.49505 8.95111C9.84196 8.72502 10.1771 8.49581 10.4961 8.26817C10.6769 8.14031 10.6769 7.85965 10.4961 7.7318C10.1771 7.50415 9.84343 7.2765 9.49505 7.04886C9.24516 6.88514 8.98791 6.72298 8.72479 6.56082C8.46167 6.39866 8.20002 6.2443 7.9413 6.09618C7.58263 5.89036 7.22837 5.69702 6.88293 5.5177C6.68743 5.41636 6.45959 5.55669 6.44489 5.78589C6.43118 5.99671 6.41945 6.21129 6.40968 6.42943L6.40866 6.45254C6.40004 6.64801 6.39301 6.84631 6.38756 7.0473C6.37874 7.3607 6.37433 7.67722 6.37433 7.99998C6.37433 8.32274 6.37874 8.64082 6.38756 8.95267Z"
|
||||
fill="#332C2A"
|
||||
/>
|
||||
</svg>
|
||||
</BlocksButtonLauncher>
|
||||
|
||||
<AtomsButtonVariant
|
||||
v-else-if="Number(gameData?.platform_type) !== 1"
|
||||
type="custom"
|
||||
class="inspection-btn inspection-btn-primary w-full color-black text-sm md:text-base flex-1"
|
||||
@click="handleGameStart"
|
||||
>
|
||||
<span>{{ tm('Txt_Game_Start') }}</span>
|
||||
|
||||
<svg
|
||||
width="16"
|
||||
height="16"
|
||||
viewBox="0 0 16 16"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
d="M10.3098 1.49172C8.86574 1.28049 7.15098 1.28055 5.70176 1.49167C3.50821 1.81315 1.81986 3.50786 1.49213 5.69168L1.4918 5.69391C1.38564 6.41904 1.33331 7.19181 1.33331 7.99998C1.33331 8.80815 1.3857 9.58136 1.49187 10.3065C1.81362 12.4934 3.50335 14.1805 5.69381 14.5079L5.69577 14.5082C6.42109 14.6143 7.19417 14.6666 7.99717 14.6666C8.80032 14.6666 9.57311 14.6143 10.3035 14.5083L10.3046 14.5082C12.4928 14.1865 14.1802 12.4917 14.5078 10.3083L14.5082 10.3061C14.6143 9.58092 14.6666 8.80815 14.6666 7.99998C14.6666 7.19527 14.6203 6.42148 14.5137 5.69347C14.1921 3.50726 12.4966 1.81316 10.3098 1.49172ZM6.38756 8.95267C6.39301 9.15365 6.40004 9.35195 6.40866 9.54742L6.40968 9.57054C6.41945 9.78867 6.43118 10.0033 6.44489 10.2141C6.45959 10.4433 6.68743 10.5836 6.88293 10.4823C7.22837 10.3029 7.58116 10.1096 7.9413 9.90379C8.20002 9.7541 8.46167 9.6013 8.72479 9.43914C8.98791 9.27854 9.24516 9.11482 9.49505 8.95111C9.84196 8.72502 10.1771 8.49581 10.4961 8.26817C10.6769 8.14031 10.6769 7.85965 10.4961 7.7318C10.1771 7.50415 9.84343 7.2765 9.49505 7.04886C9.24516 6.88514 8.98791 6.72298 8.72479 6.56082C8.46167 6.39866 8.20002 6.2443 7.9413 6.09618C7.58263 5.89036 7.22837 5.69702 6.88293 5.5177C6.68743 5.41636 6.45959 5.55669 6.44489 5.78589C6.43118 5.99671 6.41945 6.21129 6.40968 6.42943L6.40866 6.45254C6.40004 6.64801 6.39301 6.84631 6.38756 7.0473C6.37874 7.3607 6.37433 7.67722 6.37433 7.99998C6.37433 8.32274 6.37874 8.64082 6.38756 8.95267Z"
|
||||
fill="#332C2A"
|
||||
/>
|
||||
</svg>
|
||||
</AtomsButtonVariant>
|
||||
</div>
|
||||
</AtomsButton>
|
||||
<BlocksButtonLauncher
|
||||
v-if="launchingStatus"
|
||||
type="single"
|
||||
platform="pc"
|
||||
class="inspection-launcher"
|
||||
:icon-component="AtomsIconsPlayRoundFill"
|
||||
:icon-props="{ size: 16, color: '#332C2A' }"
|
||||
>
|
||||
{{ tm('Txt_Game_Start') }}
|
||||
</BlocksButtonLauncher>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -137,7 +81,6 @@
|
||||
<div
|
||||
v-if="launchingStatus"
|
||||
class="inspection-card inspection-download-card"
|
||||
:class="`platform-type-${gameData?.platform_type}`"
|
||||
>
|
||||
<h3 class="card-title text-base md:text-lg">
|
||||
{{
|
||||
@@ -147,18 +90,23 @@
|
||||
}}
|
||||
</h3>
|
||||
<div class="flex flex-row gap-3 flex-wrap">
|
||||
<BlocksButtonLauncher
|
||||
v-for="(btn, index) in enabledMarkets"
|
||||
<template
|
||||
v-for="(market, index) in enabledMarkets"
|
||||
:key="index"
|
||||
:class="getButtonClass(btn.platform)"
|
||||
class="h-[40px] md:h-[48px]"
|
||||
:platform="btn.platform as any"
|
||||
:url="btn.url"
|
||||
:type="btn.platform === 'pc' ? 'default' : 'single'"
|
||||
variant="outlined"
|
||||
>
|
||||
{{ getButtonText(btn.platform) }}
|
||||
</BlocksButtonLauncher>
|
||||
<BlocksButtonLauncher
|
||||
:type="market === 'pc' ? 'default' : 'single'"
|
||||
variant="outlined"
|
||||
:platform="market"
|
||||
:class="[
|
||||
{ 'flex-1': market === 'pc' },
|
||||
{ 'flex-1': market !== 'pc' && !device.isDesktop },
|
||||
'size-extra-small md:size-small',
|
||||
]"
|
||||
>
|
||||
{{ getButtonText(market) }}
|
||||
</BlocksButtonLauncher>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -170,6 +118,8 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { globalDateFormat } from '@seed-next/date'
|
||||
import AtomsIconsPlayRoundFill from '#layers/components/atoms/icons/PlayRoundFill.vue'
|
||||
import type { Platform } from '#layers/types/components/button'
|
||||
|
||||
const config = useRuntimeConfig()
|
||||
const stoveApiUrl = config.public.stoveApiUrl as string
|
||||
@@ -233,51 +183,21 @@ const launchingStatus = computed(() => {
|
||||
return webInspectionData.value?.launching_status
|
||||
})
|
||||
|
||||
// const market_json = {
|
||||
// pc: { url: 'https://apps.apple.com/app/id1234567890', use_yn: 0 },
|
||||
// app_store: { url: 'https://apps.apple.com/app/id1234567890', use_yn: 0 },
|
||||
// google_play: { url: 'https://play.google.com/store/apps/details?id=example', use_yn: 1 }
|
||||
// }
|
||||
|
||||
//gameData.value.market_json 값 중 use_yn === 1 인 항목만 배열로 변환
|
||||
const enabledMarkets = computed(() => {
|
||||
const platformType = Number(gameData.value.platform_type)
|
||||
const markets = Object.entries(gameData.value.market_json)
|
||||
// return Object.entries(market_json)
|
||||
.filter(([, info]: [string, any]) => info && info.use_yn === 1)
|
||||
.map(([platform, info]: [string, any]) => ({
|
||||
platform,
|
||||
url: info.url as string,
|
||||
}))
|
||||
const markets = getSupportedPlatforms(
|
||||
gameData.value.platform_type,
|
||||
gameData.value.os_type
|
||||
) as Platform[]
|
||||
|
||||
// platform_type이 1이면 app_store, google_play 제외하고 pc 추가
|
||||
if (platformType === 1) {
|
||||
const filteredMarkets = markets.filter(
|
||||
m => m.platform !== 'app_store' && m.platform !== 'google_play'
|
||||
)
|
||||
const hasPc = filteredMarkets.some(m => m.platform === 'pc')
|
||||
if (!hasPc) {
|
||||
filteredMarkets.unshift({
|
||||
platform: 'pc',
|
||||
url: '',
|
||||
})
|
||||
if (device.isMobile) {
|
||||
// markets에 pc가 있다면 지우기
|
||||
markets.splice(markets.indexOf('pc'), 1)
|
||||
|
||||
if (device.isAndroid) {
|
||||
markets.splice(markets.indexOf('app_store'), 1)
|
||||
}
|
||||
return filteredMarkets
|
||||
}
|
||||
|
||||
// platform_type이 2이면 pc 제외
|
||||
if (platformType === 2) {
|
||||
return markets.filter(m => m.platform !== 'pc')
|
||||
}
|
||||
|
||||
// platform_type이 3이면 pc 항목 추가
|
||||
if (platformType === 3) {
|
||||
const hasPc = markets.some(m => m.platform === 'pc')
|
||||
if (!hasPc) {
|
||||
markets.unshift({
|
||||
platform: 'pc',
|
||||
url: '',
|
||||
})
|
||||
if (device.isApple) {
|
||||
markets.splice(markets.indexOf('google_play'), 1)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -287,7 +207,7 @@ const enabledMarkets = computed(() => {
|
||||
const logoImgUrl = computed(() => {
|
||||
const currentLocale = locale.value || 'ko'
|
||||
const localeData = (webInspectionData.value as any)?.[currentLocale]
|
||||
return formatPathHost(localeData.img_json.bi_large)
|
||||
return formatPathHost(localeData?.img_json.bi_large)
|
||||
})
|
||||
|
||||
const communityUrl = computed(() => {
|
||||
@@ -299,17 +219,6 @@ const communityUrl = computed(() => {
|
||||
const handleCommunityClick = () => {
|
||||
window.open(communityUrl.value, '_blank')
|
||||
}
|
||||
// 버튼 클래스 결정 함수
|
||||
const getButtonClass = (platform: string) => {
|
||||
// pc가 있으면 pc만 flex-1, 나머지는 기본
|
||||
|
||||
// platform_type이 3일 때 조건 추가
|
||||
if (Number(gameData.value.platform_type) !== 2 && platform === 'pc') {
|
||||
return `flex-1 btn-platform-${platform}`
|
||||
}
|
||||
|
||||
return `btn-platform-${platform}`
|
||||
}
|
||||
|
||||
const getButtonText = (platform: string) => {
|
||||
const platformKeyMap: Record<string, string> = {
|
||||
@@ -318,24 +227,14 @@ const getButtonText = (platform: string) => {
|
||||
app_store: 'platform_app_store',
|
||||
}
|
||||
|
||||
if (platform !== 'pc' && device.isDesktop) {
|
||||
return ''
|
||||
}
|
||||
|
||||
const key = platformKeyMap[platform]
|
||||
return key ? tm(key) : ''
|
||||
}
|
||||
|
||||
const handleGameStart = () => {
|
||||
const os = device.isAndroid
|
||||
? 'google_play'
|
||||
: device.isApple
|
||||
? 'app_store'
|
||||
: 'google_play'
|
||||
|
||||
//const os = device.isAndroid ? 'google_play' : device.isApple ? 'app_store' : 'pc'
|
||||
|
||||
// platform_type이 2이면서 device.isDesktop이면 window.open(gameData.value.market_json[os].url, '_blank')
|
||||
|
||||
window.open(gameData.value.market_json[os].url, '_blank')
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
loadingStore.stopFullLoading()
|
||||
})
|
||||
@@ -415,37 +314,7 @@ definePageMeta({
|
||||
}
|
||||
|
||||
.button-group {
|
||||
@apply flex flex-row gap-3 w-full;
|
||||
}
|
||||
|
||||
.inspection-btn {
|
||||
@apply flex items-center justify-center gap-1 px-2 md:px-4 h-10 md:h-12 rounded-lg;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
.inspection-btn span {
|
||||
@apply text-[#1F1F1F];
|
||||
}
|
||||
|
||||
.inspection-btn-outline {
|
||||
@apply bg-white;
|
||||
}
|
||||
|
||||
.inspection-btn-outline:hover {
|
||||
@apply bg-gray-50;
|
||||
}
|
||||
|
||||
.inspection-btn-primary {
|
||||
@apply bg-[var(--primary)] border-[var(--primary)] text-[#000];
|
||||
}
|
||||
|
||||
.inspection-btn-primary span {
|
||||
@apply text-black;
|
||||
}
|
||||
|
||||
.inspection-btn-primary:hover {
|
||||
@apply bg-[#B89D7A];
|
||||
@apply flex flex-row gap-3;
|
||||
}
|
||||
|
||||
@media (max-width: 1024px) {
|
||||
@@ -470,69 +339,18 @@ definePageMeta({
|
||||
@apply w-full;
|
||||
}
|
||||
}
|
||||
.inspection-btn-community {
|
||||
@apply rounded-lg;
|
||||
}
|
||||
.inspection-btn-community.inspection-btn-outline {
|
||||
@apply bg-white border-none;
|
||||
}
|
||||
|
||||
.inspection-btn-community.inspection-btn-outline:hover {
|
||||
@apply bg-gray-50;
|
||||
}
|
||||
.inspection-download-card .btn-platform-pc {
|
||||
@apply w-auto flex-1;
|
||||
}
|
||||
.inspection-download-card.platform-type-3 .btn-platform-pc {
|
||||
@apply w-full flex-none hidden md:flex md:flex-1;
|
||||
|
||||
.button-group:deep(.btn-base .text) {
|
||||
@apply mr-[2px] md:mr-[4px] text-[#1F1F1F];
|
||||
}
|
||||
|
||||
.inspection-download-card .btn-platform-app_store {
|
||||
@apply flex-1 px-2 md:px-4;
|
||||
.button-group:deep(.inspection-launcher.btn-base) {
|
||||
@apply flex-1 bg-[var(--primary)] px-[20px];
|
||||
}
|
||||
.inspection-download-card.platform-type-3 .btn-platform-app_store,
|
||||
.inspection-download-card.platform-type-3 .btn-platform-google_play {
|
||||
@apply flex-1 px-2 md:px-4 md:flex-none;
|
||||
}
|
||||
:deep(.inspection-download-card .btn-platform-app_store .text) {
|
||||
@apply block md:hidden;
|
||||
}
|
||||
:deep(.inspection-download-card.platform-type-2 .btn-platform-app_store .text) {
|
||||
@apply block md:block;
|
||||
}
|
||||
:deep(.inspection-download-card .btn-platform-google_play) {
|
||||
@apply flex-1 px-2 md:px-4;
|
||||
}
|
||||
:deep(.inspection-download-card .btn-platform-google_play .text) {
|
||||
@apply block md:hidden;
|
||||
}
|
||||
:deep(
|
||||
.inspection-download-card.platform-type-2 .btn-platform-google_play .text
|
||||
) {
|
||||
@apply block md:block;
|
||||
}
|
||||
:deep(.inspection-download-card .btn-base.single .icon-platform) {
|
||||
@apply mr-2 md:mr-0;
|
||||
}
|
||||
.inspection-btn-primary.btn-base {
|
||||
@apply bg-[var(--primary)] border-[var(--primary)] text-[#000];
|
||||
}
|
||||
|
||||
.inspection-btn-primary.btn-base:deep(.text) {
|
||||
@apply flex flex-1 items-center justify-center gap-1;
|
||||
}
|
||||
.inspection-btn-primary.btn-base:deep(.icon-platform) {
|
||||
@apply hidden;
|
||||
}
|
||||
|
||||
.inspection-btn-primary.btn-base {
|
||||
@apply bg-[var(--primary)] border-[var(--primary)] text-[#000];
|
||||
}
|
||||
|
||||
.inspection-btn-primary.btn-base:deep(.text) {
|
||||
@apply flex flex-1 items-center justify-center gap-1;
|
||||
}
|
||||
.inspection-btn-primary.btn-base:deep(.icon-platform) {
|
||||
.button-group:deep(.inspection-launcher.btn-base .icon-platform) {
|
||||
@apply hidden;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,25 +1,25 @@
|
||||
/* Button Size Classes */
|
||||
@layer components {
|
||||
/* height: 64px */
|
||||
.size-large {
|
||||
/* height: 64px */
|
||||
@apply px-10 h-16 text-lg rounded-lg
|
||||
before:rounded-lg after:rounded-lg;
|
||||
}
|
||||
|
||||
/* height: 56px */
|
||||
.size-medium {
|
||||
/* height: 56px */
|
||||
@apply px-10 h-14 text-base rounded-lg
|
||||
before:rounded-lg after:rounded-lg;
|
||||
}
|
||||
|
||||
/* height: 48px */
|
||||
.size-small {
|
||||
/* height: 48px */
|
||||
@apply px-10 h-12 text-sm rounded-lg
|
||||
before:rounded-lg after:rounded-lg;
|
||||
}
|
||||
|
||||
/* height: 40px */
|
||||
.size-extra-small {
|
||||
/* height: 40px */
|
||||
@apply px-6 h-10 text-sm rounded
|
||||
before:rounded after:rounded;
|
||||
}
|
||||
|
||||
@@ -13,24 +13,28 @@ const props = withDefaults(defineProps<props>(), {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<button :class="['btn-base', props.variant]" :disabled="props.disabled">
|
||||
<button
|
||||
class="btn-base"
|
||||
:data-variant="props.variant"
|
||||
:disabled="props.disabled"
|
||||
>
|
||||
<slot />
|
||||
</button>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.btn-base {
|
||||
@apply relative w-full py-[14px] px-5 text-sm font-medium rounded-lg
|
||||
@apply relative inline-flex items-center justify-center w-full py-[14px] px-5 text-sm font-medium rounded-lg
|
||||
before:content-[''] before:absolute before:top-0 before:left-0 before:w-full before:h-full before:border before:border-black/10 before:rounded-lg before:transition-all before:duration-300 before:ease-in-out;
|
||||
}
|
||||
|
||||
.btn-base.filled {
|
||||
.btn-base[data-variant='filled'] {
|
||||
@apply bg-[var(--primary)] text-[var(--text-secondary)]
|
||||
after:content-[''] after:absolute after:top-0 after:left-0 after:w-full after:h-full after:bg-white after:rounded-lg after:transition-opacity after:duration-300 after:ease-in-out after:opacity-0
|
||||
hover:after:opacity-20;
|
||||
}
|
||||
|
||||
.btn-base.outlined {
|
||||
.btn-base[data-variant='outlined'] {
|
||||
@apply bg-white text-[#333333]
|
||||
hover:before:border-[#999];
|
||||
}
|
||||
@@ -1,9 +1,10 @@
|
||||
<script setup lang="ts">
|
||||
import type { ButtonType } from '#layers/types/components/button'
|
||||
import type { ButtonType, ButtonVariant } from '#layers/types/components/button'
|
||||
|
||||
interface props {
|
||||
type?: ButtonType
|
||||
buttonSize?: string
|
||||
size?: string
|
||||
variant?: ButtonVariant
|
||||
target?: '_self' | '_blank'
|
||||
href?: string
|
||||
backgroundColor?: string
|
||||
@@ -13,9 +14,9 @@ interface props {
|
||||
|
||||
const props = withDefaults(defineProps<props>(), {
|
||||
type: 'action',
|
||||
buttonSize: 'size-small md:size-large',
|
||||
size: 'size-extra-small md:size-medium',
|
||||
variant: 'filled',
|
||||
target: '_self',
|
||||
backgroundColor: 'var(--primary)',
|
||||
textColor: 'var(--alternative-02)',
|
||||
disabled: false,
|
||||
})
|
||||
@@ -33,6 +34,12 @@ const componentTag = computed((): string => {
|
||||
return 'button'
|
||||
}
|
||||
})
|
||||
const backgroundColor = computed(() => {
|
||||
if (props.backgroundColor) {
|
||||
return props.backgroundColor
|
||||
}
|
||||
return props.variant === 'filled' ? 'var(--primary)' : 'white'
|
||||
})
|
||||
const componentProps = computed(() => {
|
||||
if (props.type === 'external' || props.type === 'link') {
|
||||
return {
|
||||
@@ -66,10 +73,11 @@ const componentProps = computed(() => {
|
||||
<component
|
||||
:is="componentTag"
|
||||
v-bind="{ ...componentProps }"
|
||||
:class="['btn-base', props.buttonSize, { disabled: props.disabled }]"
|
||||
:class="['btn-base', props.size, { disabled: props.disabled }]"
|
||||
:data-variant="props.variant"
|
||||
:style="{
|
||||
backgroundColor: props.backgroundColor,
|
||||
color: props.textColor,
|
||||
backgroundColor: backgroundColor,
|
||||
color: props.textColor ? props.textColor : 'var(--text-secondary)',
|
||||
'--text-color': props.textColor,
|
||||
}"
|
||||
:disabled="props.disabled"
|
||||
@@ -98,17 +106,22 @@ const componentProps = computed(() => {
|
||||
<style scoped>
|
||||
.btn-base {
|
||||
@apply overflow-hidden relative inline-flex items-center justify-center font-medium cursor-pointer
|
||||
before:content-[''] before:absolute before:top-0 before:left-0 before:w-full before:h-full before:border before:border-white/10
|
||||
after:content-[''] after:absolute after:top-0 after:left-0 after:w-full after:h-full after:bg-white after:transition-opacity after:duration-300 after:ease-in-out after:opacity-0;
|
||||
}
|
||||
.btn-base:hover {
|
||||
@apply after:opacity-20;
|
||||
before:content-[''] before:absolute before:top-0 before:left-0 before:w-full before:h-full before:border before:border-white/10;
|
||||
}
|
||||
.btn-base.disabled {
|
||||
@apply cursor-default pointer-events-none
|
||||
after:bg-[var(--text-color)] after:opacity-20 after:z-[2];
|
||||
}
|
||||
|
||||
.btn-base[data-variant='filled'] {
|
||||
@apply after:content-[''] after:absolute after:top-0 after:left-0 after:w-full after:h-full after:bg-white after:transition-opacity after:duration-300 after:ease-in-out after:opacity-0
|
||||
hover:after:opacity-20;
|
||||
}
|
||||
.btn-base[data-variant='outlined'] {
|
||||
@apply before:border-[rgba(0,0,0,0.1)]
|
||||
hover:before:border-[#999];
|
||||
}
|
||||
|
||||
.btn-base.disabled .btn-content {
|
||||
@apply opacity-50;
|
||||
}
|
||||
|
||||
@@ -44,10 +44,10 @@ const onInput = (event: Event) => {
|
||||
<AtomsButton
|
||||
v-if="props.useClearButton && localValue.length > 0"
|
||||
type="action"
|
||||
button-size="size-small"
|
||||
size="size-small md:size-medium"
|
||||
background-color="#00000000"
|
||||
text-color="transparent"
|
||||
class="!absolute top-[50%] right-[12px] translate-y-[-50%] flex items-center justify-center w-auto h-auto p-0 md:right-[16px]"
|
||||
class="!absolute top-[50%] right-[12px] translate-y-[-50%] flex items-center justify-center w-auto p-0 md:right-[16px]"
|
||||
@click="onClickClearButton"
|
||||
>
|
||||
<AtomsIconsCloseCircleFill :size="16" color="rgba(0,0,0,0.15)" />
|
||||
|
||||
@@ -41,7 +41,7 @@ const onSelectOption = (option: { [key: string | number]: any }): void => {
|
||||
<div class="relative w-full max-w-[432px]">
|
||||
<button
|
||||
type="button"
|
||||
class="relative flex items-center justify-between gap-[12px] w-full py-[12px] px-[16px] bg-white border border-solid border-[1px] border-[#D9D9D9] rounded-[8px]"
|
||||
class="relative flex items-center justify-between gap-[12px] w-full py-[12px] px-[16px] bg-white border-solid border-[1px] border-[#D9D9D9] rounded-[8px]"
|
||||
@click="onToggleOpen"
|
||||
>
|
||||
<span
|
||||
|
||||
@@ -5,7 +5,7 @@ interface Props {
|
||||
}
|
||||
|
||||
withDefaults(defineProps<Props>(), {
|
||||
size: 34,
|
||||
size: 16,
|
||||
color: 'white',
|
||||
})
|
||||
</script>
|
||||
@@ -15,13 +15,13 @@ withDefaults(defineProps<Props>(), {
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
:width="size"
|
||||
:height="size"
|
||||
viewBox="0 0 34 34"
|
||||
viewBox="0 0 16 16"
|
||||
:fill="color"
|
||||
>
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
d="M22.4412 0.396022C18.8311 -0.132052 14.5442 -0.131919 10.9211 0.39589C5.43725 1.1996 1.21636 5.43636 0.397045 10.8959L0.396229 10.9015C0.130814 12.7143 0 14.6462 0 16.6667C0 18.6871 0.130974 20.6201 0.39639 22.4329C1.20078 27.9002 5.4251 32.118 10.9013 32.9366L10.9061 32.9373C12.7195 33.2026 14.6521 33.3333 16.6596 33.3333C18.6675 33.3333 20.5995 33.2025 22.4254 32.9376L22.4283 32.9372C27.8987 32.1331 32.1171 27.8959 32.9363 22.4374L32.9371 22.4318C33.2025 20.619 33.3333 18.6871 33.3333 16.6667C33.3333 14.6549 33.2175 12.7204 32.951 10.9004C32.1469 5.43487 27.9082 1.19961 22.4412 0.396022ZM12.6356 19.0484C12.6492 19.5508 12.6668 20.0466 12.6884 20.5353L12.6909 20.5931C12.7153 21.1384 12.7447 21.6749 12.7789 22.2019C12.8157 22.7749 13.3853 23.1257 13.8741 22.8724C14.7377 22.4241 15.6196 21.9407 16.52 21.4262C17.1668 21.052 17.8209 20.67 18.4787 20.2646C19.1365 19.8631 19.7796 19.4538 20.4043 19.0445C21.2716 18.4793 22.1095 17.9063 22.9069 17.3371C23.3589 17.0175 23.3589 16.3158 22.9069 15.9962C22.1095 15.4271 21.2753 14.858 20.4043 14.2889C19.7796 13.8796 19.1365 13.4742 18.4787 13.0688C17.8209 12.6634 17.1668 12.2775 16.52 11.9072C15.6233 11.3926 14.7377 10.9093 13.8741 10.461C13.3853 10.2076 12.8157 10.5584 12.7789 11.1314C12.7447 11.6585 12.7153 12.1949 12.6909 12.7403L12.6884 12.7981C12.6668 13.2867 12.6492 13.7825 12.6356 14.285C12.6136 15.0685 12.6025 15.8598 12.6025 16.6667C12.6025 17.4736 12.6136 18.2688 12.6356 19.0484Z"
|
||||
d="M10.3098 1.49172C8.86568 1.28049 7.15091 1.28055 5.7017 1.49167C3.50815 1.81315 1.8198 3.50786 1.49207 5.69168L1.49174 5.69391C1.38558 6.41904 1.33325 7.19181 1.33325 7.99998C1.33325 8.80815 1.38564 9.58136 1.49181 10.3065C1.81356 12.4934 3.50329 14.1805 5.69375 14.5079L5.69571 14.5082C6.42103 14.6143 7.19411 14.6666 7.99711 14.6666C8.80026 14.6666 9.57305 14.6143 10.3034 14.5083L10.3046 14.5082C12.4927 14.1865 14.1801 12.4917 14.5078 10.3083L14.5081 10.3061C14.6143 9.58092 14.6666 8.80815 14.6666 7.99998C14.6666 7.19527 14.6202 6.42148 14.5137 5.69347C14.192 3.50726 12.4965 1.81316 10.3098 1.49172ZM6.3875 8.95266C6.39295 9.15365 6.39998 9.35195 6.4086 9.54742L6.40962 9.57054C6.41938 9.78867 6.43112 10.0033 6.44483 10.2141C6.45952 10.4433 6.68737 10.5836 6.88287 10.4823C7.22831 10.3029 7.5811 10.1096 7.94124 9.90379C8.19995 9.7541 8.46161 9.6013 8.72473 9.43914C8.98785 9.27854 9.24509 9.11482 9.49499 8.9511C9.8419 8.72502 10.177 8.49581 10.496 8.26817C10.6768 8.14031 10.6768 7.85965 10.496 7.7318C10.177 7.50415 9.84337 7.2765 9.49499 7.04886C9.24509 6.88514 8.98785 6.72298 8.72473 6.56082C8.46161 6.39866 8.19995 6.2443 7.94124 6.09618C7.58257 5.89036 7.22831 5.69701 6.88287 5.5177C6.68737 5.41636 6.45952 5.55668 6.44483 5.78589C6.43112 5.99671 6.41938 6.21129 6.40962 6.42943L6.4086 6.45254C6.39998 6.64801 6.39295 6.84631 6.3875 7.0473C6.37868 7.3607 6.37427 7.67722 6.37427 7.99998C6.37427 8.32274 6.37868 8.64082 6.3875 8.95266Z"
|
||||
/>
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
import type { CSSProperties } from 'vue'
|
||||
import type { CSSProperties, Component } from 'vue'
|
||||
import type { PlatformTransformType } from '#layers/types/api/gameData'
|
||||
import type {
|
||||
DownloadButtonType,
|
||||
@@ -13,6 +13,8 @@ interface Props {
|
||||
variant?: ButtonVariant
|
||||
backgroundColor?: string
|
||||
textColor?: string
|
||||
iconComponent?: Component
|
||||
iconProps?: Record<string, any>
|
||||
disabled?: boolean
|
||||
}
|
||||
|
||||
@@ -29,7 +31,8 @@ const gameDataStore = useGameDataStore()
|
||||
const modalStore = useModalStore()
|
||||
const { isProcessing, validateLauncher } = useCheckGameStart()
|
||||
|
||||
const { gameData } = storeToRefs(gameDataStore)
|
||||
const { gameName, platformType, osType, marketJson } =
|
||||
storeToRefs(gameDataStore)
|
||||
|
||||
const PLATFORM_ICON_MAP: Record<Platform, string> = {
|
||||
google_play: 'AtomsIconsLogoGoogle',
|
||||
@@ -55,8 +58,8 @@ const isSingle = computed(() => props.type === 'single')
|
||||
const supportedPlatforms = computed(
|
||||
() =>
|
||||
getSupportedPlatforms(
|
||||
gameData.value?.platform_type,
|
||||
gameData.value?.os_type
|
||||
platformType.value,
|
||||
osType.value
|
||||
) as PlatformTransformType[]
|
||||
)
|
||||
const platformIcon = computed(() => PLATFORM_ICON_MAP[props.platform])
|
||||
@@ -81,11 +84,7 @@ const tmWithGameName = (key: string): string => {
|
||||
const raw = tm(key)
|
||||
if (typeof raw !== 'string') return ''
|
||||
|
||||
const withName = raw.replace(
|
||||
/%게임명%/g,
|
||||
highlight(gameData.value?.game_name || '')
|
||||
)
|
||||
|
||||
const withName = raw.replace(/%게임명%/g, highlight(gameName.value))
|
||||
const platformLines = supportedPlatforms.value
|
||||
.map(platform => highlight(formatSnakeToTitle(platform)))
|
||||
.filter(Boolean)
|
||||
@@ -105,7 +104,8 @@ const handleClick = () => {
|
||||
}
|
||||
|
||||
if (props.platform === 'pc') {
|
||||
if (device.isDesktop && gameData.value?.platform_type !== '2') {
|
||||
if (device.isDesktop && platformType.value !== '2') {
|
||||
// 디바이스 pc 환경이면서 모바일 스토어 전용이 아니면 런처 실행
|
||||
validateLauncher()
|
||||
return
|
||||
} else {
|
||||
@@ -122,14 +122,13 @@ const handleClick = () => {
|
||||
return
|
||||
}
|
||||
|
||||
const url = gameData.value?.market_json?.[target]?.url || ''
|
||||
|
||||
const url = marketJson.value?.[target]?.url ?? ''
|
||||
window.open(url, '_blank')
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
const url = gameData.value?.market_json[props.platform]?.url || ''
|
||||
const url = marketJson.value?.[props.platform]?.url ?? ''
|
||||
if (url) window.open(url, '_blank')
|
||||
}
|
||||
</script>
|
||||
@@ -158,6 +157,11 @@ const handleClick = () => {
|
||||
<span class="text">
|
||||
<slot />
|
||||
</span>
|
||||
<component
|
||||
:is="props.iconComponent"
|
||||
v-if="props.iconComponent"
|
||||
v-bind="props.iconProps"
|
||||
/>
|
||||
<span
|
||||
v-if="props.platform === 'pc' && props.type === 'default'"
|
||||
class="icon-download"
|
||||
@@ -170,27 +174,25 @@ const handleClick = () => {
|
||||
|
||||
<style scoped>
|
||||
.btn-base {
|
||||
@apply overflow-hidden inline-flex relative font-medium rounded-lg cursor-pointer
|
||||
before:content-[''] before:absolute before:top-0 before:left-0 before:w-full before:h-full before:border before:border-white/10 before:rounded-lg
|
||||
after:content-[''] after:absolute after:top-0 after:left-0 after:w-full after:h-full after:bg-white after:transition-opacity after:duration-300 after:ease-in-out after:opacity-0 after:rounded-lg;
|
||||
}
|
||||
.btn-base:hover {
|
||||
@apply after:opacity-20;
|
||||
@apply overflow-hidden inline-flex relative font-medium rounded-lg cursor-pointer;
|
||||
}
|
||||
.btn-content {
|
||||
@apply relative flex items-center w-full text-left z-[1];
|
||||
@apply relative flex items-center w-full z-[1];
|
||||
}
|
||||
.icon-platform {
|
||||
@apply w-5 h-5 flex-shrink-0;
|
||||
}
|
||||
|
||||
.btn-base[data-variant='filled'] {
|
||||
@apply bg-[#383838] text-[#ffffff];
|
||||
@apply bg-[#383838] text-[#ffffff]
|
||||
before:content-[''] before:absolute before:top-0 before:left-0 before:w-full before:h-full before:border before:border-white/10 before:rounded-lg
|
||||
after:content-[''] after:absolute after:top-0 after:left-0 after:w-full after:h-full after:bg-white after:transition-opacity after:duration-300 after:ease-in-out after:opacity-0 after:rounded-lg
|
||||
hover:after:opacity-20;
|
||||
}
|
||||
|
||||
.btn-base[data-variant='outlined'] {
|
||||
@apply bg-white text-[#1F1F1F]
|
||||
before:border-black/10
|
||||
after:hidden;
|
||||
before:content-[''] before:absolute before:top-0 before:left-0 before:w-full before:h-full before:border before:border-black/10 before:rounded-lg;
|
||||
}
|
||||
.btn-base[data-variant='outlined'][data-platform='app_store'] svg,
|
||||
.btn-base[data-variant='outlined'][data-platform='pc'] svg,
|
||||
@@ -200,25 +202,23 @@ const handleClick = () => {
|
||||
|
||||
/* default */
|
||||
.btn-base.default {
|
||||
@apply w-[296px] py-3.5 px-5
|
||||
md:w-[356px] md:py-4 md:px-6;
|
||||
}
|
||||
.btn-base.default .text {
|
||||
@apply pl-2 pr-4 line-clamp-2 text-[14px]
|
||||
md:text-[16px];
|
||||
}
|
||||
.btn-base.default .icon-download {
|
||||
@apply ml-auto pl-4;
|
||||
@apply justify-center py-3.5 px-5
|
||||
md:py-4 md:px-6;
|
||||
}
|
||||
.btn-base.default .btn-content {
|
||||
@apply justify-center;
|
||||
}
|
||||
.btn-base.default[data-platform='pc'] .btn-content {
|
||||
@apply justify-start;
|
||||
.btn-base.default .text {
|
||||
@apply line-clamp-2 text-[14px]
|
||||
md:text-[16px];
|
||||
}
|
||||
.btn-base.default[data-platform='stove'] {
|
||||
@apply bg-[#FC4420];
|
||||
.btn-base.default .icon-platform + .text {
|
||||
@apply pl-2;
|
||||
}
|
||||
.btn-base.default .icon-download {
|
||||
@apply ml-auto pl-4;
|
||||
}
|
||||
|
||||
.btn-base.default[data-variant='outlined'] .icon-download {
|
||||
@apply border-black/10;
|
||||
}
|
||||
@@ -229,7 +229,7 @@ const handleClick = () => {
|
||||
/* duplication */
|
||||
.btn-base.duplication {
|
||||
@apply bg-[16px_50%] bg-[length:auto_28px] bg-no-repeat backdrop-blur-[15px]
|
||||
pt-[22px] pl-[47px] pr-[22px] pb-[7px] text-[11px]
|
||||
pt-[25px] pl-[47px] pr-[22px] pb-[7px] text-[11px]
|
||||
md:h-[64px] md:pt-[30px] md:pl-[64px] md:pr-[28px] md:pb-[11px] md:text-[12px] md:bg-[20px_50%] md:bg-[length:auto_40px];
|
||||
}
|
||||
.btn-base.duplication[data-platform='google_play'] {
|
||||
@@ -254,13 +254,17 @@ const handleClick = () => {
|
||||
h-[40px] px-3.5
|
||||
md:h-[48px];
|
||||
}
|
||||
.btn-base.single .btn-content {
|
||||
@apply justify-center;
|
||||
}
|
||||
.btn-base.single.no-text {
|
||||
@apply min-w-[40px] px-0 md:min-w-[48px];
|
||||
}
|
||||
.btn-base.single.no-text .icon-platform {
|
||||
@apply mx-auto;
|
||||
}
|
||||
.btn-base.single .icon-platform {
|
||||
@apply mr-1;
|
||||
|
||||
.btn-base[data-variant='outlined'] {
|
||||
@apply hover:before:border-[#999];
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -365,7 +365,7 @@ onMounted(() => {
|
||||
>
|
||||
<template #trigger>
|
||||
<div
|
||||
class="relative flex items-center justify-between w-full h-[40px] px-[16px] border border-solid border-[1px] border-[#D9D9D9] rounded-[8px] bg-white cursor-pointer"
|
||||
class="relative flex items-center justify-between w-full h-[40px] px-[16px] border-solid border-[1px] border-[#D9D9D9] rounded-[8px] bg-white cursor-pointer"
|
||||
>
|
||||
<AtomsInput
|
||||
:model-value="formatDate"
|
||||
|
||||
@@ -99,7 +99,7 @@ const handlePagination = (page: number) => {
|
||||
>
|
||||
<AtomsButton
|
||||
type="action"
|
||||
button-size="size-small"
|
||||
size="size-small"
|
||||
background-color="transparent"
|
||||
text-color="#333333"
|
||||
:class="[
|
||||
|
||||
@@ -3,12 +3,9 @@ let mountedInstance: any = null
|
||||
|
||||
onMounted(() => {
|
||||
const gameDataStore = useGameDataStore()
|
||||
const { stoveGnbJson, defaultLangCode, langCodes, theme } =
|
||||
storeToRefs(gameDataStore)
|
||||
|
||||
const { gameData } = storeToRefs(gameDataStore)
|
||||
const langCodes = gameData.value?.lang_codes
|
||||
const defaultLangCode = gameData.value?.default_lang_code
|
||||
const stoveGnbData = gameData.value?.stove_gnb_json
|
||||
const designTheme = gameData.value?.design_theme
|
||||
const currentDomain =
|
||||
window.location.protocol + '//' + window.location.hostname
|
||||
|
||||
@@ -21,8 +18,8 @@ onMounted(() => {
|
||||
mobile: '',
|
||||
},
|
||||
widget: {
|
||||
notification: stoveGnbData?.notify_icon_visible ?? true,
|
||||
stoveDownload: stoveGnbData?.stove_install_button_visible ?? true,
|
||||
notification: stoveGnbJson.value?.notify_icon_visible ?? true,
|
||||
stoveDownload: stoveGnbJson.value?.stove_install_button_visible ?? true,
|
||||
languageSelect: false,
|
||||
themeSelect: false,
|
||||
stoveMenu: {
|
||||
@@ -31,16 +28,16 @@ onMounted(() => {
|
||||
},
|
||||
},
|
||||
global: {
|
||||
languageCoverages: langCodes,
|
||||
defaultSelectedLanguage: defaultLangCode ?? 'ko',
|
||||
languageCoverages: langCodes.value,
|
||||
defaultSelectedLanguage: defaultLangCode.value ?? 'ko',
|
||||
},
|
||||
loginMethod: {
|
||||
redirectCurrentPage: true,
|
||||
},
|
||||
mode: {
|
||||
theme: {
|
||||
support: designTheme === 1 ? ['light'] : ['dark'],
|
||||
default: designTheme === 1 ? 'light' : 'dark',
|
||||
support: [theme.value],
|
||||
default: theme.value,
|
||||
},
|
||||
mini: true,
|
||||
layout: 'wide',
|
||||
|
||||
@@ -42,11 +42,11 @@ const handleOutsideClick = () => {
|
||||
></p>
|
||||
<slot></slot>
|
||||
<div class="content-btns">
|
||||
<AtomsButtonVariant
|
||||
<AtomsButtonModal
|
||||
@click="setButtonEvent(() => emit('confirmButtonEvent'))"
|
||||
>
|
||||
{{ props.confirmButtonText || tm('Text_Confirm') }}
|
||||
</AtomsButtonVariant>
|
||||
</AtomsButtonModal>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -42,17 +42,17 @@ const handleOutsideClick = () => {
|
||||
></p>
|
||||
<slot></slot>
|
||||
<div class="content-btns">
|
||||
<AtomsButtonVariant
|
||||
<AtomsButtonModal
|
||||
variant="outlined"
|
||||
@click="setButtonEvent(() => emit('cancelButtonEvent'))"
|
||||
>
|
||||
{{ props.cancelButtonText || tm('Text_Cancel') }}
|
||||
</AtomsButtonVariant>
|
||||
<AtomsButtonVariant
|
||||
</AtomsButtonModal>
|
||||
<AtomsButtonModal
|
||||
@click="setButtonEvent(() => emit('confirmButtonEvent'))"
|
||||
>
|
||||
{{ props.confirmButtonText || tm('Text_Confirm') }}
|
||||
</AtomsButtonVariant>
|
||||
</AtomsButtonModal>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -374,7 +374,6 @@ onMounted(() => {
|
||||
<div ref="startRef" class="btn-start">
|
||||
<template v-if="start1depthData">
|
||||
<BlocksButtonLauncher
|
||||
type="custom"
|
||||
platform="pc"
|
||||
:background-color="
|
||||
getColorCodeFromData(start1depthData?.btn_info, 'btn')
|
||||
@@ -393,7 +392,8 @@ onMounted(() => {
|
||||
<ul>
|
||||
<li v-for="(item, key) in start2depthData" :key="key">
|
||||
<BlocksButtonLauncher
|
||||
type="custom"
|
||||
type="single"
|
||||
variant="custom"
|
||||
:platform="key"
|
||||
@click="sendLog(locale, item.tracking)"
|
||||
>
|
||||
@@ -573,25 +573,28 @@ onMounted(() => {
|
||||
.btn-start:hover .nav-2depth {
|
||||
@apply md:block;
|
||||
}
|
||||
.btn-start:deep(> .btn-base) {
|
||||
.btn-start:deep(.btn-base[data-variant='filled']) {
|
||||
@apply w-full h-[48px] px-10 font-[700] text-[16px];
|
||||
}
|
||||
.btn-start:deep(> .btn-base) .icon-platform {
|
||||
.btn-start:deep(.btn-base[data-variant='filled']) svg {
|
||||
@apply hidden;
|
||||
}
|
||||
.btn-start:deep(> .btn-base) .btn-content {
|
||||
@apply justify-center;
|
||||
}
|
||||
|
||||
.btn-start .nav-2depth {
|
||||
@apply left-[unset] right-[-40px];
|
||||
}
|
||||
.btn-start .nav-2depth:deep(.btn-base) {
|
||||
@apply w-full h-[48px] px-4 bg-transparent before:hidden after:hidden
|
||||
@apply w-full h-[48px] px-4
|
||||
hover:bg-theme-foreground-reversal-4 active:bg-theme-foreground-reversal-10;
|
||||
}
|
||||
.btn-start .nav-2depth:deep(.btn-base) .btn-content {
|
||||
@apply justify-start;
|
||||
}
|
||||
.btn-start .nav-2depth:deep(.btn-base) .text {
|
||||
@apply ml-1.5 text-[15px] text-theme-foreground-reversal;
|
||||
@apply pl-1.5 text-[15px] text-theme-foreground-reversal;
|
||||
}
|
||||
.btn-start:deep(.nav-2depth .icon-download) {
|
||||
@apply hidden;
|
||||
}
|
||||
|
||||
[data-theme='light'] {
|
||||
|
||||
@@ -7,9 +7,12 @@ import type { ButtonType } from '#layers/types/components/button'
|
||||
|
||||
interface Props {
|
||||
resourcesData: PageDataResourceGroup[]
|
||||
buttonSize?: string
|
||||
}
|
||||
|
||||
const props = defineProps<Props>()
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
buttonSize: 'size-extra-small md:size-medium',
|
||||
})
|
||||
|
||||
const { locale, tm } = useI18n()
|
||||
const device = useDevice()
|
||||
@@ -119,7 +122,7 @@ const handleButtonClick = (button: PageDataResourceGroup) => {
|
||||
<template>
|
||||
<div
|
||||
v-if="buttonList.length"
|
||||
class="flex flex-wrap justify-center gap-3 md:gap-4"
|
||||
class="flex flex-wrap justify-center items-center gap-3 md:gap-4"
|
||||
>
|
||||
<template v-for="(button, index) in buttonList" :key="index">
|
||||
<template v-if="button.btn_info?.detail?.btn_type === 'RUN'">
|
||||
@@ -138,6 +141,7 @@ const handleButtonClick = (button: PageDataResourceGroup) => {
|
||||
<AtomsButton
|
||||
v-else
|
||||
:type="getButtonType(button.btn_info)"
|
||||
:size="buttonSize"
|
||||
:href="button.btn_info?.detail?.action?.url"
|
||||
:target="button.btn_info?.detail?.action?.link_target"
|
||||
:background-color="getColorCodeFromData(button.btn_info, 'btn')"
|
||||
|
||||
@@ -22,9 +22,9 @@ const { tm } = useI18n()
|
||||
class="text-info"
|
||||
></p>
|
||||
|
||||
<AtomsButtonVariant class="max-w-[300px]" @click="downloadLauncher">
|
||||
<AtomsButtonModal class="max-w-[300px]" @click="downloadLauncher">
|
||||
{{ tm('Text_Download') }}
|
||||
</AtomsButtonVariant>
|
||||
</AtomsButtonModal>
|
||||
<p
|
||||
v-dompurify-html="tm('Alert_Client_Run_Normally')"
|
||||
class="text-tip"
|
||||
|
||||
@@ -333,7 +333,7 @@ defineExpose({
|
||||
<div class="mt-auto px-5 pb-10 md:px-10 md:pb-12">
|
||||
<AtomsButton
|
||||
class="w-full"
|
||||
button-size="size-small md:size-medium"
|
||||
size="size-small md:size-medium"
|
||||
:disabled="!canSubmit || isSubmitting"
|
||||
@click="handleSubmit"
|
||||
>
|
||||
|
||||
@@ -115,7 +115,10 @@ const handleMove = (
|
||||
<SplideTrack>
|
||||
<slot />
|
||||
</SplideTrack>
|
||||
<BlocksSlideArrows v-if="props.arrows" :arrows-data="props.arrowsData" />
|
||||
<BlocksButtonSlideArrows
|
||||
v-if="props.arrows"
|
||||
:arrows-data="props.arrowsData"
|
||||
/>
|
||||
</Splide>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -118,7 +118,10 @@ const handleMove = (
|
||||
<SplideTrack>
|
||||
<slot />
|
||||
</SplideTrack>
|
||||
<BlocksSlideArrows v-if="props.arrows" :arrows-data="props.arrowsData" />
|
||||
<BlocksButtonSlideArrows
|
||||
v-if="props.arrows"
|
||||
:arrows-data="props.arrowsData"
|
||||
/>
|
||||
</Splide>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -98,6 +98,9 @@ const handleMove = (
|
||||
<SplideTrack>
|
||||
<slot />
|
||||
</SplideTrack>
|
||||
<BlocksSlideArrows v-if="props.arrows" :arrows-data="props.arrowsData" />
|
||||
<BlocksButtonSlideArrows
|
||||
v-if="props.arrows"
|
||||
:arrows-data="props.arrowsData"
|
||||
/>
|
||||
</Splide>
|
||||
</template>
|
||||
|
||||
@@ -92,7 +92,7 @@ defineExpose({
|
||||
<SplideTrack>
|
||||
<slot />
|
||||
</SplideTrack>
|
||||
<BlocksSlideArrows
|
||||
<BlocksButtonSlideArrows
|
||||
v-if="props.arrows"
|
||||
:arrows-data="props.arrowsData"
|
||||
class="type-full"
|
||||
|
||||
@@ -180,7 +180,10 @@ onBeforeUnmount(() => {
|
||||
/>
|
||||
</SplideSlide>
|
||||
</SplideTrack>
|
||||
<BlocksSlideArrows v-if="props.arrows" :arrows-data="props.arrowsData" />
|
||||
<BlocksButtonSlideArrows
|
||||
v-if="props.arrows"
|
||||
:arrows-data="props.arrowsData"
|
||||
/>
|
||||
</Splide>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -6,7 +6,7 @@ export default defineNuxtRouteMiddleware(to => {
|
||||
if (to.path.includes('/error')) return
|
||||
|
||||
// inspection 페이지는 실행X -----
|
||||
if (to.path.includes('inspection')) return
|
||||
if (to.path.includes('/inspection')) return
|
||||
|
||||
const gameDataStore = useGameDataStore()
|
||||
const { langCodes, intro } = storeToRefs(gameDataStore)
|
||||
|
||||
@@ -14,7 +14,7 @@ export default defineNuxtRouteMiddleware(async (to, _from) => {
|
||||
if (to.path.includes('/error')) return
|
||||
|
||||
// inspection 페이지는 실행X -----
|
||||
if (to.path.includes('inspection')) return
|
||||
if (to.path.includes('/inspection')) return
|
||||
|
||||
const gameDataStore = useGameDataStore()
|
||||
const pageDataStore = usePageDataStore()
|
||||
|
||||
@@ -140,7 +140,6 @@ export default defineEventHandler(async event => {
|
||||
}
|
||||
|
||||
const stoveApiServerBaseUrl = runtimeConfig.public.stoveApiUrlServer
|
||||
const baseDomain = runtimeConfig.public.baseDomain
|
||||
|
||||
let gameDataResponse: GameDataResponse | null = null
|
||||
let gameDataLangCodes: string[] | null = null
|
||||
@@ -182,7 +181,10 @@ export default defineEventHandler(async event => {
|
||||
// 1-1. 정적 파일 패스
|
||||
if (isStaticFile(event.path)) return
|
||||
|
||||
// 1-2. 특정 경로 패스 (API, 리소스)
|
||||
// 1-2. /inspection 패스
|
||||
if (fullPath.includes('/inspection')) return
|
||||
|
||||
// 1-3. 특정 경로 패스 (API, 리소스)
|
||||
if (shouldSkipPath(fullPath)) return
|
||||
|
||||
// 캐시 키 생성 (게임 ID 포함하여 충돌 방지)
|
||||
|
||||
@@ -6,15 +6,19 @@ export const useGameDataStore = defineStore('gameData', () => {
|
||||
gameId: null as GameDataValue['game_id'] | null,
|
||||
gameCode: null as GameDataValue['game_code'] | null,
|
||||
gameName: null as GameDataValue['game_name'] | null,
|
||||
stoveGnbJson: null as GameDataValue['stove_gnb_json'] | null,
|
||||
langCodes: null as GameDataValue['lang_codes'] | null,
|
||||
defaultLangCode: null as GameDataValue['default_lang_code'] | null,
|
||||
gaCode: null as GameDataValue['ga_code'] | null,
|
||||
platformType: null as GameDataValue['platform_type'] | null,
|
||||
osType: null as GameDataValue['os_type'] | null,
|
||||
theme: null as 'light' | 'dark' | null,
|
||||
intro: null as GameDataValue['intro'] | null,
|
||||
imgJson: null as GameDataValue['img_json'] | null,
|
||||
snsJson: null as GameDataValue['sns_json'] | null,
|
||||
urlJson: null as GameDataValue['url_json'] | null,
|
||||
marketJson: null as GameDataValue['market_json'] | null,
|
||||
fontFamily: null as GameDataValue['game_font']['font_family'] | null,
|
||||
gnb: null as GameDataValue['gnb'] | null,
|
||||
eventBanner: null as GameDataValue['event_banner'] | null,
|
||||
fontFamily: null as GameDataValue['game_font']['font_family'] | null,
|
||||
@@ -27,15 +31,19 @@ export const useGameDataStore = defineStore('gameData', () => {
|
||||
state.gameId = data?.game_id
|
||||
state.gameCode = data?.game_code
|
||||
state.gameName = data?.game_name
|
||||
state.stoveGnbJson = data?.stove_gnb_json
|
||||
state.langCodes = data?.lang_codes
|
||||
state.defaultLangCode = data?.default_lang_code
|
||||
state.gaCode = data?.ga_code
|
||||
state.platformType = data?.platform_type
|
||||
state.osType = data?.os_type
|
||||
state.theme = data?.design_theme === 1 ? 'light' : 'dark'
|
||||
state.intro = data?.intro
|
||||
state.imgJson = data?.img_json
|
||||
state.snsJson = data?.sns_json
|
||||
state.urlJson = data?.url_json
|
||||
state.marketJson = data?.market_json
|
||||
state.fontFamily = data?.game_font?.font_family
|
||||
state.gnb = data?.gnb
|
||||
state.eventBanner = data?.event_banner
|
||||
state.fontFamily = data?.game_font?.font_family
|
||||
|
||||
@@ -530,7 +530,7 @@ onMounted(async () => {
|
||||
/>
|
||||
<AtomsButton
|
||||
type="action"
|
||||
button-size="size-small"
|
||||
size="size-small"
|
||||
background-color="#383838"
|
||||
text-color="#FFFFFF"
|
||||
class="relative flex items-center justify-center w-full gap-[4px] px-0 sm:w-[143px] sm:shrink-0 md:h-[56px] md:text-[16px] md:leading-[24px] md:tracking-[-0.48px]"
|
||||
@@ -575,7 +575,7 @@ onMounted(async () => {
|
||||
<template v-for="month in monthSelectList" :key="month">
|
||||
<AtomsButton
|
||||
type="action"
|
||||
button-size="size-small"
|
||||
size="size-small"
|
||||
background-color="#FAFAFA"
|
||||
text-color="#CCCCCC"
|
||||
:class="[
|
||||
@@ -617,7 +617,7 @@ onMounted(async () => {
|
||||
</div>
|
||||
<AtomsButton
|
||||
type="action"
|
||||
button-size="size-small"
|
||||
size="size-small"
|
||||
background-color="#383838"
|
||||
text-color="#FFFFFF"
|
||||
class="shrink-0 w-[40px] h-[40px] p-0 md:w-auto md:px-[22px]"
|
||||
@@ -720,7 +720,7 @@ onMounted(async () => {
|
||||
>
|
||||
<AtomsButton
|
||||
type="action"
|
||||
button-size="size-small"
|
||||
size="size-small"
|
||||
background-color="transparent"
|
||||
text-color="transparent"
|
||||
class="coupon-item coupon-item-use"
|
||||
@@ -772,10 +772,10 @@ onMounted(async () => {
|
||||
<ClientOnly>
|
||||
<Teleport to="body">
|
||||
<BlocksModalLayer
|
||||
:is-open="isSelectCharacterModalOpen"
|
||||
:is-show-dimmed="true"
|
||||
:is-outside-close="true"
|
||||
modal-name="modal-coupon-character-select"
|
||||
:is-open="isSelectCharacterModalOpen"
|
||||
area-class="max-w-[480px] p-6 bg-white rounded-[20px]"
|
||||
close-class="hidden"
|
||||
>
|
||||
@@ -797,20 +797,20 @@ onMounted(async () => {
|
||||
<div
|
||||
class="relative flex items-center justify-center gap-[8px] w-full"
|
||||
>
|
||||
<AtomsButtonVariant
|
||||
<AtomsButtonModal
|
||||
variant="outlined"
|
||||
class="max-w-[128px]"
|
||||
@click="closeSelectCharacterModal"
|
||||
>
|
||||
{{ tm('Text_Cancel') }}
|
||||
</AtomsButtonVariant>
|
||||
<AtomsButtonVariant
|
||||
</AtomsButtonModal>
|
||||
<AtomsButtonModal
|
||||
:disabled="isSelectCharacter ? false : true"
|
||||
class="max-w-[128px]"
|
||||
@click="handleCouponRegister"
|
||||
>
|
||||
{{ tm('Text_Confirm') }}
|
||||
</AtomsButtonVariant>
|
||||
</AtomsButtonModal>
|
||||
</div>
|
||||
</div>
|
||||
</BlocksModalLayer>
|
||||
|
||||
@@ -228,7 +228,7 @@ const handleMoveFocus = (target: 'pc' | 'mobile') => {
|
||||
<BlocksButtonLauncher
|
||||
v-else-if="breakpoints.isMd || breakpoints.isDesktop"
|
||||
platform="pc"
|
||||
class="!w-full !max-w-[300px]"
|
||||
class="w-[300px]"
|
||||
@click="
|
||||
handleSendLog(
|
||||
t('Download_Button_PC_Download', {}, { locale: 'ko' })
|
||||
@@ -310,7 +310,7 @@ const handleMoveFocus = (target: 'pc' | 'mobile') => {
|
||||
: true
|
||||
"
|
||||
:platform="`${os.platformCode as Platform}`"
|
||||
class="!w-full"
|
||||
class="w-full"
|
||||
@click="handleSendLog(formatSnakeToTitle(os.platformCode))"
|
||||
>
|
||||
<span>{{ os.platformText }}</span>
|
||||
@@ -384,7 +384,7 @@ const handleMoveFocus = (target: 'pc' | 'mobile') => {
|
||||
</ul>
|
||||
<AtomsButton
|
||||
type="action"
|
||||
button-size="size-small"
|
||||
size="size-small"
|
||||
background-color="#383838"
|
||||
text-color="#FFFFFF"
|
||||
class="shrink-0 w-[206px] px-0 text-[16px]"
|
||||
@@ -445,7 +445,7 @@ const handleMoveFocus = (target: 'pc' | 'mobile') => {
|
||||
|
||||
<AtomsButton
|
||||
type="link"
|
||||
button-size="size-small"
|
||||
size="size-small"
|
||||
background-color="#383838"
|
||||
text-color="#FFFFFF"
|
||||
class="w-full px-0"
|
||||
|
||||
@@ -337,7 +337,7 @@ onMounted(() => {
|
||||
<AtomsButton
|
||||
v-if="card.status === 'N'"
|
||||
type="external"
|
||||
button-size="size-small md:size-large"
|
||||
size="size-small md:size-medium"
|
||||
background-color="#383838"
|
||||
text-color="#FFFFFF"
|
||||
@click="handleClickSetup(card)"
|
||||
@@ -347,7 +347,7 @@ onMounted(() => {
|
||||
<AtomsButton
|
||||
v-else
|
||||
type="action"
|
||||
button-size="size-small md:size-large"
|
||||
size="size-small md:size-medium"
|
||||
background-color="#EBEBEB"
|
||||
text-color="#999999"
|
||||
disabled
|
||||
|
||||
@@ -200,7 +200,8 @@ const handleLoadMoreRecent = () => {
|
||||
]"
|
||||
/>
|
||||
<AtomsIconsPlayRoundFill
|
||||
class="drop-shadow-[0_0_6px_rgba(0,0,0,0.25)] absolute bottom-[14px] right-[14px] w-[20px] h-[20px] sm:bottom-[18px] sm:right-[18px] md:bottom-[23px] md:right-[23px] md:w-[33px] md:h-[33px]"
|
||||
:size="breakpoints.isMobile ? 24 : 40"
|
||||
class="drop-shadow-[0_0_6px_rgba(0,0,0,0.25)] absolute bottom-[12px] right-[12px] sm:bottom-[16px] sm:right-[16px] md:bottom-[16px] md:right-[16px] lg:bottom-[16px] lg:right-[16px]"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
@@ -252,7 +253,8 @@ const handleLoadMoreRecent = () => {
|
||||
class="w-full h-full object-cover group-hover:scale-110 transition-transform duration-300"
|
||||
/>
|
||||
<AtomsIconsPlayRoundFill
|
||||
class="drop-shadow-[0_0_6px_rgba(0,0,0,0.25)] absolute bottom-[14px] right-[14px] w-[20px] h-[20px]"
|
||||
size="24"
|
||||
class="drop-shadow-[0_0_6px_rgba(0,0,0,0.25)] absolute bottom-[12px] right-[12px]"
|
||||
/>
|
||||
</div>
|
||||
<div class="p-2 pt-5 md:p-3 md:pt-5">
|
||||
@@ -273,7 +275,7 @@ const handleLoadMoreRecent = () => {
|
||||
<div v-if="hasMore" class="mt-[40px] flex justify-center md:mt-[80px]">
|
||||
<AtomsButton
|
||||
type="action"
|
||||
button-size="size-small md:size-medium"
|
||||
size="size-small md:size-medium"
|
||||
background-color="#383838"
|
||||
text-color="#FFFFFF"
|
||||
@click="handleLoadMoreRecent"
|
||||
|
||||
@@ -57,6 +57,7 @@ const buttonListData = computed(() => {
|
||||
<WidgetsButtonList
|
||||
v-if="buttonListData"
|
||||
:resources-data="buttonListData"
|
||||
button-size="size-small md:size-large"
|
||||
class="mt-[56px]"
|
||||
/>
|
||||
<WidgetsDescription
|
||||
|
||||
@@ -5,10 +5,10 @@ export type ButtonType =
|
||||
| 'action'
|
||||
| 'link'
|
||||
|
||||
export type DownloadButtonType = 'default' | 'single' | 'duplication' | 'custom'
|
||||
export type DownloadButtonType = 'default' | 'single' | 'duplication'
|
||||
|
||||
export type ButtonSize = 'large' | 'medium' | 'small' | 'extra-small'
|
||||
|
||||
export type ButtonVariant = 'filled' | 'outlined'
|
||||
export type ButtonVariant = 'filled' | 'outlined' | 'custom'
|
||||
|
||||
export type Platform = 'google_play' | 'app_store' | 'pc' | 'stove'
|
||||
|
||||
Reference in New Issue
Block a user