feat. 마켓 버튼 구현
This commit is contained in:
@@ -8,14 +8,13 @@ interface props {
|
|||||||
href?: string
|
href?: string
|
||||||
rel?: string
|
rel?: string
|
||||||
backgroundColor?: string
|
backgroundColor?: string
|
||||||
backgroundImage?: string
|
|
||||||
textColor?: string
|
textColor?: string
|
||||||
disabled?: boolean
|
disabled?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = withDefaults(defineProps<props>(), {
|
const props = withDefaults(defineProps<props>(), {
|
||||||
type: 'action',
|
type: 'action',
|
||||||
buttonSize: 'size-extra-small md:size-medium',
|
buttonSize: 'size-extra-small md:size-large',
|
||||||
backgroundColor: 'var(--primary)',
|
backgroundColor: 'var(--primary)',
|
||||||
textColor: 'var(--alternative-02)',
|
textColor: 'var(--alternative-02)',
|
||||||
disabled: false,
|
disabled: false,
|
||||||
@@ -53,29 +52,17 @@ const componentProps = computed(() => {
|
|||||||
|
|
||||||
return baseProps
|
return baseProps
|
||||||
})
|
})
|
||||||
const buttonStyles = computed(() => {
|
|
||||||
const styles: Record<string, string> = {
|
|
||||||
backgroundColor: props.backgroundColor,
|
|
||||||
color: props.textColor,
|
|
||||||
}
|
|
||||||
|
|
||||||
if (props.backgroundImage) {
|
|
||||||
styles.backgroundImage = `url(${props.backgroundImage})`
|
|
||||||
styles.backgroundSize = 'contain'
|
|
||||||
styles.backgroundPosition = 'center'
|
|
||||||
styles.backgroundRepeat = 'no-repeat'
|
|
||||||
}
|
|
||||||
|
|
||||||
return styles
|
|
||||||
})
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<component
|
<component
|
||||||
:is="componentTag"
|
:is="componentTag"
|
||||||
v-bind="{ ...componentProps, ...$attrs }"
|
v-bind="{ ...componentProps }"
|
||||||
:class="['btn-base', props.buttonSize, $attrs?.class]"
|
:class="['btn-base', props.buttonSize]"
|
||||||
:style="buttonStyles"
|
:style="{
|
||||||
|
backgroundColor: props.backgroundColor,
|
||||||
|
color: props.textColor,
|
||||||
|
}"
|
||||||
>
|
>
|
||||||
<span class="btn-content">
|
<span class="btn-content">
|
||||||
<slot />
|
<slot />
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ const componentProps = computed(() => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<component :is="componentTag" v-bind="{ ...$attrs, ...componentProps }">
|
<component :is="componentTag" v-bind="{ ...componentProps }">
|
||||||
<slot />
|
<slot />
|
||||||
</component>
|
</component>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ interface ButtonListProps {
|
|||||||
|
|
||||||
const props = defineProps<ButtonListProps>()
|
const props = defineProps<ButtonListProps>()
|
||||||
|
|
||||||
|
const { gameData } = useGameDataStore()
|
||||||
|
|
||||||
const BUTTON_TYPE_MAP = {
|
const BUTTON_TYPE_MAP = {
|
||||||
URL: {
|
URL: {
|
||||||
_self: 'internal' as const,
|
_self: 'internal' as const,
|
||||||
@@ -34,6 +36,32 @@ const getButtonType = (btnInfo: PageDataResourceGroupBtnInfo): ButtonType => {
|
|||||||
|
|
||||||
return DEFAULT_BUTTON_TYPE
|
return DEFAULT_BUTTON_TYPE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const getButtonBackgroundImage = (
|
||||||
|
btnInfo: PageDataResourceGroupBtnInfo
|
||||||
|
): string => {
|
||||||
|
const marketType = btnInfo?.detail?.market_type
|
||||||
|
const marketImageMap: Record<string, string> = {
|
||||||
|
google_play: '/images/common/btn_logo-google.svg',
|
||||||
|
app_store: '/images/common/btn_logo-app.svg',
|
||||||
|
pc: '/images/common/btn_logo-pc.svg',
|
||||||
|
}
|
||||||
|
|
||||||
|
if (marketType && marketImageMap[marketType]) {
|
||||||
|
return marketImageMap[marketType]
|
||||||
|
}
|
||||||
|
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleButtonClick = (btnInfo: PageDataResourceGroupBtnInfo) => {
|
||||||
|
const marketType = btnInfo?.detail?.market_type
|
||||||
|
if (marketType) {
|
||||||
|
const url = gameData?.market[marketType]?.url
|
||||||
|
window.open(url, '_blank')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -61,8 +89,21 @@ const getButtonType = (btnInfo: PageDataResourceGroupBtnInfo): ButtonType => {
|
|||||||
})
|
})
|
||||||
"
|
"
|
||||||
:disabled="button.btn_info?.disabled"
|
:disabled="button.btn_info?.disabled"
|
||||||
|
:class="button.btn_info?.detail?.market_type ? 'btn-market' : ''"
|
||||||
|
:style="{
|
||||||
|
backgroundImage: `url(${getButtonBackgroundImage(button.btn_info)})`,
|
||||||
|
}"
|
||||||
|
@click="handleButtonClick(button.btn_info)"
|
||||||
>
|
>
|
||||||
{{ button.btn_info?.txt_btn_name }}
|
{{ button.btn_info?.txt_btn_name }}
|
||||||
</AtomsButton>
|
</AtomsButton>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
:deep(.btn-market) {
|
||||||
|
@apply flex items-start bg-[16px_50%] bg-[length:auto_34px] bg-no-repeat
|
||||||
|
min-w-[113px] pt-[23px] pl-[44px] pr-[22px] text-[11px]
|
||||||
|
md:min-w-[150px] md:pt-[30px] md:pl-[64px] md:pr-[28px] md:text-[12px] md:bg-[20px_50%] md:bg-[length:auto_40px];
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ export interface GameDataValue {
|
|||||||
sns: GameDataSns
|
sns: GameDataSns
|
||||||
footer: string // JSON 문자열로 변경
|
footer: string // JSON 문자열로 변경
|
||||||
comm_img: GameDataCommImg
|
comm_img: GameDataCommImg
|
||||||
|
market: Record<string, { url: string }>
|
||||||
}
|
}
|
||||||
|
|
||||||
// ===== 세부 데이터 타입들 =====
|
// ===== 세부 데이터 타입들 =====
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 7.5 KiB After Width: | Height: | Size: 7.5 KiB |
Reference in New Issue
Block a user