generated from VLADIMIR/template_frontend
up
This commit is contained in:
@@ -6,6 +6,7 @@ import { useRouter } from 'vue-router'
|
|||||||
import { getAuthClient } from '@/api/auth_client'
|
import { getAuthClient } from '@/api/auth_client'
|
||||||
import type { Scenario } from '@/api/generated/crabs/evening_detective_server'
|
import type { Scenario } from '@/api/generated/crabs/evening_detective_server'
|
||||||
import HeaderMenu from '@/components/HeaderMenu.vue'
|
import HeaderMenu from '@/components/HeaderMenu.vue'
|
||||||
|
import SiteFooter from '@/components/SiteFooter.vue'
|
||||||
|
|
||||||
const client = getAuthClient()
|
const client = getAuthClient()
|
||||||
|
|
||||||
@@ -66,6 +67,7 @@ getScenarios()
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<SiteFooter />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<HeaderMenu active="catalog" />
|
<HeaderMenu active="catalog" />
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import { RouterLink } from 'vue-router'
|
|||||||
|
|
||||||
import { getAuthClient } from '@/api/auth_client'
|
import { getAuthClient } from '@/api/auth_client'
|
||||||
import HeaderText from '@/components/HeaderText.vue'
|
import HeaderText from '@/components/HeaderText.vue'
|
||||||
|
import SiteFooter from '@/components/SiteFooter.vue'
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
kind: 'terms' | 'privacy' | 'consent'
|
kind: 'terms' | 'privacy' | 'consent'
|
||||||
@@ -73,6 +74,7 @@ onMounted(async () => {
|
|||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<SiteFooter />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
+32
-12
@@ -1,11 +1,14 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { NButton } from 'naive-ui'
|
import { NButton } from 'naive-ui'
|
||||||
import { ref } from 'vue'
|
import { ref, watchPostEffect } from 'vue'
|
||||||
import { RouterLink } from 'vue-router'
|
import { RouterLink, useRoute } from 'vue-router'
|
||||||
|
|
||||||
import HeaderMenu from '@/components/HeaderMenu.vue'
|
import HeaderMenu from '@/components/HeaderMenu.vue'
|
||||||
import MessagePaper from '@/components/MessagePaper.vue'
|
import MessagePaper from '@/components/MessagePaper.vue'
|
||||||
|
import SiteFooter from '@/components/SiteFooter.vue'
|
||||||
|
|
||||||
|
const route = useRoute()
|
||||||
|
const homeScroll = ref<HTMLElement | null>(null)
|
||||||
const howItWorks = ref<HTMLElement | null>(null)
|
const howItWorks = ref<HTMLElement | null>(null)
|
||||||
|
|
||||||
const steps = [
|
const steps = [
|
||||||
@@ -23,13 +26,33 @@ const steps = [
|
|||||||
text: 'Сопоставьте факты и сформулируйте общее решение. Какая версия объясняет всё?',
|
text: 'Сопоставьте факты и сформулируйте общее решение. Какая версия объясняет всё?',
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
function scrollToHowItWorks() {
|
||||||
|
const container = homeScroll.value
|
||||||
|
const section = howItWorks.value
|
||||||
|
if (!container || !section) return
|
||||||
|
|
||||||
|
container.scrollTo({
|
||||||
|
top:
|
||||||
|
container.scrollTop +
|
||||||
|
section.getBoundingClientRect().top -
|
||||||
|
container.getBoundingClientRect().top -
|
||||||
|
parseFloat(getComputedStyle(section).scrollMarginTop),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
watchPostEffect(() => {
|
||||||
|
if (route.hash === '#how-it-works') {
|
||||||
|
scrollToHowItWorks()
|
||||||
|
}
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<HeaderMenu active="main" />
|
<HeaderMenu active="main" />
|
||||||
|
|
||||||
<main class="center-block-custom home-scroll">
|
<div ref="homeScroll" class="center-block-custom home-scroll">
|
||||||
<div class="width1200 home-content">
|
<main class="width1200 home-content">
|
||||||
<section class="hero" aria-labelledby="home-title">
|
<section class="hero" aria-labelledby="home-title">
|
||||||
<div class="hero-copy">
|
<div class="hero-copy">
|
||||||
<p class="eyebrow">Вечерний детектив · расследование своей компанией</p>
|
<p class="eyebrow">Вечерний детектив · расследование своей компанией</p>
|
||||||
@@ -44,11 +67,7 @@ const steps = [
|
|||||||
Выбрать дело
|
Выбрать дело
|
||||||
</n-button>
|
</n-button>
|
||||||
</RouterLink>
|
</RouterLink>
|
||||||
<n-button
|
<n-button size="large" secondary @click="scrollToHowItWorks">
|
||||||
size="large"
|
|
||||||
secondary
|
|
||||||
@click="howItWorks?.scrollIntoView({ block: 'start' })"
|
|
||||||
>
|
|
||||||
Как проходит игра
|
Как проходит игра
|
||||||
</n-button>
|
</n-button>
|
||||||
</div>
|
</div>
|
||||||
@@ -81,7 +100,7 @@ const steps = [
|
|||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section ref="howItWorks" class="how-it-works" aria-labelledby="how-title">
|
<section id="how-it-works" ref="howItWorks" class="how-it-works" aria-labelledby="how-title">
|
||||||
<div class="section-heading">
|
<div class="section-heading">
|
||||||
<p class="eyebrow">От первой улики до разгадки</p>
|
<p class="eyebrow">От первой улики до разгадки</p>
|
||||||
<h2 id="how-title">Как проходит игра</h2>
|
<h2 id="how-title">Как проходит игра</h2>
|
||||||
@@ -109,8 +128,9 @@ const steps = [
|
|||||||
</n-button>
|
</n-button>
|
||||||
</RouterLink>
|
</RouterLink>
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</main>
|
||||||
</main>
|
<SiteFooter @show-how-it-works="scrollToHowItWorks" />
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import { useRoute } from 'vue-router'
|
|||||||
import { getAuthClient } from '@/api/auth_client'
|
import { getAuthClient } from '@/api/auth_client'
|
||||||
import type { GameReview, Scenario } from '@/api/generated/crabs/evening_detective_server'
|
import type { GameReview, Scenario } from '@/api/generated/crabs/evening_detective_server'
|
||||||
import HeaderMenu from '@/components/HeaderMenu.vue'
|
import HeaderMenu from '@/components/HeaderMenu.vue'
|
||||||
|
import SiteFooter from '@/components/SiteFooter.vue'
|
||||||
|
|
||||||
const message = useMessage()
|
const message = useMessage()
|
||||||
const client = getAuthClient()
|
const client = getAuthClient()
|
||||||
@@ -94,6 +95,7 @@ getReviews(Number(scenarioId))
|
|||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
|
<SiteFooter />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<HeaderMenu active="catalog" />
|
<HeaderMenu active="catalog" />
|
||||||
|
|||||||
@@ -0,0 +1,92 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { RouterLink } from 'vue-router'
|
||||||
|
|
||||||
|
const emit = defineEmits<{ showHowItWorks: [] }>()
|
||||||
|
|
||||||
|
const year = new Date().getFullYear()
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<footer class="site-footer">
|
||||||
|
<div class="footer-content width1200">
|
||||||
|
<div class="footer-brand">
|
||||||
|
<RouterLink to="/" class="footer-name">Вечерний детектив</RouterLink>
|
||||||
|
<p>Расследования своей компанией</p>
|
||||||
|
<p class="copyright">© {{ year }} Вечерний детектив</p>
|
||||||
|
</div>
|
||||||
|
<nav aria-label="Навигация в подвале" class="footer-group">
|
||||||
|
<h2>Навигация</h2>
|
||||||
|
<RouterLink to="/catalog">Каталог дел</RouterLink>
|
||||||
|
<RouterLink to="/#how-it-works" @click="emit('showHowItWorks')">
|
||||||
|
Как проходит игра
|
||||||
|
</RouterLink>
|
||||||
|
</nav>
|
||||||
|
<div class="footer-group">
|
||||||
|
<h2>Связь</h2>
|
||||||
|
<a href="https://vk.ru/club231783859">Группа ВКонтакте</a>
|
||||||
|
</div>
|
||||||
|
<nav aria-label="Документы" class="footer-group">
|
||||||
|
<h2>Документы</h2>
|
||||||
|
<RouterLink to="/user-agreement">Пользовательское соглашение</RouterLink>
|
||||||
|
<RouterLink to="/privacy-policy">Политика конфиденциальности</RouterLink>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.site-footer {
|
||||||
|
border-top: 1px solid var(--vt-c-divider-dark-1);
|
||||||
|
color: var(--vt-c-text-dark-2);
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-content {
|
||||||
|
display: grid;
|
||||||
|
gap: 24px;
|
||||||
|
max-width: 100%;
|
||||||
|
padding: 32px 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-group {
|
||||||
|
align-items: flex-start;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-group h2,
|
||||||
|
.footer-brand .footer-name {
|
||||||
|
color: var(--vt-c-text-dark-1);
|
||||||
|
font-size: 15px;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.site-footer a {
|
||||||
|
color: inherit;
|
||||||
|
overflow-wrap: anywhere;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.site-footer a:hover {
|
||||||
|
color: var(--vt-c-text-dark-1);
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
.site-footer a:focus-visible {
|
||||||
|
outline: 2px solid var(--vt-c-text-dark-1);
|
||||||
|
outline-offset: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.copyright {
|
||||||
|
margin-top: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (width >= 1024px) {
|
||||||
|
.footer-content {
|
||||||
|
gap: 32px;
|
||||||
|
grid-template-columns: 1.2fr 1fr 1fr 1.2fr;
|
||||||
|
padding: 40px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
Reference in New Issue
Block a user