diff --git a/app/app.vue b/app/app.vue index 8e15df4..00977ce 100644 --- a/app/app.vue +++ b/app/app.vue @@ -1,7 +1,11 @@ + + + + diff --git a/layers/components/atoms/Video.vue b/layers/components/atoms/Video.vue new file mode 100644 index 0000000..c792e95 --- /dev/null +++ b/layers/components/atoms/Video.vue @@ -0,0 +1,86 @@ + + + + + diff --git a/layers/components/blocks/CardNews.vue b/layers/components/blocks/CardNews.vue index f871987..70dad2c 100644 --- a/layers/components/blocks/CardNews.vue +++ b/layers/components/blocks/CardNews.vue @@ -10,28 +10,25 @@ interface Props { } const props = defineProps() -const {locale} = useI18n() +const { locale } = useI18n() const { sendLog, useAnalyticsLogDataDirect } = useAnalytics() -const handleLinkClick = (title) => { +const handleLinkClick = (title: string) => { const trackingData = { tracking: { click_item: title, action_type: 'click', - click_sarea: '' - } + click_sarea: '', + }, } sendLog(locale.value, useAnalyticsLogDataDirect(trackingData, 1)) } - - diff --git a/layers/components/blocks/HybridLink.vue b/layers/components/blocks/HybridLink.vue deleted file mode 100644 index 892b7b5..0000000 --- a/layers/components/blocks/HybridLink.vue +++ /dev/null @@ -1,39 +0,0 @@ - - - diff --git a/layers/components/blocks/StoveGnb.vue b/layers/components/blocks/StoveGnb.vue index 1ea552f..0351197 100644 --- a/layers/components/blocks/StoveGnb.vue +++ b/layers/components/blocks/StoveGnb.vue @@ -9,7 +9,7 @@ const { gameData } = useGameDataStore() const stoveInflowPath = runtimeConfig.public.stoveInflowPath const stoveGameNo = runtimeConfig.public.stoveGameNo -const gnbData = gameData?.stove_gnb +const gnbData = gameData?.stove_gnb_json const languageCodes = computed(() => { if (Array.isArray(availableLocales)) { diff --git a/layers/components/blocks/VisualContent.vue b/layers/components/blocks/VisualContent.vue index 26e9b77..3c6f2e7 100644 --- a/layers/components/blocks/VisualContent.vue +++ b/layers/components/blocks/VisualContent.vue @@ -1,5 +1,7 @@ + + diff --git a/layers/components/blocks/loading/Local.vue b/layers/components/blocks/loading/Local.vue index 3135eb6..4eea746 100644 --- a/layers/components/blocks/loading/Local.vue +++ b/layers/components/blocks/loading/Local.vue @@ -14,42 +14,29 @@ const canTeleport = (localId: string) => { + + diff --git a/layers/components/blocks/modal/YouTube.vue b/layers/components/blocks/modal/YouTube.vue index 1152300..457f8f3 100644 --- a/layers/components/blocks/modal/YouTube.vue +++ b/layers/components/blocks/modal/YouTube.vue @@ -1,5 +1,5 @@ diff --git a/layers/components/widgets/ButtonList.vue b/layers/components/widgets/ButtonList.vue index acb5cef..3da173c 100644 --- a/layers/components/widgets/ButtonList.vue +++ b/layers/components/widgets/ButtonList.vue @@ -13,6 +13,9 @@ interface ButtonListProps { const props = defineProps() const { gameData } = useGameDataStore() +const { locale } = useI18n() +const { sendLog, useAnalyticsLogDataDirect } = useAnalytics() + const BUTTON_TYPE_MAP = { URL: { _self: 'internal' as const, @@ -54,15 +57,18 @@ const getButtonBackgroundImage = ( return '' } -const { locale } = useI18n() -const { sendLog, useAnalyticsLogDataDirect } = useAnalytics() - -const handleButtonClick = (btnInfo: PageDataResourceGroupBtnInfo, index: any) => { - sendLog(locale.value, useAnalyticsLogDataDirect(props.resourcesData[index], props.pageVerTmplSeq)) +const handleButtonClick = ( + btnInfo: PageDataResourceGroupBtnInfo, + index: any +) => { + sendLog( + locale.value, + useAnalyticsLogDataDirect(props.resourcesData[index], props.pageVerTmplSeq) + ) const marketType = btnInfo?.detail?.market_type if (marketType) { - const url = gameData?.market[marketType]?.url + const url = gameData?.market_json[marketType]?.url window.open(url, '_blank') return } @@ -100,7 +106,7 @@ const handleButtonClick = (btnInfo: PageDataResourceGroupBtnInfo, index: any) => }" @click="handleButtonClick(button.btn_info, index)" > - {{ button.btn_info?.txt_btn_name }} + {{ button.btn_info?.txt_btn_name }} diff --git a/layers/components/widgets/Description.vue b/layers/components/widgets/Description.vue index 3b83e8f..32a5d20 100644 --- a/layers/components/widgets/Description.vue +++ b/layers/components/widgets/Description.vue @@ -7,7 +7,13 @@ const props = defineProps<{ + + diff --git a/layers/components/widgets/SubTitle.vue b/layers/components/widgets/SubTitle.vue index 2c5699c..e04c3bd 100644 --- a/layers/components/widgets/SubTitle.vue +++ b/layers/components/widgets/SubTitle.vue @@ -1,13 +1,18 @@ diff --git a/layers/components/widgets/VideoPlay.vue b/layers/components/widgets/VideoPlay.vue index 9c1e057..a443495 100644 --- a/layers/components/widgets/VideoPlay.vue +++ b/layers/components/widgets/VideoPlay.vue @@ -6,19 +6,19 @@ const props = defineProps<{ pageVerTmplSeq: number }>() -// YouTube 모달 스토어 사용 const modalStore = useModalStore() - -const {locale} = useI18n() +const { locale } = useI18n() const { sendLog, useAnalyticsLogDataDirect } = useAnalytics() - // 비디오 플레이 버튼 클릭 핸들러 const handleVideoPlayClick = () => { const youtubeUrl = props.resourcesData?.display?.text ?? '' modalStore.handleOpenYoutube({ youtubeUrl }) - sendLog(locale.value, useAnalyticsLogDataDirect(props.resourcesData, props.pageVerTmplSeq)) + sendLog( + locale.value, + useAnalyticsLogDataDirect(props.resourcesData, props.pageVerTmplSeq) + ) } diff --git a/layers/composables/useAnalytics.ts b/layers/composables/useAnalytics.ts index c913a03..19f1b4a 100644 --- a/layers/composables/useAnalytics.ts +++ b/layers/composables/useAnalytics.ts @@ -1,9 +1,11 @@ import * as amplitude from '@amplitude/analytics-browser' -import type { - AnalyticsDetailType, -} from '../types/AnalyticsType' import type { PageDataResourceGroup } from '#layers/types/api/pageData' -import type { IdentityInfo, ActionInfo, MarketingInfo } from '../types/Stove' +import type { AnalyticsDetailType } from '#layers/types/AnalyticsType' +import type { + IdentityInfo, + ActionInfo, + MarketingInfo, +} from '#layers/types/Stove' declare const svcLog: any declare const twq: any @@ -63,7 +65,6 @@ export const useAnalyticsLogDataDirect = ( return logData } - // target에 {XX1, XX2}와 같은 형태가 포함되어 있을 경우 options.clickItem으로부터 값 추출하여 세팅 const findValueFromOption = (target: string, { options = {} }: any) => { if (target.includes('{') && target.includes('}')) { @@ -340,5 +341,11 @@ const sendMarketingScript = ({ } export default () => { - return { sendGA, sendSA, sendLog, sendMarketingScript, useAnalyticsLogDataDirect } + return { + sendGA, + sendSA, + sendLog, + sendMarketingScript, + useAnalyticsLogDataDirect, + } } diff --git a/layers/composables/useBreakpoints.ts b/layers/composables/useBreakpoints.ts index 39e8f96..ccbed4e 100644 --- a/layers/composables/useBreakpoints.ts +++ b/layers/composables/useBreakpoints.ts @@ -1,3 +1,7 @@ +import { useMediaQuery } from '@vueuse/core' +import { getDeviceSrc } from '#layers/utils/styleUtil' +import type { PageDataResourceGroupResPath } from '#layers/types/api/pageData' + const BREAKPOINTS = { xs: 360, sm: 768, @@ -6,18 +10,49 @@ const BREAKPOINTS = { } as const /** - * 확실한 반응형 브레이크포인트 헬퍼 (useWindowSize 기반) + * useMediaQuery 기반 반응형 브레이크포인트 */ -export const useResponsiveBreakpointsReliable = () => { - const { width } = useWindowSize() +export const useResponsiveBreakpoints = () => { + const ssrWidth = BREAKPOINTS.xs + const isXs = useMediaQuery(`(min-width: ${BREAKPOINTS.xs}px)`, { ssrWidth }) + const isSm = useMediaQuery(`(min-width: ${BREAKPOINTS.sm}px)`, { ssrWidth }) + const isMd = useMediaQuery(`(min-width: ${BREAKPOINTS.md}px)`, { ssrWidth }) + const isLg = useMediaQuery(`(min-width: ${BREAKPOINTS.lg}px)`, { ssrWidth }) + const isMobile = useMediaQuery(`(max-width: ${BREAKPOINTS.md - 1}px)`, { + ssrWidth, + }) + const isTablet = useMediaQuery( + `(min-width: ${BREAKPOINTS.sm}px) and (max-width: ${BREAKPOINTS.md - 1}px)`, + { ssrWidth } + ) + const isDesktop = useMediaQuery(`(min-width: ${BREAKPOINTS.md}px)`, { + ssrWidth, + }) return computed(() => ({ - xs: width.value >= BREAKPOINTS.xs, - sm: width.value >= BREAKPOINTS.sm, - md: width.value >= BREAKPOINTS.md, - lg: width.value >= BREAKPOINTS.lg, - isMobile: width.value < BREAKPOINTS.md, - isTablet: width.value >= BREAKPOINTS.sm && width.value < BREAKPOINTS.md, - isDesktop: width.value >= BREAKPOINTS.md, + isXs: isXs.value, + isSm: isSm.value, + isMd: isMd.value, + isLg: isLg.value, + isMobile: isMobile.value, + isTablet: isTablet.value, + isDesktop: isDesktop.value, })) } + +export const useResponsiveSrc = () => { + const breakpoints = useResponsiveBreakpoints() + + const getCurrentSrc = ( + path: PageDataResourceGroupResPath, + options?: { + resourcesType?: 'image' | 'video' + } + ) => { + const result = getDeviceSrc(path, options) + if (!result) return '' + return breakpoints.value.isMobile ? result.mobileSrc : result.pcSrc + } + + return { getCurrentSrc } +} diff --git a/layers/composables/useResourcesData.ts b/layers/composables/useResourcesData.ts index af76908..0f0c258 100644 --- a/layers/composables/useResourcesData.ts +++ b/layers/composables/useResourcesData.ts @@ -14,7 +14,7 @@ export const useResourcesData = () => { const stoveApiBaseUrl = config.public.stoveApiUrl const apiUrl = `${stoveApiBaseUrl}/pub-comm/v1.0/template/operateResources` - const queryParams: Record = { + const queryParams: Record = { page_seq: pageSeq, page_ver: pageVer, page_ver_tmpl_seq: pageVerTmplSeq, diff --git a/layers/composables/useTemplateRegistry.ts b/layers/composables/useTemplateRegistry.ts index 325dfa1..bbca03e 100644 --- a/layers/composables/useTemplateRegistry.ts +++ b/layers/composables/useTemplateRegistry.ts @@ -7,6 +7,8 @@ import GrGallery03 from '#layers/templates/GrGallery03/index.vue' import GrDetail01 from '#layers/templates/GrDetail01/index.vue' import GrDetail02 from '#layers/templates/GrDetail02/index.vue' import GrDetail03 from '#layers/templates/GrDetail03/index.vue' +// import GrBoard01 from '#layers/templates/GrBoard01/index.vue' +import GrContents01 from '#layers/templates/GrContents01/index.vue' const templateRegistry = { GR_VISUAL_01: { component: GrVisual01 }, @@ -19,7 +21,7 @@ const templateRegistry = { GR_DETAIL_01: { component: GrDetail01 }, GR_DETAIL_02: { component: GrDetail02 }, GR_DETAIL_03: { component: GrDetail03 }, - // GR_CONTENTS_01: { component: GrContents01 }, + GR_CONTENTS_01: { component: GrContents01 }, } as const type TemplateKey = keyof typeof templateRegistry diff --git a/layers/templates/GrContents01/index.vue b/layers/templates/GrContents01/index.vue new file mode 100644 index 0000000..a6e98b9 --- /dev/null +++ b/layers/templates/GrContents01/index.vue @@ -0,0 +1,146 @@ + + + + + diff --git a/layers/templates/GrDetail01/index.vue b/layers/templates/GrDetail01/index.vue index 8a62136..651d74d 100644 --- a/layers/templates/GrDetail01/index.vue +++ b/layers/templates/GrDetail01/index.vue @@ -1,16 +1,21 @@