Procházet zdrojové kódy

+ 번역 모듈 추가
+ 재생버튼 추가
+ index 하단에 데이터 연동

송용우 před 2 měsíci
rodič
revize
f42d7d9458
6 změnil soubory, kde provedl 500 přidání a 200 odebrání
  1. 10 0
      app/assets/scss/sub.scss
  2. 396 183
      app/components/header.vue
  3. 65 16
      app/pages/index.vue
  4. 9 1
      nuxt.config.ts
  5. 19 0
      package-lock.json
  6. 1 0
      package.json

+ 10 - 0
app/assets/scss/sub.scss

@@ -441,4 +441,14 @@
   color: #333!important;
   background-color: #fff!important;
   border-color: #ccc!important;
+}
+
+
+.skiptranslate > iframe {
+  top: auto !important;
+  bottom: 0px;
+}
+
+body{
+  top:0px!important;
 }

+ 396 - 183
app/components/header.vue

@@ -1,204 +1,417 @@
 <template>
-    <header>
-        <div class="header--wrap" :class="{ 'white': isScrolled || isMobileMenuOpen }">
-            <div class="header--container">
-                <NuxtLink class="logo--wrap" to="/">그린웨일글로벌</NuxtLink>
-                <ul class="menu--wrap">
-                    <li class="menu--item">
-                        <NuxtLink to="/company/intro">Company</NuxtLink>
-                        <ul class="gnb--wrap">
-                            <li><NuxtLink to="/company/intro">회사소개</NuxtLink></li>
-                            <li><NuxtLink to="/company/history">회사연혁</NuxtLink></li>
-                            <li><NuxtLink to="/company/partners">협력업체</NuxtLink></li>
-                            <li><NuxtLink to="/company/catalog">회사소개자료</NuxtLink></li>
-                        </ul>
-                    </li>
-                    <li class="menu--item">
-                        <NuxtLink to="/products/materials">Products</NuxtLink>
-                        <ul class="gnb--wrap">
-                            <li><NuxtLink to="/products/materials">Materials</NuxtLink></li>
-                            <li><NuxtLink to="/products/solutions">Solutions</NuxtLink></li>
-                        </ul>
-                    </li>
-                    <li class="menu--item">
-                        <NuxtLink to="/technology/facilities">Technology</NuxtLink>
-                        <ul class="gnb--wrap">
-                            <li><NuxtLink to="/technology/facilities">시설</NuxtLink></li>
-                            <li><NuxtLink to="/technology/patents">특허 / 인증</NuxtLink></li>
-                        </ul>
-                    </li>
-                    <li class="menu--item">
-                        <NuxtLink to="/media/news">Media</NuxtLink>
-                        <ul class="gnb--wrap">
-                            <li><NuxtLink to="/media/news">환경뉴스</NuxtLink></li>
-                            <li><NuxtLink to="/media/press">보도자료</NuxtLink></li>
-                        </ul>
-                    </li>
-                    <li class="menu--item">
-                        <NuxtLink to="/contact/notice">Contact</NuxtLink>
-                        <ul class="gnb--wrap">
-                            <li><NuxtLink to="/contact/notice">공지사항</NuxtLink></li>
-                            <li><NuxtLink to="/contact/faq">FAQ</NuxtLink></li>
-                            <li><NuxtLink to="/contact/support">고객센터</NuxtLink></li>
-                            <li><NuxtLink to="/contact/location">오시는길</NuxtLink></li>
-                        </ul>
-                    </li>
-                </ul>
-                <div class="lang--wrap" :class="{ 'active': isLangOpen }" @click="toggleLang" ref="langWrap">
-                    <i class="ico"></i>
-                    <p>KR</p>
-                    <ul class="select--wrap">
-                        <li>Arabic</li>
-                        <li>Chinese (Simplified)</li>
-                        <li>Chinese (Traditional)</li>
-                        <li>English</li>
-                        <li>Esperanto</li>
-                        <li>French</li>
-                    </ul>
-                </div>
-                <div class="ham--wrap" :class="{ 'active': isMobileMenuOpen }">
-                    <UButton @click="toggleMobileMenu"></UButton>
-                </div>
-            </div>
+  <header>
+    <div class="header--wrap" :class="{ white: isScrolled || isMobileMenuOpen }">
+      <div class="header--container">
+        <NuxtLink class="logo--wrap" to="/">그린웨일글로벌</NuxtLink>
+        <ul class="menu--wrap">
+          <li class="menu--item">
+            <NuxtLink to="/company/intro">Company</NuxtLink>
+            <ul class="gnb--wrap">
+              <li><NuxtLink to="/company/intro">회사소개</NuxtLink></li>
+              <li><NuxtLink to="/company/history">회사연혁</NuxtLink></li>
+              <li><NuxtLink to="/company/partners">협력업체</NuxtLink></li>
+              <li><NuxtLink to="/company/catalog">회사소개자료</NuxtLink></li>
+            </ul>
+          </li>
+          <li class="menu--item">
+            <NuxtLink to="/products/materials">Products</NuxtLink>
+            <ul class="gnb--wrap">
+              <li><NuxtLink to="/products/materials">Materials</NuxtLink></li>
+              <li><NuxtLink to="/products/solutions">Solutions</NuxtLink></li>
+            </ul>
+          </li>
+          <li class="menu--item">
+            <NuxtLink to="/technology/facilities">Technology</NuxtLink>
+            <ul class="gnb--wrap">
+              <li><NuxtLink to="/technology/facilities">시설</NuxtLink></li>
+              <li><NuxtLink to="/technology/patents">특허 / 인증</NuxtLink></li>
+            </ul>
+          </li>
+          <li class="menu--item">
+            <NuxtLink to="/media/news">Media</NuxtLink>
+            <ul class="gnb--wrap">
+              <li><NuxtLink to="/media/news">환경뉴스</NuxtLink></li>
+              <li><NuxtLink to="/media/press">보도자료</NuxtLink></li>
+            </ul>
+          </li>
+          <li class="menu--item">
+            <NuxtLink to="/contact/notice">Contact</NuxtLink>
+            <ul class="gnb--wrap">
+              <li><NuxtLink to="/contact/notice">공지사항</NuxtLink></li>
+              <li><NuxtLink to="/contact/faq">FAQ</NuxtLink></li>
+              <li><NuxtLink to="/contact/support">고객센터</NuxtLink></li>
+              <li><NuxtLink to="/contact/location">오시는길</NuxtLink></li>
+            </ul>
+          </li>
+        </ul>
+        <div class="lang--wrap" :class="{ active: isLangOpen }" ref="langWrap" @click="toggleLang">
+          <div class="ico"></div>
+          <p>{{ currentLang }}</p>
+          <ul class="select--wrap" :class="{ active: isLangOpen }">
+            <li @click.stop="changeLang('ko')">한국어</li>
+            <li @click.stop="changeLang('en')">English</li>
+            <li @click.stop="changeLang('zh-CN')">中文(简体)</li>
+            <li @click.stop="changeLang('zh-TW')">中文(繁體)</li>
+            <li @click.stop="changeLang('ja')">日本語</li>
+            <li @click.stop="changeLang('es')">Español</li>
+            <li @click.stop="changeLang('fr')">Français</li>
+            <li @click.stop="changeLang('de')">Deutsch</li>
+            <li @click.stop="changeLang('ru')">Русский</li>
+            <li @click.stop="changeLang('ar')">العربية</li>
+            <li @click.stop="changeLang('el')">Ελληνικά</li>
+            <li @click.stop="changeLang('la')">Latina</li>
+            <li @click.stop="changeLang('ms')">Bahasa Melayu</li>
+            <li @click.stop="changeLang('vi')">Tiếng Việt</li>
+            <li @click.stop="changeLang('eo')">Esperanto</li>
+            <li @click.stop="changeLang('it')">Italiano</li>
+            <li @click.stop="changeLang('id')">Bahasa Indonesia</li>
+            <li @click.stop="changeLang('km')">ភាសាខ្មែរ</li>
+            <li @click.stop="changeLang('th')">ไทย</li>
+            <li @click.stop="changeLang('tr')">Türkçe</li>
+            <li @click.stop="changeLang('pt')">Português (Brasil)</li>
+            <li @click.stop="changeLang('hu')">Magyar</li>
+            <li @click.stop="changeLang('el')">Ελληνικά</li>
+            <li @click.stop="changeLang('la')">Latina</li>
+            <li @click.stop="changeLang('ms')">Bahasa Melayu</li>
+            <li @click.stop="changeLang('vi')">Tiếng Việt</li>
+            <li @click.stop="changeLang('eo')">Esperanto</li>
+            <li @click.stop="changeLang('it')">Italiano</li>
+            <li @click.stop="changeLang('id')">Bahasa Indonesia</li>
+            <li @click.stop="changeLang('km')">ភាសាខ្មែរ</li>
+            <li @click.stop="changeLang('th')">ไทย</li>
+            <li @click.stop="changeLang('tr')">Türkçe</li>
+            <li @click.stop="changeLang('pt')">Português (Brasil)</li>
+            <li @click.stop="changeLang('hu')">Magyar</li>
+          </ul>
+        </div>
+        <div class="ham--wrap" :class="{ active: isMobileMenuOpen }">
+          <UButton @click="toggleMobileMenu"></UButton>
         </div>
