Files
webapp/app/components/AppLocaleCurrencySelector.vue
2026-04-21 10:34:54 +07:00

108 lines
3.6 KiB
Vue

<script setup lang="ts">
import type { AppLocale } from '~/composables/useLocaleCurrency'
const {
locale,
currency,
localeOptions,
currencyOptions,
languageCode,
currencyCode,
ratesProviderUrl,
setLocale,
setCurrency,
t,
} = useLocaleCurrency()
const isOpen = ref(false)
const switchLocalePath = useSwitchLocalePath()
function closeSelector() {
isOpen.value = false
}
async function changeLocale(code: AppLocale) {
const nextPath = switchLocalePath(code)
await setLocale(code)
if (nextPath) {
await navigateTo(nextPath)
}
}
</script>
<template>
<div class="relative">
<button
type="button"
class="btn h-11 min-h-0 gap-2 rounded-full border-0 bg-transparent px-3 text-xs font-black uppercase tracking-[0.08em] shadow-none transition hover:bg-white/70"
:aria-label="t('settings.open')"
:aria-expanded="String(isOpen)"
@click="isOpen = !isOpen"
>
<svg viewBox="0 0 24 24" fill="none" class="h-4 w-4" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
<circle cx="12" cy="12" r="10" />
<path d="M2 12h20" />
<path d="M12 2a15.3 15.3 0 0 1 0 20" />
<path d="M12 2a15.3 15.3 0 0 0 0 20" />
</svg>
<span>{{ languageCode }} · {{ currencyCode }}</span>
</button>
<div
v-if="isOpen"
class="absolute left-0 top-[calc(100%+0.7rem)] z-[110] w-[292px] rounded-[28px] bg-[#f3eee6] p-3 text-[#2f2418] shadow-[0_24px_60px_rgba(35,30,25,0.22)]"
>
<div class="rounded-[22px] bg-white p-3">
<p class="px-2 text-[11px] font-black uppercase tracking-[0.16em] text-[#8a7761]">{{ t('settings.language') }}</p>
<div class="mt-2 grid grid-cols-2 gap-1.5">
<button
v-for="item in localeOptions"
:key="item.code"
type="button"
class="rounded-2xl px-3 py-2 text-left text-sm font-bold transition"
:class="locale === item.code ? 'bg-[#2f2418] text-white' : 'bg-[#f6f1ea] text-[#5f4b33] hover:bg-[#eee6dc]'"
@click="changeLocale(item.code)"
>
<span class="block">{{ item.nativeLabel }}</span>
<span class="mt-0.5 block text-[11px] opacity-65">{{ item.label }}</span>
</button>
</div>
</div>
<div class="mt-2 rounded-[22px] bg-white p-3">
<p class="px-2 text-[11px] font-black uppercase tracking-[0.16em] text-[#8a7761]">{{ t('settings.currency') }}</p>
<div class="mt-2 grid grid-cols-2 gap-1.5">
<button
v-for="item in currencyOptions"
:key="item.code"
type="button"
class="rounded-2xl px-3 py-2 text-left text-sm font-bold transition"
:class="currency === item.code ? 'bg-[#2f2418] text-white' : 'bg-[#f6f1ea] text-[#5f4b33] hover:bg-[#eee6dc]'"
@click="setCurrency(item.code)"
>
<span class="block">{{ item.code }}</span>
<span class="mt-0.5 block text-[11px] opacity-65">{{ item.symbol }} · {{ item.label }}</span>
</button>
</div>
</div>
<button
type="button"
class="mt-2 h-10 w-full rounded-full bg-[#2f2418] text-sm font-black text-white transition hover:bg-[#493823]"
@click="closeSelector"
>
{{ t('settings.apply') }}
</button>
<a
:href="ratesProviderUrl"
target="_blank"
rel="noopener noreferrer"
class="mt-2 block px-2 text-center text-[10px] font-bold uppercase tracking-[0.12em] text-[#8a7761] transition hover:text-[#2f2418]"
>
{{ t('settings.ratesBy') }}
</a>
</div>
</div>
</template>