-import { getResponsiveResolvedSrc } from "#layers/utils/dataUtil";
+import { getResponsiveSrc, getDisplayText } from "#layers/utils/dataUtil";
import type { PageDataComponent } from "#layers/types/api/pageData";
const props = defineProps<{ componentData: PageDataComponent }>();
-const displayText = computed(() => {
- return (
- props.componentData?.resources[0]?.["groups"]?.[0]?.display?.ko?.text || ""
- );
+const resources = computed(() => {
+ return props.componentData?.resources;
});
-const assetPath = computed(() => {
- // [TODO] 이미지 그룹 여러개 처리
- // [TODO] 언어 처리
- return props.componentData?.resources[0]?.["groups"]?.[0]?.img_path?.ko;
+
+const displayText = getDisplayText({
+ resources: resources.value,
});
-const imageSrcs = computed(() => {
- if (!assetPath.value?.path_mo || !assetPath.value?.path_pc) {
- return { mobileSrc: "", pcSrc: "" };
- }
- return getResponsiveResolvedSrc(assetPath.value);
+const imageSrc = getResponsiveSrc({
+ resources: resources.value,
+ type: "img",
});
![]()
diff --git a/layers/components/templates/MainTitle.vue b/layers/components/templates/MainTitle.vue
index 7d9c425..60ed49c 100644
--- a/layers/components/templates/MainTitle.vue
+++ b/layers/components/templates/MainTitle.vue
@@ -1,38 +1,33 @@
diff --git a/layers/components/templates/VideoPlay.vue b/layers/components/templates/VideoPlay.vue
index 879e898..80cb732 100644
--- a/layers/components/templates/VideoPlay.vue
+++ b/layers/components/templates/VideoPlay.vue
@@ -1,26 +1,26 @@
diff --git a/layers/server/api/gameData.get.ts b/layers/server/api/gameData.get.ts
deleted file mode 100644
index 4d8fc1a..0000000
--- a/layers/server/api/gameData.get.ts
+++ /dev/null
@@ -1,52 +0,0 @@
-import { commonFetch } from "#layers/utils/apiUtil";
-import { getHeader } from "h3";
-import type {
- GameDataResponse,
- GameDataValue,
-} from "#layers/types/api/gameData";
-
-export default defineEventHandler(async (event) => {
- const config = useRuntimeConfig();
- const baseDomain = (config.public.baseDomain || ".onstove.com") as string;
- const stoveApiBaseUrl = config.public.stoveApiUrl;
- const apiUrl = `${stoveApiBaseUrl}/pub-comm/v1.0/template/game`;
- let gameAlias = "";
-
- try {
- // 미들웨어에서 설정한 gameAlias가 있다면 우선 사용
- if (event.context.gameAlias) {
- gameAlias = event.context.gameAlias;
- } else {
- const host = getHeader(event, "host") || "";
- const isGameAliasExtractable = host.includes(baseDomain);
-
- if (isGameAliasExtractable) {
- const subdomain = host.split(".")[0];
- if (subdomain && subdomain !== "www") {
- gameAlias = subdomain;
- }
- }
- }
- } catch (error) {
- console.log("gameAlias extraction error: ", error);
- }
-
- try {
- const queryParams: Record = {
- game_alias: gameAlias,
- lang_code: "ko",
- };
-
- const response = (await commonFetch("GET", apiUrl, {
- query: queryParams,
- })) as GameDataResponse | null;
-
- if (response?.code === 0 && "value" in response) {
- event.context.gameData = response.value;
- return response.value as GameDataValue;
- }
- } catch (error) {
- console.error(error);
- return {};
- }
-});
diff --git a/layers/types/api/gameData.ts b/layers/types/api/gameData.ts
index 9710591..3d72011 100644
--- a/layers/types/api/gameData.ts
+++ b/layers/types/api/gameData.ts
@@ -18,31 +18,30 @@ export interface GameDataValue {
game_id: string;
game_code: number;
s3_folder_name: string;
- default_lang_code: string;
+ game_name: string;
ga_code: string;
favicon_path: string;
design_theme: number;
- key_color_codes: string[];
- lang_codes: string[];
+ lang_codes: string; // JSON 문자열로 변경
+ key_color_codes: string; // JSON 문자열로 변경
use_game_font: boolean;
footer_dev_ci_img_yn: boolean;
- game_font: GameDataFont;
- global: GameDataGlobal;
+ footer_dev_ci_img_path: string;
+ game_font: string; // JSON 문자열로 변경
+ globals: GameDataGlobal[]; // 배열로 변경
gnb: GameDataGnb;
- quick_menus: GameDataQuickMenu[];
- stove_gnb: GameDataStoveGnb;
- comm_img: GameDataCommImg;
- meta_tag: GameDataMetaTag;
- youtube: GameDataYoutube;
- sns: GameDataSns;
- market: GameDataMarket;
- footer: GameDataFooter;
+ intro: GameDataIntro;
+ inspection: Record; // 동적 객체
+ stove_gnb: string; // JSON 문자열로 변경
+ meta_tag: string; // JSON 문자열로 변경
+ sns: string; // JSON 문자열로 변경
+ footer: string; // JSON 문자열로 변경
}
// Global 설정 타입
export interface GameDataGlobal {
- system_font: GameDataFont;
- lang: GameDataLang;
+ system_font: string; // JSON 문자열로 변경
+ lang: string; // JSON 문자열로 변경
}
// 폰트 타입
@@ -61,12 +60,18 @@ export interface GameDataLang {
// GNB 설정 타입
export interface GameDataGnb {
game_gnb_ver: string;
- display_start_dt: number;
+ display_start_dt: string; // ISO 문자열로 변경
theme_type: string;
bi_path: string;
- lang_codes: string[];
- buttons: any[];
- menus: GameDataMenu[];
+ lang_codes: string; // JSON 문자열로 변경
+ buttons: GameDataButton[];
+ menus: Record; // 동적 객체로 변경
+}
+
+// 버튼 타입
+export interface GameDataButton {
+ depth_type: number;
+ button: string; // JSON 문자열로 변경
}
// 메뉴 타입
@@ -78,7 +83,16 @@ export interface GameDataMenu {
click_action_type: number;
url_path: string;
link_target: string;
- tracking: GameDataTracking;
+ children: Record; // 중첩 메뉴를 위한 children 속성 추가
+ tracking: string; // JSON 문자열로 변경
+}
+
+// 인트로 타입
+export interface GameDataIntro {
+ seq: number;
+ display_start_dt: string;
+ display_end_dt: string;
+ page_url: string;
}
// 트래킹 타입
@@ -108,6 +122,15 @@ export interface GameDataStoveGnb {
stove_install_button_visible: string;
}
+// 파비콘 경로 타입
+export interface GameDataFaviconPath {
+ "16_16": string;
+ "32_32": string;
+ "72_72": string;
+ "180_180": string;
+ "192_192": string;
+}
+
// 공통 이미지 타입
export interface GameDataCommImg {
groups: GameDataCommImgGroup[];
@@ -226,5 +249,69 @@ export interface GameDataApiResult {
error: string | null;
}
+// JSON 문자열 파싱을 위한 유틸리티 타입들
+export interface ParsedKeyColorCodes {
+ extra: string;
+ primary: string;
+ secondary: string;
+ "text-primary": string;
+ "text-secondary": string;
+}
+
+export interface ParsedGameFont {
+ "font-family": string;
+}
+
+export interface ParsedGlobal {
+ system_font: ParsedGameFont;
+ lang: GameDataLang;
+}
+
+export interface ParsedButton {
+ google_play: {
+ label: Record;
+ url: string;
+ tracking: GameDataTracking;
+ };
+ app_store: {
+ label: Record;
+ url: string;
+ tracking: GameDataTracking;
+ };
+}
+
+export interface ParsedStoveGnb {
+ skin_type: string;
+ stove_install_button_visible: string;
+}
+
+export interface ParsedSns {
+ kakao: GameDataSnsItem;
+ twitter: GameDataSnsItem;
+ discord: GameDataSnsItem;
+ youtube: GameDataSnsItem;
+ instagram: GameDataSnsItem;
+ facebook: GameDataSnsItem;
+ tiktok: GameDataSnsItem;
+}
+
+export interface ParsedFooter {
+ use_game_rating: boolean;
+ game_rating_info: GameDataGameRatingInfo;
+ use_dev_ci_url: boolean;
+ dev_ci_url: string;
+ fund_display_yn: boolean;
+ fund_display_url: string;
+}
+
+// 파비콘 경로 파싱 타입
+export interface ParsedFaviconPath {
+ "16_16": string;
+ "32_32": string;
+ "72_72": string;
+ "180_180": string;
+ "192_192": string;
+}
+
// 기존 gameData 타입과의 호환성을 위한 별칭
export type gameData = GameDataValue;
diff --git a/layers/utils/dataUtil.ts b/layers/utils/dataUtil.ts
index d071ff1..2cbca8f 100644
--- a/layers/utils/dataUtil.ts
+++ b/layers/utils/dataUtil.ts
@@ -17,24 +17,78 @@ export const getResolvedSrc = (path: string): string => {
return `${rootPath}${path}`;
};
+// [TODO] data 타입 정의
+export const getDisplayText = ({
+ resources,
+ groupsDepth = 0,
+}: {
+ resources: any;
+ groupsDepth?: number;
+}): string => {
+ const group = resources[0]?.groups?.[groupsDepth];
+ return group?.display?.text ?? "";
+};
+
+// [TODO] data 타입 정의
+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;
+};
+
// 반응형 클래스 리턴하는 함수
export const getResponsiveClass = () => {
return ["bg-[image:var(--mobile-bg)]", "sm:bg-[image:var(--pc-bg)]"];
};
// 반응형 이미지 리턴하는 함수
-export const getResponsiveResolvedSrc = (
- path: ResponsiveImagePath,
- type: ImageType = "img"
-): ResponsiveImageResult => {
- // 필수 경로가 없으면 null 반환
- if (!path?.path_mo || !path?.path_pc) {
+export const getResponsiveSrc = ({
+ resources,
+ type = "img",
+ groupsDepth = 0,
+
+ test,
+}: {
+ resources: any;
+ type?: ImageType;
+ groupsDepth?: number;
+
+ test?: string;
+}): ResponsiveImageResult | ResponsiveImagePath => {
+ const path = getAssetPath({ resources, groupsDepth, test });
+
+ if (!path?.path_mo) {
return null;
}
- // 이미지 경로 해석
const resolvedImages = {
- pc: getResolvedSrc(path.path_pc),
+ pc: getResolvedSrc(path.path_pc || path.path_mo),
mobile: getResolvedSrc(path.path_mo),
};
diff --git a/tailwind.config.ts b/tailwind.config.ts
index 1591ea4..b27994b 100644
--- a/tailwind.config.ts
+++ b/tailwind.config.ts
@@ -11,6 +11,23 @@ export default {
lg: "1440px", // Large PC: 1440px+
},
spacing: {},
+ colors: {
+ "theme-foreground": "var(--foreground)",
+ "theme-foreground-10": "var(--foreground-10)",
+
+ "theme-foreground-reversal": "var(--foreground-reversal)",
+ "theme-foreground-reversal-10": "var(--foreground-reversal-10)",
+ "theme-foreground-reversal-30": "var(--foreground-reversal-30)",
+ "theme-foreground-reversal-40": "var(--foreground-reversal-40)",
+ "theme-foreground-reversal-70": "var(--foreground-reversal-70)",
+
+ // "theme-primary": "var(--light-primary)",
+ // "theme-secondary": "var(--light-secondary)",
+ // "theme-surface": "var(--light-surface)",
+ // "theme-text-secondary": "var(--light-textSecondary)",
+ // "theme-accent": "var(--light-accent)",
+ // "theme-border": "var(--light-border)",
+ },
},
},
} satisfies Config;
diff --git a/tsconfig.json b/tsconfig.json
index b0de953..767efac 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -2,7 +2,7 @@
"extends": "./.nuxt/tsconfig.json",
"compilerOptions": {
"baseUrl": ".",
- "types": ["nuxt", "node"],
+ "types": ["nuxt", "node", "@nuxtjs/i18n"],
"moduleResolution": "bundler",
"paths": {
"@/*": ["."],