-        <div class="mobile--header--wrap" :class="{ 'active': isMobileMenuOpen }">
-            <div class="mobile--menu--wrap">
-                <ul>
-                    <li>
-                        <div @click="toggleAccordion('company')" :class="{ 'active': activeAccordion === 'company' }">
-                            Company<i class="ico"></i>
-                        </div>
-                        <ul :class="{ 'active': activeAccordion === 'company' }">
-                            <li><NuxtLink @click="closeMobileMenu" to="/company/intro">회사소개</NuxtLink></li>
-                            <li><NuxtLink @click="closeMobileMenu" to="/company/history">회사연혁</NuxtLink></li>
-                            <li><NuxtLink @click="closeMobileMenu" to="/company/partners">협력업체</NuxtLink></li>
-                            <li><NuxtLink @click="closeMobileMenu" to="/company/catalog">회사소개자료</NuxtLink></li>
-                        </ul>
-                    </li>
-                    <li>
-                        <div @click="toggleAccordion('products')" :class="{ 'active': activeAccordion === 'products' }">
-                            Products<i class="ico"></i>
-                        </div>
-                        <ul :class="{ 'active': activeAccordion === 'products' }">
-                            <li><NuxtLink @click="closeMobileMenu" to="/products/materials">Materials</NuxtLink></li>
-                            <li><NuxtLink @click="closeMobileMenu" to="/products/solutions">Solutions</NuxtLink></li>
-                        </ul>
-                    </li>
-                    <li>
-                        <div @click="toggleAccordion('technology')" :class="{ 'active': activeAccordion === 'technology' }">
-                            Technology<i class="ico"></i>
-                        </div>
-                        <ul :class="{ 'active': activeAccordion === 'technology' }">
-                            <li><NuxtLink @click="closeMobileMenu" to="/technology/facilities">시설</NuxtLink></li>
-                            <li><NuxtLink @click="closeMobileMenu" to="/technology/patents">특허 / 인증</NuxtLink></li>
-                        </ul>
-                    </li>
-                    <li>
-                        <div @click="toggleAccordion('media')" :class="{ 'active': activeAccordion === 'media' }">
-                            Media<i class="ico"></i>
-                        </div>
-                        <ul :class="{ 'active': activeAccordion === 'media' }">
-                            <li><NuxtLink @click="closeMobileMenu" to="/media/news">환경뉴스</NuxtLink></li>
-                            <li><NuxtLink @click="closeMobileMenu" to="/media/press">보도자료</NuxtLink></li>
-                        </ul>
-                    </li>
-                    <li>
-                        <div @click="toggleAccordion('contact')" :class="{ 'active': activeAccordion === 'contact' }">
-                            Contact<i class="ico"></i>
-                        </div>
-                        <ul :class="{ 'active': activeAccordion === 'contact' }">
-                            <li><NuxtLink @click="closeMobileMenu" to="/contact/notice">공지사항</NuxtLink></li>
-                            <li><NuxtLink @click="closeMobileMenu" to="/contact/faq">FAQ</NuxtLink></li>
-                            <li><NuxtLink @click="closeMobileMenu" to="/contact/support">고객센터</NuxtLink></li>
-                            <li><NuxtLink @click="closeMobileMenu" to="/contact/location">오시는길</NuxtLink></li>
-                        </ul>
-                    </li>
-                </ul>
+      </div>
+    </div>
+    <div class="mobile--header--wrap" :class="{ active: isMobileMenuOpen }">
+      <div class="mobile--menu--wrap">
+        <ul>
+          <li>
+            <div
+              @click="toggleAccordion('company')"
+              :class="{ active: activeAccordion === 'company' }"
+            >
+              Company<i class="ico"></i>
+            </div>
+            <ul :class="{ active: activeAccordion === 'company' }">
+              <li>
+                <NuxtLink @click="closeMobileMenu" to="/company/intro">회사소개</NuxtLink>
+              </li>
+              <li>
+                <NuxtLink @click="closeMobileMenu" to="/company/history"
+                  >회사연혁</NuxtLink
+                >
+              </li>
+              <li>
+                <NuxtLink @click="closeMobileMenu" to="/company/partners"
+                  >협력업체</NuxtLink
+                >
+              </li>
+              <li>
+                <NuxtLink @click="closeMobileMenu" to="/company/catalog"
+                  >회사소개자료</NuxtLink
+                >
+              </li>
+            </ul>
+          </li>
+          <li>
+            <div
+              @click="toggleAccordion('products')"
+              :class="{ active: activeAccordion === 'products' }"
+            >
+              Products<i class="ico"></i>
+            </div>
+            <ul :class="{ active: activeAccordion === 'products' }">
+              <li>
+                <NuxtLink @click="closeMobileMenu" to="/products/materials"
+                  >Materials</NuxtLink
+                >
+              </li>
+              <li>
+                <NuxtLink @click="closeMobileMenu" to="/products/solutions"
+                  >Solutions</NuxtLink
+                >
+              </li>
+            </ul>
+          </li>
+          <li>
+            <div
+              @click="toggleAccordion('technology')"
+              :class="{ active: activeAccordion === 'technology' }"
+            >
+              Technology<i class="ico"></i>
+            </div>
+            <ul :class="{ active: activeAccordion === 'technology' }">
+              <li>
+                <NuxtLink @click="closeMobileMenu" to="/technology/facilities"
+                  >시설</NuxtLink
+                >
+              </li>
+              <li>
+                <NuxtLink @click="closeMobileMenu" to="/technology/patents"
+                  >특허 / 인증</NuxtLink
+                >
+              </li>
+            </ul>
+          </li>
+          <li>
+            <div
+              @click="toggleAccordion('media')"
+              :class="{ active: activeAccordion === 'media' }"
+            >
+              Media<i class="ico"></i>
             </div>
