feat: 언어선택 박스 수정

This commit is contained in:
“hyeonggkim”
2025-10-27 19:42:42 +09:00
parent 641988b033
commit 1f72069418
2 changed files with 122 additions and 16 deletions

View File

@@ -1,21 +1,69 @@
<template>
<div class="bg-white">
<select
v-model="selectedLocale"
<div class="relative">
<!-- 커스텀 드롭다운 버튼 -->
<button
:disabled="isChanging"
class="text-black px-2 py-1 rounded-md"
class="flex items-center gap-2 px-3 py-2 rounded-lg text-[#CCCCCC] transition-colors duration-200 w-[180px] bg-[#292929] border border-[#595959]"
:class="{ 'opacity-50 cursor-not-allowed': isChanging }"
@change="switchLanguage"
@click="toggleDropdown"
>
<option
<!-- 지구본 아이콘 -->
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_5964_1685)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M14.6666 8.00065C14.6666 11.6825 11.6818 14.6673 7.99992 14.6673C4.31802 14.6673 1.33325 11.6825 1.33325 8.00065C1.33325 4.31875 4.31802 1.33398 7.99992 1.33398C11.6818 1.33398 14.6666 4.31875 14.6666 8.00065ZM6.89756 13.2199C6.03596 11.8504 5.50924 10.2901 5.36895 8.66732H2.70785C2.99033 10.9326 4.69347 12.7567 6.89756 13.2199ZM2.70785 7.33398H5.36895C5.50924 5.71116 6.03596 4.15086 6.89756 2.78138C4.69347 3.24458 2.99033 5.06868 2.70785 7.33398ZM13.292 8.66732C13.0095 10.9326 11.3064 12.7567 9.10228 13.2199C9.96388 11.8504 10.4906 10.2901 10.6309 8.66732H13.292ZM13.292 7.33398C13.0095 5.06868 11.3064 3.24458 9.10228 2.78138C9.96388 4.15086 10.4906 5.71116 10.6309 7.33398H13.292ZM7.99992 12.468C7.28662 11.3201 6.84273 10.0202 6.70801 8.66732H9.29183C9.15711 10.0202 8.71322 11.3201 7.99992 12.468ZM6.70801 7.33398H9.29183C9.15711 5.98112 8.71322 4.68121 7.99992 3.5333C7.28662 4.68121 6.84273 5.98112 6.70801 7.33398Z" fill="#CCCCCC"/>
</g>
<defs>
<clipPath id="clip0_5964_1685">
<rect width="16" height="16" fill="#CCCCCC"/>
</clipPath>
</defs>
</svg>
<!-- 현재 언어 텍스트 -->
<span class="flex-1 text-sm text-left">{{ getCurrentLanguageName() }}</span>
<!-- 드롭다운 화살표 -->
<svg
class="w-3 h-3 text-gray-300 transition-transform duration-200"
:class="{ 'rotate-180': isDropdownOpen }"
viewBox="0 0 12 12" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
<path d="M6.69999 4.285L9.59499 7.125C9.91999 7.445 9.69499 8 9.23499 8H2.75999C2.29999 8 2.07499 7.445 2.39999 7.125L5.29499 4.285C5.68499 3.905 6.30499 3.905 6.69499 4.285H6.69999Z" fill="#EBEBEB"/>
</svg>
</button>
<!-- 드롭다운 메뉴 -->
<div
v-if="isDropdownOpen"
class="absolute bottom-full left-0 mt-1 w-[180px] rounded-lg shadow-lg z-50 bg-[#383838] border border-[#595959]"
>
<button
v-for="localeOption in availableLanguages"
:key="localeOption"
:value="localeOption"
class="w-full flex items-center gap-2 px-3 py-2 text-left text-white hover:text-[#fc4420] transition-colors duration-200 first:rounded-t-lg last:rounded-b-lg"
:class="{ 'text-[#fc4420]': selectedLocale === localeOption }"
@click="selectLanguage(localeOption)"
>
{{ localeOption }}
</option>
</select>
<span v-if="isChanging" class="ml-2 text-sm text-gray-500">
<svg
width="15"
height="11"
viewBox="0 0 15 11"
fill="none"
xmlns="http://www.w3.org/2000/svg"
class="transition-opacity duration-200"
:class="{ 'opacity-0': selectedLocale !== localeOption, 'opacity-100': selectedLocale === localeOption }"
>
<path fill-rule="evenodd" clip-rule="evenodd" d="M14.6339 0.366117C15.1221 0.854272 15.1221 1.64573 14.6339 2.13388L6.30057 10.4672C6.05437 10.7134 5.71664 10.8458 5.36872 10.8324C5.0208 10.8191 4.69421 10.6612 4.46762 10.3968L0.300952 5.53571C-0.148326 5.01155 -0.0876239 4.22243 0.436533 3.77315C0.960691 3.32387 1.74982 3.38458 2.19909 3.90873L5.48729 7.74496L12.8661 0.366117C13.3543 -0.122039 14.1458 -0.122039 14.6339 0.366117Z" fill="#FC4420"/>
</svg>
<span class="text-sm" :class="{ 'text-[#fc4420]': selectedLocale === localeOption }">{{ getLanguageName(localeOption) }}</span>
</button>
</div>
<!-- 변경 표시 -->
<span v-if="isChanging" class="ml-2 text-sm text-gray-400">
변경 중...
</span>
</div>
@@ -31,11 +79,53 @@ const availableLanguages = computed(() => {
const { locale, setLocale } = useI18n()
const switchLocalePath = useSwitchLocalePath()
const router = useRouter()
const pageDataStore = usePageDataStore()
const selectedLocale = ref(locale.value)
const selectedLocale = ref<string>(locale.value)
const isChanging = ref(false)
const isDropdownOpen = ref(false)
// 언어 코드를 한국어 이름으로 변환하는 함수
const getLanguageName = (localeCode: string) => {
const languageNames: Record<string, string> = {
'ko': '한국어',
'en': 'English',
'ja': '日本語',
'zh-cn': '简体中文',
'zh-tw': '繁體中文',
'es': 'Español',
'fr': 'Français',
'de': 'Deutsch',
'pt': 'Português',
'th': 'ไทย',
'it': 'Italiano'
}
return languageNames[localeCode] || localeCode
}
// 현재 언어 이름 반환
const getCurrentLanguageName = () => {
return getLanguageName(selectedLocale.value)
}
// 드롭다운 토글 함수
const toggleDropdown = () => {
if (!isChanging.value) {
isDropdownOpen.value = !isDropdownOpen.value
}
}
// 언어 선택 함수
const selectLanguage = async (localeCode: string) => {
if (localeCode === selectedLocale.value || isChanging.value) {
isDropdownOpen.value = false
return
}
selectedLocale.value = localeCode
isDropdownOpen.value = false
await switchLanguage()
}
// 언어 변경 함수 (CSR 방식)
const switchLanguage = async () => {
@@ -45,13 +135,13 @@ const switchLanguage = async () => {
try {
// URL 경로를 통해 언어 변경
const path = switchLocalePath(selectedLocale.value)
const path = switchLocalePath(selectedLocale.value as any)
if (path) {
// 페이지 데이터 초기화 (새로운 언어로 다시 로드되도록)
pageDataStore.clearPageData()
// 언어 변경 및 라우팅
await setLocale(selectedLocale.value)
await setLocale(selectedLocale.value as any)
// await router.push(path)
// 페이지 새로고침을 통해 데이터 재로드 보장
@@ -70,4 +160,20 @@ 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)
})
})
</script>

View File

@@ -97,7 +97,7 @@
</div>
<div class="copyright-area mt-6 text-gray-500 md:mt-4">
<span>&copy; Smilegate. All rights reserved</span>
<span>{{ tm('Footer_Copyright') }}</span>
</div>
<div class="logo-area flex mt-6 md:mt-6">