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)
|
||||
const currentLocaleDisplay = computed(() => {
|
||||
return locale.value.toUpperCase()
|
||||
})
|
||||
// Get flag image path for a locale
|
||||
const getFlagPath = (code: string) => `/flags/${code}.png`
|
||||
|
||||
// Handle locale change
|
||||
const changeLocale = async (code: string) => {
|
||||
|
|
@ -34,14 +32,19 @@ const changeLocale = async (code: string) => {
|
|||
class="language-btn"
|
||||
: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
|
||||
anchor="bottom right"
|
||||
self="top right"
|
||||
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);">
|
||||
{{ $t('language.label') }}
|
||||
</q-item-label>
|
||||
|
|
@ -56,7 +59,11 @@ const changeLocale = async (code: string) => {
|
|||
class="language-item"
|
||||
>
|
||||
<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-label class="font-semibold" style="color: var(--text-primary);">
|
||||
|
|
@ -81,21 +88,33 @@ const changeLocale = async (code: string) => {
|
|||
.language-btn {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
background: linear-gradient(135deg, var(--primary) 0%, #2f5ed7 100%);
|
||||
color: white;
|
||||
background: #ffffff;
|
||||
border: 2px solid var(--border-color);
|
||||
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 {
|
||||
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 {
|
||||
font-size: 12px;
|
||||
font-weight: 800;
|
||||
letter-spacing: 0.5px;
|
||||
.flag-icon {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
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 {
|
||||
|
|
@ -120,12 +139,14 @@ const changeLocale = async (code: string) => {
|
|||
}
|
||||
|
||||
:global(.dark) .language-btn {
|
||||
background: linear-gradient(135deg, #3b82f6 0%, #1e40af 100%);
|
||||
box-shadow: 0 2px 8px rgba(59, 130, 246, 0.4);
|
||||
background: #1e293b;
|
||||
border-color: rgba(255, 255, 255, 0.15);
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
: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) {
|
||||
|
|
|
|||
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