-            <div class="mobile--lang--wrap">
-                <div class="lang--wrap" :class="{ 'active': isLangOpen2 }" @click="toggleLang2" ref="langWrap2">
-                    <i class="ico"></i>
-                    <p>KR</p>
-                    <ul class="select--wrap">
-                        <li>Arabic</li>
-                        <li>Chinese (Simplified)</li>
-                        <li>Chinese (Traditional)</li>
-                        <li>English</li>
-                        <li>Esperanto</li>
-                        <li>French</li>
-                    </ul>
-                </div>
+            <ul :class="{ active: activeAccordion === 'media' }">
+              <li>
+                <NuxtLink @click="closeMobileMenu" to="/media/news">환경뉴스</NuxtLink>
+              </li>
+              <li>
+                <NuxtLink @click="closeMobileMenu" to="/media/press">보도자료</NuxtLink>
+              </li>
+            </ul>
+          </li>
+          <li>
+            <div
+              @click="toggleAccordion('contact')"
+              :class="{ active: activeAccordion === 'contact' }"
+            >
+              Contact<i class="ico"></i>
             </div>
+            <ul :class="{ active: activeAccordion === 'contact' }">
+              <li>
+                <NuxtLink @click="closeMobileMenu" to="/contact/notice"
+                  >공지사항</NuxtLink
+                >
+              </li>
+              <li><NuxtLink @click="closeMobileMenu" to="/contact/faq">FAQ</NuxtLink></li>
+              <li>
+                <NuxtLink @click="closeMobileMenu" to="/contact/support"
+                  >고객센터</NuxtLink
+                >
+              </li>
+              <li>
+                <NuxtLink @click="closeMobileMenu" to="/contact/location"
+                  >오시는길</NuxtLink
+                >
+              </li>
+            </ul>
+          </li>
+        </ul>
+      </div>
+      <div class="mobile--lang--wrap">
+        <div class="lang--wrap" :class="{ active: isLangOpen2 }" ref="langWrap2" @click="toggleLang2">
+          <div class="ico"></div>
+          <p>{{ currentLang }}</p>
+          <ul class="select--wrap" :class="{ active: isLangOpen2 }">
+            <li @click.stop="changeLang('ko')">한국어</li>
+            <li @click.stop="changeLang('en')">English</li>
+            <li @click.stop="changeLang('zh-CN')">中文(简体)</li>
+            <li @click.stop="changeLang('zh-TW')">中文(繁體)</li>
+            <li @click.stop="changeLang('ja')">日본語</li>
+            <li @click.stop="changeLang('es')">Español</li>
+            <li @click.stop="changeLang('fr')">Français</li>
+            <li @click.stop="changeLang('de')">Deutsch</li>
+            <li @click.stop="changeLang('ru')">Русский</li>
+            <li @click.stop="changeLang('ar')">العربية</li>
+            <li @click.stop="changeLang('el')">Ελληνικά</li>
+            <li @click.stop="changeLang('la')">Latina</li>
+            <li @click.stop="changeLang('ms')">Bahasa Melayu</li>
+            <li @click.stop="changeLang('vi')">Tiếng Việt</li>
+            <li @click.stop="changeLang('eo')">Esperanto</li>
+            <li @click.stop="changeLang('it')">Italiano</li>
+            <li @click.stop="changeLang('id')">Bahasa Indonesia</li>
+            <li @click.stop="changeLang('km')">ភាសាខ្មែរ</li>
+            <li @click.stop="changeLang('th')">ไทย</li>
+            <li @click.stop="changeLang('tr')">Türkçe</li>
+            <li @click.stop="changeLang('pt')">Português (Brasil)</li>
+            <li @click.stop="changeLang('hu')">Magyar</li>
+          </ul>
         </div>
