refactor schedule module, added new filters
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
<template>
|
||||
<select v-model="faculty" @change="filter" class="py-2 px-4 pe-9 block w-full border-gray-200 rounded-lg text-xs focus:border-blue-500 focus:ring-blue-500 disabled:opacity-50 disabled:pointer-events-none">
|
||||
<option :value="null">
|
||||
Выбрать факультет
|
||||
</option>
|
||||
<option v-for="facultyOption in faculties" :value="facultyOption.slug">{{ facultyOption.title }}</option>
|
||||
</select>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {Link} from "@inertiajs/vue3";
|
||||
import BasicIcon from "@/componentss/ui/icons/BasicIcon.vue";
|
||||
import {debounce} from "lodash";
|
||||
|
||||
export default {
|
||||
name: "FacultyFilter",
|
||||
components: {
|
||||
BasicIcon,
|
||||
Link,
|
||||
},
|
||||
props: {
|
||||
faculties: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
faculty_filter: {
|
||||
type: Object,
|
||||
default: () => ({ value: null }),
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
faculty: this.faculty_filter.value || null,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
filter: debounce(function () {
|
||||
let url = new URL(window.location.href);
|
||||
url.searchParams.delete('page');
|
||||
url.searchParams.delete('form');
|
||||
|
||||
if (this.faculty === null) {
|
||||
url.searchParams.delete('faculty');
|
||||
} else {
|
||||
url.searchParams.set('faculty', this.faculty);
|
||||
}
|
||||
|
||||
let newUrl = url.toString();
|
||||
|
||||
this.$inertia.visit(newUrl, {
|
||||
method: 'get',
|
||||
preserveState: true,
|
||||
});
|
||||
}, 500),
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,99 @@
|
||||
<template>
|
||||
<button
|
||||
@click="toggleShowFavorites"
|
||||
type="button"
|
||||
:disabled="isLoading" :class="
|
||||
favorite_filter.value !== null ? 'bg-primary text-white hover:bg-primary-dark': 'text-gray-700 hover:bg-gray-100',
|
||||
isLoading ? '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"
|
||||
>
|
||||
<BasicIcon name="heart" class="shrink-0 size-4"/>
|
||||
<span>Избранное</span>
|
||||
</button>
|
||||
|
||||
</template>
|
||||
<script>
|
||||
import {Link} from "@inertiajs/vue3";
|
||||
import BasicIcon from "@/componentss/ui/icons/BasicIcon.vue";
|
||||
import {debounce} from "lodash";
|
||||
|
||||
export default {
|
||||
name: "FavoriteFilter",
|
||||
components: {
|
||||
BasicIcon,
|
||||
Link,
|
||||
},
|
||||
props: {
|
||||
favorite_filter: {
|
||||
type: Object,
|
||||
},
|
||||
favoriteGroups: {
|
||||
type: Object
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// Инициализируйте локальное свойство данных для управления состоянием загрузки
|
||||
isLoading: false, // Вы также можете инициализировать его на основе пропса, если это необходимо: this.initialLoadingProp || false
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
toggleShowFavorites() {
|
||||
this.isLoading = true; // Теперь вы изменяете свое локальное свойство данных
|
||||
|
||||
if (this.favorite_filter.value === null) {
|
||||
this.filterFavorite(() => {
|
||||
this.isLoading = false; // Отключаем состояние загрузки после завершения
|
||||
});
|
||||
} else {
|
||||
this.clearFilterFavorite(() => {
|
||||
this.isLoading = false; // Отключаем состояние загрузки после завершения
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
filterFavorite: debounce(function (callback) {
|
||||
let url = new URL(window.location.href);
|
||||
const keysToDelete = [];
|
||||
|
||||
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 = [];
|
||||
|
||||
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,
|
||||
});
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,79 @@
|
||||
<template>
|
||||
<form>
|
||||
<div class="relative z-10 space-x-3 px-3 py-2 bg-white border rounded-lg shadow-lg shadow-gray-100">
|
||||
<div class="flex justify-between">
|
||||
<div class="flex w-full">
|
||||
<label for="hs-search-article-1"
|
||||
class="block text-sm text-gray-700 font-medium dark:text-white">
|
||||
<span class="sr-only">Поиск</span>
|
||||
</label>
|
||||
<input
|
||||
@keydown.enter.prevent
|
||||
autocomplete="off"
|
||||
v-model="searchInput"
|
||||
@input="search"
|
||||
type="search"
|
||||
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="Поиск"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {Link} from "@inertiajs/vue3";
|
||||
import BasicIcon from "@/componentss/ui/icons/BasicIcon.vue";
|
||||
import {debounce} from "lodash";
|
||||
|
||||
export default {
|
||||
name: "SearchFilter",
|
||||
components: {
|
||||
BasicIcon,
|
||||
Link,
|
||||
},
|
||||
props: {
|
||||
search_filter: {
|
||||
type: Object,
|
||||
default: () => ({ value: null }),
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
searchInput: this.search_filter.value,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
search: debounce(function () {
|
||||
if(this.searchInput === "") {
|
||||
let url = new URL(window.location.href);
|
||||
url.searchParams.delete('search');
|
||||
let newUrl = url.toString();
|
||||
this.$inertia.visit(newUrl,{
|
||||
method: 'get',
|
||||
preserveState: true,
|
||||
replace: true,
|
||||
});
|
||||
} else {
|
||||
let url = new URL(window.location.href);
|
||||
url.searchParams.delete('page');
|
||||
let newUrl = url.toString();
|
||||
this.$inertia.visit(newUrl,{
|
||||
method: 'get',
|
||||
data: {
|
||||
search: this.searchInput,
|
||||
},
|
||||
preserveState: true,
|
||||
replace: true,
|
||||
})
|
||||
}
|
||||
}, 500),
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
Reference in New Issue
Block a user