From 470d8a62c774c69172110f4cad6222728240caa6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9Chyeonggkim=E2=80=9D?= <โ€œhyeonggkim@smilegate.comโ€> Date: Mon, 27 Oct 2025 21:18:12 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=EC=97=90=EB=9F=AC=20=EC=B6=94=EA=B0=80?= =?UTF-8?q?=20=EC=A4=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/pages/error.vue | 9 + app/pages/index.vue | 2 + error.vue | 221 +++++++++++++++++ layers/components/blocks/LanguageSwitcher.vue | 224 ++++++++++++------ layers/components/layouts/Footer.vue | 157 ++++++++---- layers/middleware/init.route.global.ts | 2 +- layers/utils/dataUtil.ts | 2 +- public/images/common/img_error.png | Bin 0 -> 22819 bytes public/images/common/logo-stove.svg | 3 + 9 files changed, 494 insertions(+), 126 deletions(-) create mode 100644 app/pages/error.vue create mode 100644 error.vue create mode 100644 public/images/common/img_error.png create mode 100644 public/images/common/logo-stove.svg diff --git a/app/pages/error.vue b/app/pages/error.vue new file mode 100644 index 0000000..1068f43 --- /dev/null +++ b/app/pages/error.vue @@ -0,0 +1,9 @@ + \ No newline at end of file diff --git a/app/pages/index.vue b/app/pages/index.vue index dceae28..43db7c4 100644 --- a/app/pages/index.vue +++ b/app/pages/index.vue @@ -7,6 +7,8 @@ const { pageData } = storeToRefs(pageDataStore) const currentLayout = computed(() => getLayoutType(pageData.value)) +console.log("๐Ÿš€ ~ currentLayout:", currentLayout) + definePageMeta({ layout: false, // ๋™์  ๋ ˆ์ด์•„์›ƒ์„ ์œ„ํ•ด ๊ธฐ๋ณธ ๋ ˆ์ด์•„์›ƒ ๋น„ํ™œ์„ฑํ™” }) diff --git a/error.vue b/error.vue new file mode 100644 index 0000000..dc92961 --- /dev/null +++ b/error.vue @@ -0,0 +1,221 @@ + + + + + + \ No newline at end of file diff --git a/layers/components/blocks/LanguageSwitcher.vue b/layers/components/blocks/LanguageSwitcher.vue index 979af39..5fdc18f 100644 --- a/layers/components/blocks/LanguageSwitcher.vue +++ b/layers/components/blocks/LanguageSwitcher.vue @@ -1,14 +1,33 @@ @@ -74,17 +86,12 @@ const gameDataStore = useGameDataStore() // ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ์–ธ์–ด ๋ชฉ๋ก const availableLanguages = computed(() => { - return gameDataStore.gameData?.lang_codes || ['ko'] + return gameDataStore.gameData?.lang_codes?.map(localeCode => ({ + code: localeCode, + name: getLanguageName(localeCode) + })) || [{ code: 'ko', name: 'ํ•œ๊ตญ์–ด' }] }) -const { locale, setLocale } = useI18n() -const switchLocalePath = useSwitchLocalePath() -const pageDataStore = usePageDataStore() - -const selectedLocale = ref(locale.value) -const isChanging = ref(false) -const isDropdownOpen = ref(false) - // ์–ธ์–ด ์ฝ”๋“œ๋ฅผ ํ•œ๊ตญ์–ด ์ด๋ฆ„์œผ๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜ const getLanguageName = (localeCode: string) => { const languageNames: Record = { @@ -103,18 +110,19 @@ const getLanguageName = (localeCode: string) => { return languageNames[localeCode] || localeCode } -// ํ˜„์žฌ ์–ธ์–ด ์ด๋ฆ„ ๋ฐ˜ํ™˜ -const getCurrentLanguageName = () => { - return getLanguageName(selectedLocale.value) -} +const { locale, setLocale } = useI18n() +const switchLocalePath = useSwitchLocalePath() +const pageDataStore = usePageDataStore() +const selectedLocale = ref(locale.value) +const isChanging = ref(false) +const isDropdownOpen = ref(false) // ๋“œ๋กญ๋‹ค์šด ํ† ๊ธ€ ํ•จ์ˆ˜ const toggleDropdown = () => { if (!isChanging.value) { isDropdownOpen.value = !isDropdownOpen.value } } - // ์–ธ์–ด ์„ ํƒ ํ•จ์ˆ˜ const selectLanguage = async (localeCode: string) => { if (localeCode === selectedLocale.value || isChanging.value) { @@ -122,12 +130,11 @@ const selectLanguage = async (localeCode: string) => { return } - selectedLocale.value = localeCode + selectedLocale.value = localeCode as any isDropdownOpen.value = false await switchLanguage() } - -// ์–ธ์–ด ๋ณ€๊ฒฝ ํ•จ์ˆ˜ (CSR ๋ฐฉ์‹) +// ์–ธ์–ด ๋ณ€๊ฒฝ ํ•จ์ˆ˜ (์„œ๋ฒ„ ๋ฏธ๋“œ์›จ์–ด๋ฅผ ํ†ตํ•œ gameData ๊ฐฑ์‹ ) const switchLanguage = async () => { if (!selectedLocale.value || isChanging.value) return @@ -139,18 +146,26 @@ const switchLanguage = async () => { if (path) { // ํŽ˜์ด์ง€ ๋ฐ์ดํ„ฐ ์ดˆ๊ธฐํ™” (์ƒˆ๋กœ์šด ์–ธ์–ด๋กœ ๋‹ค์‹œ ๋กœ๋“œ๋˜๋„๋ก) pageDataStore.clearPageData() - + window.location.href = path // ์–ธ์–ด ๋ณ€๊ฒฝ ๋ฐ ๋ผ์šฐํŒ… - await setLocale(selectedLocale.value as any) - // await router.push(path) + // await setLocale(selectedLocale.value as any) + + // ์ „์ฒด ํŽ˜์ด์ง€์— ํŽ˜์ด๋“œ ์•„์›ƒ ํšจ๊ณผ ์ ์šฉ + // document.body.style.transition = 'opacity 0.1s ease-out' + // document.body.style.opacity = '0' + + // // ํŽ˜์ด๋“œ ์•„์›ƒ ์™„๋ฃŒ ํ›„ ํŽ˜์ด์ง€ ์ด๋™ + // await new Promise(resolve => setTimeout(resolve, 100)) + + // ์„œ๋ฒ„ ๋ฏธ๋“œ์›จ์–ด๋ฅผ ํ†ตํ•ด gameData ๊ฐฑ์‹ ์„ ์œ„ํ•ด ํŽ˜์ด์ง€ ์ƒˆ๋กœ๊ณ ์นจ + // ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์„œ๋ฒ„ ๋ฏธ๋“œ์›จ์–ด๊ฐ€ ์ƒˆ๋กœ์šด ์–ธ์–ด๋กœ gameData๋ฅผ ๋‹ค์‹œ ๊ฐ€์ ธ์˜ด - // ํŽ˜์ด์ง€ ์ƒˆ๋กœ๊ณ ์นจ์„ ํ†ตํ•ด ๋ฐ์ดํ„ฐ ์žฌ๋กœ๋“œ ๋ณด์žฅ - await nextTick() - window.location.reload() } } catch { // ์˜ค๋ฅ˜ ๋ฐœ์ƒ ์‹œ ์ด์ „ ์–ธ์–ด๋กœ ๋ณต์› selectedLocale.value = locale.value + // ํŽ˜์ด๋“œ ํšจ๊ณผ ๋ณต์› + document.body.style.opacity = '1' } finally { isChanging.value = false } @@ -160,20 +175,85 @@ const switchLanguage = async () => { watch(locale, newLocale => { selectedLocale.value = newLocale }) - -// ์™ธ๋ถ€ ํด๋ฆญ ์‹œ ๋“œ๋กญ๋‹ค์šด ๋‹ซ๊ธฐ -onMounted(() => { - const handleClickOutside = (event: Event) => { - const target = event.target as HTMLElement - if (!target.closest('.relative')) { - isDropdownOpen.value = false - } - } - - document.addEventListener('click', handleClickOutside) - - onUnmounted(() => { - document.removeEventListener('click', handleClickOutside) - }) -}) + \ No newline at end of file diff --git a/layers/components/layouts/Footer.vue b/layers/components/layouts/Footer.vue index 259cb8a..e927e8c 100644 --- a/layers/components/layouts/Footer.vue +++ b/layers/components/layouts/Footer.vue @@ -24,12 +24,12 @@
  • -

    {{ tm('Footer_AgeRating') }}

    +

    {{ footerAgeRating }}