Rework admin panel and other
This commit is contained in:
@@ -60,7 +60,7 @@
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<a @click="this.removeCookieBvi()" href="#" class="hover:opacity-70 py-3 open-bvi ">
|
||||
<a @click="this.toggleBvi" href="#" class="hover:opacity-70 py-3 open-bvi ">
|
||||
<svg :class="!underSliderHeader ? 'text-white' : 'text-black'" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5"
|
||||
stroke="currentColor"
|
||||
class="w-6 h-6 duration-300 md:block hidden">
|
||||
@@ -72,7 +72,7 @@
|
||||
</a>
|
||||
|
||||
|
||||
<Link :href="route('client.schedule')" class="hover:opacity-70 py-3">
|
||||
<Link :href="route('client.schedule.index')" class="hover:opacity-70 py-3">
|
||||
<svg :class="!underSliderHeader ? 'text-white' : 'text-black'" xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"
|
||||
class="w-6 h-6 duration-300 md:block hidden">
|
||||
@@ -92,8 +92,22 @@
|
||||
<span :class="!underSliderHeader ? 'text-white' : 'text-black'" class="md:hidden">Поиск</span>
|
||||
</a>
|
||||
|
||||
<a class="hover:opacity-70 py-3 cursor-pointer" data-hs-overlay="#open-search-sveden-modal">
|
||||
|
||||
</div>
|
||||
|
||||
<svg :class="!underSliderHeader ? 'text-white' : 'text-black'" xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"
|
||||
class="w-6 h-6 duration-300 md:block hidden">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="m11.25 11.25.041-.02a.75.75 0 0 1 1.063.852l-.708 2.836a.75.75 0 0 0 1.063.853l.041-.021M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9-3.75h.008v.008H12V8.25Z" />
|
||||
</svg>
|
||||
|
||||
|
||||
<span :class="!underSliderHeader ? 'text-white' : 'text-black'" class="md:hidden">Поиск</span>
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -103,6 +117,7 @@
|
||||
import {Link} from "@inertiajs/vue3";
|
||||
import BasicIcon from "@/componentss/ui/icons/BasicIcon.vue";
|
||||
import {helpers} from "@/mixins/Helpers.js";
|
||||
import {mapActions} from "vuex";
|
||||
|
||||
|
||||
export default {
|
||||
@@ -122,11 +137,7 @@ export default {
|
||||
Link,
|
||||
},
|
||||
methods: {
|
||||
removeCookieBvi() {
|
||||
if (this.getCookie('bvi_panelActive') === 'true') {
|
||||
this.deleteCookiesWithPrefix('bvi')
|
||||
}
|
||||
}
|
||||
...mapActions(['toggleBvi'])
|
||||
},
|
||||
|
||||
|
||||
|
||||
@@ -1,184 +1,157 @@
|
||||
<template>
|
||||
<header :class="[
|
||||
{ 'header-filter': headerFilter },
|
||||
{ 'under-slider-bg': underSliderHeader },
|
||||
isBviActive ? 'static' : 'fixed top-0 left-0 right-0'
|
||||
]"
|
||||
class="flex duration-500 flex-wrap md:justify-start md:flex-nowrap z-50 w-full text-sm py-3 md:py-0">
|
||||
<nav class="max-w-screen-xl w-full mx-auto px-4 py-3" aria-label="Global">
|
||||
<div class="relative lg:flex md:items-center md:justify-between">
|
||||
<div class="flex items-center justify-between">
|
||||
<Link class="flex-none text-xl font-semibold"
|
||||
:href="route('index')" aria-label="NTSPI">
|
||||
<img :key="currentLogo" class="max-w-[300px] transition-all duration-300" :src="currentLogo" alt="Логотип">
|
||||
|
||||
|
||||
<header :class="[{ 'header-filter': headerFilter }, { 'under-slider-bg': underSliderHeader }]"
|
||||
class="flex duration-500 fixed top-0 left-0 right-0 flex-wrap md:justify-start md:flex-nowrap z-50 w-full text-sm py-3 md:py-0">
|
||||
<nav class="max-w-screen-xl w-full mx-auto px-4 py-3" aria-label="Global">
|
||||
<div class="relative lg:flex md:items-center md:justify-between">
|
||||
<div class="flex items-center justify-between">
|
||||
<Link class="flex-none text-xl font-semibold"
|
||||
:href="route('index')" aria-label="NTSPI">
|
||||
<transition name="logo" mode="out-in">
|
||||
<img :key="currentLogo" class="max-w-[300px] logo-transition" :src="currentLogo" alt="Логотип">
|
||||
</transition>
|
||||
</Link>
|
||||
<div class="lg:hidden">
|
||||
<button :class="{ 'text-black': underSliderHeader, 'text-white': !underSliderHeader }"
|
||||
type="button"
|
||||
id="open-mobile-btn"
|
||||
class="flex justify-center items-center w-9 h-9 text-sm font-semibold rounded-lg border border-gray-200 hover:bg-gray-100 hover:text-gray-800 disabled:opacity-50 disabled:pointer-events-none"
|
||||
aria-haspopup="dialog"
|
||||
aria-expanded="false"
|
||||
aria-controls="open-mobile-nav"
|
||||
data-hs-overlay="#open-mobile-nav"
|
||||
>
|
||||
<svg class="hs-collapse-open:hidden flex-shrink-0 w-4 h-4" xmlns="http://www.w3.org/2000/svg" width="24"
|
||||
height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
|
||||
stroke-linecap="round" stroke-linejoin="round">
|
||||
<line x1="3" x2="21" y1="6" y2="6"/>
|
||||
<line x1="3" x2="21" y1="12" y2="12"/>
|
||||
<line x1="3" x2="21" y1="18" y2="18"/>
|
||||
</svg>
|
||||
<svg class="hs-collapse-open:block hidden flex-shrink-0 w-4 h-4" xmlns="http://www.w3.org/2000/svg"
|
||||
width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
|
||||
stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M18 6 6 18"/>
|
||||
<path d="m6 6 12 12"/>
|
||||
</svg>
|
||||
</button>
|
||||
<div class="lg:hidden">
|
||||
<button :class="{ 'text-black border-gray-500': underSliderHeader, 'text-white border-gray-200': !underSliderHeader }"
|
||||
type="button"
|
||||
id="open-mobile-btn"
|
||||
class="flex justify-center items-center w-9 h-9 text-sm font-semibold rounded-lg border hover:bg-gray-100 hover:text-gray-800 disabled:opacity-50 disabled:pointer-events-none"
|
||||
aria-haspopup="dialog"
|
||||
aria-expanded="false"
|
||||
aria-controls="open-mobile-nav"
|
||||
data-hs-overlay="#open-mobile-nav">
|
||||
<svg class="hs-collapse-open:hidden flex-shrink-0 w-4 h-4" xmlns="http://www.w3.org/2000/svg" width="24"
|
||||
height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
|
||||
stroke-linecap="round" stroke-linejoin="round">
|
||||
<line x1="3" x2="21" y1="6" y2="6"/>
|
||||
<line x1="3" x2="21" y1="12" y2="12"/>
|
||||
<line x1="3" x2="21" y1="18" y2="18"/>
|
||||
</svg>
|
||||
<svg class="hs-collapse-open:block hidden flex-shrink-0 w-4 h-4" xmlns="http://www.w3.org/2000/svg"
|
||||
width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
|
||||
stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M18 6 6 18"/>
|
||||
<path d="m6 6 12 12"/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<DesktopNavBar v-if="sections" :sections="sections" :under-slider-header="underSliderHeader" />
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<DesktopNavBar v-if="sections" :sections="sections" :under-slider-header="underSliderHeader" />
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
|
||||
<MobileNavbar v-if="sections" :sections="sections" />
|
||||
|
||||
<SearchModal open_id="open-search-modal" />
|
||||
<MobileNavbar v-if="sections" :sections="sections" />
|
||||
<SearchModal open_id="open-search-modal">
|
||||
<ClientGlobalSearch :open_id="open_id" />
|
||||
</SearchModal>
|
||||
<SearchModal open_id="open-search-sveden-modal">
|
||||
<ClientStaticSearch :open_id="open_id" />
|
||||
</SearchModal>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import {Link} from "@inertiajs/vue3";
|
||||
import * as isvek from "bvi"
|
||||
import { Link } from "@inertiajs/vue3";
|
||||
import BasicIcon from "@/componentss/ui/icons/BasicIcon.vue";
|
||||
import MobileNavbar from "@/Navbars/MobileNavbar.vue";
|
||||
import DesktopNavBar from "@/Navbars/DesktopNavBar.vue";
|
||||
import {mapGetters} from "vuex";
|
||||
import { mapGetters, mapActions } from "vuex";
|
||||
import SearchModal from "@/componentss/shared/modals/SearchModal.vue";
|
||||
import {helpers} from "@/mixins/Helpers.js";
|
||||
|
||||
import { helpers } from "@/mixins/Helpers.js";
|
||||
import {defineAsyncComponent} from "vue";
|
||||
|
||||
export default {
|
||||
mixins: [helpers],
|
||||
name: 'MainPageNavBar',
|
||||
components: {
|
||||
DesktopNavBar,
|
||||
SearchModal,
|
||||
MobileNavbar,
|
||||
BasicIcon,
|
||||
Link,
|
||||
},
|
||||
props: {
|
||||
sections: {
|
||||
type: Object,
|
||||
},
|
||||
sliderRef: {
|
||||
default: true
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
scrollPosition: 0,
|
||||
headerFilter: false,
|
||||
underSliderHeader: true,
|
||||
bvi: null,
|
||||
isActiveBvi: null,
|
||||
logos: {
|
||||
default: '/logos/white_ntspi_logo.svg',
|
||||
alternate: '/logos/ntspi-logo.svg',
|
||||
},
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
iniBvi() {
|
||||
if (this.getCookie('bvi_panelActive') === null) {
|
||||
this.bvi = new isvek.Bvi({
|
||||
target: '.open-bvi',
|
||||
fontSize: 24,
|
||||
theme: 'black',
|
||||
speech: false,
|
||||
reload: true,
|
||||
panelHide: true
|
||||
});
|
||||
}
|
||||
},
|
||||
components: {
|
||||
DesktopNavBar,
|
||||
SearchModal,
|
||||
MobileNavbar,
|
||||
BasicIcon,
|
||||
Link,
|
||||
ClientGlobalSearch: defineAsyncComponent(() =>
|
||||
import('@/componentss/features/search/components/GlobalSearch.vue')
|
||||
),
|
||||
ClientStaticSearch: defineAsyncComponent(() =>
|
||||
import('@/componentss/features/search/components/StaticSearch.vue')
|
||||
),
|
||||
},
|
||||
props: {
|
||||
sections: {
|
||||
type: Object,
|
||||
},
|
||||
sliderRef: {
|
||||
default: true
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
scrollPosition: 0,
|
||||
headerFilter: false,
|
||||
underSliderHeader: true,
|
||||
logos: {
|
||||
default: '/logos/white_ntspi_logo.svg',
|
||||
alternate: '/logos/ntspi-logo.svg',
|
||||
},
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleScroll() {
|
||||
// Сохраняем текущую позицию прокрутки
|
||||
this.scrollPosition = window.pageYOffset;
|
||||
|
||||
// Проверяем, существует ли слайдер
|
||||
if (this.lastSlider) {
|
||||
const slider = this.lastSlider;
|
||||
|
||||
// Проверяем, совпадает ли текущий маршрут с маршрутом слайдера
|
||||
if (this.IS_SAME_ROUTE(slider.url)) {
|
||||
// Определяем, находится ли слайдер в области видимости
|
||||
const isSliderVisible = slider.top <= this.scrollPosition && slider.bottom >= this.scrollPosition;
|
||||
|
||||
// Если слайдер виден, underSliderHeader будет false, иначе true
|
||||
this.underSliderHeader = !isSliderVisible;
|
||||
}
|
||||
}
|
||||
|
||||
// Активируем фильтр заголовка, если прокрутка превышает 90 пикселей
|
||||
this.headerFilter = this.scrollPosition > 50;
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
lastSlider(newVal) {
|
||||
if (this.IS_SAME_ROUTE(newVal?.url)) {
|
||||
this.underSliderHeader = newVal.bottom < 0; // Пример логики
|
||||
}
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
window.addEventListener('scroll', this.handleScroll);
|
||||
|
||||
if (this.getCookie('bvi_panelActive') === null) {
|
||||
this.iniBvi();
|
||||
}
|
||||
},
|
||||
beforeDestroy() {
|
||||
window.removeEventListener('scroll', this.handleScroll);
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['lastSlider']),
|
||||
currentLogo() {
|
||||
return this.underSliderHeader ? this.logos.alternate : this.logos.default;
|
||||
},
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
lastSlider(newVal) {
|
||||
if (this.IS_SAME_ROUTE(newVal?.url)) {
|
||||
this.underSliderHeader = newVal.bottom < 0;
|
||||
}
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
window.addEventListener('scroll', this.handleScroll);
|
||||
this.initializeBvi();
|
||||
},
|
||||
beforeDestroy() {
|
||||
window.removeEventListener('scroll', this.handleScroll);
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['lastSlider', 'isBviActive']),
|
||||
currentLogo() {
|
||||
if (this.isBviActive) {
|
||||
return this.logos.default
|
||||
}
|
||||
return this.underSliderHeader ? this.logos.alternate : this.logos.default;
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.initializeBvi = mapActions(['initializeBvi']).initializeBvi;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
|
||||
.header-filter {
|
||||
transition: all 0.3s;
|
||||
backdrop-filter: saturate(180%) blur(7px);
|
||||
transition: all 0.3s;
|
||||
backdrop-filter: saturate(180%) blur(7px);
|
||||
}
|
||||
|
||||
.under-slider-bg {
|
||||
background: hsla(0,0%,100%,.6)
|
||||
background: hsla(0,0%,100%,.6);
|
||||
}
|
||||
|
||||
.logo-transition {
|
||||
transition: opacity 0.3s ease-out;
|
||||
}
|
||||
|
||||
.logo-enter, .logo-leave-to {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.logo-enter-to, .logo-leave {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
|
||||
</style>
|
||||
</style>
|
||||
@@ -59,7 +59,7 @@
|
||||
class="flex items-center gap-x-3 py-2 px-2.5 text-sm rounded-lg hover:bg-gray-[#EFEFEF] focus:outline-none focus:bg-gray-100"
|
||||
:class="(IS_SAME_ROUTE(page.path) ? 'text-blue-600 bg-white border border-[#E4E4E7]' : 'text-gray-700')"
|
||||
>
|
||||
<BasicIcon class="w-4" :name="page.icon" />
|
||||
<BasicIcon v-if="page.icon" class="w-4" :name="page.icon" />
|
||||
{{ page.title }}
|
||||
</a>
|
||||
</li>
|
||||
@@ -72,8 +72,8 @@
|
||||
|
||||
|
||||
<li class="">
|
||||
<Link :href="route('client.schedule')"
|
||||
:class="(IS_SAME_ROUTE(route('client.schedule')) ? 'text-blue-600 bg-white border border-[#E4E4E7]' : 'text-gray-700')"
|
||||
<Link :href="route('client.schedule.index')"
|
||||
:class="(IS_SAME_ROUTE(route('client.schedule.index')) ? 'text-blue-600 bg-white border border-[#E4E4E7]' : 'text-gray-700')"
|
||||
class="flex items-center gap-x-3 py-2 px-2.5 text-sm rounded-lg hover:bg-gray-100 dark:hover:bg-neutral-700 dark:text-neutral-400 dark:hover:text-neutral-300" href="#">
|
||||
<BasicIcon class="w-4" name="schedule" />
|
||||
Расписание
|
||||
|
||||
Reference in New Issue
Block a user