Rework frontend
This commit is contained in:
@@ -40,7 +40,7 @@
|
||||
</div>
|
||||
<template v-for="page in subsection.pages" :key="page.id">
|
||||
<a
|
||||
:class="{ 'text-[#135aae] hover:text-gray-800 font-semibold': isSameRoute(page.path), 'text-gray-800 hover:text-[#2C6288]': !isSameRoute(page.path) }"
|
||||
:class="{ 'text-[#135aae] hover:text-gray-800 font-semibold': IS_SAME_ROUTE(page.path), 'text-gray-800 hover:text-[#2C6288]': !IS_SAME_ROUTE(page.path) }"
|
||||
class="flex items-center gap-x-2"
|
||||
:href="(page.is_url) ? page.path : route('page.view', page.path) + '/'">
|
||||
<div class="grow">
|
||||
@@ -101,13 +101,13 @@
|
||||
<script>
|
||||
|
||||
import {Link} from "@inertiajs/vue3";
|
||||
import BaseIcon from "@/Components/BaseComponents/BaseIcon.vue";
|
||||
import jsonIcons from "@/Components/other/icons.json";
|
||||
import {defineAsyncComponent} from "vue";
|
||||
import BasicIcon from "@/componentss/ui/icons/BasicIcon.vue";
|
||||
import {helpers} from "@/mixins/Helpers.js";
|
||||
|
||||
|
||||
export default {
|
||||
name: 'DesktopNavBar',
|
||||
mixins: [helpers],
|
||||
name: 'DesktopNavBar',
|
||||
props: {
|
||||
sections: {
|
||||
type: Object,
|
||||
@@ -116,55 +116,12 @@ export default {
|
||||
}
|
||||
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
icons: jsonIcons,
|
||||
}
|
||||
},
|
||||
|
||||
components: {
|
||||
BaseIcon,
|
||||
ClientGlobalSearch: defineAsyncComponent(() =>
|
||||
import('@/Components/ClientGlobalSearch.vue')
|
||||
),
|
||||
BasicIcon,
|
||||
Link,
|
||||
},
|
||||
methods: {
|
||||
isSameRoute(route) {
|
||||
if (route === this.$page.props.ziggy.location) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const currentLocation = this.$page.props.ziggy.location;
|
||||
const currentUrl = this.$page.props.ziggy.url + '/' + route;
|
||||
|
||||
if (currentLocation === currentUrl) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
hasActivePage(section) {
|
||||
// Проверяем, есть ли активная страница в секции или подсекции
|
||||
// if (!section || !section.pages) return false; // Проверка на наличие section и pages
|
||||
|
||||
if (section.pages) {
|
||||
return section.pages.some(page => this.isSameRoute(page.path));
|
||||
}
|
||||
|
||||
if (section.subSections) {
|
||||
return section.subSections.some(subSection => this.hasActivePage(subSection));
|
||||
}
|
||||
|
||||
|
||||
|
||||
// // Проверяем наличие активной страницы в подсекциях
|
||||
// const hasActiveInSubSections = section.subSections && section.subSections.some(subSection => this.hasActivePage(subSection));
|
||||
//
|
||||
// console.log(hasActiveInSubSections)
|
||||
//
|
||||
//
|
||||
// return hasActiveInPages || hasActiveInSubSections;
|
||||
},
|
||||
removeCookieBvi() {
|
||||
if (this.getCookie('bvi_panelActive') === 'true') {
|
||||
this.deleteCookiesWithPrefix('bvi')
|
||||
|
||||
@@ -58,12 +58,11 @@
|
||||
<script>
|
||||
|
||||
import {Link} from "@inertiajs/vue3";
|
||||
import axios from "axios";
|
||||
import BaseIcon from "@/Components/BaseComponents/BaseIcon.vue";
|
||||
import MobileNavbar from "@/Navbars/MobileNavbar.vue";
|
||||
import SearchModal from "@/Components/Modals/SearchModal.vue";
|
||||
import {defineAsyncComponent} from "vue";
|
||||
import DesktopNavBar from "@/Navbars/DesktopNavBar.vue";
|
||||
import SearchModal from "@/componentss/shared/modals/SearchModal.vue";
|
||||
import BasicIcon from "@/componentss/ui/icons/BasicIcon.vue";
|
||||
|
||||
|
||||
export default {
|
||||
@@ -81,10 +80,7 @@ export default {
|
||||
DesktopNavBar,
|
||||
SearchModal,
|
||||
MobileNavbar,
|
||||
BaseIcon,
|
||||
ClientGlobalSearch: defineAsyncComponent(() =>
|
||||
import('@/Components/ClientGlobalSearch.vue')
|
||||
),
|
||||
BasicIcon,
|
||||
Link,
|
||||
},
|
||||
methods: {
|
||||
@@ -96,11 +92,7 @@ export default {
|
||||
const currentLocation = this.$page.props.ziggy.location;
|
||||
const currentUrl = this.$page.props.ziggy.url + '/' + route;
|
||||
|
||||
if (currentLocation === currentUrl) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
return currentLocation === currentUrl;
|
||||
},
|
||||
hasActivePage(section) {
|
||||
// Проверяем, есть ли активная страница в секции или подсекции
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
<template>
|
||||
|
||||
<header :style=" underSliderHeader ? 'background: hsla(0,0%,100%,.6)' : '' "
|
||||
:class="{ 'header-filter': headerFilter }"
|
||||
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">
|
||||
<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 dark:text-white dark:focus:outline-none dark:focus:ring-1 dark:focus:ring-gray-600"
|
||||
<Link class="flex-none text-xl font-semibold"
|
||||
:href="route('index')" aria-label="NTSPI">
|
||||
<img class="max-w-[300px] duration-300" :src="currentLogo" alt="Логотип">
|
||||
</Link>
|
||||
<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="underSliderHeader ? 'text-black' : 'text-white'"
|
||||
<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"
|
||||
@@ -54,23 +55,23 @@
|
||||
<script>
|
||||
|
||||
import {Link} from "@inertiajs/vue3";
|
||||
import ClientGlobalSearch from "@/Components/ClientGlobalSearch.vue";
|
||||
import * as isvek from "bvi"
|
||||
import BaseIcon from "@/Components/BaseComponents/BaseIcon.vue";
|
||||
import BasicIcon from "@/componentss/ui/icons/BasicIcon.vue";
|
||||
import MobileNavbar from "@/Navbars/MobileNavbar.vue";
|
||||
import SearchModal from "@/Components/Modals/SearchModal.vue";
|
||||
import DesktopNavBar from "@/Navbars/DesktopNavBar.vue";
|
||||
import {mapGetters} from "vuex";
|
||||
import SearchModal from "@/componentss/shared/modals/SearchModal.vue";
|
||||
import {helpers} from "@/mixins/Helpers.js";
|
||||
|
||||
|
||||
export default {
|
||||
name: 'MainPageNavBar',
|
||||
mixins: [helpers],
|
||||
name: 'MainPageNavBar',
|
||||
components: {
|
||||
DesktopNavBar,
|
||||
SearchModal,
|
||||
MobileNavbar,
|
||||
BaseIcon,
|
||||
ClientGlobalSearch,
|
||||
BasicIcon,
|
||||
Link,
|
||||
},
|
||||
props: {
|
||||
@@ -95,22 +96,6 @@ export default {
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
isSameRoute(route) {
|
||||
if (route === this.$page.props.ziggy.location) {
|
||||
return true;
|
||||
}
|
||||
const currentLocation = this.$page.props.ziggy.location;
|
||||
const currentUrl = this.$page.props.ziggy.url + '/' + route;
|
||||
return currentLocation === currentUrl;
|
||||
},
|
||||
hasActivePage(section) {
|
||||
if (section.pages) {
|
||||
return section.pages.some(page => this.isSameRoute(page.path));
|
||||
}
|
||||
if (section.subSections) {
|
||||
return section.subSections.some(subSection => this.hasActivePage(subSection));
|
||||
}
|
||||
},
|
||||
iniBvi() {
|
||||
if (this.getCookie('bvi_panelActive') === null) {
|
||||
this.bvi = new isvek.Bvi({
|
||||
@@ -123,22 +108,31 @@ export default {
|
||||
});
|
||||
}
|
||||
},
|
||||
handleScroll() {
|
||||
if (this.lastSlider) {
|
||||
const slider = this.lastSlider;
|
||||
this.scrollPosition = window.pageYOffset;
|
||||
if (this.isSameRoute(slider.url)) {
|
||||
this.underSliderHeader = slider.bottom < this.scrollPosition;
|
||||
}
|
||||
this.headerFilter = this.scrollPosition > 90;
|
||||
} else {
|
||||
this.headerFilter = true;
|
||||
}
|
||||
},
|
||||
},
|
||||
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.isSameRoute(newVal?.url)) {
|
||||
if (this.IS_SAME_ROUTE(newVal?.url)) {
|
||||
this.underSliderHeader = newVal.bottom < 0; // Пример логики
|
||||
}
|
||||
},
|
||||
@@ -170,5 +164,21 @@ export default {
|
||||
backdrop-filter: saturate(180%) blur(7px);
|
||||
}
|
||||
|
||||
.under-slider-bg {
|
||||
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>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<li>
|
||||
<Link
|
||||
:href="route('index')"
|
||||
:class="(isSameRoute(route('index')) ? 'text-blue-600 bg-white border border-[#E4E4E7]' : 'text-gray-700')"
|
||||
:class="(IS_SAME_ROUTE(route('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-[#EFEFEF]" href="#">
|
||||
<svg class="size-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="m3 9 9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/><polyline points="9 22 9 12 15 12 15 22"/></svg>
|
||||
Главная
|
||||
@@ -28,10 +28,10 @@
|
||||
<li v-for="section in sections.data" class="hs-accordion" :id="'nav-section-accordion-' + section.slug">
|
||||
<button
|
||||
:id="'nav-section-accordion-btn-' + section.slug"
|
||||
:class="(hasActivePage(section) ? 'text-blue-600 bg-gray-100' : 'text-gray-700')"
|
||||
:class="(HAS_ACTIVE_PAGE(section) ? 'text-blue-600 bg-gray-100' : 'text-gray-700')"
|
||||
type="button"
|
||||
class="hs-accordion-toggle hs-accordion-active:text-blue-600 w-full text-start flex items-center gap-x-3 py-2 px-2.5 text-sm rounded-lg focus:outline-none" aria-expanded="true" aria-controls="users-accordion">
|
||||
<BaseIcon class="w-4" name="line" />
|
||||
<BasicIcon class="w-4" name="line" />
|
||||
{{ section.title }}
|
||||
<svg class="flex-shrink-0 hs-accordion-active:block ms-auto hidden size-4 text-gray-600 group-hover:text-gray-500" 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 15-6-6-6 6"/></svg>
|
||||
<svg class="flex-shrink-0 hs-accordion-active:hidden ms-auto block size-4 text-gray-600 group-hover:text-gray-500" 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="m6 9 6 6 6-6"/></svg>
|
||||
@@ -41,7 +41,7 @@
|
||||
<li v-for="subSection in section.subSections" class="hs-accordion" :id="'nav-sub-section-accordion-' + subSection.slug">
|
||||
<button
|
||||
:id="'nav-sub-section-accordion-btn-' + subSection.slug"
|
||||
:class="(hasActivePage(subSection) ? 'text-blue-600 bg-gray-100' : 'text-gray-700')"
|
||||
:class="(HAS_ACTIVE_PAGE(subSection) ? 'text-blue-600 bg-gray-100' : 'text-gray-700')"
|
||||
type="button"
|
||||
class="hs-accordion-toggle hs-accordion-active:text-blue-600 w-full text-start flex items-center gap-x-3 py-2 px-2.5 text-sm rounded-lg focus:outline-none " aria-expanded="true" :aria-controls="'nav-accordion-' + subSection.slug">
|
||||
{{ subSection.title }}
|
||||
@@ -57,9 +57,9 @@
|
||||
<a
|
||||
:href="(page.is_url) ? page.path : route('page.view', page.path) + '/'"
|
||||
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="(isSameRoute(page.path) ? 'text-blue-600 bg-white border border-[#E4E4E7]' : 'text-gray-700')"
|
||||
:class="(IS_SAME_ROUTE(page.path) ? 'text-blue-600 bg-white border border-[#E4E4E7]' : 'text-gray-700')"
|
||||
>
|
||||
<BaseIcon class="w-4" :name="page.icon" />
|
||||
<BasicIcon class="w-4" :name="page.icon" />
|
||||
{{ page.title }}
|
||||
</a>
|
||||
</li>
|
||||
@@ -73,22 +73,22 @@
|
||||
|
||||
<li class="">
|
||||
<Link :href="route('client.schedule')"
|
||||
:class="(isSameRoute(route('client.schedule')) ? 'text-blue-600 bg-white border border-[#E4E4E7]' : 'text-gray-700')"
|
||||
:class="(IS_SAME_ROUTE(route('client.schedule')) ? '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="#">
|
||||
<BaseIcon class="w-4" name="schedule" />
|
||||
<BasicIcon class="w-4" name="schedule" />
|
||||
Расписание
|
||||
</Link>
|
||||
</li>
|
||||
<li>
|
||||
<a class="flex items-center gap-x-3 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:hover:bg-neutral-700 dark:text-neutral-400 dark:hover:text-neutral-300" href="#">
|
||||
<BaseIcon class="w-4" name="eye" />
|
||||
<BasicIcon class="w-4" name="eye" />
|
||||
Режим для слабовидящих
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a aria-haspopup="dialog" aria-expanded="false" aria-controls="hs-full-screen-modal-below-md" data-hs-overlay="#open-search-modal"
|
||||
class="flex items-center gap-x-3 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:hover:bg-neutral-700 dark:text-neutral-400 dark:hover:text-neutral-300" href="#">
|
||||
<BaseIcon class="w-4" name="search" />
|
||||
<BasicIcon class="w-4" name="search" />
|
||||
Поиск
|
||||
</a>
|
||||
</li>
|
||||
@@ -97,96 +97,32 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import {Link} from "@inertiajs/vue3";
|
||||
import BaseIcon from "@/Components/BaseComponents/BaseIcon.vue";
|
||||
import jsonIcons from "@/Components/other/icons.json";
|
||||
import {defineAsyncComponent} from "vue";
|
||||
import BasicIcon from "@/componentss/ui/icons/BasicIcon.vue";
|
||||
import {helpers} from "@/mixins/Helpers.js";
|
||||
|
||||
|
||||
export default {
|
||||
name: 'MobileNavbar',
|
||||
props: {
|
||||
mixins: [helpers],
|
||||
props: {
|
||||
sections: {
|
||||
type: Object,
|
||||
}
|
||||
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
icons: jsonIcons,
|
||||
}
|
||||
},
|
||||
components: {
|
||||
BaseIcon,
|
||||
ClientGlobalSearch: defineAsyncComponent(() =>
|
||||
import('@/Components/ClientGlobalSearch.vue')
|
||||
),
|
||||
BasicIcon,
|
||||
Link,
|
||||
},
|
||||
methods: {
|
||||
isSameRoute(route) {
|
||||
if (route === this.$page.props.ziggy.location) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const currentLocation = this.$page.props.ziggy.location;
|
||||
const currentUrl = this.$page.props.ziggy.url + '/' + route;
|
||||
|
||||
if (currentLocation === currentUrl) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
hasActivePage(section) {
|
||||
// Проверяем, есть ли активная страница в секции или подсекции
|
||||
// if (!section || !section.pages) return false; // Проверка на наличие section и pages
|
||||
|
||||
if (section.pages) {
|
||||
return section.pages.some(page => this.isSameRoute(page.path));
|
||||
}
|
||||
|
||||
if (section.subSections) {
|
||||
return section.subSections.some(subSection => this.hasActivePage(subSection));
|
||||
}
|
||||
|
||||
|
||||
|
||||
// // Проверяем наличие активной страницы в подсекциях
|
||||
// const hasActiveInSubSections = section.subSections && section.subSections.some(subSection => this.hasActivePage(subSection));
|
||||
//
|
||||
// console.log(hasActiveInSubSections)
|
||||
//
|
||||
//
|
||||
// return hasActiveInPages || hasActiveInSubSections;
|
||||
},
|
||||
},
|
||||
|
||||
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
.header-filter {
|
||||
transition: all 0.3s;
|
||||
backdrop-filter: saturate(180%) blur(7px);
|
||||
background: hsla(0, 0%, 100%, .6);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user