diff --git a/src/components/CommunityComponents/CommunityHeader.vue b/src/components/CommunityComponents/CommunityHeader.vue index 4df062434b011c1515a9be2f159dc8ab200db754..afd63a75c4fb1c7ac271c6eaaf9c94096fec4728 100644 --- a/src/components/CommunityComponents/CommunityHeader.vue +++ b/src/components/CommunityComponents/CommunityHeader.vue @@ -1,6 +1,7 @@ <template> - <!-- TODO PUT A LOADER HERE --> - <div v-if="loading">LASTER...</div> + <div v-if="loading" class="flex place-content-center mx-4"> + <LoaderSpinner /> + </div> <div v-else class="flex items-center justify-between mx-4"> <router-link :to="'/community/' + community.communityId" @@ -83,6 +84,7 @@ <script> import CommunityHamburger from "@/components/CommunityComponents/CommunityHamburger"; import ColoredButton from "@/components/BaseComponents/ColoredButton"; +import LoaderSpinner from "@/components/BaseComponents/LoaderSpinner"; import CommunityService from "@/services/community.service"; import CustomFooterModal from "@/components/BaseComponents/CustomFooterModal"; import { parseCurrentUser } from "@/utils/token-utils"; @@ -97,6 +99,7 @@ export default { CommunityHamburger, ColoredButton, CustomFooterModal, + LoaderSpinner, }, computed: { userid() { diff --git a/src/components/CommunityComponents/CommunityHome.vue b/src/components/CommunityComponents/CommunityHome.vue index f52a2fddcaba4ace9c5be33a7cdfc3901695ace8..bc068b83aaef9300e1211ffe3993c35558b84295 100644 --- a/src/components/CommunityComponents/CommunityHome.vue +++ b/src/components/CommunityComponents/CommunityHome.vue @@ -1,78 +1,84 @@ <template> - <section class="w-full px-5 py-4 mx-auto rounded-md"> - <CommunityHeader :admin="false" class="mb-5" /> + <div> + <div v-if="loading" class="flex place-content-center"> + <LoaderSpinner /> + </div> + <section v-else class="w-full px-5 py-4 mx-auto rounded-md"> + <CommunityHeader :admin="false" class="mb-5" /> - <!-- Search field --> - <div class="relative" id="searchComponent"> - <span class="absolute inset-y-0 left-0 flex items-center pl-3"> - <svg class="w-5 h-5 text-gray-400" viewBox="0 0 24 24" fill="none"> - <path - d="M21 21L15 15M17 10C17 13.866 13.866 17 10 17C6.13401 17 3 13.866 3 10C3 6.13401 6.13401 3 10 3C13.866 3 17 6.13401 17 10Z" - stroke="currentColor" - stroke-width="2" - stroke-linecap="round" - stroke-linejoin="round" - ></path> - </svg> - </span> + <!-- Search field --> + <div class="relative" id="searchComponent"> + <span class="absolute inset-y-0 left-0 flex items-center pl-3"> + <svg class="w-5 h-5 text-gray-400" viewBox="0 0 24 24" fill="none"> + <path + d="M21 21L15 15M17 10C17 13.866 13.866 17 10 17C6.13401 17 3 13.866 3 10C3 6.13401 6.13401 3 10 3C13.866 3 17 6.13401 17 10Z" + stroke="currentColor" + stroke-width="2" + stroke-linecap="round" + stroke-linejoin="round" + ></path> + </svg> + </span> - <input - type="text" - 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> + <input + type="text" + 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> - <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 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> - <!-- 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)" + <!-- 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> - - <!-- 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> - </section> + </section> + </div> </template> <script> import ItemCard from "@/components/ItemComponents/ItemCard"; import CommunityHeader from "@/components/CommunityComponents/CommunityHeader"; import PaginationTemplate from "@/components/BaseComponents/PaginationTemplate"; +import LoaderSpinner from "@/components/BaseComponents/LoaderSpinner"; import { GetCommunity, @@ -85,6 +91,7 @@ export default { CommunityHeader, ItemCard, PaginationTemplate, + LoaderSpinner, }, computed: { searchedItems() { @@ -123,6 +130,8 @@ export default { showItems: true, showSearchedItems: false, + loading: false, + //Variables connected to pagination currentPage: 0, pageSize: 12, @@ -181,9 +190,11 @@ export default { }, }, async beforeMount() { + this.loading = true; await this.getCommunityFromAPI(); //To get the id of the community before mounting the view await this.getListingsOfCommunityFromAPI(); this.updateVisibleTodos(); + this.loading = false; }, }; </script> diff --git a/src/views/CommunityViews/CommunityView.vue b/src/views/CommunityViews/CommunityView.vue index 52e711014b45736bf30d0a21122e03eb24262b55..c36cae56b1b1f9fc41e3167726663944cf1e94f4 100644 --- a/src/views/CommunityViews/CommunityView.vue +++ b/src/views/CommunityViews/CommunityView.vue @@ -1,68 +1,80 @@ <template> - <!-- My communities, with pagination --> - <div v-if="loggedIn"> - <div class="flex flex-row p-4 relative"> - <div class="text-xl md:text-2xl text-primary-light font-medium w-full"> - Mine grupper - </div> - <UserAddIcon - class="cursor-pointer max-h-6 max-w-6 float-right grow text-primary-dark" - @click="$router.push('/newCommunity')" - alt="Opprett ny gruppe" - /> - </div> - <CommunityList :communities="visibleMyCommunities" :member="true" /> - - <!-- pagination my communities --> - <div class="flex justify-center"> - <PaginationTemplate - v-bind:items="myCommunities" - v-on:page:update="updatePageMyCommunities" - v-bind:currentPage="currentPageMyCommunities" - v-bind:pageSize="pageSizeMyCommunities" - class="mt-4" - /> + <div> + <div v-if="loading" class="flex place-content-center p-8"> + <LoaderSpinner /> </div> - </div> + <div v-else> + <!-- My communities, with pagination --> + <div v-if="loggedIn"> + <div class="flex flex-row p-4 relative"> + <div + class="text-xl md:text-2xl text-primary-light font-medium w-full" + > + Mine grupper + </div> + <UserAddIcon + class="cursor-pointer max-h-6 max-w-6 float-right grow text-primary-dark" + @click="$router.push('/newCommunity')" + alt="Opprett ny gruppe" + /> + </div> + <CommunityList :communities="visibleMyCommunities" :member="true" /> - <!-- Public communities, with search and pagination --> - <p class="text-xl md:text-2xl text-primary-light font-medium w-full p-4"> - Offentlige grupper - </p> - <!-- Search field --> - <div class="relative mt-1 mx-2" id="searchComponent"> - <span class="absolute inset-y-0 left-0 flex items-center pl-3"> - <div class="w-5 h-5 text-gray-400"> - <SearchIcon /> + <!-- pagination my communities --> + <div class="flex justify-center"> + <PaginationTemplate + v-bind:items="myCommunities" + v-on:page:update="updatePageMyCommunities" + v-bind:currentPage="currentPageMyCommunities" + v-bind:pageSize="pageSizeMyCommunities" + class="mt-4" + /> + </div> </div> - </span> - <input - type="text" - id="searchInput" - 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> + <!-- Public communities, with search and pagination --> + <p class="text-xl md:text-2xl text-primary-light font-medium w-full p-4"> + Offentlige grupper + </p> + <!-- Search field --> + <div class="relative mt-1 mx-2" id="searchComponent"> + <span class="absolute inset-y-0 left-0 flex items-center pl-3"> + <div class="w-5 h-5 text-gray-400"> + <SearchIcon /> + </div> + </span> - <!-- Public communities list, two lists, one for when it's searched and one for pagination --> - <div v-if="showPaginated"> - <CommunityList :communities="visiblePublicCommunities" :member="false" /> - </div> - <div v-if="showSearched"> - <CommunityList :communities="searchPublicCommunities" :member="false" /> - </div> - <!-- pagination Public communities --> - <div class="flex justify-center"> - <PaginationTemplate - v-bind:items="publicCommunities" - v-on:page:update="updatePagePublicCommunities" - v-bind:currentPage="currentPagePublicCommunities" - v-bind:pageSize="pageSizePublicCommunities" - class="my-4" - /> + <input + type="text" + id="searchInput" + 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> + + <!-- Public communities list, two lists, one for when it's searched and one for pagination --> + <div v-if="showPaginated"> + <CommunityList + :communities="visiblePublicCommunities" + :member="false" + /> + </div> + <div v-if="showSearched"> + <CommunityList :communities="searchPublicCommunities" :member="false" /> + </div> + <!-- pagination Public communities --> + <div class="flex justify-center"> + <PaginationTemplate + v-bind:items="publicCommunities" + v-on:page:update="updatePagePublicCommunities" + v-bind:currentPage="currentPagePublicCommunities" + v-bind:pageSize="pageSizePublicCommunities" + class="my-4" + /> + </div> + </div> </div> </template> @@ -71,11 +83,13 @@ import CommunityList from "@/components/CommunityComponents/CommunityList.vue"; import { UserAddIcon, SearchIcon } from "@heroicons/vue/outline"; import PaginationTemplate from "@/components/BaseComponents/PaginationTemplate"; import CommunityService from "@/services/community.service"; +import LoaderSpinner from "@/components/BaseComponents/LoaderSpinner"; export default { name: "HomeView", data() { return { + loading: false, loggedIn: false, myCommunities: [], publicCommunities: [], @@ -97,6 +111,7 @@ export default { UserAddIcon, PaginationTemplate, SearchIcon, + LoaderSpinner, }, computed: { searchPublicCommunities() { @@ -160,6 +175,7 @@ export default { }, }, async mounted() { + this.loading = true; await this.load(); //Double loop not bad :) for (var i = 0; i < this.publicCommunities.length; i++) { @@ -172,8 +188,8 @@ export default { } } } - this.updateVisibleCommunities(); + this.loading = false; }, }; </script> diff --git a/src/views/UserProfileViews/MyCommunitiesView.vue b/src/views/UserProfileViews/MyCommunitiesView.vue index 6a5c376b0ac2cde7dcc8ee0dff1cfef2ca5cb6d5..e474528640a45dc3254256ee8ef9afef3871f7ea 100644 --- a/src/views/UserProfileViews/MyCommunitiesView.vue +++ b/src/views/UserProfileViews/MyCommunitiesView.vue @@ -1,16 +1,23 @@ <template> - <!-- My communities, with pagination --> - <div class="flex flex-row p-4 relative"> - <div class="text-xl md:text-2xl text-primary-light font-medium w-full"> - Mine grupper + <div> + <div v-if="loading" class="flex place-content-center p-8"> + <LoaderSpinner /> + </div> + <div v-else> + <!-- My communities, with pagination --> + <div class="flex flex-row p-4 relative"> + <div class="text-xl md:text-2xl text-primary-light font-medium w-full"> + Mine grupper + </div> + <UserAddIcon + class="cursor-pointer max-h-6 max-w-6 float-right grow text-primary-dark" + @click="$router.push('/newCommunity')" + alt="Opprett ny gruppe" + /> + </div> + <CommunityList :communities="myCommunities" :member="true" /> </div> - <UserAddIcon - class="cursor-pointer max-h-6 max-w-6 float-right grow text-primary-dark" - @click="$router.push('/newCommunity')" - alt="Opprett ny gruppe" - /> </div> - <CommunityList :communities="myCommunities" :member="true" /> </template> <script> @@ -22,6 +29,7 @@ export default { data() { return { myCommunities: [], + loading: false, }; }, components: { @@ -29,7 +37,9 @@ export default { UserAddIcon, }, async beforeCreate() { + this.loading = true; this.myCommunities = await CommunityService.getUserCommunities(); + this.loading = false; }, }; </script>