Merge branch 'feature/202509XX-cl' into feature/20250910-all

This commit is contained in:
clkim
2025-09-11 14:40:05 +09:00
24 changed files with 275 additions and 229 deletions

View File

@@ -27,11 +27,10 @@ export default defineEventHandler(async (event) => {
} }
} }
} catch (error) { } catch (error) {
console.log("gameAlias extraction error: ", error); console.error("gameAlias extraction error: ", error);
} }
try { try {
const queryParams: Record<string, string> = { const queryParams: Record<string, string> = {
game_alias: gameAlias, game_alias: gameAlias,
}; };
@@ -44,9 +43,15 @@ export default defineEventHandler(async (event) => {
event.context.gameData = response.value; event.context.gameData = response.value;
// lang_codes를 사용해서 동적으로 i18n 설정 업데이트 // lang_codes를 사용해서 동적으로 i18n 설정 업데이트
if (response.value.lang_codes && Array.isArray(response.value.lang_codes)) { if (
response.value.lang_codes &&
Array.isArray(response.value.lang_codes)
) {
event.context.availableLocales = response.value.lang_codes; event.context.availableLocales = response.value.lang_codes;
event.context.defaultLocale = response.value.default_lang_code || response.value.lang_codes[0] || 'ko'; event.context.defaultLocale =
response.value.default_lang_code ||
response.value.lang_codes[0] ||
"ko";
} }
return response.value as GameDataValue; return response.value as GameDataValue;

View File

@@ -9,7 +9,7 @@
</template> </template>
<style> <style>
@import "#layers/assets/css/theme.css"; @import "#layers/assets/css/app.css";
</style> </style>
<script setup lang="ts"> <script setup lang="ts">

View File

@@ -1,7 +1,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { storeToRefs } from "pinia"; import { storeToRefs } from "pinia";
import { usePageDataStore } from "#layers/stores/usePageDataStore"; import { usePageDataStore } from "#layers/stores/usePageDataStore";
import Section from "#layers/components/molecules/Section.vue"; import Template from "#layers/components/molecules/Template.vue";
const pageDataStore = usePageDataStore(); const pageDataStore = usePageDataStore();
const { pageData } = storeToRefs(pageDataStore); const { pageData } = storeToRefs(pageDataStore);
@@ -34,7 +34,7 @@ watchEffect(() => {
<template> <template>
<NuxtLayout :name="layout"> <NuxtLayout :name="layout">
<ClientOnly> <ClientOnly>
<Section :templates="pageData?.templates ?? []" /> <Template :templates="pageData?.templates ?? []" />
</ClientOnly> </ClientOnly>
</NuxtLayout> </NuxtLayout>
</template> </template>

View File

@@ -1,7 +1,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { storeToRefs } from "pinia"; import { storeToRefs } from "pinia";
import { usePageDataStore } from "#layers/stores/usePageDataStore"; import { usePageDataStore } from "#layers/stores/usePageDataStore";
import Section from "#layers/components/molecules/Section.vue"; import Template from "#layers/components/molecules/Template.vue";
const pageDataStore = usePageDataStore(); const pageDataStore = usePageDataStore();
const { pageData } = storeToRefs(pageDataStore); const { pageData } = storeToRefs(pageDataStore);
@@ -34,7 +34,7 @@ watchEffect(() => {
<template> <template>
<NuxtLayout :name="layout"> <NuxtLayout :name="layout">
<ClientOnly> <ClientOnly>
<Section :templates="pageData?.templates ?? []" /> <Template :templates="pageData?.templates ?? []" />
</ClientOnly> </ClientOnly>
</NuxtLayout> </NuxtLayout>
</template> </template>

View File

@@ -1,7 +1,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { storeToRefs } from "pinia"; import { storeToRefs } from "pinia";
import { usePageDataStore } from "#layers/stores/usePageDataStore"; import { usePageDataStore } from "#layers/stores/usePageDataStore";
import Section from "#layers/components/molecules/Section.vue"; import Template from "#layers/components/molecules/Template.vue";
const pageDataStore = usePageDataStore(); const pageDataStore = usePageDataStore();
const { pageData } = storeToRefs(pageDataStore); const { pageData } = storeToRefs(pageDataStore);
@@ -9,6 +9,11 @@ const { pageData } = storeToRefs(pageDataStore);
// const layout = pageData.value?.meta?.layout ?? "default"; // const layout = pageData.value?.meta?.layout ?? "default";
const layout = "default"; // 기본 레이아웃 사용 const layout = "default"; // 기본 레이아웃 사용
// definePageMeta를 사용하여 레이아웃을 미리 설정
definePageMeta({
layout: false, // 기본 레이아웃 비활성화
});
// definePageMeta를 사용하여 레이아웃을 미리 설정 // definePageMeta를 사용하여 레이아웃을 미리 설정
watchEffect(() => { watchEffect(() => {
if (pageData.value?.meta_tag) { if (pageData.value?.meta_tag) {
@@ -29,7 +34,7 @@ watchEffect(() => {
<template> <template>
<NuxtLayout :name="layout"> <NuxtLayout :name="layout">
<ClientOnly> <ClientOnly>
<Section :templates="pageData?.templates ?? []" /> <Template :templates="pageData?.templates ?? []" />
</ClientOnly> </ClientOnly>
</NuxtLayout> </NuxtLayout>
</template> </template>

View File

@@ -1,7 +1,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { storeToRefs } from "pinia"; import { storeToRefs } from "pinia";
import { usePageDataStore } from "#layers/stores/usePageDataStore"; import { usePageDataStore } from "#layers/stores/usePageDataStore";
import Section from "#layers/components/molecules/Section.vue"; import Template from "#layers/components/molecules/Template.vue";
const pageDataStore = usePageDataStore(); const pageDataStore = usePageDataStore();
const { pageData } = storeToRefs(pageDataStore); const { pageData } = storeToRefs(pageDataStore);
@@ -43,7 +43,7 @@ watchEffect(() => {
<template> <template>
<NuxtLayout :name="layout"> <NuxtLayout :name="layout">
<ClientOnly> <ClientOnly>
<Section :templates="pageData?.templates ?? []" /> <Template :templates="pageData?.templates ?? []" />
</ClientOnly> </ClientOnly>
</NuxtLayout> </NuxtLayout>
</template> </template>

View File

@@ -1,3 +1,6 @@
@import "./base/_theme.css";
@import "./base/_reset.css";
@tailwind base; @tailwind base;
@tailwind components; @tailwind components;
@tailwind utilities; @tailwind utilities;

View File

@@ -0,0 +1,6 @@
/* CSS 리셋 및 기본 스타일 */
@layer base {
body {
background-color: #000;
}
}

View File

@@ -1,4 +1,4 @@
/* 라이트 테마 기본 색상 */ /* CSS 변수 정의 - @layer 밖에 위치 */
:root { :root {
--foreground: #ffffff; --foreground: #ffffff;
--foreground-10: #ffffff; --foreground-10: #ffffff;
@@ -39,11 +39,13 @@
--border: #475569; --border: #475569;
} }
/* Gradient 텍스트 스타일 */ /* 커스텀 컴포넌트 스타일 */
.text-gradient-pink { @layer components {
background: linear-gradient(270deg, #e872ff 0%, #ff357e 100%); .text-gradient-pink {
-webkit-background-clip: text; background: linear-gradient(270deg, #e872ff 0%, #ff357e 100%);
-webkit-text-fill-color: transparent; -webkit-background-clip: text;
background-clip: text; -webkit-text-fill-color: transparent;
color: transparent; background-clip: text;
color: transparent;
}
} }

View File

@@ -12,14 +12,19 @@ const gnbList = gameData?.gnb?.menus as GameDataGnb["menus"];
class="bg-theme-foreground text-theme-foreground-reversal relative z-50" class="bg-theme-foreground text-theme-foreground-reversal relative z-50"
> >
<LayoutStoveGnb /> <LayoutStoveGnb />
<div data-name="header-game" class="px-[40px] h-16 flex items-center"> <div
data-name="header-game"
class="px-[40px] h-16 flex items-center whitespace-nowrap"
>
<!-- 로고 --> <!-- 로고 -->
<div data-name="header-logo" class="mr-[40px]"> <div data-name="header-logo" class="mr-[40px]">
<img <AtomsLocaleLink to="/brand">
:src="gameData?.gnb?.bi_path" <img
:alt="gameData?.game_name" :src="gameData?.gnb?.bi_path"
class="h-[30px]" :alt="gameData?.game_name"
/> class="h-[30px]"
/>
</AtomsLocaleLink>
</div> </div>
<!-- 메인 네비게이션 --> <!-- 메인 네비게이션 -->
@@ -44,7 +49,7 @@ const gnbList = gameData?.gnb?.menus as GameDataGnb["menus"];
</MoleculesLink> </MoleculesLink>
<div <div
v-if="gnbItem.children" v-if="gnbItem.children"
class="absolute top-full left-[-28px] min-w-[190px] pt-[4px]" class="absolute top-full left-[-28px] min-w-[190px] pt-[4px] pointer-events-none group-hover:pointer-events-auto"
> >
<ul <ul
class="bg-theme-foreground-10 rounded-[20px] shadow-lg opacity-0 invisible group-hover:opacity-100 group-hover:visible transition-all duration-200 z-50 p-3" class="bg-theme-foreground-10 rounded-[20px] shadow-lg opacity-0 invisible group-hover:opacity-100 group-hover:visible transition-all duration-200 z-50 p-3"
@@ -80,56 +85,9 @@ const gnbList = gameData?.gnb?.menus as GameDataGnb["menus"];
</nav> </nav>
<!-- 오른쪽 영역 --> <!-- 오른쪽 영역 -->
<div data-name="header-right" class="relative group ml-auto"> <div data-name="header-right" class="ml-auto">
<button <div class="relative group">
class="bg-amber-600 hover:bg-amber-700 text-white px-6 py-3 rounded-lg font-medium transition-colors" <AtomsButton size="small">게임 시작</AtomsButton>
>
게임 시작
</button>
<!-- 2단계 드롭다운 메뉴 -->
<div
class="absolute top-full right-0 mt-2 w-64 bg-gray-800 rounded-lg shadow-lg opacity-0 invisible group-hover:opacity-100 group-hover:visible transition-all duration-200 z-50 p-3"
>
<div class="px-4 py-2">
<a
href="#"
class="flex items-center space-x-3 hover:bg-gray-700 transition-colors"
>
<div
class="w-8 h-8 bg-orange-500 rounded flex items-center justify-center"
>
<span class="text-white font-bold text-sm">S</span>
</div>
<span>PC 버전 다운로드</span>
</a>
</div>
<div class="px-4 py-2">
<a
href="#"
class="flex items-center space-x-3 hover:bg-gray-700 transition-colors"
>
<svg class="w-8 h-8" viewBox="0 0 24 24" fill="currentColor">
<path
d="M3,20.5V3.5C3,2.91 3.34,2.39 3.84,2.15L13.69,12L3.84,21.85C3.34,21.6 3,21.09 3,20.5M16.81,15.12L6.05,21.34L14.54,12.85L16.81,15.12M20.16,10.81C20.5,11.08 20.75,11.5 20.75,12C20.75,12.5 20.53,12.9 20.18,13.18L17.89,14.5L15.39,12L17.89,9.5L20.16,10.81M6.05,2.66L16.81,8.88L14.54,11.15L6.05,2.66Z"
/>
</svg>
<span>Google Store</span>
</a>
</div>
<div class="px-4 py-2">
<a
href="#"
class="flex items-center space-x-3 hover:bg-gray-700 transition-colors"
>
<svg class="w-8 h-8" viewBox="0 0 24 24" fill="currentColor">
<path
d="M18.71,19.5C17.88,20.74 17,21.95 15.66,21.97C14.32,22 13.89,21.18 12.37,21.18C10.84,21.18 10.37,21.95 9.1,22C7.79,22.05 6.8,20.68 5.96,19.47C4.25,17 2.94,12.45 4.7,9.39C5.57,7.87 7.13,6.91 8.82,6.88C10.1,6.86 11.32,7.75 12.11,7.75C12.89,7.75 14.37,6.68 15.92,6.84C16.57,6.87 18.39,7.1 19.56,8.82C19.47,8.88 17.39,10.1 17.41,12.63C17.44,15.65 20.06,16.66 20.09,16.67C20.06,16.74 19.67,18.11 18.71,19.5M13,3.5C13.73,2.67 14.94,2.04 15.94,2C16.07,3.17 15.6,4.35 14.9,5.19C14.21,6.04 13.07,6.7 11.95,6.61C11.8,5.46 12.36,4.26 13,3.5Z"
/>
</svg>
<span>App Store</span>
</a>
</div>
</div> </div>
</div> </div>
</div> </div>

View File

@@ -15,15 +15,10 @@ const isShowTemplate = (template: PageDataTemplate) => {
v-for="(template, index) in props.templates" v-for="(template, index) in props.templates"
:key="template.template_code ?? index" :key="template.template_code ?? index"
> >
<section v-if="isShowTemplate(template)" class="relative"> <component
<TemplatesBackground v-if="isShowTemplate(template)"
v-if="template.components?.background" :is="registry[template.template_code]?.component"
:component-data="template.components?.background" :components="template.components"
/> />
<component
:is="registry[template.template_code]?.component"
:components="template.components"
/>
</section>
</template> </template>
</template> </template>

View File

@@ -1,21 +1,31 @@
<script setup lang="ts"> <script setup lang="ts">
import { getResponsiveSrc, getResponsiveClass } from "#layers/utils/dataUtil"; import {
getResourcesData,
getResponsiveSrc,
getResponsiveClass,
} from "#layers/utils/dataUtil";
import type { PageDataComponent } from "#layers/types/api/pageData"; import type { PageDataComponent } from "#layers/types/api/pageData";
const props = defineProps<{ componentData: PageDataComponent }>(); const props = defineProps<{ componentData: PageDataComponent }>();
const assetType = computed(() => { const resourcesData = computed(() => {
return props.componentData?.component_type; return getResourcesData({
resources: props.componentData?.resources,
});
}); });
const resources = computed(() => { const bgStyles = computed(() => {
return props.componentData?.resources; const result = getResponsiveSrc({
pathArray: resourcesData.value?.res_path,
type: "bg",
});
return result && typeof result === "object" && "--pc-bg" in result
? result
: {};
}); });
const hasImage = computed(() => {
const imageSrc = getResponsiveSrc({ return (
resources: resources.value, resourcesData.value?.group_type === "image" && resourcesData.value?.res_path
type: "bg", );
test: "test2",
}); });
</script> </script>
@@ -23,10 +33,10 @@ const imageSrc = getResponsiveSrc({
<div class="absolute inset-0 w-full h-full"> <div class="absolute inset-0 w-full h-full">
<!-- 이미지 타입--> <!-- 이미지 타입-->
<div <div
v-if="assetType === 'IMG' && imageSrc" v-if="hasImage"
class="w-full h-full bg-cover bg-center bg-no-repeat" class="w-full h-full bg-cover bg-center bg-no-repeat"
:class="getResponsiveClass()" :class="getResponsiveClass()"
:style="imageSrc" :style="bgStyles"
></div> ></div>
<!-- 비디오 타입 --> <!-- 비디오 타입 -->

View File

@@ -1,35 +1,42 @@
<script setup lang="ts"> <script setup lang="ts">
import { getResponsiveSrc, getDisplayText } from "#layers/utils/dataUtil"; import { getResourcesData, getResponsiveSrc } from "#layers/utils/dataUtil";
import type { PageDataComponent } from "#layers/types/api/pageData"; import type { PageDataComponent } from "#layers/types/api/pageData";
const props = defineProps<{ componentData: PageDataComponent }>(); const props = defineProps<{ componentData: PageDataComponent }>();
const resources = computed(() => { const resourcesData = computed(() => {
return props.componentData?.resources; return getResourcesData({
resources: props.componentData?.resources,
});
}); });
const displayText = getDisplayText({ const displayText = resourcesData.value?.display?.text;
resources: resources.value,
});
const imageSrc = getResponsiveSrc({ const imageSrc = getResponsiveSrc({
resources: resources.value, pathArray: resourcesData.value?.res_path,
type: "img", type: "image",
}); });
</script> </script>
<template> <template>
<div> <div v-if="resourcesData">
<img <img
:src="imageSrc?.mobileSrc" v-if="imageSrc && 'mobileSrc' in imageSrc"
:src="imageSrc.mobileSrc"
:alt="displayText" :alt="displayText"
class="w-full sm:hidden" class="w-full sm:hidden"
/> />
<!-- PC 이미지 (sm 이상) --> <!-- PC 이미지 (sm 이상) -->
<img <img
:src="imageSrc?.pcSrc" v-if="imageSrc && 'pcSrc' in imageSrc"
:src="imageSrc.pcSrc"
:alt="displayText" :alt="displayText"
class="w-full hidden sm:block" class="w-full hidden sm:block"
/> />
</div> </div>
<p
v-else
v-html="displayText?.replace(/\n/g, '<br/>') || ''"
class="text-center"
></p>
</template> </template>

View File

@@ -1,35 +1,45 @@
<script setup lang="ts"> <script setup lang="ts">
import { getResponsiveSrc, getDisplayText } from "#layers/utils/dataUtil"; import { getResourcesData, getResponsiveSrc } from "#layers/utils/dataUtil";
import type { PageDataComponent } from "#layers/types/api/pageData"; import type { PageDataComponent } from "#layers/types/api/pageData";
const props = defineProps<{ componentData: PageDataComponent }>(); const props = defineProps<{ componentData: PageDataComponent }>();
const resources = computed(() => { const resourcesData = computed(() => {
return props.componentData?.resources; return getResourcesData({
resources: props.componentData?.resources,
});
}); });
const displayText = getDisplayText({ const displayText = resourcesData.value?.display?.text;
resources: resources.value,
});
const imageSrc = getResponsiveSrc({ const imageSrc = getResponsiveSrc({
resources: resources.value, pathArray: resourcesData.value?.res_path,
type: "img", type: "image",
}); });
</script> </script>
<template> <template>
<h2> <h2>
<img <template v-if="resourcesData">
:src="imageSrc?.mobileSrc" <img
:alt="displayText" v-if="imageSrc && 'mobileSrc' in imageSrc"
class="w-full sm:hidden" :src="imageSrc.mobileSrc"
/> :alt="displayText"
class="w-full sm:hidden"
/>
<!-- PC 이미지 (sm 이상) --> <!-- PC 이미지 (sm 이상) -->
<img <img
:src="imageSrc?.pcSrc" v-if="imageSrc && 'pcSrc' in imageSrc"
:alt="displayText" :src="imageSrc.pcSrc"
class="w-full hidden sm:block" :alt="displayText"
/> class="w-full hidden sm:block"
/>
</template>
<span
v-else
v-html="displayText?.replace(/\n/g, '<br/>')"
class="text-center"
>
</span>
</h2> </h2>
</template> </template>

View File

@@ -0,0 +1,45 @@
<script setup lang="ts">
import { getResourcesData, getResponsiveSrc } from "#layers/utils/dataUtil";
import type { PageDataComponent } from "#layers/types/api/pageData";
const props = defineProps<{ componentData: PageDataComponent }>();
const resourcesData = computed(() => {
return getResourcesData({
resources: props.componentData?.resources,
});
});
const displayText = resourcesData.value?.display?.text;
const imageSrc = getResponsiveSrc({
pathArray: resourcesData.value?.res_path,
type: "image",
});
</script>
<template>
<h3>
<template v-if="resourcesData">
<img
v-if="imageSrc && 'mobileSrc' in imageSrc"
:src="imageSrc.mobileSrc"
:alt="displayText"
class="w-full sm:hidden"
/>
<!-- PC 이미지 (sm 이상) -->
<img
v-if="imageSrc && 'pcSrc' in imageSrc"
:src="imageSrc.pcSrc"
:alt="displayText"
class="w-full hidden sm:block"
/>
</template>
<span
v-else
v-html="displayText?.replace(/\n/g, '<br/>')"
class="text-center"
>
</span>
</h3>
</template>

View File

@@ -1,26 +1,35 @@
<script setup lang="ts"> <script setup lang="ts">
import { getResponsiveSrc, getResponsiveClass } from "#layers/utils/dataUtil"; import {
getResourcesData,
getResponsiveSrc,
getResponsiveClass,
} from "#layers/utils/dataUtil";
import type { PageDataComponent } from "#layers/types/api/pageData"; import type { PageDataComponent } from "#layers/types/api/pageData";
const props = defineProps<{ componentData: PageDataComponent }>(); const props = defineProps<{ componentData: PageDataComponent }>();
const resources = computed(() => { const resourcesData = computed(() => {
return props.componentData?.resources; return getResourcesData({
resources: props.componentData?.resources,
});
}); });
const bgStyles = computed(() => {
const imageSrc = getResponsiveSrc({ const result = getResponsiveSrc({
resources: resources.value, pathArray: resourcesData.value?.res_path,
type: "bg", type: "bg",
});
test: "test", return result && typeof result === "object" && "--pc-bg" in result
? result
: {};
}); });
</script> </script>
<template> <template>
<button <button
v-if="resourcesData"
class="bg-cover bg-center bg-no-repeat w-[66px] h-[66px] lg:w-[100px] lg:h-[100px]" class="bg-cover bg-center bg-no-repeat w-[66px] h-[66px] lg:w-[100px] lg:h-[100px]"
:class="getResponsiveClass()" :class="getResponsiveClass()"
:style="imageSrc" :style="bgStyles"
> >
<span class="sr-only">videoPlay</span> <span class="sr-only">videoPlay</span>
</button> </button>

View File

@@ -28,7 +28,7 @@ export const useGetGameAlias = () => {
} }
} }
} catch (error) { } catch (error) {
console.log("useGetGameAlias server error: ", error); console.error("useGetGameAlias server error: ", error);
} }
} }
@@ -46,7 +46,7 @@ export const useGetGameAlias = () => {
} }
} }
} catch (error) { } catch (error) {
console.log("useGetGameAlias client error: ", error); console.error("useGetGameAlias client error: ", error);
} }
} }
return ""; return "";

View File

@@ -6,7 +6,6 @@ interface Props {
} }
const props = defineProps<Props>(); const props = defineProps<Props>();
console.log("components:", props.components);
// YouTube 모달 상태 관리 // YouTube 모달 상태 관리
const isYouTubeModalOpen = ref(false); const isYouTubeModalOpen = ref(false);
@@ -28,24 +27,30 @@ const handleCloseModal = () => {
</script> </script>
<template> <template>
<div <section class="relative h-[640px] lg:h-[1000px]">
class="relative flex flex-col items-center justify-center h-[640px] lg:h-[1000px] gap-4" <TemplatesBackground
> v-if="props.components?.background"
<TemplatesMainTitle :component-data="props.components?.background"
v-if="props.components.mainTitle"
:component-data="props.components.mainTitle"
class="w-[355px] lg:w-[944px]"
/> />
<TemplatesDescription <div
v-if="props.components.description" class="relative h-full flex flex-col items-center justify-center gap-4"
:component-data="props.components.description" >
/> <TemplatesMainTitle
<TemplatesVideoPlay v-if="props.components.mainTitle"
v-if="props.components.videoPlay" :component-data="props.components.mainTitle"
:component-data="props.components.videoPlay" class="w-[355px] lg:w-[944px]"
@click="handleVideoPlayClick" />
/> <TemplatesDescription
</div> v-if="props.components.description"
:component-data="props.components.description"
/>
<TemplatesVideoPlay
v-if="props.components.videoPlay"
:component-data="props.components.videoPlay"
@click="handleVideoPlayClick"
/>
</div>
</section>
<!-- YouTube 모달 --> <!-- YouTube 모달 -->
<YouTubeModal <YouTubeModal

View File

@@ -7,7 +7,5 @@ const props = defineProps<Props>();
</script> </script>
<template> <template>
<div <section class="template-section"></section>
class="relative flex flex-col items-center justify-center h-[640px] lg:h-[1000px] gap-4"
></div>
</template> </template>

View File

@@ -4,10 +4,34 @@ interface Props {
} }
const props = defineProps<Props>(); const props = defineProps<Props>();
console.log("components:", props.components);
</script> </script>
<template> <template>
<div <section class="relative h-[640px] lg:h-[1000px]">
class="relative flex flex-col items-center justify-center h-[640px] lg:h-[1000px] gap-4" <TemplatesBackground
></div> v-if="props.components?.background"
:component-data="props.components?.background"
/>
<div
class="relative h-full flex flex-col items-center justify-center gap-4"
>
<TemplatesSubTitle
v-if="props.components.subTitle"
:component-data="props.components.subTitle"
class="text-[24px] font-[500] text-[#ffffff] leading-[34px]"
/>
<TemplatesMainTitle
v-if="props.components.mainTitle"
:component-data="props.components.mainTitle"
class="text-[50px] font-[700] text-[#c7a28b] leading-[70px]"
/>
<TemplatesDescription
v-if="props.components.cardDescription"
:component-data="props.components.cardDescription"
class="text-[20px] font-[500] text-white/70 leading-[30px]"
/>
</div>
</section>
</template> </template>

View File

@@ -1,4 +1,4 @@
export type ImageType = "img" | "bg"; export type ImageType = "image" | "bg";
export interface ResponsiveImagePath { export interface ResponsiveImagePath {
path_mo?: string; path_mo?: string;

View File

@@ -18,48 +18,16 @@ export const getResolvedSrc = (path: string): string => {
}; };
// [TODO] data 타입 정의 // [TODO] data 타입 정의
export const getDisplayText = ({ export const getResourcesData = ({
resources, resources,
groupsDepth = 0, groupsDepth = 0,
}: { }: {
resources: any; resources: any;
groupsDepth?: number; groupsDepth?: number;
}): string => { }) => {
const group = resources[0]?.groups?.[groupsDepth]; const group = resources[0]?.groups?.[groupsDepth];
return group?.display?.text ?? "";
};
// [TODO] data 타입 정의 return group ?? null;
export const getAssetPath = ({
resources,
groupsDepth = 0,
test,
}: {
resources: any;
groupsDepth?: number;
test?: string;
}): ResponsiveImagePath | null => {
// const group = resources[0]?.groups?.[groupsDepth].resource_data;
// const imgPath = group?.resource_data?.img_path;
const group = resources[groupsDepth];
if (test) {
if (test === "test") {
const tests = {
path_mo: group?.resource_data?.img_path.comm,
};
return tests ?? null;
}
if (test === "test2") {
return group?.resource_data?.img_path.comm ?? null;
}
}
const imgPath = group?.resource_data?.img_path.ko;
return imgPath ?? null;
}; };
// 반응형 클래스 리턴하는 함수 // 반응형 클래스 리턴하는 함수
@@ -69,40 +37,30 @@ export const getResponsiveClass = () => {
// 반응형 이미지 리턴하는 함수 // 반응형 이미지 리턴하는 함수
export const getResponsiveSrc = ({ export const getResponsiveSrc = ({
resources, pathArray,
type = "img", type = "image",
groupsDepth = 0,
test,
}: { }: {
resources: any; pathArray: any;
type?: ImageType; type?: ImageType;
groupsDepth?: number;
test?: string;
}): ResponsiveImageResult | ResponsiveImagePath => { }): ResponsiveImageResult | ResponsiveImagePath => {
const path = getAssetPath({ resources, groupsDepth, test }); if (!pathArray?.path_mo) {
if (!path?.path_mo) {
return null; return null;
} }
const resolvedImages = { const resolvedImages = {
pc: getResolvedSrc(path.path_pc || path.path_mo), pc: getResolvedSrc(pathArray.path_pc || pathArray.path_mo),
mobile: getResolvedSrc(path.path_mo), mobile: getResolvedSrc(pathArray.path_mo),
}; };
// 타입별 반환 객체 생성 if (type === "image") {
const resultMap: Record<ImageType, ResponsiveImageResult> = { return {
img: {
mobileSrc: resolvedImages.mobile, mobileSrc: resolvedImages.mobile,
pcSrc: resolvedImages.pc, pcSrc: resolvedImages.pc,
}, };
bg: { }
"--pc-bg": `url(${resolvedImages.pc})`,
"--mobile-bg": `url(${resolvedImages.mobile})`,
},
};
return resultMap[type]; return {
"--pc-bg": `url(${resolvedImages.pc})`,
"--mobile-bg": `url(${resolvedImages.mobile})`,
};
}; };

View File

@@ -93,6 +93,12 @@ export default defineNuxtConfig({
stove81Plug: process.env.STOVE_81PLUG, stove81Plug: process.env.STOVE_81PLUG,
}, },
}, },
postcss: {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
},
vite: { vite: {
server: { server: {
// 개발 환경에서는 모든 호스트 허용 // 개발 환경에서는 모든 호스트 허용