-    </header>
+      </div>
+    </div>
+    <!-- Hidden Google Translate component for functionality -->
+    <ClientOnly>
+      <GoogleTranslate />
+    </ClientOnly>
+  </header>
 </template>
 
 <script setup>
-import { ref, onMounted, onUnmounted } from 'vue'
-
-const isScrolled = ref(false)
-const isLangOpen = ref(false)
-const isLangOpen2 = ref(false)
-const isMobileMenuOpen = ref(false)
-const activeAccordion = ref(null)
-const langWrap = ref(null)
-const langWrap2 = ref(null)
-
-const handleScroll = () => {
-  // 모바일 메뉴가 열려있으면 스크롤 위치와 상관없이 white 클래스 유지
-  if (isMobileMenuOpen.value) {
-    isScrolled.value = true
-  } else {
-    isScrolled.value = window.scrollY > 0
+  import { ref, onMounted, onUnmounted } from "vue";
+  import { useGoogleTranslate } from '#imports';
+
+  const isScrolled = ref(false);
+  const isMobileMenuOpen = ref(false);
+  const activeAccordion = ref(null);
+  const isLangOpen = ref(false);
+  const isLangOpen2 = ref(false);
+  const currentLang = ref('한국어');
+  const langWrap = ref(null);
+  const langWrap2 = ref(null);
+  
+  // Google Translate 기능 사용
+  let setLanguage;
+  try {
+    const googleTranslate = useGoogleTranslate();
+    setLanguage = googleTranslate.setLanguage;
+  } catch (error) {
+    console.warn('Google Translate not available:', error);
+    setLanguage = (lang) => console.log('Would translate to:', lang);
   }
-}
+  
+  // 언어 매핑
+  const langMap = {
+    'ko': '한국어',
+    'en': 'English',
+    'zh-CN': '中文(简体)',
+    'zh-TW': '中文(繁體)',
+    'ja': '日本語',
+    'es': 'Español',
+    'fr': 'Français',
+    'de': 'Deutsch',
+    'ru': 'Русский',
+    'ar': 'العربية',
+    'el': 'Ελληνικά',     // 그리스어
+    'la': 'Latina',       // 라틴어
+    'ms': 'Bahasa Melayu', // 말레이어
+    'vi': 'Tiếng Việt',   // 베트남어
+    'eo': 'Esperanto',    // 에스페란토어
+    'it': 'Italiano',     // 이탈리아어
+    'id': 'Bahasa Indonesia', // 인도네시아어
+    'km': 'ភាសាខ្មែរ',      // 크메르어
+    'th': 'ไทย',          // 태국어
+    'tr': 'Türkçe',       // 튀르키예어
+    'pt': 'Português (Brasil)', // 포르투갈어(브라질)
+    'hu': 'Magyar'        // 헝가리어
+  };
 
-const toggleLang = () => {
-  isLangOpen.value = !isLangOpen.value
-}
+  const handleScroll = () => {
+    // 모바일 메뉴가 열려있으면 스크롤 위치와 상관없이 white 클래스 유지
+    if (isMobileMenuOpen.value) {
+      isScrolled.value = true;
+    } else {
+      isScrolled.value = window.scrollY > 0;
+    }
+  };
 
-const toggleLang2 = () => {
-  isLangOpen2.value = !isLangOpen2.value
-}
+  const toggleMobileMenu = () => {
+    isMobileMenuOpen.value = !isMobileMenuOpen.value;
+  };
+  
+  const toggleLang = () => {
+    isLangOpen.value = !isLangOpen.value;
+  };
 
-const toggleMobileMenu = () => {
-  isMobileMenuOpen.value = !isMobileMenuOpen.value;
-}
+  const toggleLang2 = () => {
+    isLangOpen2.value = !isLangOpen2.value;
+  };
+  
+  const changeLang = (langCode) => {
+    // 먼저 드롭다운을 닫음
+    isLangOpen.value = false;
+    isLangOpen2.value = false;
+    
+    // UI 업데이트
+    currentLang.value = langMap[langCode] || langCode.toUpperCase();
+    
+    // Google Translate 모듈 사용하여 언어 변경
+    setLanguage(langCode);
+    
+    // localStorage에 선택된 언어 저장
+    if (typeof window !== 'undefined') {
+      localStorage.setItem('selectedLanguage', langCode);
+    }
+    
+    console.log(`Language changed to: ${langCode}`);
+  };
+  
+  // 페이지 로드 시 저장된 언어 복원
+  const restoreLanguage = () => {
+    if (typeof window !== 'undefined') {
+      const savedLang = localStorage.getItem('selectedLanguage');
+      if (savedLang && savedLang !== 'ko') {
+        currentLang.value = langMap[savedLang] || savedLang.toUpperCase();
+      }
+    }
+  };
 
-const toggleAccordion = (section) => {
-  if (activeAccordion.value === section) {
-    activeAccordion.value = null
-  } else {
-    activeAccordion.value = section
-  }
+  const toggleAccordion = (section) => {
+    if (activeAccordion.value === section) {
+      activeAccordion.value = null;
+    } else {
+      activeAccordion.value = section;
+    }
+  };
+
+  const closeMobileMenu = () => {
+    isMobileMenuOpen.value = false;
+    activeAccordion.value = null;
+  };
+  
+  const handleClickOutside = (event) => {
+    if (langWrap.value && !langWrap.value.contains(event.target)) {
+      isLangOpen.value = false;
+    }
+  };
+
+  const handleClickOutside2 = (event) => {
+    if (langWrap2.value && !langWrap2.value.contains(event.target)) {
+      isLangOpen2.value = false;
+    }
+  };
+  
+
+
+  onMounted(() => {
+    window.addEventListener("scroll", handleScroll);
+    document.addEventListener('click', handleClickOutside);
+    document.addEventListener('click', handleClickOutside2);
+    
+    // 저장된 언어 설정 복원
+    restoreLanguage();
+  });
+
+  onUnmounted(() => {
+    window.removeEventListener("scroll", handleScroll);
+    document.removeEventListener('click', handleClickOutside);
+    document.removeEventListener('click', handleClickOutside2);
+  });
+</script>
+
+<style scoped>
+/* 드롭다운 애니메이션 및 상태 관리 */
+.lang--wrap .select--wrap {
+  opacity: 0;
+  pointer-events: none;
+  transition: all 0.3s ease;
 }
 
-const closeMobileMenu = () => {
-  isMobileMenuOpen.value = false
-  activeAccordion.value = null
+.lang--wrap.active .select--wrap {
+  opacity: 1;
+  pointer-events: all;
 }
 
-const handleClickOutside = (event) => {
-  if (langWrap.value && !langWrap.value.contains(event.target)) {
-    isLangOpen.value = false
-  }
+/* 모바일 드롭다운 */
+.mobile--lang--wrap .lang--wrap .select--wrap {
+  opacity: 0;
+  pointer-events: none;
+  transition: all 0.3s ease;
+  max-height: 300px; /* 높이 조정 */
 }
 
-const handleClickOutside2 = (event) => {
-  if (langWrap2.value && !langWrap2.value.contains(event.target)) {
-    isLangOpen2.value = false
-  }
+.mobile--lang--wrap .lang--wrap.active .select--wrap {
+  opacity: 1;
+  pointer-events: all;
 }
 
-onMounted(() => {
-  window.addEventListener('scroll', handleScroll)
-  document.addEventListener('click', handleClickOutside)
-  document.addEventListener('click', handleClickOutside2)
-})
-
-onUnmounted(() => {
-  window.removeEventListener('scroll', handleScroll)
-  document.removeEventListener('click', handleClickOutside)
-  document.removeEventListener('click', handleClickOutside2)
-})
-</script>
+/* 데스크톱 드롭다운 높이 조정 */
+.lang--wrap .select--wrap {
+  max-height: 300px; /* 높이 조정 */
+}
+</style>

+ 65 - 16
app/pages/index.vue

@@ -172,21 +172,18 @@
         </div>
         <div class="content--wrap">
           <div class="news--card--wrap">
-            <NuxtLink to="/media/news" class="news">
-              <h4 class="news--title">4천억 규모 녹색펀드 첫 투자 대상 선정. 친환경 플라스틱 '3개 1호' 달성</h4>
-              <p class="news--cont">그린웨일글로벌은 환경부가 조성한 4000억원 규모의 '녹색인프라 해외수출 지원펀드'의 첫 투자 대상으로 선정됐다고 11일 밝혔다. 동시에 기술보증기금으로부터 친환경 플라스틱 소재 산 SFMK솔루션에서 진행중인 숙박업소 기반 스마트 커머스 플랫폼 누루GO(NURUGO)와 생분해성 친환경 소재 전문 기업 그린웨일글로벌(Green Whale Global)이 “누르고, 줄이고, 연결 </p>
-              <span class="news--date">2025.07.11</span>
-            </NuxtLink>
-            <NuxtLink to="/media/news" class="news">
-              <h4 class="news--title">SFMK솔루션 - 그린웨일글로벌, '누르고 줄이고 연결하다' 슬로건 아래 MOU 체결</h4>
-              <p class="news--cont">SFMK솔루션에서 진행중인 숙박업소 기반 스마트 커머스 플랫폼 누루GO(NURUGO)와 생분해성 친환경 소재 전문 기업 그린웨일글로벌(Green Whale Global)이 “누르고, 줄이고, 연결하다' 슬로건 아래 MOU</p>
-              <span class="news--date">2025.07.01</span>
-            </NuxtLink>
-            <NuxtLink to="/media/news" class="news">
-              <h4 class="news--title">그린웨일글로벌, 실로암인더스트리와 친환경 제품 위탁생산 협약 체결 그린웨일글로벌, 실로암인더스트리와 친환경 제품 위탁생산 협약 체결</h4>
-              <p class="news--cont">친환경 소재 전문기업 그린웨일글로벌(대표 윤태균)이 지난 15일, 시각장애인 근로자들의 고용안정과 친환경 산업 활성화를 위한 의미 있는 협력을 발표했다. 그린웨일글로벌은 실로암인더스트리와 어쩌고</p>
-              <span class="news--date">2025.05.30</span>
-            </NuxtLink>
+            <a
+              v-for="news in displayNews"
+              :key="news.id"
+              :href="news.link"
+              target="_blank"
+              rel="noopener noreferrer"
+              class="news"
+            >
+              <h4 class="news--title">{{ news.title }}</h4>
+              <!-- <p class="news--cont">뉴스 내용이 없어서 주석 처리</p> -->
+              <span class="news--date">{{ news.date }}</span>
+            </a>
           </div>
           <div class="black--btn--wrap">
             <NuxtLink class="black--btn" to="/media/news">더보기<i class="ico"></i></NuxtLink>
@@ -195,4 +192,56 @@
       </div>
     </section>
   </main>
-</template>
+</template>
+
+<script setup>
+import { ref, computed, onMounted } from "vue";
+
+const newsData = ref([]);
+
+// API에서 뉴스 데이터 가져오기 (최신 3개만)
+const fetchNewsList = async () => {
+  try {
+    const response = await $postForm(`/board_list/media`, {
+      boardId: 'news',
+      page: 1,
+      searchKind: "",
+      searchKeyword: "",
+    });
+
+    if (response && response.success && response.list) {
+      const newData = response.list.slice(0, 3).map((item, index) => {
+        return {
+          id: index + 1,
+          title: item.title,
+          date: item.regdate,
+          link: item.etc1 || "#", // etc1 필드에 외부 링크 저장
+        };
+      });
+      
+      newsData.value = newData;
+    } else {
+      console.error("뉴스 데이터 로드 실패");
+    }
+  } catch (error) {
+    console.error("뉴스 데이터 로드 중 오류:", error);
+  }
+};
+
+// 표시할 뉴스 데이터 (최대 3개)
+const displayNews = computed(() => {
+  return newsData.value.length > 0 ? newsData.value : [
+    {
+      id: 1,
+      title: "뉴스 데이터를 불러오는 중입니다...",
+      date: "2025.01.01",
+      link: "#"
+    }
+  ];
+});
+
+// 컴포넌트 마운트 시 데이터 로드
+onMounted(() => {
+  fetchNewsList();
+});
+</script>

+ 9 - 1
nuxt.config.ts

@@ -25,7 +25,15 @@ export default defineNuxtConfig({
       ]
     },
   },  
-  modules: ['@nuxt/ui'],
+  modules: ['@nuxt/ui', 'nuxt-google-translate'],
+  
+  googleTranslate: {
+    defaultLanguage: 'ko',
+    supportedLanguages: ['ko', 'en', 'zh-CN', 'zh-TW', 'ja', 'es', 'fr', 'de', 'ru', 'ar', 'el', 'la', 'ms', 'vi', 'eo', 'it', 'id', 'km', 'th', 'tr', 'pt', 'hu'],
+    hideGoogleBranding: true,
+    autoDisplay: false
+  },
+  
   ui: {
     colorMode: false
   },

+ 19 - 0
package-lock.json

@@ -14,6 +14,7 @@
         "gsap": "^3.13.0",
         "jquery": "^3.7.1",
         "nuxt": "^4.1.2",
+        "nuxt-google-translate": "^1.3.5",
         "pretendard": "^1.3.9",
         "summernote": "^0.9.1",
         "swiper": "^12.0.2",
@@ -7635,6 +7636,14 @@
         "yallist": "^3.0.2"
       }
     },
+    "node_modules/lucide-vue-next": {
+      "version": "0.487.0",
+      "resolved": "https://registry.npmjs.org/lucide-vue-next/-/lucide-vue-next-0.487.0.tgz",
+      "integrity": "sha512-ilVgu9EHkfId7WSjmoPkzp13cuzpSGO5J16AmltjRHFoj6MlCBGY8BzsBU/ISKVlDheUxM+MsIYjNo/1hSEa6w==",
+      "peerDependencies": {
+        "vue": ">=3.0.1"
+      }
+    },
     "node_modules/magic-regexp": {
       "version": "0.10.0",
       "resolved": "https://registry.npmjs.org/magic-regexp/-/magic-regexp-0.10.0.tgz",
@@ -8251,6 +8260,16 @@
         }
       }
     },
+    "node_modules/nuxt-google-translate": {
+      "version": "1.3.5",
+      "resolved": "https://registry.npmjs.org/nuxt-google-translate/-/nuxt-google-translate-1.3.5.tgz",
+      "integrity": "sha512-ZE9isPtumowhc5wdt76IJSVCWcSRIPENZZGcS1qPv5hx+l8CE5ki0FivKnC8sV1ojszfN030aOH6s5Clqwroqg==",
+      "dependencies": {
+        "@nuxt/kit": "^3.15.2",
+        "defu": "^6.1.4",
+        "lucide-vue-next": "^0.487.0"
+      }
+    },
     "node_modules/nuxt/node_modules/@nuxt/kit": {
       "version": "4.1.2",
       "resolved": "https://registry.npmjs.org/@nuxt/kit/-/kit-4.1.2.tgz",

+ 1 - 0
package.json

@@ -17,6 +17,7 @@
     "gsap": "^3.13.0",
     "jquery": "^3.7.1",
     "nuxt": "^4.1.2",
+    "nuxt-google-translate": "^1.3.5",
     "pretendard": "^1.3.9",
     "summernote": "^0.9.1",
     "swiper": "^12.0.2",