diff --git a/src/components/BaseComponents/PaginationTemplate.vue b/src/components/BaseComponents/PaginationTemplate.vue new file mode 100644 index 0000000000000000000000000000000000000000..0d96ee5d7fcea9955cf6c9a85546b7c4033b21b3 --- /dev/null +++ b/src/components/BaseComponents/PaginationTemplate.vue @@ -0,0 +1,37 @@ +<template> + <div v-if="totalPages() > 0"> + <span v-if="showPreviousLink()" + class="cursor-pointer inline-flex items-center p-2 text-sm font-medium text-gray-500 bg-white rounded-lg border border-gray-300 hover:bg-gray-100 hover:text-gray-700" + @click="updatePage(currentPage - 1)"> + Forrige + </span> + <label class="mx-2">{{ currentPage + 1 }} av {{ totalPages() }}</label> + <span + v-if="showNextLink()" + class="cursor-pointer inline-flex items-center p-2 text-sm font-medium text-gray-500 bg-white rounded-lg border border-gray-300 hover:bg-gray-100 hover:text-gray-700" + @click="updatePage(currentPage + 1)"> + Neste + </span> + </div> +</template> + +<script> +export default { + name: 'paginationTemplate', + props: ['items', 'currentPage', 'pageSize'], + methods: { + updatePage(pageNumber) { + this.$emit('page:update', pageNumber); + }, + totalPages() { + return Math.ceil(this.items.length / this.pageSize); + }, + showPreviousLink() { + return this.currentPage == 0 ? false : true; + }, + showNextLink() { + return this.currentPage == (this.totalPages() - 1) ? false : true; + } + } +} +</script> diff --git a/src/components/CommunityComponents/CommunityHome.vue b/src/components/CommunityComponents/CommunityHome.vue index 99e3e48a02cfe8ae489140457f9d8ee61f4ba37d..a625f2fe57ceaac318b237ee858d440f39a0005b 100644 --- a/src/components/CommunityComponents/CommunityHome.vue +++ b/src/components/CommunityComponents/CommunityHome.vue @@ -1,5 +1,5 @@ <template> - <section class="w-full px-5 py-4 mx-auto rounded-md"> + <section class="w-full px-5 py-4 mx-auto rounded-md "> <CommunityHeader :admin-status="false" :community="community" @@ -26,19 +26,39 @@ class="w-full py-3 pl-10 pr-4 text-gray-700 bg-white border rounded-md dark:bg-gray-800 dark:text-gray-300 dark:border-gray-600 focus:border-primary-medium dark:focus:border-primary-medium focus:outline-none focus:ring" placeholder="Search" v-model="search" + @change="searchWritten" /> </div> - <!-- Item cards --> - <div class="absolute inset-x-0 px-6 py-3"> - <div - class="grid grid-flow-row-dense grid-cols-2 md:grid-cols-4 lg:grid-cols-5 w-full place-items-center" - > - <ItemCard - v-for="item in searchedItems" - :key="item" - :item="item" - @click="goToItemInfoPage(item.listingID)" + + <div class="absolute inset-x-0 px-5 py-3"> + + <!-- ItemCards --> + <div class="flex items-center justify-center w-screen"> + <!-- Shows items based on pagination --> + <div + class="grid grid-flow-row-dense grid-cols-2 md:grid-cols-4 lg:grid-cols-5 w-full" + v-if="showItems"> + <ItemCard v-for="item in visibleItems" :key="item" :item="item" @click="goToItemInfoPage(item.listingID)" /> + </div> + + <!-- Shows items based on search field input --> + <div + class="grid grid-flow-row-dense grid-cols-2 md:grid-cols-4 lg:grid-cols-5 w-full place-items-center" + v-if="showSearchedItems"> + <ItemCard v-for="item in searchedItems" :key="item" :item="item" @click="goToItemInfoPage(item.listingID)" /> + </div> + </div> + + + <!-- pagination --> + <div class="flex justify-center" v-if="showItems"> + <PaginationTemplate + v-bind:items="items" + v-on:page:update="updatePage" + v-bind:currentPage="currentPage" + v-bind:pageSize="pageSize" + class="mt-10" /> </div> </div> @@ -46,8 +66,10 @@ </template> <script> -import CommunityHeader from "@/components/CommunityComponents/CommunityHeader.vue"; import ItemCard from "@/components/ItemComponents/ItemCard"; +import CommunityHeader from "@/components/CommunityComponents/CommunityHeader"; +import PaginationTemplate from "@/components/BaseComponents/PaginationTemplate"; + import { GetCommunity, GetListingsInCommunity, @@ -59,6 +81,7 @@ export default { components: { CommunityHeader, ItemCard, + PaginationTemplate, }, computed: { @@ -93,6 +116,14 @@ export default { search: "", communityID: -1, community: {}, + + showItems: true, + showSearchedItems: false, + + //Variables connected to pagination + currentPage: 0, + pageSize: 12, + visibleItems: [], }; }, methods: { @@ -120,10 +151,36 @@ export default { let res = await getItemPictures(itemid); return res; }, + searchWritten: function (){ + //This method triggers when search input field is changed + if(this.search.length > 0){ + this.showItems = false; + this.showSearchedItems = true; + } + else{ + this.showItems = true; + this.showSearchedItems = false; + } + }, + + //Pagination + updatePage(pageNumber) { + this.currentPage = pageNumber; + this.updateVisibleTodos(); + }, + updateVisibleTodos() { + this.visibleItems = this.items.slice(this.currentPage * this.pageSize, (this.currentPage * this.pageSize) + this.pageSize); + + // if we have 0 visible items, go back a page + if (this.visibleItems.length === 0 && this.currentPage > 0) { + this.updatePage(this.currentPage -1); + } + }, }, - beforeMount() { - this.getCommunityFromAPI(); //To get the id of the community before mounting the view - this.getListingsOfCommunityFromAPI(); + async beforeMount() { + await this.getCommunityFromAPI(); //To get the id of the community before mounting the view + await this.getListingsOfCommunityFromAPI(); + this.updateVisibleTodos(); }, }; </script>