diff --git a/layers/components/blocks/VisualContent.vue b/layers/components/blocks/VisualContent.vue
index c791dd5..1b7ed2b 100644
--- a/layers/components/blocks/VisualContent.vue
+++ b/layers/components/blocks/VisualContent.vue
@@ -1,37 +1,87 @@
-
+
+
-
+
+
+
diff --git a/layers/components/widgets/Background.vue b/layers/components/widgets/Background.vue
index a8bba45..4812e09 100644
--- a/layers/components/widgets/Background.vue
+++ b/layers/components/widgets/Background.vue
@@ -2,10 +2,14 @@
import { getResponsiveClass, getResponsiveSrc } from '#layers/utils/dataUtil'
import type { PageDataResourceGroup } from '#layers/types/api/pageData'
-const props = defineProps<{
+interface Props {
resourcesData: PageDataResourceGroup
- gradientClass?: string
-}>()
+ gradient?: boolean
+}
+
+const props = withDefaults(defineProps(), {
+ gradient: false,
+})
const resPath = computed(() => {
return props.resourcesData?.res_path
@@ -37,10 +41,10 @@ const posterSrc = computed(() => {
-
+
-
+
-
+
+
diff --git a/layers/components/widgets/ButtonList.vue b/layers/components/widgets/ButtonList.vue
index fd1737c..d5d9830 100644
--- a/layers/components/widgets/ButtonList.vue
+++ b/layers/components/widgets/ButtonList.vue
@@ -1,21 +1,32 @@
-
+
{{ button.btn_info?.txt_btn_name }}
-
+
diff --git a/layers/components/widgets/Description.vue b/layers/components/widgets/Description.vue
index 369ac83..3b83e8f 100644
--- a/layers/components/widgets/Description.vue
+++ b/layers/components/widgets/Description.vue
@@ -1,17 +1,13 @@
-
+
diff --git a/layers/components/widgets/MainTitle.vue b/layers/components/widgets/MainTitle.vue
index 283dab7..b8a3156 100644
--- a/layers/components/widgets/MainTitle.vue
+++ b/layers/components/widgets/MainTitle.vue
@@ -1,17 +1,13 @@
-
+
diff --git a/layers/components/widgets/SubTitle.vue b/layers/components/widgets/SubTitle.vue
index aa208af..2c5699c 100644
--- a/layers/components/widgets/SubTitle.vue
+++ b/layers/components/widgets/SubTitle.vue
@@ -1,17 +1,13 @@
-
+
diff --git a/layers/components/widgets/VideoPlay.vue b/layers/components/widgets/VideoPlay.vue
index efc79eb..e4d714f 100644
--- a/layers/components/widgets/VideoPlay.vue
+++ b/layers/components/widgets/VideoPlay.vue
@@ -21,11 +21,14 @@ const handleVideoPlayClick = () => {
diff --git a/layers/composables/useBreakpoints.ts b/layers/composables/useBreakpoints.ts
new file mode 100644
index 0000000..342ae60
--- /dev/null
+++ b/layers/composables/useBreakpoints.ts
@@ -0,0 +1,11 @@
+/**
+ * 반응형 브레이크포인트 계산 헬퍼
+ */
+export const useResponsiveBreakpoints = () => {
+ return useBreakpoints({
+ xs: 360, // Mobile: 360px ~ 767px
+ sm: 768, // Tablet: 768px ~ 1023px
+ md: 1024, // PC: 1024px ~ 1439px
+ lg: 1440, // Large PC: 1440px+
+ })
+}
diff --git a/layers/server/routes/robots.txt.ts b/layers/server/routes/robots.txt.ts
index 2cb19a1..ffb5192 100644
--- a/layers/server/routes/robots.txt.ts
+++ b/layers/server/routes/robots.txt.ts
@@ -1,78 +1,88 @@
// server/routes/robots.txt.ts
type RobotsConfig = {
- userAgent?: string | string[]
- allow?: string[]
- disallow?: string[]
- sitemap?: string | string[]
- host?: string
- cache?: { sMaxAge?: number; staleWhileRevalidate?: number }
- }
+ userAgent?: string | string[]
+ allow?: string[]
+ disallow?: string[]
+ sitemap?: string | string[]
+ host?: string
+ cache?: { sMaxAge?: number; staleWhileRevalidate?: number }
+}
- export default defineEventHandler(async (event) => {
- const host =
- (getHeader(event, "host") || getRequestHost(event)).toString() || "";
- const baseDomain = process.env.BASE_DOMAIN || ".onstove.com";
- const isGameAliasExtractable = host.includes(baseDomain);
+export default defineEventHandler(async event => {
+ const host =
+ (getHeader(event, 'host') || getRequestHost(event)).toString() || ''
+ const baseDomain = process.env.BASE_DOMAIN || '.onstove.com'
+ const isGameAliasExtractable = host.includes(baseDomain)
- let gameAlias = "";
+ let gameAlias = ''
if (isGameAliasExtractable) {
- gameAlias = host.split(".")[0];
+ gameAlias = host.split('.')[0]
}
-// if (gameAlias && gameAlias !== "www") {
-// event.context.gameAlias = gameAlias;
-// }
-// }
- // robots 설정을 직접 가져오기 (미들웨어 context 사용)
-
- let config: RobotsConfig;
-
- try {
-
- // robots 설정 추출
- config = {
- userAgent: "*",
- allow: ["/"],
- disallow: ["/error", "/inspection/", "/inspection/*", "/html/*"],
- sitemap: [`https://static-pubcomm.gate8.com/local/template/${gameAlias}/sitemap.xml`],
- host: `${gameAlias}.onstove.com`,
- cache: { sMaxAge: 300, staleWhileRevalidate: 600 }
- };
- } catch (error) {
- console.error('Failed to fetch robots config:', error);
-
- // 에러 발생 시 기본값 반환
- config = {
- userAgent: "*",
- allow: ["/"],
- disallow: ["/error", "/inspection/", "/inspection/*", "/html/*"],
- cache: { sMaxAge: 300, staleWhileRevalidate: 600 }
- };
+ // if (gameAlias && gameAlias !== "www") {
+ // event.context.gameAlias = gameAlias;
+ // }
+ // }
+ // robots 설정을 직접 가져오기 (미들웨어 context 사용)
+
+ let config: RobotsConfig
+
+ try {
+ // robots 설정 추출
+ config = {
+ userAgent: '*',
+ allow: ['/'],
+ disallow: ['/error', '/inspection/', '/inspection/*', '/html/*'],
+ sitemap: [
+ `https://static-pubcomm.gate8.com/local/template/${gameAlias}/sitemap.xml`,
+ ],
+ host: `${gameAlias}.onstove.com`,
+ cache: { sMaxAge: 300, staleWhileRevalidate: 600 },
}
-
- setHeader(event, "Content-Type", "text/plain; charset=utf-8")
-
- // 캐시 헤더 (CDN 친화)
- const sMax = config.cache?.sMaxAge ?? 300
- const swr = config.cache?.staleWhileRevalidate ?? 600
- setHeader(event, "Cache-Control", `public, s-maxage=${sMax}, stale-while-revalidate=${swr}`)
-
- // 여러 user-agent 지원
- const agents = Array.isArray(config.userAgent) ? config.userAgent : [config.userAgent ?? "*"]
-
- const lines: string[] = []
- for (const ua of agents) {
- lines.push(`User-agent: ${ua}`)
- for (const p of config.allow ?? []) lines.push(`Allow: ${p}`)
- for (const p of config.disallow ?? []) lines.push(`Disallow: ${p}`)
- lines.push("") // 블록 구분 공백
+ } catch (error) {
+ console.error('Failed to fetch robots config:', error)
+
+ // 에러 발생 시 기본값 반환
+ config = {
+ userAgent: '*',
+ allow: ['/'],
+ disallow: ['/error', '/inspection/', '/inspection/*', '/html/*'],
+ cache: { sMaxAge: 300, staleWhileRevalidate: 600 },
}
-
- const sitemaps = Array.isArray(config.sitemap) ? config.sitemap : (config.sitemap ? [config.sitemap] : [])
- for (const sm of sitemaps) lines.push(`Sitemap: ${sm}`)
- if (config.host) lines.push(`Host: ${config.host}`)
-
- // 마지막 개행
- return lines.join("\n").trim() + "\n"
- })
-
\ No newline at end of file
+ }
+
+ setHeader(event, 'Content-Type', 'text/plain; charset=utf-8')
+
+ // 캐시 헤더 (CDN 친화)
+ const sMax = config.cache?.sMaxAge ?? 300
+ const swr = config.cache?.staleWhileRevalidate ?? 600
+ setHeader(
+ event,
+ 'Cache-Control',
+ `public, s-maxage=${sMax}, stale-while-revalidate=${swr}`
+ )
+
+ // 여러 user-agent 지원
+ const agents = Array.isArray(config.userAgent)
+ ? config.userAgent
+ : [config.userAgent ?? '*']
+
+ const lines: string[] = []
+ for (const ua of agents) {
+ lines.push(`User-agent: ${ua}`)
+ for (const p of config.allow ?? []) lines.push(`Allow: ${p}`)
+ for (const p of config.disallow ?? []) lines.push(`Disallow: ${p}`)
+ lines.push('') // 블록 구분 공백
+ }
+
+ const sitemaps = Array.isArray(config.sitemap)
+ ? config.sitemap
+ : config.sitemap
+ ? [config.sitemap]
+ : []
+ for (const sm of sitemaps) lines.push(`Sitemap: ${sm}`)
+ if (config.host) lines.push(`Host: ${config.host}`)
+
+ // 마지막 개행
+ return lines.join('\n').trim() + '\n'
+})
diff --git a/layers/templates/GrVisual01/index.vue b/layers/templates/GrVisual01/index.vue
index af6ce98..1922597 100644
--- a/layers/templates/GrVisual01/index.vue
+++ b/layers/templates/GrVisual01/index.vue
@@ -7,28 +7,36 @@ const props = defineProps()
-