167 lines
3.7 KiB
Vue
167 lines
3.7 KiB
Vue
<script setup>
|
|
import { ref, watch, onMounted } from "vue"
|
|
import { useRoute, useRouter } from "vue-router"
|
|
import { useMessage } from "naive-ui"
|
|
|
|
const message = useMessage()
|
|
const route = useRoute()
|
|
const router = useRouter()
|
|
|
|
const city = ref(route.params.region || 'moscow')
|
|
const cities = ref([])
|
|
|
|
const phone = "8 (800) 000-00-00"
|
|
const phoneRaw = "88000000000"
|
|
|
|
onMounted(async () => {
|
|
const res = await fetch('/api/regions')
|
|
const data = await res.json()
|
|
cities.value = data.map(r => ({ label: r.name, value: r.slug }))
|
|
})
|
|
|
|
// синхронизируем селектор при навигации (кнопка «назад» и т.п.)
|
|
watch(() => route.params.region, (val) => {
|
|
if (val && val !== city.value) city.value = val
|
|
})
|
|
|
|
// переходим на страницу выбранного региона
|
|
watch(city, (val) => {
|
|
if (val !== route.params.region) router.push(`/${val}`)
|
|
})
|
|
|
|
function handlePhoneClick() {
|
|
const isMobile = /Android|iPhone|iPad|iPod|Opera Mini|IEMobile|WPDesktop/i
|
|
.test(navigator.userAgent)
|
|
|
|
if (isMobile) {
|
|
window.location.href = `tel:${phoneRaw}`
|
|
} else {
|
|
navigator.clipboard.writeText(phone)
|
|
message.success("Номер скопирован")
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<header class="header">
|
|
<div class="inner">
|
|
|
|
<div class="col left">
|
|
<div class="logo">LOGO</div>
|
|
</div>
|
|
|
|
<div class="col center">
|
|
<div class="title">Удалённый бухгалтер</div>
|
|
<n-select
|
|
v-model:value="city"
|
|
:options="cities"
|
|
size="small"
|
|
class="city"
|
|
/>
|
|
</div>
|
|
|
|
<div class="col right">
|
|
<div
|
|
class="phone"
|
|
@click="handlePhoneClick"
|
|
title="Нажмите чтобы скопировать"
|
|
>
|
|
{{ phone }}
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
</header>
|
|
</template>
|
|
|
|
<style scoped>
|
|
|
|
.header {
|
|
padding: 26px 0;
|
|
background: linear-gradient(120deg, #ffd000, #ff7a00, #ff2a00);
|
|
background-size: 300% 300%;
|
|
animation: gradientMove 10s ease infinite, headerAppear .7s ease;
|
|
box-shadow: 0 8px 22px rgba(0,0,0,0.25);
|
|
}
|
|
|
|
@keyframes gradientMove {
|
|
0% { background-position: 0% 50%; }
|
|
50% { background-position: 100% 50%; }
|
|
100% { background-position: 0% 50%; }
|
|
}
|
|
|
|
@keyframes headerAppear {
|
|
from { opacity: 0; transform: translateY(-40px); }
|
|
to { opacity: 1; transform: translateY(0); }
|
|
}
|
|
|
|
.inner {
|
|
max-width: 1600px;
|
|
margin: 0 auto;
|
|
padding: 0 60px;
|
|
display: grid;
|
|
grid-template-columns: repeat(3,1fr);
|
|
align-items: center;
|
|
}
|
|
|
|
.col {
|
|
display: flex;
|
|
align-items: center;
|
|
}
|
|
|
|
.left { justify-content: flex-start; }
|
|
.center { flex-direction: column; text-align: center; }
|
|
.right { justify-content: flex-end; }
|
|
|
|
.logo {
|
|
font-size: 24px;
|
|
font-weight: 800;
|
|
letter-spacing: 1px;
|
|
color: black;
|
|
transition: transform .25s ease;
|
|
}
|
|
|
|
.logo:hover { transform: scale(1.08); }
|
|
|
|
.title {
|
|
font-size: 20px;
|
|
font-weight: 700;
|
|
color: black;
|
|
}
|
|
|
|
.city { margin-top: 8px; width: 190px; }
|
|
|
|
.phone {
|
|
font-weight: 700;
|
|
font-size: 18px;
|
|
color: black;
|
|
padding: 7px 16px;
|
|
border-radius: 12px;
|
|
background: rgba(255,255,255,0.35);
|
|
backdrop-filter: blur(8px);
|
|
border: 1px solid rgba(255,255,255,0.35);
|
|
cursor: pointer;
|
|
transition: all .25s ease;
|
|
}
|
|
|
|
.phone:hover {
|
|
background: rgba(255,255,255,0.6);
|
|
transform: translateY(-2px);
|
|
box-shadow: 0 4px 12px rgba(0,0,0,.2);
|
|
}
|
|
|
|
@media (max-width: 900px) {
|
|
.inner {
|
|
grid-template-columns: 1fr;
|
|
gap: 12px;
|
|
padding: 0 25px;
|
|
text-align: center;
|
|
}
|
|
.left, .right { justify-content: center; }
|
|
.logo { font-size: 22px; }
|
|
.title { font-size: 18px; }
|
|
.phone { font-size: 16px; }
|
|
}
|
|
|
|
</style>
|