Changes
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="w-full h-[67px] fixed pointer-events-none" id="visor"></div>
|
||||
<div class="w-full h-[67px] fixed pointer-events-none bvi-no-styles" id="visor"></div>
|
||||
|
||||
<nav class="order-last hidden w-56 shrink-0 lg:block">
|
||||
<div v-if="headerNavs.length > 0" class="sticky top-[100px] h-[calc(100vh-121px)]">
|
||||
|
||||
@@ -45,8 +45,18 @@ export default {
|
||||
methods: {
|
||||
filter: debounce(function () {
|
||||
let url = new URL(window.location.href);
|
||||
// Создаем массив для хранения всех ключей, которые нужно удалить
|
||||
const keysToDelete = [];
|
||||
|
||||
// Перебираем все параметры и добавляем ключи, начинающиеся с 'category', в массив
|
||||
for (const [key] of url.searchParams) {
|
||||
if (key.startsWith('direction')) {
|
||||
keysToDelete.push(key);
|
||||
}
|
||||
}
|
||||
// Удаляем все ключи из массива
|
||||
keysToDelete.forEach(key => url.searchParams.delete(key));
|
||||
url.searchParams.delete('page');
|
||||
url.searchParams.delete('direction[]');
|
||||
let newUrl = url.toString();
|
||||
this.$inertia.visit(newUrl, {
|
||||
method: 'get',
|
||||
@@ -58,9 +68,18 @@ export default {
|
||||
}, 500),
|
||||
clearFilter() {
|
||||
let url = new URL(window.location.href);
|
||||
url.searchParams.delete('direction[]');
|
||||
// Создаем массив для хранения всех ключей, которые нужно удалить
|
||||
const keysToDelete = [];
|
||||
|
||||
// Перебираем все параметры и добавляем ключи, начинающиеся с 'category', в массив
|
||||
for (const [key] of url.searchParams) {
|
||||
if (key.startsWith('direction')) {
|
||||
keysToDelete.push(key);
|
||||
}
|
||||
}
|
||||
// Удаляем все ключи из массива
|
||||
keysToDelete.forEach(key => url.searchParams.delete(key));
|
||||
this.direction = [];
|
||||
this.searchTerm = ''; // Сбросить поле поиска
|
||||
let newUrl = url.toString();
|
||||
this.$inertia.visit(newUrl, {
|
||||
method: 'get',
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
<template>
|
||||
<!--Фильтр-->
|
||||
|
||||
|
||||
<button type="button"
|
||||
aria-haspopup="dialog" aria-expanded="false" aria-controls="hs-offcanvas-example" data-hs-overlay="#hs-offcanvas-example"
|
||||
class="flex w-full py-2 px-4 items-center gap-x-2 text-xs font-medium rounded-lg border border-gray-200 text-gray-700 hover:bg-gray-100 focus:outline-none focus:bg-primaryBlue focus:text-white disabled:opacity-50 disabled:pointer-events-none">
|
||||
<BaseIcon class="shrink-0 size-4" name="settings" />
|
||||
<span>Фильтры</span>
|
||||
</button>
|
||||
|
||||
|
||||
<!--Конец Фильтра-->
|
||||
<div id="hs-offcanvas-example" class="hs-overlay hs-overlay-open:translate-x-0 hidden -translate-x-full fixed top-0 start-0 transition-all duration-300 transform h-full max-w-xs w-full z-[80] bg-white border-e overflow-auto" role="dialog" tabindex="-1" aria-labelledby="hs-offcanvas-example-label">
|
||||
<div class="flex justify-between items-center py-3 px-4 border-b">
|
||||
<h3 id="hs-offcanvas-example-label" class="font-bold text-gray-800">
|
||||
Фильтры
|
||||
</h3>
|
||||
<button type="button" class="size-8 inline-flex justify-center items-center gap-x-2 rounded-full border border-transparent bg-gray-100 text-gray-800 hover:bg-gray-200 focus:outline-none focus:bg-gray-200 disabled:opacity-50 disabled:pointer-events-none" aria-label="Close" data-hs-overlay="#hs-offcanvas-example">
|
||||
<span class="sr-only">Close</span>
|
||||
<svg class="shrink-0 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="M18 6 6 18"></path>
|
||||
<path d="m6 6 12 12"></path>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<div class="p-4">
|
||||
<div class="hs-accordion-group">
|
||||
<div class="hs-accordion" :id="'id' + formEdu_filter.type">
|
||||
<button class="hs-accordion-toggle hs-accordion-active:text-blue-600 py-3 inline-flex items-center gap-x-3 w-full font-semibold text-start text-gray-800 hover:text-gray-500 focus:outline-none focus:text-gray-500 rounded-lg disabled:opacity-50 disabled:pointer-events-none" aria-expanded="false" aria-controls="hs-basic-with-arrow-collapse-two">
|
||||
<svg class="hs-accordion-active:hidden block 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="m6 9 6 6 6-6"></path>
|
||||
</svg>
|
||||
<svg class="hs-accordion-active:block hidden 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="m18 15-6-6-6 6"></path>
|
||||
</svg>
|
||||
Формат обучения
|
||||
</button>
|
||||
<div id="hs-basic-with-arrow-collapse-two" class="hs-accordion-content hidden w-full overflow-hidden transition-[height] duration-300" role="region" :aria-labelledby="'id' + formEdu_filter.type">
|
||||
<FormEducationalFilter :forms="forms_educational" :formEdu_filter="formEdu_filter" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import BaseIcon from "@/Components/BaseComponents/BaseIcon.vue";
|
||||
import CategoryFilter from "@/Components/BuilderUi/Events/Filters/CategoryFilter.vue";
|
||||
import TagFilter from "@/Components/BuilderUi/Events/Filters/TagFilter.vue";
|
||||
import SortingByFilter from "@/Components/BuilderUi/Events/Filters/SortingByFilter.vue";
|
||||
import FormEducationalFilter from "@/Components/BuilderUi/Programs/Filters/FormEducationalFilter.vue";
|
||||
import BudgetFilter from "@/Components/BuilderUi/Programs/Filters/BudgetFilter.vue";
|
||||
import DirectionFilter from "@/Components/BuilderUi/Programs/Filters/DirectionFilter.vue";
|
||||
|
||||
export default {
|
||||
name: "ClientScheduleFilter",
|
||||
components: {
|
||||
DirectionFilter,
|
||||
BudgetFilter, FormEducationalFilter, SortingByFilter, TagFilter, CategoryFilter, BaseIcon},
|
||||
data() {
|
||||
return {
|
||||
}
|
||||
},
|
||||
|
||||
props: {
|
||||
faculty_filter: {
|
||||
type: Object,
|
||||
},
|
||||
formEdu_filter: {
|
||||
type: Object
|
||||
},
|
||||
forms_educational: {
|
||||
type: Object
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
</style>
|
||||
@@ -1,32 +1,34 @@
|
||||
<template>
|
||||
<div ref="sliderRef" class="relative z-0 min-h-[calc(100vh)] items-center">
|
||||
<div class="absolute -z-10 h-full w-full before:absolute before:z-10 before:h-full before:w-full before:bg-black/30">
|
||||
<a :href="(!slider.settings.link_text) ? slider.link : '#'" v-for="(slider, index) in slidersCarousel.data" :class="`brightness-[${slider.image.shading}]`"
|
||||
class="absolute -z-10 h-full w-full before:absolute before:z-10 before:h-full before:w-full ">
|
||||
<img
|
||||
alt="Thumbnail"
|
||||
loading="eager"
|
||||
decoding="async"
|
||||
data-nimg="fill"
|
||||
class="object-cover brightness-[0.7] transition-opacity duration-1000 absolute inset-0 h-full w-full"
|
||||
class="object-cover transition-opacity duration-1000 absolute inset-0 h-full w-full"
|
||||
sizes="100vw"
|
||||
v-for="(slider, index) in slidersCarousel.data"
|
||||
:key="index"
|
||||
:src="'/storage/' + slider.image"
|
||||
:src="'/storage/' + slider.image.url"
|
||||
:class="{ 'opacity-1': currentIndex === index, 'opacity-0': currentIndex !== index }"
|
||||
/>
|
||||
</div>
|
||||
<div v-show="currentIndex === index" v-for="(item, index) in slidersCarousel.data" :key="index" class="mx-auto max-w-screen-md px-5 pt-[150px] pb-0">
|
||||
<h1 class="text-brand-primary mb-3 mt-2 text-3xl font-semibold tracking-tight text-white lg:text-5xl lg:leading-tight">
|
||||
</a>
|
||||
<div v-show="currentIndex === index" v-for="(item, index) in slidersCarousel.data" :key="index" class="mx-auto max-w-screen-md px-5 pt-[150px] pb-0 bvi-no-styles">
|
||||
<h1 v-if="item.title" :class="`text-${item.settings.text_position}`" class="text-brand-primary mb-3 mt-2 text-3xl font-semibold tracking-tight text-white lg:text-5xl lg:leading-tight">
|
||||
{{ item.title }}
|
||||
</h1>
|
||||
<div class="mt-8 flex space-x-3 text-gray-500 mb-8">
|
||||
<div class="flex flex-col gap-3 md:flex-row md:items-center">
|
||||
<div class="flex gap-3">
|
||||
<p class="text-gray-100 line-clamp-3"><a href="/author/erika-oliver">{{ item.content }}</a></p>
|
||||
<div v-if="item.content" class="mt-8 space-x-3 text-gray-500 mb-8">
|
||||
<div class="gap-3 md:flex-row md:items-center">
|
||||
<div class="gap-3">
|
||||
<p :class="`text-${item.settings.text_position}`" class="text-gray-100 line-clamp-3">
|
||||
{{ item.content }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<a :href="item.link" class="py-3 px-4 inline-flex items-center gap-x-2 text-sm font-semibold rounded-lg border border-white text-white hover:border-white/70 hover:text-white/70 disabled:opacity-50 disabled:pointer-events-none">
|
||||
{{ item.link_text }}
|
||||
<a v-if="item.settings.link_text" :href="item.link" class="py-3 px-4 inline-flex items-center gap-x-2 text-sm font-semibold rounded-lg border border-white text-white hover:border-white/70 hover:text-white/70 disabled:opacity-50 disabled:pointer-events-none">
|
||||
{{ item.settings.link_text }}
|
||||
</a>
|
||||
</div>
|
||||
<div v-if="slidersCarousel.data.length >= 2" class="mx-auto max-w-screen-md px-5">
|
||||
|
||||
@@ -69,8 +69,6 @@
|
||||
<DirectionFilter :direction_filter="direction_filter" :direction_studies="direction_studies" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -69,10 +69,7 @@ export default {
|
||||
// stroke_width: 1.5,
|
||||
// stroke: 'currentColor',
|
||||
},
|
||||
|
||||
|
||||
|
||||
home: {
|
||||
home: {
|
||||
path: '<path stroke-linecap="round" stroke-linejoin="round" d="m2.25 12 8.954-8.955c.44-.439 1.152-.439 1.591 0L21.75 12M4.5 9.75v10.125c0 .621.504 1.125 1.125 1.125H9.75v-4.875c0-.621.504-1.125 1.125-1.125h2.25c.621 0 1.125.504 1.125 1.125V21h4.125c.621 0 1.125-.504 1.125-1.125V9.75M8.25 21h8.25"/>',
|
||||
viewBox: '0 0 24 24',
|
||||
fill: 'none',
|
||||
@@ -81,4 +78,16 @@ home: {
|
||||
},
|
||||
|
||||
|
||||
settings: {
|
||||
path: '<path stroke-linecap="round" stroke-linejoin="round" d="M10.5 6h9.75M10.5 6a1.5 1.5 0 1 1-3 0m3 0a1.5 1.5 0 1 0-3 0M3.75 6H7.5m3 12h9.75m-9.75 0a1.5 1.5 0 0 1-3 0m3 0a1.5 1.5 0 0 0-3 0m-3.75 0H7.5m9-6h3.75m-3.75 0a1.5 1.5 0 0 1-3 0m3 0a1.5 1.5 0 0 0-3 0m-9.75 0h9.75"/>',
|
||||
viewBox: '0 0 24 24',
|
||||
fill: 'none',
|
||||
stroke_width: 1.5,
|
||||
stroke: 'currentColor',
|
||||
},
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -60,9 +60,7 @@
|
||||
</template>
|
||||
</template>
|
||||
|
||||
|
||||
|
||||
<a href="#" class="hover:opacity-70 py-3 className">
|
||||
<a @click="this.removeCookieBvi()" 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">
|
||||
@@ -167,6 +165,11 @@ export default {
|
||||
//
|
||||
// return hasActiveInPages || hasActiveInSubSections;
|
||||
},
|
||||
removeCookieBvi() {
|
||||
if (this.getCookie('bvi_panelActive') === 'true') {
|
||||
this.deleteCookiesWithPrefix('bvi')
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
|
||||
@@ -36,72 +36,8 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="navbar-collapse-with-animation"
|
||||
class="hs-collapse hidden overflow-hidden transition-all duration-300 basis-full grow lg:block">
|
||||
<div
|
||||
class="overflow-hidden overflow-y-auto max-h-[75vh] [&::-webkit-scrollbar]:w-2 [&::-webkit-scrollbar-thumb]:rounded-full [&::-webkit-scrollbar-track]:bg-gray-100 [&::-webkit-scrollbar-thumb]:bg-gray-300">
|
||||
<div
|
||||
class="flex flex-col gap-x-0 mt-5 md:flex-row md:items-center md:justify-end md:gap-x-7 md:mt-0 md:ps-7 md:divide-y-0 md:divide-solid">
|
||||
<template v-for="section in this.sections.data" :key="section.id">
|
||||
<div
|
||||
class="hs-dropdown [--strategy:static] md:[--strategy:absolute] [--adaptive:none] md:[--trigger:hover] py-3 md:py-6">
|
||||
<button type="button"
|
||||
class="active:text-blue-600 flex items-center w-full text-black hover:text-gray-300 font-medium">
|
||||
{{ section.title }}
|
||||
|
||||
</button>
|
||||
<div
|
||||
class="hs-dropdown-menu transition-opacity duration-150 md:duration-500 hs-dropdown-open:opacity-100 opacity-0 w-full hidden z-10 top-full start-0 min-w-[15rem] bg-white md:shadow-2xl rounded-lg py-2 md:p-4 before:absolute before:-top-5 before:start-0 before:w-full before:h-5">
|
||||
<div class="grid px-5 grid-cols-1 md:grid-cols-10">
|
||||
|
||||
<template v-for="subsection in section.subSections" :key="subsection.id">
|
||||
<div class="md:col-span-3">
|
||||
<div class="flex flex-col py-6 px-3 md:px-6">
|
||||
<div class="space-y-4">
|
||||
<div class="flex items-center mb-2 gap-x-2">
|
||||
<span class="text-xs font-bold uppercase text-gray-800">{{
|
||||
subsection.title
|
||||
}}</span>
|
||||
</div>
|
||||
|
||||
<template v-for="page in subsection.pages" :key="page.id">
|
||||
<a :class="{'text-secondDarkBlue hover:text-gray-800 font-semibold ' : isSameRoute(page.path), 'text-gray-800 hover:text-gray-500' : !isSameRoute(page.path) }"
|
||||
class="flex items-center gap-x-2"
|
||||
:href="(page.is_url) ? page.path : route('page.view', page.path) + '/'">
|
||||
<div class="grow">
|
||||
<p>{{ page.title }}</p>
|
||||
</div>
|
||||
</a>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<a href="#" class="hover:opacity-70 py-3 className">
|
||||
<BaseIcon name="eye" class="w-6 h-6 duration-300 md:block hidden" />
|
||||
<span class="md:hidden">Режим для слабовидящих</span>
|
||||
</a>
|
||||
|
||||
|
||||
<Link :href="route('client.schedule')" class="hover:opacity-70 py-3">
|
||||
<BaseIcon name="schedule" class="w-6 h-6 text-black md:block hidden" />
|
||||
<span class="md:hidden text-black">Расписание</span>
|
||||
</Link>
|
||||
|
||||
<a class="hover:opacity-70 py-3 cursor-pointer" data-hs-overlay="#hs-full-screen-modal-below-md">
|
||||
<BaseIcon name="search" class="w-6 h-6 text-black md:block hidden" />
|
||||
<span class="md:hidden text-black">Поиск</span>
|
||||
</a>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<DesktopNavBar v-if="sections" :sections="sections" />
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
@@ -127,6 +63,7 @@ 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";
|
||||
|
||||
|
||||
export default {
|
||||
@@ -141,6 +78,7 @@ export default {
|
||||
return {}
|
||||
},
|
||||
components: {
|
||||
DesktopNavBar,
|
||||
SearchModal,
|
||||
MobileNavbar,
|
||||
BaseIcon,
|
||||
|
||||
@@ -44,6 +44,7 @@
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
|
||||
<MobileNavbar v-if="sections" :sections="sections" />
|
||||
|
||||
|
||||
@@ -63,6 +64,7 @@ import SearchModal from "@/Components/Modals/SearchModal.vue";
|
||||
import DesktopNavBar from "@/Navbars/DesktopNavBar.vue";
|
||||
|
||||
|
||||
|
||||
export default {
|
||||
name: 'MainPageNavBar',
|
||||
components: {
|
||||
@@ -87,6 +89,7 @@ export default {
|
||||
headerFilter: false,
|
||||
underSliderHeader: this.sliderRef,
|
||||
bvi: null,
|
||||
isActiveBvi: null,
|
||||
logos: {
|
||||
default: '/logos/white_ntspi_logo.svg',
|
||||
alternate: '/logos/ntspi-logo.svg',
|
||||
@@ -123,6 +126,19 @@ export default {
|
||||
|
||||
},
|
||||
|
||||
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
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
handleScroll() {
|
||||
if (typeof this.sliderRef === 'object') {
|
||||
const mainSlider = this.sliderRef;
|
||||
@@ -133,30 +149,19 @@ export default {
|
||||
this.headerFilter = true
|
||||
}
|
||||
},
|
||||
getCookie(name) {
|
||||
let cookies = document.cookie.split(';');
|
||||
for (let i = 0; i < cookies.length; i++) {
|
||||
let cookie = cookies[i].trim();
|
||||
if (cookie.startsWith(name + '=')) {
|
||||
return cookie.substring(name.length + 1);
|
||||
}
|
||||
}
|
||||
return null; // Если cookie не найден
|
||||
}
|
||||
|
||||
|
||||
|
||||
},
|
||||
mounted() {
|
||||
window.addEventListener('scroll', this.handleScroll)
|
||||
// if (this.getCookie('bvi_panelActive') === null) {
|
||||
// this.bvi = new isvek.Bvi({
|
||||
// target: '.className',
|
||||
// fontSize: 24,
|
||||
// theme: 'black',
|
||||
// speech: false,
|
||||
// reload: true,
|
||||
// });
|
||||
// }
|
||||
|
||||
|
||||
if (this.getCookie('bvi_panelActive') === null) {
|
||||
this.iniBvi()
|
||||
}
|
||||
|
||||
|
||||
},
|
||||
beforeDestroy() {
|
||||
window.removeEventListener('scroll', this.handleScroll)
|
||||
|
||||
@@ -106,8 +106,11 @@ export default {
|
||||
<!-- Icon Block -->
|
||||
<div class="text-center">
|
||||
<div class="flex justify-center items-center size-12 bg-gray-50 border border-gray-200 rounded-full mx-auto">
|
||||
<svg class="flex-shrink-0 size-5 text-gray-600" 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"><rect width="10" height="14" x="3" y="8" rx="2"/><path d="M5 4a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v16a2 2 0 0 1-2 2h-2.4"/><path d="M8 18h.01"/></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-6">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M4.26 10.147a60.438 60.438 0 0 0-.491 6.347A48.62 48.62 0 0 1 12 20.904a48.62 48.62 0 0 1 8.232-4.41 60.46 60.46 0 0 0-.491-6.347m-15.482 0a50.636 50.636 0 0 0-2.658-.813A59.906 59.906 0 0 1 12 3.493a59.903 59.903 0 0 1 10.399 5.84c-.896.248-1.783.52-2.658.814m-15.482 0A50.717 50.717 0 0 1 12 13.489a50.702 50.702 0 0 1 7.74-3.342M6.75 15a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5Zm0 0v-3.675A55.378 55.378 0 0 1 12 8.443m-7.007 11.55A5.981 5.981 0 0 0 6.75 15.75v-1.5" />
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
<div class="mt-3">
|
||||
<h3 class="text-lg font-semibold text-gray-800">Направление подготовки</h3>
|
||||
<p class="mt-1 text-gray-600">{{ program.data.directionStudy.name }} {{ program.data.directionStudy.code }}</p>
|
||||
@@ -118,7 +121,9 @@ export default {
|
||||
<!-- Icon Block -->
|
||||
<div class="text-center">
|
||||
<div class="flex justify-center items-center size-12 bg-gray-50 border border-gray-200 rounded-full mx-auto">
|
||||
<svg class="flex-shrink-0 size-5 text-gray-600" 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="M20 7h-9"/><path d="M14 17H5"/><circle cx="17" cy="17" r="3"/><circle cx="7" cy="7" r="3"/></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-6">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M6.75 3v2.25M17.25 3v2.25M3 18.75V7.5a2.25 2.25 0 0 1 2.25-2.25h13.5A2.25 2.25 0 0 1 21 7.5v11.25m-18 0A2.25 2.25 0 0 0 5.25 21h13.5A2.25 2.25 0 0 0 21 18.75m-18 0v-7.5A2.25 2.25 0 0 1 5.25 9h13.5A2.25 2.25 0 0 1 21 11.25v7.5m-9-6h.008v.008H12v-.008ZM12 15h.008v.008H12V15Zm0 2.25h.008v.008H12v-.008ZM9.75 15h.008v.008H9.75V15Zm0 2.25h.008v.008H9.75v-.008ZM7.5 15h.008v.008H7.5V15Zm0 2.25h.008v.008H7.5v-.008Zm6.75-4.5h.008v.008h-.008v-.008Zm0 2.25h.008v.008h-.008V15Zm0 2.25h.008v.008h-.008v-.008Zm2.25-4.5h.008v.008H16.5v-.008Zm0 2.25h.008v.008H16.5V15Z" />
|
||||
</svg>
|
||||
</div>
|
||||
<div class="mt-3">
|
||||
<h3 class="text-lg font-semibold text-gray-800">Срок обучения</h3>
|
||||
@@ -148,7 +153,9 @@ export default {
|
||||
<!-- Icon Block -->
|
||||
<div class="text-center">
|
||||
<div class="flex justify-center items-center size-12 bg-gray-50 border border-gray-200 rounded-full mx-auto">
|
||||
<svg class="flex-shrink-0 size-5 text-gray-600" 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="M14 9a2 2 0 0 1-2 2H6l-4 4V4c0-1.1.9-2 2-2h8a2 2 0 0 1 2 2v5Z"/><path d="M18 9h2a2 2 0 0 1 2 2v11l-4-4h-6a2 2 0 0 1-2-2v-1"/></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-6">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M18 18.72a9.094 9.094 0 0 0 3.741-.479 3 3 0 0 0-4.682-2.72m.94 3.198.001.031c0 .225-.012.447-.037.666A11.944 11.944 0 0 1 12 21c-2.17 0-4.207-.576-5.963-1.584A6.062 6.062 0 0 1 6 18.719m12 0a5.971 5.971 0 0 0-.941-3.197m0 0A5.995 5.995 0 0 0 12 12.75a5.995 5.995 0 0 0-5.058 2.772m0 0a3 3 0 0 0-4.681 2.72 8.986 8.986 0 0 0 3.74.477m.94-3.197a5.971 5.971 0 0 0-.94 3.197M15 6.75a3 3 0 1 1-6 0 3 3 0 0 1 6 0Zm6 3a2.25 2.25 0 1 1-4.5 0 2.25 2.25 0 0 1 4.5 0Zm-13.5 0a2.25 2.25 0 1 1-4.5 0 2.25 2.25 0 0 1 4.5 0Z" />
|
||||
</svg>
|
||||
</div>
|
||||
<div class="mt-3">
|
||||
<h3 class="text-lg font-semibold text-gray-800">Количество мест на прием</h3>
|
||||
|
||||
@@ -5,23 +5,34 @@ import { debounce } from "lodash";
|
||||
import { Link } from "@inertiajs/vue3";
|
||||
import MainPageNavBar from "@/Navbars/MainPageNavbar.vue";
|
||||
import BaseIcon from "@/Components/BaseComponents/BaseIcon.vue";
|
||||
import ClientScheduleFilter from "@/Components/BuilderUi/Schedules/ClientScheduleFilter.vue";
|
||||
|
||||
export default {
|
||||
name: "Index",
|
||||
data() {
|
||||
return {
|
||||
searchInput: this.searchRequest,
|
||||
favoriteGroups: JSON.parse(localStorage.getItem('favoriteGroups')) || [],
|
||||
searchInput: this.filters.search_filter.value,
|
||||
favoriteGroups: JSON.parse(localStorage.getItem('favoriteGroups')),
|
||||
showFavorites: false,
|
||||
loading: false,
|
||||
};
|
||||
},
|
||||
components: {BaseIcon, MainPageNavBar, ClientFooterDown, MainNavbar, Link},
|
||||
props: [
|
||||
'educationalGroups',
|
||||
'mainSections',
|
||||
'searchRequest',
|
||||
'navigation',
|
||||
],
|
||||
components: {ClientScheduleFilter, BaseIcon, MainPageNavBar, ClientFooterDown, MainNavbar, Link},
|
||||
|
||||
props: {
|
||||
navigation: {
|
||||
type: Object
|
||||
},
|
||||
filters: {
|
||||
type: Object
|
||||
},
|
||||
forms_education: {
|
||||
type: Object
|
||||
},
|
||||
schedulesByFaculty: {
|
||||
type: Object
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
search: debounce(function () {
|
||||
this.$inertia.reload({
|
||||
@@ -34,7 +45,7 @@ export default {
|
||||
});
|
||||
}, 300),
|
||||
toggleFavorite(group) {
|
||||
const index = this.favoriteGroups.findIndex(g => g.id === group.id);
|
||||
const index = this.favoriteGroups.findIndex(g => g === group);
|
||||
if (index === -1) {
|
||||
this.favoriteGroups.push(group);
|
||||
} else {
|
||||
@@ -43,18 +54,65 @@ export default {
|
||||
localStorage.setItem('favoriteGroups', JSON.stringify(this.favoriteGroups));
|
||||
},
|
||||
isFavorite(group) {
|
||||
return this.favoriteGroups.some(g => g.id === group.id);
|
||||
return this.favoriteGroups.some(g => g === group);
|
||||
},
|
||||
toggleShowFavorites() {
|
||||
this.showFavorites = !this.showFavorites;
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
filteredGroups() {
|
||||
if (this.showFavorites) {
|
||||
return this.educationalGroups.data.filter(group => this.favoriteGroups.some(g => g.id === group.id));
|
||||
this.loading = true; // Включаем состояние загрузки
|
||||
|
||||
if (this.filters.favorite_filter.value === null) {
|
||||
this.filterFavorite(() => {
|
||||
this.loading = false; // Выключаем состояние загрузки после завершения
|
||||
});
|
||||
} else {
|
||||
this.clearFilterFavorite(() => {
|
||||
this.loading = false; // Выключаем состояние загрузки после завершения
|
||||
});
|
||||
}
|
||||
return this.educationalGroups.data;
|
||||
},
|
||||
|
||||
filterFavorite: debounce(function (callback) {
|
||||
let url = new URL(window.location.href);
|
||||
// Создаем массив для хранения всех ключей, которые нужно удалить
|
||||
const keysToDelete = [];
|
||||
|
||||
// Перебираем все параметры и добавляем ключи, начинающиеся с 'category', в массив
|
||||
for (const [key] of url.searchParams) {
|
||||
if (key.startsWith('favorite')) {
|
||||
keysToDelete.push(key);
|
||||
}
|
||||
}
|
||||
// Удаляем все ключи из массива
|
||||
keysToDelete.forEach(key => url.searchParams.delete(key));
|
||||
let newUrl = url.toString();
|
||||
this.$inertia.visit(newUrl, {
|
||||
method: 'get',
|
||||
preserveState: true,
|
||||
data: {
|
||||
favorite: (this.favoriteGroups.length !== 0) ? this.favoriteGroups : "",
|
||||
},
|
||||
onFinish: callback, // Вызываем колбэк после завершения запроса
|
||||
});
|
||||
}, 500),
|
||||
clearFilterFavorite(callback) {
|
||||
let url = new URL(window.location.href);
|
||||
// Создаем массив для хранения всех ключей, которые нужно удалить
|
||||
const keysToDelete = [];
|
||||
|
||||
// Перебираем все параметры и добавляем ключи, начинающиеся с 'category', в массив
|
||||
for (const [key] of url.searchParams) {
|
||||
if (key.startsWith('favorite')) {
|
||||
keysToDelete.push(key);
|
||||
}
|
||||
}
|
||||
// Удаляем все ключи из массива
|
||||
keysToDelete.forEach(key => url.searchParams.delete(key));
|
||||
let newUrl = url.toString();
|
||||
this.$inertia.visit(newUrl, {
|
||||
method: 'get',
|
||||
preserveState: true,
|
||||
onFinish: callback, // Вызываем колбэк после завершения запроса
|
||||
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
@@ -69,14 +127,13 @@ export default {
|
||||
<article class="w-full min-w-0 mt-4 px-1 md:px-6">
|
||||
<div class="relative overflow-hidden">
|
||||
<div class="max-w-[85rem] mx-auto sm:px-6 lg:px-8 py-10 sm:pb-12 sm:py-5">
|
||||
<div class="text-center">
|
||||
<h1 class="text-2xl sm:text-4xl font-bold text-gray-800 dark:text-gray-200">
|
||||
<div class="">
|
||||
<h1 class="text-2xl sm:text-4xl font-bold text-gray-800 text-center">
|
||||
Расписание занятий
|
||||
</h1>
|
||||
|
||||
|
||||
<div class="text-center">
|
||||
<p class="mt-3 text-gray-600 dark:text-gray-400">
|
||||
<div class="">
|
||||
<p class="mt-3 text-gray-600 text-center">
|
||||
Просто введите название группы
|
||||
</p>
|
||||
</div>
|
||||
@@ -100,7 +157,7 @@ export default {
|
||||
id="hs-search-article-1"
|
||||
class="py-2.5 px-4 block w-full border-transparent rounded-lg disabled:opacity-50 disabled:cursor-not-allowed disabled:bg-gray-100"
|
||||
placeholder="Поиск"
|
||||
:disabled="showFavorites"
|
||||
:disabled="filters.favorite_filter.value !== null"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
@@ -108,24 +165,20 @@ export default {
|
||||
</form>
|
||||
<div class="">
|
||||
<div class="grid grid-cols-2 gap-3">
|
||||
<button @click="toggleShowFavorites" type="button"
|
||||
:class="showFavorites ? 'bg-primaryBlue text-white hover:bg-secondDarkBlue' : 'text-gray-700 hover:bg-gray-100'"
|
||||
class="flex w-full py-2 px-4 items-center gap-x-2 text-xs font-medium rounded-lg border border-gray-200 focus:outline-none disabled:opacity-50 disabled:pointer-events-none">
|
||||
<button
|
||||
@click="toggleShowFavorites"
|
||||
type="button"
|
||||
:disabled="favoriteGroups.length === 0 || loading"
|
||||
:class="
|
||||
filters.favorite_filter.value !== null ? 'bg-primaryBlue text-white hover:bg-secondDarkBlue': 'text-gray-700 hover:bg-gray-100',
|
||||
loading ? 'animate-pulse' : ''
|
||||
"
|
||||
class="flex w-full py-2 px-4 items-center gap-x-2 text-xs font-medium rounded-lg border border-gray-200 focus:outline-none disabled:opacity-50 disabled:pointer-events-none"
|
||||
>
|
||||
<BaseIcon name="heart" class="shrink-0 size-4"/>
|
||||
<span>Избранные расписания</span>
|
||||
</button>
|
||||
<button type="button"
|
||||
class="flex w-full py-2 px-4 items-center gap-x-2 text-xs font-medium rounded-lg border border-gray-200 text-gray-700 hover:bg-gray-100 focus:outline-none focus:bg-primaryBlue focus:text-white disabled:opacity-50 disabled:pointer-events-none">
|
||||
<svg class="shrink-0 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="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"/>
|
||||
<circle cx="9" cy="7" r="4"/>
|
||||
<line x1="19" x2="19" y1="8" y2="14"/>
|
||||
<line x1="22" x2="16" y1="11" y2="11"/>
|
||||
</svg>
|
||||
<span>Follow</span>
|
||||
<span>Избранное</span>
|
||||
</button>
|
||||
<ClientScheduleFilter :forms_educational="this.forms_education" :form-edu_filter="this.filters.form_education_filter" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -133,131 +186,59 @@ export default {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mx-auto max-w-2xl hs-accordion-group grid grid-cols-1 lg:grid-cols-2 gap-3">
|
||||
<div v-if="!showFavorites">
|
||||
<div class="mx-auto max-w-2xl hs-accordion-group grid gap-3">
|
||||
<div class="space-y-4">
|
||||
<transition-group name="fade">
|
||||
<template v-for="educationalGroup in filteredGroups" :key="educationalGroup.id">
|
||||
<div
|
||||
class="hs-accordion hs-accordion-active:border-gray-200 bg-white border-b dark:hs-accordion-active:border-gray-700 dark:bg-gray-800 dark:border-transparent"
|
||||
id="hs-active-bordered-heading-one">
|
||||
<div class="flex">
|
||||
<button @click="toggleFavorite(educationalGroup)">
|
||||
<transition name="heart" mode="out-in">
|
||||
<BaseIcon
|
||||
v-if="isFavorite(educationalGroup)"
|
||||
name="heart_filled"
|
||||
class="shrink-0 size-4 text-red-500"
|
||||
key="filled"
|
||||
/>
|
||||
<BaseIcon
|
||||
v-else
|
||||
name="heart"
|
||||
class="shrink-0 size-4"
|
||||
key="outline"
|
||||
/>
|
||||
</transition>
|
||||
<template v-for="(faculty, title) in schedulesByFaculty">
|
||||
<div class="">
|
||||
<h2 class="text-center text-gray-800 font-medium">{{ title }}</h2>
|
||||
<hr class="mt-2 mb-4">
|
||||
<template v-for="educationalGroup in faculty" :key="educationalGroup.data.id">
|
||||
<div class="hs-accordion hs-accordion-active:border-gray-200 bg-white border border-transparent rounded-xl" id="hs-active-bordered-heading-one">
|
||||
<div class="flex py-4 px-5 gap-x-3">
|
||||
<button @click="toggleFavorite(educationalGroup.data.id)">
|
||||
<transition name="heart" mode="out-in">
|
||||
<BaseIcon
|
||||
v-if="isFavorite(educationalGroup.data.id)"
|
||||
name="heart_filled"
|
||||
class="shrink-0 size-4 text-red-500"
|
||||
key="filled"
|
||||
/>
|
||||
<BaseIcon
|
||||
v-else
|
||||
name="heart"
|
||||
class="shrink-0 size-4"
|
||||
key="outline"
|
||||
/>
|
||||
</transition>
|
||||
|
||||
</button>
|
||||
</button>
|
||||
<button class="hs-accordion-toggle hs-accordion-active:text-blue-600 inline-flex justify-between items-center gap-x-3 w-full font-semibold text-start text-gray-800 hover:text-gray-500 disabled:opacity-50 disabled:pointer-events-none" aria-expanded="false" aria-controls="hs-basic-active-bordered-collapse-one">
|
||||
<span class="flex items-center gap-x-2">{{ educationalGroup.data.title }}</span>
|
||||
<svg class="hs-accordion-active:hidden block size-3.5" 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="M5 12h14"></path>
|
||||
<path d="M12 5v14"></path>
|
||||
</svg>
|
||||
<svg class="hs-accordion-active:block hidden size-3.5" 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="M5 12h14"></path>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<button
|
||||
class="hs-accordion-toggle hs-accordion-active:text-blue-600 inline-flex justify-between items-center gap-x-3 w-full font-semibold text-start text-gray-800 py-4 px-5 hover:text-gray-500 disabled:opacity-50 disabled:pointer-events-none dark:hs-accordion-active:text-blue-500 dark:text-gray-200 dark:hover:text-gray-400 dark:focus:outline-none dark:focus:text-gray-400"
|
||||
aria-controls="hs-basic-active-bordered-collapse-one">
|
||||
|
||||
<div class="flex items-center gap-x-2"><span>{{ educationalGroup.title }}</span> <span
|
||||
class="font-light text-sm uppercase text-gray-500">{{ educationalGroup.faculty }}</span></div>
|
||||
<svg class="hs-accordion-active:hidden block w-3.5 h-3.5"
|
||||
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="M5 12h14"/>
|
||||
<path d="M12 5v14"/>
|
||||
</svg>
|
||||
<svg class="hs-accordion-active:block hidden w-3.5 h-3.5"
|
||||
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="M5 12h14"/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<div id="hs-basic-active-bordered-collapse-one"
|
||||
class="hs-accordion-content hidden w-full overflow-hidden transition-[height] duration-300"
|
||||
aria-labelledby="hs-active-bordered-heading-one">
|
||||
<div class="pb-4 px-5 grid gap-3 grid-cols-1">
|
||||
<template v-for="schedule in educationalGroup.schedules" :key="schedule.id">
|
||||
<template v-for="file in schedule.file">
|
||||
<a :href="'storage/' + file.path" target="_blank"
|
||||
class="py-3 px-4 inline-flex items-center gap-x-2 text-sm font-medium rounded-lg border border-gray-200 bg-white text-gray-500 shadow-sm hover:bg-gray-50 disabled:opacity-50 disabled:pointer-events-none dark:bg-slate-900 dark:border-gray-700 dark:text-gray-400 dark:hover:bg-gray-800 dark:focus:outline-none dark:focus:ring-1 dark:focus:ring-gray-600">
|
||||
{{ file.title }}
|
||||
</a>
|
||||
</template>
|
||||
</template>
|
||||
<div id="hs-basic-active-bordered-collapse-one" class="hs-accordion-content hidden w-full overflow-hidden transition-[height] duration-300" role="region" aria-labelledby="hs-active-bordered-heading-one">
|
||||
<div class="pb-4 px-5 grid gap-3 grid-cols-1">
|
||||
<template v-for="schedule in educationalGroup.data.schedules" :key="schedule.id">
|
||||
<template v-for="file in schedule.file">
|
||||
<a :href="'storage/' + file.path" target="_blank"
|
||||
class="py-3 px-4 inline-flex items-center gap-x-2 text-sm font-medium rounded-lg border border-gray-200 bg-white text-gray-500 shadow-sm hover:bg-gray-50 disabled:opacity-50 disabled:pointer-events-none dark:bg-slate-900 dark:border-gray-700 dark:text-gray-400 dark:hover:bg-gray-800 dark:focus:outline-none dark:focus:ring-1 dark:focus:ring-gray-600">
|
||||
{{ file.title }}
|
||||
</a>
|
||||
</template>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</transition-group>
|
||||
</div>
|
||||
<div v-else>
|
||||
<transition-group name="fade">
|
||||
<template v-for="educationalGroup in favoriteGroups" :key="educationalGroup.id">
|
||||
<div
|
||||
class="hs-accordion hs-accordion-active:border-gray-200 bg-white border-b dark:hs-accordion-active:border-gray-700 dark:bg-gray-800 dark:border-transparent"
|
||||
id="hs-active-bordered-heading-one">
|
||||
<div class="flex">
|
||||
<button @click="toggleFavorite(educationalGroup)">
|
||||
<transition name="heart" mode="out-in">
|
||||
<BaseIcon
|
||||
v-if="isFavorite(educationalGroup)"
|
||||
name="heart_filled"
|
||||
class="shrink-0 size-4 text-red-500"
|
||||
key="filled"
|
||||
/>
|
||||
<BaseIcon
|
||||
v-else
|
||||
name="heart"
|
||||
class="shrink-0 size-4"
|
||||
key="outline"
|
||||
/>
|
||||
</transition>
|
||||
|
||||
</button>
|
||||
|
||||
<button
|
||||
class="hs-accordion-toggle hs-accordion-active:text-blue-600 inline-flex justify-between items-center gap-x-3 w-full font-semibold text-start text-gray-800 py-4 px-5 hover:text-gray-500 disabled:opacity-50 disabled:pointer-events-none dark:hs-accordion-active:text-blue-500 dark:text-gray-200 dark:hover:text-gray-400 dark:focus:outline-none dark:focus:text-gray-400"
|
||||
aria-controls="hs-basic-active-bordered-collapse-one">
|
||||
|
||||
<div class="flex items-center gap-x-2"><span>{{ educationalGroup.title }}</span> <span
|
||||
class="font-light text-sm uppercase text-gray-500">{{ educationalGroup.faculty }}</span></div>
|
||||
<svg class="hs-accordion-active:hidden block w-3.5 h-3.5"
|
||||
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="M5 12h14"/>
|
||||
<path d="M12 5v14"/>
|
||||
</svg>
|
||||
<svg class="hs-accordion-active:block hidden w-3.5 h-3.5"
|
||||
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="M5 12h14"/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<div id="hs-basic-active-bordered-collapse-one"
|
||||
class="hs-accordion-content hidden w-full overflow-hidden transition-[height] duration-300"
|
||||
aria-labelledby="hs-active-bordered-heading-one">
|
||||
<div class="pb-4 px-5 grid gap-3 grid-cols-1">
|
||||
<template v-for="schedule in educationalGroup.schedules" :key="schedule.id">
|
||||
<template v-for="file in schedule.file">
|
||||
<a :href="'storage/' + file.path" target="_blank"
|
||||
class="py-3 px-4 inline-flex items-center gap-x-2 text-sm font-medium rounded-lg border border-gray-200 bg-white text-gray-500 shadow-sm hover:bg-gray-50 disabled:opacity-50 disabled:pointer-events-none dark:bg-slate-900 dark:border-gray-700 dark:text-gray-400 dark:hover:bg-gray-800 dark:focus:outline-none dark:focus:ring-1 dark:focus:ring-gray-600">
|
||||
{{ file.title }}
|
||||
</a>
|
||||
</template>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
</transition-group>
|
||||
|
||||
@@ -4,12 +4,13 @@
|
||||
<MainPageNavBar :sections="$page.props.navigation" :slider-ref="sliderRef" />
|
||||
<ClientMainSlider @slider-mounted="setSliderRef" :slidersCarousel="sliders" />
|
||||
<section class="max-w-screen-xl w-full mx-auto px-4 py-3 pb-10">
|
||||
<h2 class="text-brand-primary my-6 md:mb-[50px] md:mt-[80px] text-2xl font-semibold tracking-tight text-black lg:text-[32px] lg:leading-tight">Последние новости</h2>
|
||||
<div class="grid gap-10 pb-10 md:grid-cols-2 lg:gap-10 xl:grid-cols-3">
|
||||
<template v-for="post in posts.data" :key="post.id">
|
||||
<ClientPost :post="post" />
|
||||
</template>
|
||||
</div>
|
||||
<h2 class="text-brand-primary my-6 md:mb-[50px] md:mt-[80px] text-2xl font-semibold tracking-tight text-black lg:text-[32px] lg:leading-tight bvi-show">Последние новости</h2>
|
||||
<div class="grid gap-10 pb-10 md:grid-cols-2 lg:gap-10 xl:grid-cols-3 bvi-no-styles">
|
||||
<template v-for="post in posts.data" :key="post.id">
|
||||
<ClientPost :post="post" />
|
||||
</template>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="flex justify-center">
|
||||
@@ -184,6 +185,7 @@ import BaseMetaHead from "@/Components/BaseComponents/BaseMetaHead.vue";
|
||||
import PageResourceList from "@/Components/BuilderUi/Pages/Blocks/PageResourceList.vue";
|
||||
import AppHead from "@/Components/AppHead.vue";
|
||||
import ContactSectionBlock from "@/Components/BaseComponents/BaseBuilderUi/Blocks/Contacts/ContactSectionBlock.vue";
|
||||
import Cookies from "js-cookie";
|
||||
|
||||
|
||||
|
||||
@@ -238,6 +240,7 @@ export default {
|
||||
},
|
||||
|
||||
methods: {
|
||||
Cookies,
|
||||
setSliderRef(ref) {
|
||||
this.sliderRef = ref;
|
||||
},
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
</Head>
|
||||
<MainPageNavBar class="border-b" :sections="$page.props.navigation"></MainPageNavBar>
|
||||
|
||||
<div class="w-full h-[67px] fixed pointer-events-none" id="visor"></div>
|
||||
<div class="w-full h-[67px] fixed pointer-events-none bvi-no-styles" id="visor"></div>
|
||||
<div class="flex flex-col h-screen">
|
||||
<main class="flex-grow">
|
||||
<div class="relative mx-auto mt-[67px] max-w-screen-xl px-4 py-10 md:flex md:flex-row md:py-10">
|
||||
|
||||
@@ -7,6 +7,7 @@ import { createInertiaApp } from '@inertiajs/vue3';
|
||||
import { ZiggyVue } from '../../vendor/tightenco/ziggy/dist/vue.m';
|
||||
import {linksReform} from "@/mixins/LinksReform.js";
|
||||
import YSmartCaptcha from 'vue3-yandex-smartcaptcha'
|
||||
import cookieMixin from "@/mixins/cookieMixin.js";
|
||||
|
||||
// const appName = import.meta.env.VITE_APP_NAME || 'НТГСПИ';
|
||||
|
||||
@@ -20,6 +21,7 @@ createInertiaApp({
|
||||
return createSSRApp({ render: () => h(App, props) })
|
||||
.use(plugin)
|
||||
.mixin(linksReform)
|
||||
.mixin(cookieMixin)
|
||||
.use(ZiggyVue)
|
||||
.use(YSmartCaptcha, {
|
||||
siteKey: "ysc1_jxb2IcslgBuHgHbmmKY1F7Nvb8zYHuAeBgjoaTka6886f893",
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
export default {
|
||||
methods: {
|
||||
// Устанавливаем куки
|
||||
setCookie(name, value, days) {
|
||||
let expires = "";
|
||||
if (days) {
|
||||
const date = new Date();
|
||||
date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000)); // Устанавливаем срок действия куки
|
||||
expires = "; expires=" + date.toUTCString();
|
||||
}
|
||||
document.cookie = name + "=" + (value || "") + expires + "; path=/"; // Устанавливаем куки
|
||||
},
|
||||
|
||||
// Получаем куки
|
||||
getCookie(name) {
|
||||
const nameEQ = name + "="; // Форматируем имя куки
|
||||
const ca = document.cookie.split(';'); // Разбиваем куки по точке с запятой
|
||||
for (let i = 0; i < ca.length; i++) {
|
||||
let c = ca[i];
|
||||
while (c.charAt(0) === ' ') c = c.substring(1, c.length); // Убираем пробелы
|
||||
if (c.indexOf(nameEQ) === 0) return c.substring(nameEQ.length, c.length); // Если найдено, возвращаем значение
|
||||
}
|
||||
return null; // Если кука не найдена
|
||||
},
|
||||
|
||||
// Удаляем куки
|
||||
deleteCookie(name) {
|
||||
// Получаем текущий домен
|
||||
const domain = window.location.hostname.includes('.') ? '.' + window.location.hostname : window.location.hostname;
|
||||
document.cookie = name + '=; Max-Age=-99999999; path=/; domain=' + domain; // Устанавливаем срок действия в прошлом
|
||||
},
|
||||
|
||||
deleteCookiesWithPrefix(prefix) {
|
||||
const cookies = document.cookie.split(';'); // Получаем все куки
|
||||
for (let cookie of cookies) {
|
||||
const cookieName = cookie.split('=')[0].trim(); // Получаем имя куки
|
||||
if (cookieName.startsWith(prefix)) { // Проверяем, начинается ли имя куки с заданного префикса
|
||||
this.deleteCookie(cookieName); // Удаляем куку
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user