feat: add language switcher component with flag icons for English and Thai locales.
This commit is contained in:
parent
ada40b05e8
commit
38137f62c1
3 changed files with 39 additions and 18 deletions
|
|
@ -15,10 +15,8 @@ const availableLocales = computed(() => {
|
||||||
}))
|
}))
|
||||||
})
|
})
|
||||||
|
|
||||||
// Get current locale display (TH or EN)
|
// Get flag image path for a locale
|
||||||
const currentLocaleDisplay = computed(() => {
|
const getFlagPath = (code: string) => `/flags/${code}.png`
|
||||||
return locale.value.toUpperCase()
|
|
||||||
})
|
|
||||||
|
|
||||||
// Handle locale change
|
// Handle locale change
|
||||||
const changeLocale = async (code: string) => {
|
const changeLocale = async (code: string) => {
|
||||||
|
|
@ -34,14 +32,19 @@ const changeLocale = async (code: string) => {
|
||||||
class="language-btn"
|
class="language-btn"
|
||||||
:aria-label="$t('language.label')"
|
:aria-label="$t('language.label')"
|
||||||
>
|
>
|
||||||
<span class="language-text">{{ currentLocaleDisplay }}</span>
|
<!-- Show current locale flag -->
|
||||||
|
<img
|
||||||
|
:src="getFlagPath(locale)"
|
||||||
|
:alt="locale.toUpperCase()"
|
||||||
|
class="flag-icon"
|
||||||
|
/>
|
||||||
|
|
||||||
<q-menu
|
<q-menu
|
||||||
anchor="bottom right"
|
anchor="bottom right"
|
||||||
self="top right"
|
self="top right"
|
||||||
class="language-menu"
|
class="language-menu"
|
||||||
>
|
>
|
||||||
<q-list style="min-width: 150px">
|
<q-list style="min-width: 180px">
|
||||||
<q-item-label header class="text-xs font-bold uppercase tracking-wider" style="color: var(--text-secondary);">
|
<q-item-label header class="text-xs font-bold uppercase tracking-wider" style="color: var(--text-secondary);">
|
||||||
{{ $t('language.label') }}
|
{{ $t('language.label') }}
|
||||||
</q-item-label>
|
</q-item-label>
|
||||||
|
|
@ -56,7 +59,11 @@ const changeLocale = async (code: string) => {
|
||||||
class="language-item"
|
class="language-item"
|
||||||
>
|
>
|
||||||
<q-item-section avatar>
|
<q-item-section avatar>
|
||||||
<span class="text-lg">{{ loc.code === 'th' ? '🇹🇭' : '🇺🇸' }}</span>
|
<img
|
||||||
|
:src="getFlagPath(loc.code)"
|
||||||
|
:alt="loc.code.toUpperCase()"
|
||||||
|
class="flag-icon-menu"
|
||||||
|
/>
|
||||||
</q-item-section>
|
</q-item-section>
|
||||||
<q-item-section>
|
<q-item-section>
|
||||||
<q-item-label class="font-semibold" style="color: var(--text-primary);">
|
<q-item-label class="font-semibold" style="color: var(--text-primary);">
|
||||||
|
|
@ -81,21 +88,33 @@ const changeLocale = async (code: string) => {
|
||||||
.language-btn {
|
.language-btn {
|
||||||
width: 40px;
|
width: 40px;
|
||||||
height: 40px;
|
height: 40px;
|
||||||
background: linear-gradient(135deg, var(--primary) 0%, #2f5ed7 100%);
|
background: #ffffff;
|
||||||
color: white;
|
border: 2px solid var(--border-color);
|
||||||
transition: all 0.3s ease;
|
transition: all 0.3s ease;
|
||||||
box-shadow: 0 2px 8px rgba(75, 130, 247, 0.3);
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||||
|
overflow: hidden;
|
||||||
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.language-btn:hover {
|
.language-btn:hover {
|
||||||
transform: scale(1.05);
|
transform: scale(1.05);
|
||||||
box-shadow: 0 4px 12px rgba(75, 130, 247, 0.4);
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
||||||
|
border-color: var(--primary);
|
||||||
}
|
}
|
||||||
|
|
||||||
.language-text {
|
.flag-icon {
|
||||||
font-size: 12px;
|
width: 28px;
|
||||||
font-weight: 800;
|
height: 28px;
|
||||||
letter-spacing: 0.5px;
|
object-fit: cover;
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flag-icon-menu {
|
||||||
|
width: 28px;
|
||||||
|
height: 20px;
|
||||||
|
object-fit: cover;
|
||||||
|
border-radius: 4px;
|
||||||
|
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
.language-item {
|
.language-item {
|
||||||
|
|
@ -120,12 +139,14 @@ const changeLocale = async (code: string) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
:global(.dark) .language-btn {
|
:global(.dark) .language-btn {
|
||||||
background: linear-gradient(135deg, #3b82f6 0%, #1e40af 100%);
|
background: #1e293b;
|
||||||
box-shadow: 0 2px 8px rgba(59, 130, 246, 0.4);
|
border-color: rgba(255, 255, 255, 0.15);
|
||||||
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
|
||||||
}
|
}
|
||||||
|
|
||||||
:global(.dark) .language-btn:hover {
|
:global(.dark) .language-btn:hover {
|
||||||
box-shadow: 0 4px 12px rgba(59, 130, 246, 0.5);
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
|
||||||
|
border-color: var(--primary);
|
||||||
}
|
}
|
||||||
|
|
||||||
:global(.dark) :deep(.language-menu) {
|
:global(.dark) :deep(.language-menu) {
|
||||||
|
|
|
||||||
BIN
Frontend-Learner/public/flags/en.png
Normal file
BIN
Frontend-Learner/public/flags/en.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 23 KiB |
BIN
Frontend-Learner/public/flags/th.png
Normal file
BIN
Frontend-Learner/public/flags/th.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.5 KiB |
Loading…
Add table
Add a link
Reference in a new issue