Add pagination
This commit is contained in:
parent
678f068c9c
commit
1f7f70a459
|
@ -0,0 +1,72 @@
|
||||||
|
<template>
|
||||||
|
<div class="flex flex-col md:flex-row justify-between items-center space-y-3 md:space-y-0">
|
||||||
|
<div class="text-sm text-gray-600" v-text="desc"></div>
|
||||||
|
<div v-if="modelValue.last_page > 1" class="items-center flex space-x-2">
|
||||||
|
<div class="hidden sm:flex text-gray-600 text-sm" v-text="pages"></div>
|
||||||
|
<button
|
||||||
|
v-if="modelValue.current_page !== 1"
|
||||||
|
href="#"
|
||||||
|
class="rounded !ml-0 sm:!ml-2 flex w-6 h-6 items-center justify-center leading-none shadow bg-blue-700 hover:bg-blue-600 items-center justify-center"
|
||||||
|
@click.prevent="goto(modelValue.current_page - 1)"
|
||||||
|
>
|
||||||
|
<chevron class="rotate-90 text-white w-2 h-2"></chevron>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
v-for="(button, index) in pageButtons"
|
||||||
|
:key="index"
|
||||||
|
href="#"
|
||||||
|
class="rounded text-sm w-6 h-6 text-white flex items-center justify-center leading-none shadow"
|
||||||
|
:class="{'bg-blue-500': button.current, 'bg-blue-700 hover:bg-blue-600': !button.current}"
|
||||||
|
@click.prevent="goto(button.page)"
|
||||||
|
v-text="button.page"
|
||||||
|
></button>
|
||||||
|
<button
|
||||||
|
v-if="modelValue.current_page !== modelValue.last_page"
|
||||||
|
href="#"
|
||||||
|
class="flex rounded text-sm w-6 h-6 items-center justify-center leading-none shadow bg-blue-700 hover:bg-blue-600 items-center justify-center"
|
||||||
|
@click.prevent="goto(modelValue.current_page + 1)"
|
||||||
|
>
|
||||||
|
<chevron class="-rotate-90 text-white w-2 h-2"></chevron>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import {computed} from 'vue';
|
||||||
|
import Chevron from './icons/Chevron.vue';
|
||||||
|
const emits = defineEmits(['reload']);
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
modelValue: {
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
function goto(page) {
|
||||||
|
if (page === props.modelValue.current_page) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
emits('reload', page);
|
||||||
|
}
|
||||||
|
|
||||||
|
const pageButtons = computed(() => {
|
||||||
|
var from = Math.max(1, props.modelValue.current_page - 2);
|
||||||
|
var to = Math.min(props.modelValue.last_page, props.modelValue.current_page + 2);
|
||||||
|
|
||||||
|
return Array(to + 1)
|
||||||
|
.fill(0)
|
||||||
|
.map((index, key) => key)
|
||||||
|
.slice(from)
|
||||||
|
.map((page) => {
|
||||||
|
return {
|
||||||
|
page: page,
|
||||||
|
current: page === props.modelValue.current_page,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
const pages = computed(() => `Seite ${props.modelValue.current_page} von ${props.modelValue.last_page}`);
|
||||||
|
const desc = computed(() => `${props.modelValue.from} - ${props.modelValue.to} von ${props.modelValue.total} Einträgen`);
|
||||||
|
</script>
|
|
@ -50,10 +50,13 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="relative min-h-48">
|
<div class="relative min-h-48">
|
||||||
<div class="relative" v-for="member in searchResults" :id="member.id" v-if="!searching">
|
<div class="relative grid grid-cols-[repeat(auto-fit,minmax(200px,1fr))] gap-2 mt-2">
|
||||||
|
<div v-for="member in searchResults.data" :id="member.id">
|
||||||
{{ member.name }}
|
{{ member.name }}
|
||||||
</div>
|
</div>
|
||||||
<div class="absolute flex h-full w-full justify-center items-center opacity-80" v-if="searching">
|
</div>
|
||||||
|
<pagination class="mt-5" :model-value="searchResults" @reload="searchForMember($event)" v-if="searchResults.current_page"></pagination>
|
||||||
|
<div class="absolute flex h-full w-full top-0 left-0 justify-center items-center backdrop-blur-sm" v-if="searching">
|
||||||
<spinner class="w-20 h-20"></spinner>
|
<spinner class="w-20 h-20"></spinner>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -100,6 +103,7 @@ import VBtn from '../VBtn.vue';
|
||||||
import Spinner from '../Spinner.vue';
|
import Spinner from '../Spinner.vue';
|
||||||
import useAdremaLogin from '../../composables/useAdremaLogin.js';
|
import useAdremaLogin from '../../composables/useAdremaLogin.js';
|
||||||
import useEventMeta from '../../composables/useEventMeta.js';
|
import useEventMeta from '../../composables/useEventMeta.js';
|
||||||
|
import Pagination from '../Pagination.vue';
|
||||||
|
|
||||||
const eventMeta = useEventMeta();
|
const eventMeta = useEventMeta();
|
||||||
const {login, logout, user, loginData, searchData, searchForMember, resetSearchData, searchResults, searching} = useAdremaLogin();
|
const {login, logout, user, loginData, searchData, searchForMember, resetSearchData, searchResults, searching} = useAdremaLogin();
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
<template>
|
||||||
|
<svg height="223.651" viewBox="0 0 105.911 55.913" width="423.642" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path
|
||||||
|
d="M0 4.66a4.57 4.57 0 0 1 1.41-3.295c1.882-1.82 4.928-1.82 6.808 0l44.737 43.3 44.738-43.3c1.881-1.82 4.927-1.82 6.807 0a4.552 4.552 0 0 1 0 6.589L56.36 54.547c-1.881 1.82-4.927 1.82-6.807 0L1.41 7.954A4.57 4.57 0 0 1 0 4.66Z"
|
||||||
|
style="stroke-width: 1.18403"
|
||||||
|
fill="currentColor"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</template>
|
|
@ -48,20 +48,21 @@ export default function useAdremaLogin() {
|
||||||
loginToken.value = null;
|
loginToken.value = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const searchForMember = debounce(async function () {
|
const searchForMember = debounce(async function (page = 1) {
|
||||||
searching.value = true;
|
searching.value = true;
|
||||||
const response = await axios.post(
|
const response = await axios.post(
|
||||||
'/remote/nami/search',
|
'/remote/nami/search',
|
||||||
{
|
{
|
||||||
...searchData.value,
|
...searchData.value,
|
||||||
untergliederungId: searchData.value.untergliederungId ? [searchData.value.untergliederungId] : [],
|
untergliederungId: searchData.value.untergliederungId ? [searchData.value.untergliederungId] : [],
|
||||||
|
page: page,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
headers: {'X-Adrema-Token': loginToken.value.token},
|
headers: {'X-Adrema-Token': loginToken.value.token},
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
searchResults.value = response.data.data;
|
searchResults.value = response.data;
|
||||||
searching.value = false;
|
searching.value = false;
|
||||||
}, 500);
|
}, 500);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue