186 lines
5.3 KiB
Vue
186 lines
5.3 KiB
Vue
<template>
|
|
<q-layout view="lHr lpr lFr" class="bg-transparent">
|
|
<q-header class="main-content text-grey glass">
|
|
<div ref="headerContainer" class="flex q-ma-md justify-between no-wrap items-center">
|
|
<base-logo ref="logo" class="text-h6"/>
|
|
<div
|
|
ref="menuContainer"
|
|
class="row items-center q-ml-md no-wrap"
|
|
style="min-width: 42px"
|
|
>
|
|
<div
|
|
ref="buttonsContainer"
|
|
:class="{ 'invisible absolute': !showFullMenu }"
|
|
class="flex row no-wrap"
|
|
>
|
|
<q-btn
|
|
v-for="item in menuItems"
|
|
:key="item.id"
|
|
flat
|
|
no-caps
|
|
@click="scrollToElement(item.ref)"
|
|
ref="menuButtons"
|
|
>
|
|
<span class="text-no-wrap">{{ $t(item.title) }}</span>
|
|
</q-btn>
|
|
</div>
|
|
<q-btn
|
|
v-if="!showFullMenu"
|
|
flat
|
|
round
|
|
icon="menu"
|
|
@click="showDrawer = !showDrawer"
|
|
/>
|
|
<q-btn outline color="primary" class="q-ml-sm">
|
|
<div class="flex items-center no-wrap">
|
|
<span class="text-bold">{{ locale.split('-')[0] }}</span>
|
|
</div>
|
|
|
|
<q-menu>
|
|
<q-list style="min-width: 100px">
|
|
<q-item
|
|
v-for="lang in langNames"
|
|
:key="lang"
|
|
clickable
|
|
v-close-popup
|
|
@click="setLocale(lang)"
|
|
>
|
|
<q-item-section>
|
|
<q-item-label :class="isCurrentLang(lang.locale) ? 'text-primary' : ''">{{ lang.label }}</q-item-label>
|
|
</q-item-section>
|
|
</q-item>
|
|
</q-list>
|
|
</q-menu>
|
|
</q-btn>
|
|
</div>
|
|
<q-resize-observer @resize="checkSpace"/>
|
|
</div>
|
|
</q-header>
|
|
|
|
<q-drawer v-model="showDrawer" side="right" overlay>
|
|
<div class="flex column items-end q-gutter-y-md q-pa-md">
|
|
<q-btn
|
|
flat
|
|
round
|
|
icon="mdi-close"
|
|
@click="showDrawer = !showDrawer"
|
|
/>
|
|
<q-btn
|
|
v-for="item in menuItems"
|
|
:key="item.id"
|
|
flat
|
|
no-caps
|
|
@click="scrollToElement(item.ref)"
|
|
>
|
|
<span class="text-no-wrap text-h6">{{ $t(item.title) }}</span>
|
|
</q-btn>
|
|
</div>
|
|
</q-drawer>
|
|
|
|
<q-page-container
|
|
class="main-content q-pa-none q-ma-none bg-transparent"
|
|
>
|
|
<q-page class="column">
|
|
<hero-banner/>
|
|
<problem-section/>
|
|
<how-works-section id='how_works'/>
|
|
<price-section id='price'/>
|
|
<faq-section id='FAQ'/>
|
|
<footer-section id='contacts'/>
|
|
</q-page>
|
|
</q-page-container>
|
|
</q-layout>
|
|
|
|
</template>
|
|
|
|
<script setup>
|
|
import { ref, onMounted, nextTick } from 'vue'
|
|
import baseLogo from 'components/BaseLogo.vue'
|
|
import heroBanner from 'components/HeroBanner.vue'
|
|
import problemSection from 'components/ProblemSection.vue'
|
|
import HowWorksSection from 'components/HowWorksSection.vue'
|
|
import PriceSection from 'components/PriceSection.vue'
|
|
import FaqSection from 'components/FAQSection.vue'
|
|
import FooterSection from 'components/FooterSection.vue'
|
|
|
|
const showDrawer = ref(false)
|
|
|
|
const menuItems = [
|
|
{ id: 0, title: 'main__how_it_works', ref: 'how_works' },
|
|
{ id: 1, title: 'main__price', ref: 'price' },
|
|
{ id: 2, title: 'main__faq', ref: 'FAQ' },
|
|
{ id: 3, title: 'main__contacts', ref: 'contacts' }
|
|
]
|
|
|
|
const showFullMenu = ref(true)
|
|
const menuButtons = ref([])
|
|
const headerContainer = ref(null)
|
|
const logo = ref(null)
|
|
const menuContainer = ref(null)
|
|
|
|
const calculateButtonsWidth = () => {
|
|
return menuButtons.value.reduce(
|
|
(total, btn) => total + (btn?.$el.offsetWidth || 0), 0
|
|
)
|
|
}
|
|
|
|
const checkSpace = () => {
|
|
if (!headerContainer.value || !logo.value || !menuContainer.value) return
|
|
|
|
const headerWidth = headerContainer.value.offsetWidth
|
|
const logoWidth = logo.value.$el.offsetWidth
|
|
const menuMargin = parseFloat(getComputedStyle(menuContainer.value).marginLeft) || 0
|
|
const availableWidth = headerWidth - logoWidth - menuMargin - 40 // 40px - запас
|
|
|
|
const buttonsWidth = calculateButtonsWidth()
|
|
|
|
showFullMenu.value = buttonsWidth <= availableWidth
|
|
}
|
|
|
|
onMounted(async () => {
|
|
await nextTick()
|
|
checkSpace()
|
|
})
|
|
|
|
|
|
import { scroll } from 'quasar'
|
|
const { getScrollTarget, setVerticalScrollPosition } = scroll
|
|
|
|
const scrollToElement = (id) => {
|
|
const el = document.querySelector('#' + id)
|
|
const target = getScrollTarget(el)
|
|
const offset = el.offsetTop - 12
|
|
const duration = 300
|
|
setVerticalScrollPosition(target, offset, duration)
|
|
showDrawer.value = false
|
|
}
|
|
|
|
import { useI18n } from 'vue-i18n'
|
|
import { setGlobalLocale } from 'src/boot/i18n'
|
|
|
|
const { locale } = useI18n({ useScope: 'global' })
|
|
const langNames = [
|
|
{ locale: 'en-US', label: 'English'},
|
|
{ locale: 'ru-RU', label: 'Русский'}
|
|
]
|
|
|
|
const isCurrentLang = (lang) => locale.value === lang
|
|
|
|
const setLocale = (newLocale) => {
|
|
setGlobalLocale(newLocale.locale)
|
|
}
|
|
|
|
</script>
|
|
|
|
<style scoped>
|
|
.invisible {
|
|
opacity: 0;
|
|
pointer-events: none;
|
|
}
|
|
|
|
.glass {
|
|
background-color: rgba(255, 255, 255, 0.8) !important;
|
|
backdrop-filter: blur(8px);
|
|
}
|
|
</style>
|