fix: [PWT-169] 사전 등록 > 기기 체크 없이 스토브 앱 다운로드 버튼 노출되는 현상 문의
This commit is contained in:
@@ -27,10 +27,10 @@ const getEventNavigation = async (): Promise<Record<
|
||||
const response = (await commonFetch('GET', apiUrl, {
|
||||
query: queryParams,
|
||||
})) as EventNavigationResponse | null
|
||||
|
||||
if (response?.code === 0 && 'value' in response) {
|
||||
return response.value
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
|
||||
@@ -22,11 +22,13 @@ const { tm } = useI18n()
|
||||
const { width } = useWindowSize()
|
||||
const device = useDevice()
|
||||
const gameDataStore = useGameDataStore()
|
||||
const pageDataStore = usePageDataStore()
|
||||
const scrollStore = useScrollStore()
|
||||
const breakpoints = useResponsiveBreakpoints()
|
||||
const modalStore = useModalStore()
|
||||
|
||||
const { gameData } = storeToRefs(gameDataStore)
|
||||
const { pageLayoutType } = storeToRefs(pageDataStore)
|
||||
const { isPassedStoveGnb } = storeToRefs(scrollStore)
|
||||
|
||||
const navAreaRef = ref<HTMLElement | null>(null)
|
||||
@@ -48,45 +50,29 @@ const hasGnbMenus = computed(() => {
|
||||
return Object.keys(menus).length > 0
|
||||
})
|
||||
|
||||
const currentPath = computed(() => formatPathWithoutLocale(route.path))
|
||||
const gnb1depthButtonData = computed(
|
||||
() => gnbData.value?.buttons[0]?.button_json as GameDataResourceGroup
|
||||
)
|
||||
const gnb2depthButtonData = computed(
|
||||
() => gnbData.value?.buttons[1]?.button_json as GameDataResourceGroupSet
|
||||
)
|
||||
const currentPath = computed(() => formatPathWithoutLocale(route.path))
|
||||
const supportedPlatforms = computed(
|
||||
() =>
|
||||
getSupportedPlatforms(gameData.value?.os_type, {
|
||||
platformType: gameData.value?.platform_type,
|
||||
}) as PlatformTransformType[]
|
||||
getSupportedPlatforms(
|
||||
gameData.value?.os_type,
|
||||
gameData.value?.platform_type
|
||||
) as PlatformTransformType[]
|
||||
)
|
||||
|
||||
const pathMatches = (base: string, current: string) => {
|
||||
if (!base || base === '/') return current === '/'
|
||||
return current === base
|
||||
}
|
||||
|
||||
/** 자식 중 활성 링크 존재 여부 */
|
||||
// 자식 중 활성 링크 존재 여부 확인
|
||||
const hasActiveChild = (children?: GameDataMenuChildren) => {
|
||||
const cur = currentPath.value
|
||||
return formatToArray(children).some(child => {
|
||||
if (!child?.url_path || !isInternalUrl(child.url_path)) return false
|
||||
return pathMatches(formatPathWithoutLocale(child.url_path), cur)
|
||||
if (!child?.url_path || child.click_action_type === 2) return false
|
||||
return formatPathWithoutLocale(child.url_path) === currentPath.value
|
||||
})
|
||||
}
|
||||
|
||||
/** 1Depth 활성화 여부 */
|
||||
const isNavItemActive = (gnbItem: GameDataMenu): boolean => {
|
||||
const cur = currentPath.value
|
||||
const base = gnbItem?.url_path
|
||||
const selfActive =
|
||||
!!base &&
|
||||
isInternalUrl(base) &&
|
||||
pathMatches(formatPathWithoutLocale(base), cur)
|
||||
return selfActive || hasActiveChild(gnbItem.children)
|
||||
}
|
||||
|
||||
// navAreaRef의 넓이를 구하는 함수
|
||||
const calculateNavWidth = () => {
|
||||
if (!import.meta.client) return
|
||||
@@ -158,7 +144,9 @@ const handleMenuOpen = () => {
|
||||
scrollStore.controlScrollLock(true)
|
||||
}
|
||||
|
||||
const handleMenuClose = () => {
|
||||
const handleMenuClose = (isPassing: boolean = false) => {
|
||||
if (isPassing) return
|
||||
|
||||
isMenuOpen.value = false
|
||||
scrollStore.controlScrollLock(false)
|
||||
}
|
||||
@@ -198,7 +186,7 @@ const showNotSupportedOSAlert = () => {
|
||||
}
|
||||
|
||||
const handleStartClick = () => {
|
||||
if (breakpoints.value.isDesktop) return
|
||||
if (device.isDesktop) return
|
||||
|
||||
const target = device.isAndroid
|
||||
? 'google_play'
|
||||
@@ -259,7 +247,7 @@ onMounted(() => {
|
||||
</button>
|
||||
<div
|
||||
:class="['nav-wrap', { 'is-open': isMenuOpen }]"
|
||||
@click="handleMenuClose"
|
||||
@click="handleMenuClose()"
|
||||
>
|
||||
<div ref="navAreaRef" class="nav-area" @click.stop>
|
||||
<div class="nav-logo">
|
||||
@@ -277,7 +265,7 @@ onMounted(() => {
|
||||
<div
|
||||
v-for="(gnbItem, key) in gnbData?.menus"
|
||||
:key="key"
|
||||
class="nav-item"
|
||||
class="nav-item group"
|
||||
:class="{
|
||||
'is-hidden':
|
||||
overflowNam > 0 &&
|
||||
@@ -285,19 +273,21 @@ onMounted(() => {
|
||||
Object.keys(gnbData?.menus).length - overflowNam,
|
||||
}"
|
||||
>
|
||||
<AtomsLocaleLink
|
||||
:to="isNotClickable(gnbItem) ? '#' : gnbItem.url_path"
|
||||
:target="gnbItem.link_target"
|
||||
<component
|
||||
:is="isNotClickable(gnbItem) ? 'span' : 'AtomsLocaleLink'"
|
||||
:to="gnbItem?.url_path"
|
||||
:target="gnbItem?.link_target"
|
||||
:class="[
|
||||
'nav-1depth',
|
||||
{ 'has-link': !isNotClickable(gnbItem) },
|
||||
{ active: isNavItemActive(gnbItem) },
|
||||
{
|
||||
'router-link-active': hasActiveChild(gnbItem.children),
|
||||
},
|
||||
]"
|
||||
@click="handleMenuClose"
|
||||
@click="handleMenuClose(isNotClickable(gnbItem))"
|
||||
>
|
||||
<span>{{ gnbItem.menu_name }}</span>
|
||||
<AtomsIconsWebLinkLine
|
||||
v-if="gnbItem.link_target === '_blank'"
|
||||
v-if="gnbItem?.link_target === '_blank'"
|
||||
/>
|
||||
<AtomsIconsArrowDownFill
|
||||
v-if="has2depthButton(gnbItem)"
|
||||
@@ -307,7 +297,7 @@ onMounted(() => {
|
||||
v-if="!has2depthButton(gnbItem)"
|
||||
class="ml-auto md:hidden"
|
||||
/>
|
||||
</AtomsLocaleLink>
|
||||
</component>
|
||||
<Transition name="fade">
|
||||
<div v-if="has2depthButton(gnbItem)" class="nav-2depth">
|
||||
<ul>
|
||||
@@ -315,23 +305,27 @@ onMounted(() => {
|
||||
v-for="child in gnbItem.children"
|
||||
:key="child.menu_name"
|
||||
>
|
||||
<AtomsLocaleLink
|
||||
<component
|
||||
:is="
|
||||
isNotClickable(child) ? 'span' : 'AtomsLocaleLink'
|
||||
"
|
||||
:to="child.url_path"
|
||||
:target="child.link_target"
|
||||
@click="handleMenuClose"
|
||||
class="item-link"
|
||||
@click="handleMenuClose(isNotClickable(child))"
|
||||
>
|
||||
<span>{{ child.menu_name }}</span>
|
||||
<AtomsIconsWebLinkLine
|
||||
v-if="child.link_target === '_blank'"
|
||||
v-if="child?.link_target === '_blank'"
|
||||
/>
|
||||
</AtomsLocaleLink>
|
||||
</component>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</Transition>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="overflowNam > 0" class="more">
|
||||
<div v-if="overflowNam > 0" class="more group">
|
||||
<button class="btn-more">
|
||||
<AtomsIconsOptionHorizontalFill class="mx-auto" />
|
||||
<span class="sr-only">more</span>
|
||||
@@ -347,29 +341,46 @@ onMounted(() => {
|
||||
Object.keys(gnbData?.menus).length - overflowNam,
|
||||
}"
|
||||
>
|
||||
<AtomsLocaleLink
|
||||
:to="gnbItem.url_path"
|
||||
:target="gnbItem.link_target"
|
||||
:class="`${isNavItemActive(gnbItem) ? 'active' : ''}`"
|
||||
@click="handleMenuClose"
|
||||
<component
|
||||
:is="
|
||||
isNotClickable(gnbItem) ? 'span' : 'AtomsLocaleLink'
|
||||
"
|
||||
:to="gnbItem?.url_path"
|
||||
:target="gnbItem?.link_target"
|
||||
:class="[
|
||||
'nav-1depth',
|
||||
'item-link',
|
||||
{
|
||||
'router-link-active': hasActiveChild(
|
||||
gnbItem.children
|
||||
),
|
||||
},
|
||||
]"
|
||||
@click="handleMenuClose(isNotClickable(gnbItem))"
|
||||
>
|
||||
<span>{{ gnbItem.menu_name }}</span>
|
||||
</AtomsLocaleLink>
|
||||
<div v-if="gnbItem.children">
|
||||
</component>
|
||||
<div v-if="gnbItem?.children">
|
||||
<ul>
|
||||
<li
|
||||
v-for="child in gnbItem.children"
|
||||
:key="child.menu_name"
|
||||
>
|
||||
<AtomsLocaleLink
|
||||
:to="child.url_path"
|
||||
:target="child.link_target"
|
||||
<component
|
||||
:is="
|
||||
isNotClickable(child)
|
||||
? 'span'
|
||||
: 'AtomsLocaleLink'
|
||||
"
|
||||
:to="child?.url_path"
|
||||
:target="child?.link_target"
|
||||
class="item-link"
|
||||
>
|
||||
<span>{{ child.menu_name }}</span>
|
||||
<AtomsIconsWebLinkLine
|
||||
v-if="child.link_target === '_blank'"
|
||||
v-if="child?.link_target === '_blank'"
|
||||
/>
|
||||
</AtomsLocaleLink>
|
||||
</component>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
@@ -388,13 +399,20 @@ onMounted(() => {
|
||||
? '_self'
|
||||
: '_blank'
|
||||
"
|
||||
class="nav-1depth text-gradient-pink"
|
||||
:class="[
|
||||
'nav-1depth',
|
||||
{ 'router-link-active': pageLayoutType === 'promotion' },
|
||||
]"
|
||||
@click="handleMenuClose"
|
||||
>
|
||||
<AtomsIconsStarFill />
|
||||
<span>{{ tm('Gnb_Event') }}</span>
|
||||
<AtomsIconsStarFill />
|
||||
<AtomsIconsArrowRightLine class="ml-auto md:hidden" />
|
||||
<span
|
||||
class="flex items-center gap-1 flex-1 text-gradient-pink"
|
||||
>
|
||||
<AtomsIconsStarFill />
|
||||
<span>{{ tm('Gnb_Event') }}</span>
|
||||
<AtomsIconsStarFill />
|
||||
<AtomsIconsArrowRightLine class="ml-auto md:hidden" />
|
||||
</span>
|
||||
</AtomsLocaleLink>
|
||||
</div>
|
||||
</div>
|
||||
@@ -405,9 +423,7 @@ onMounted(() => {
|
||||
<template v-if="gnb1depthButtonData">
|
||||
<component
|
||||
:is="
|
||||
breakpoints.isDesktop
|
||||
? 'BlocksButtonLauncher'
|
||||
: 'AtomsButton'
|
||||
device.isDesktop ? 'BlocksButtonLauncher' : 'AtomsButton'
|
||||
"
|
||||
type="custom"
|
||||
platform="pc"
|
||||
@@ -436,7 +452,7 @@ onMounted(() => {
|
||||
</template>
|
||||
</div>
|
||||
</ClientOnly>
|
||||
<button class="btn-close" @click="handleMenuClose">
|
||||
<button class="btn-close" @click="handleMenuClose()">
|
||||
<AtomsIconsCloseLine
|
||||
size="24"
|
||||
color="var(--foreground-reversal)"
|
||||
@@ -477,6 +493,24 @@ onMounted(() => {
|
||||
@apply top-[11px] left-[12px];
|
||||
}
|
||||
|
||||
a {
|
||||
@apply transition-[background] hover:bg-theme-foreground-reversal-4 active:bg-theme-foreground-reversal-10;
|
||||
}
|
||||
a.nav-1depth:not(.item-link) {
|
||||
@apply md:hover:bg-transparent md:active:bg-transparent;
|
||||
}
|
||||
|
||||
.nav-1depth.router-link-active {
|
||||
@apply bg-theme-foreground-reversal-8 md:bg-transparent;
|
||||
}
|
||||
.more-list .nav-1depth.router-link-active {
|
||||
@apply bg-theme-foreground-reversal-8;
|
||||
}
|
||||
.nav-item:hover .nav-1depth::after,
|
||||
.nav-1depth.router-link-active::after {
|
||||
@apply opacity-100 md:transition-opacity;
|
||||
}
|
||||
|
||||
.nav-wrap {
|
||||
@apply fixed top-0 left-0 bottom-0 w-0 mt-[var(--scroll-position,48px)] md:relative md:w-full md:h-full md:mt-0;
|
||||
}
|
||||
@@ -516,13 +550,6 @@ onMounted(() => {
|
||||
.nav-item::after {
|
||||
@apply content-[''] h-px my-2 mx-3 bg-theme-foreground-reversal-8 md:hidden;
|
||||
}
|
||||
.nav-item:hover .nav-1depth::after,
|
||||
.nav-1depth.active::after {
|
||||
@apply opacity-100 md:transition-opacity;
|
||||
}
|
||||
.nav-item:hover .nav-2depth {
|
||||
@apply md:block;
|
||||
}
|
||||
|
||||
.nav-1depth {
|
||||
@apply flex items-center py-[9px] px-3 gap-1 rounded-[12px] md:h-full md:py-0 md:px-0;
|
||||
@@ -530,23 +557,16 @@ onMounted(() => {
|
||||
.nav-1depth::after {
|
||||
@apply md:content-[''] md:absolute md:bottom-0 md:left-0 md:w-full md:h-[2px] md:bg-theme-foreground-reversal md:opacity-0;
|
||||
}
|
||||
.nav-1depth.active {
|
||||
@apply bg-theme-foreground-reversal-8 md:bg-transparent;
|
||||
}
|
||||
.nav-1depth.has-link {
|
||||
@apply cursor-pointer hover:bg-theme-foreground-reversal-4 active:bg-theme-foreground-reversal-10 md:hover:bg-transparent md:active:bg-transparent;
|
||||
}
|
||||
|
||||
.nav-2depth {
|
||||
@apply text-[15px] md:hidden md:absolute md:top-[64px] md:left-[-28px] md:pt-1;
|
||||
@apply text-[15px] group-hover:block md:hidden md:absolute md:top-[64px] md:left-[-28px] md:pt-1;
|
||||
}
|
||||
.nav-2depth ul {
|
||||
@apply bg-theme-foreground-10 rounded-[20px] md:min-w-[190px] md:p-3 md:shadow-lg;
|
||||
}
|
||||
.nav-2depth a {
|
||||
@apply flex items-center gap-1 py-[9px] px-5 rounded-[12px] transition-colors
|
||||
md:py-[11px] md:px-4
|
||||
hover:bg-theme-foreground-reversal-4 active:bg-theme-foreground-reversal-10;
|
||||
.nav-2depth .item-link {
|
||||
@apply flex items-center gap-1 py-[9px] px-5 rounded-[12px]
|
||||
md:py-[11px] md:px-4;
|
||||
}
|
||||
|
||||
.official {
|
||||
@@ -562,25 +582,24 @@ onMounted(() => {
|
||||
.more {
|
||||
@apply relative hidden ml-[32px] pt-[11px] md:block;
|
||||
}
|
||||
.more:hover .more-list {
|
||||
@apply md:block;
|
||||
}
|
||||
.btn-more {
|
||||
@apply w-[40px] h-[40px] rounded-[12px] bg-theme-foreground-reversal-6 hover:bg-theme-foreground-reversal-10 active:bg-theme-foreground-reversal-4;
|
||||
}
|
||||
.more-list {
|
||||
@apply hidden absolute top-[64px] left-[-20px] pt-1;
|
||||
@apply hidden absolute top-[64px] left-[-20px] pt-1 group-hover:block;
|
||||
}
|
||||
.list-inner {
|
||||
@apply min-w-[190px] p-3 rounded-[20px] bg-theme-foreground-10 shadow-lg;
|
||||
}
|
||||
.more-list a {
|
||||
@apply flex items-center gap-1 py-[10px] px-4 rounded-[12px] transition-colors
|
||||
hover:bg-theme-foreground-reversal-4 active:bg-theme-foreground-reversal-10;
|
||||
.more-list .item-link {
|
||||
@apply flex items-center gap-1 py-[10px] px-4 rounded-[12px];
|
||||
}
|
||||
.more-list li a {
|
||||
.more-list li .item-link {
|
||||
@apply px-6;
|
||||
}
|
||||
.more-list .nav-1depth {
|
||||
@apply after:hidden;
|
||||
}
|
||||
|
||||
.official ~ .event {
|
||||
@apply md:ml-[64px]
|
||||
|
||||
@@ -42,7 +42,6 @@ const currentStep = ref<1 | 2>(1)
|
||||
const isSubmitting = ref(false)
|
||||
const isCheckedMarketing = ref(false)
|
||||
const isExpandedMarketing = ref(false)
|
||||
const isValidated = ref(false) // 검증 완료 여부 (중복 검증 방지)
|
||||
|
||||
const canSubmit = computed(() => isCheckedMarketing.value)
|
||||
const errorMessages = computed<Record<number, string>>(() => ({
|
||||
@@ -168,7 +167,6 @@ const handleOpenPreregist = async (): Promise<void> => {
|
||||
})
|
||||
}
|
||||
|
||||
isValidated.value = true // 검증 완료 플래그
|
||||
isModalOpen.value = true
|
||||
currentStep.value = 1
|
||||
}
|
||||
@@ -186,11 +184,8 @@ const handleSubmit = async (): Promise<void> => {
|
||||
return
|
||||
}
|
||||
|
||||
// 이미 검증을 통과한 경우 재검증 스킵
|
||||
if (!isValidated.value) {
|
||||
const isValid = await checkValidation()
|
||||
if (!isValid) return
|
||||
}
|
||||
const isValid = await checkValidation()
|
||||
if (!isValid) return
|
||||
|
||||
isSubmitting.value = true
|
||||
try {
|
||||
@@ -199,7 +194,7 @@ const handleSubmit = async (): Promise<void> => {
|
||||
event_code: props.preregistCode,
|
||||
lang_code: locale.value,
|
||||
terms_type: 3,
|
||||
device_type: device.isMobile ? 'mobile' : 'pc',
|
||||
device_type: device.isDesktop ? 'pc' : 'mobile',
|
||||
country_code: countryCode.value || 'KR',
|
||||
necessary_consent1: 'Y',
|
||||
necessary_consent2: 'Y',
|
||||
@@ -234,7 +229,6 @@ const handleCloseModal = (): void => {
|
||||
isCheckedMarketing.value = false
|
||||
isExpandedMarketing.value = false
|
||||
isSubmitting.value = false
|
||||
isValidated.value = false // 검증 플래그도 초기화
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
@@ -385,6 +379,7 @@ defineExpose({
|
||||
</p>
|
||||
<div class="flex items-center gap-3">
|
||||
<div
|
||||
v-if="device.isDesktop"
|
||||
class="flex size-[108px] p-4 shrink-0 items-center justify-center rounded-lg bg-white/[0.04] backdrop-blur-[15px] md:size-[124px] md:p-4.5"
|
||||
>
|
||||
<AtomsImg
|
||||
@@ -396,6 +391,7 @@ defineExpose({
|
||||
</div>
|
||||
<div class="flex flex-1 flex-col gap-3">
|
||||
<a
|
||||
v-if="device.isDesktop ? true : device.isAndroid"
|
||||
href="https://play.google.com/store/search?q=stove&c=apps"
|
||||
target="_blank"
|
||||
class="flex h-12 w-full items-center justify-center gap-1.5 rounded-lg bg-white/[0.04] px-8 pl-8 pr-10 text-sm font-medium leading-5 tracking-[-0.42px] text-white no-underline backdrop-blur-[15px] transition-colors duration-200 hover:bg-white/[0.08] md:h-14 md:gap-2 md:text-base md:leading-6 md:tracking-[-0.48px]"
|
||||
@@ -404,6 +400,7 @@ defineExpose({
|
||||
<span>Google Play</span>
|
||||
</a>
|
||||
<a
|
||||
v-if="device.isDesktop ? true : device.isApple"
|
||||
href="https://apps.apple.com/app/stove-app-stove-app/id1342134971"
|
||||
target="_blank"
|
||||
class="flex h-12 w-full items-center justify-center gap-1.5 rounded-lg bg-white/[0.04] px-8 pl-8 pr-10 text-sm font-medium leading-5 tracking-[-0.42px] text-white no-underline backdrop-blur-[15px] transition-colors duration-200 hover:bg-white/[0.08] md:h-14 md:gap-2 md:text-base md:leading-6 md:tracking-[-0.48px]"
|
||||
|
||||
@@ -2,17 +2,23 @@ import type { PageDataValue } from '#layers/types/api/pageData'
|
||||
|
||||
export const usePageDataStore = defineStore('pageData', () => {
|
||||
const pageData = ref<PageDataValue | null>(null)
|
||||
const pageLayoutType = ref<'default' | 'promotion' | null>(null)
|
||||
|
||||
const setPageData = (response: PageDataValue) => {
|
||||
clearPageData()
|
||||
|
||||
pageData.value = response
|
||||
pageLayoutType.value = getLayoutType(pageData.value)
|
||||
}
|
||||
|
||||
const clearPageData = () => {
|
||||
pageData.value = null
|
||||
pageLayoutType.value = null
|
||||
}
|
||||
|
||||
return {
|
||||
pageData,
|
||||
pageLayoutType,
|
||||
setPageData,
|
||||
clearPageData,
|
||||
}
|
||||
|
||||
@@ -14,7 +14,6 @@ const props = defineProps<Props>()
|
||||
|
||||
// Configuration
|
||||
const runtimeConfig = useRuntimeConfig()
|
||||
const breakpoints = useResponsiveBreakpoints()
|
||||
const device = useDevice()
|
||||
|
||||
const dataResourcesUrl = runtimeConfig.public.dataResourcesUrl as string
|
||||
@@ -200,7 +199,7 @@ const splideOptions = computed(() => {
|
||||
})
|
||||
|
||||
const isRunButtonVisible = (marketType?: Platform): boolean => {
|
||||
if (breakpoints.value?.isDesktop) return true
|
||||
if (device.isDesktop) return true
|
||||
|
||||
switch (marketType) {
|
||||
case 'google_play':
|
||||
@@ -291,7 +290,7 @@ const handlePreregistClick = () => {
|
||||
{{ tm('Preregist_Btn_Preegist') }}
|
||||
</BlocksButtonLauncher>
|
||||
<template
|
||||
v-for="platform in getSupportedPlatforms(gameData?.os_type)"
|
||||
v-for="platform in getSupportedPlatforms(gameData?.os_type, '2')"
|
||||
:key="`preregist-${platform}`"
|
||||
>
|
||||
<BlocksButtonLauncher
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* @description gameData, pageData 처리에 필요한 유틸리티 함수를 제공합니다.
|
||||
*/
|
||||
|
||||
import type { PlatformType } from '#layers/types/api/gameData'
|
||||
import type { OsType, PlatformType } from '#layers/types/api/gameData'
|
||||
import type {
|
||||
PageDataValue,
|
||||
PageDataResourceContainer,
|
||||
@@ -23,12 +23,10 @@ const OS_TYPE_MAP: Record<string, string[]> = {
|
||||
* OS 타입에 따라 가능한 플랫폼 목록을 반환합니다.
|
||||
*/
|
||||
export const getSupportedPlatforms = (
|
||||
osType: string | number,
|
||||
options?: { platformType?: PlatformType }
|
||||
osType: OsType,
|
||||
platformType: PlatformType
|
||||
): string[] => {
|
||||
const type = String(osType)
|
||||
const platformType = String(options?.platformType ?? '0')
|
||||
const storePlatforms = OS_TYPE_MAP[type] ?? []
|
||||
const storePlatforms = OS_TYPE_MAP[osType] ?? []
|
||||
|
||||
switch (platformType) {
|
||||
case '1': // PC 전용
|
||||
@@ -37,11 +35,9 @@ export const getSupportedPlatforms = (
|
||||
case '2': // 모바일 스토어 전용
|
||||
return storePlatforms
|
||||
|
||||
default:
|
||||
case '3': // PC + 모바일 스토어 모두
|
||||
return ['pc', ...storePlatforms]
|
||||
|
||||
default: // 기본: OS_TYPE_MAP
|
||||
return storePlatforms
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -45,15 +45,6 @@ export const formatPathWithoutLocale = (path: string): string => {
|
||||
return path.replace(/^\/[a-z]{2}(?=\/|$)/, '') || '/'
|
||||
}
|
||||
|
||||
/**
|
||||
* URL이 내부 링크인지 확인합니다.
|
||||
* @param url 확인할 URL
|
||||
* @returns 내부 링크 여부
|
||||
*/
|
||||
export const isInternalUrl = (url?: string): boolean => {
|
||||
return !!url && !url.startsWith('http')
|
||||
}
|
||||
|
||||
/**
|
||||
* 리소스 경로를 완전한 호스트 URL로 변환합니다.
|
||||
* @param path 리소스 경로
|
||||
|
||||
Reference in New Issue
Block a user