diff --git a/src/components/CommunityComponents/CommunityHome.vue b/src/components/CommunityComponents/CommunityHome.vue index 63ccc0be85db9364b8f79ca0d1ab2fd19769fb87..8004946f513cee97738fbd7b432d5651dd7e117c 100644 --- a/src/components/CommunityComponents/CommunityHome.vue +++ b/src/components/CommunityComponents/CommunityHome.vue @@ -1,7 +1,10 @@ <template> <section class="w-full px-5 py-4 mx-auto rounded-md"> - - <CommunityHeader :admin-status="false" :community="community" class="mb-5"/> + <CommunityHeader + :admin-status="false" + :community="community" + class="mb-5" + /> <!-- Search field --> <div class="relative" id="searchComponent"> @@ -28,7 +31,9 @@ <!-- 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"> + <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" /> </div> </div> @@ -61,7 +66,11 @@ export default { return filteredItems; }, }, - + created() { + if (this.$store.state.user.token !== null) { + this.isLoggedIn = true; + } + }, data() { return { items: [], @@ -77,18 +86,20 @@ export default { }; }, methods: { - getCommunityFromAPI: async function (){ - this.communityID = await this.$router.currentRoute.value.params.communityID; + getCommunityFromAPI: async function () { + this.communityID = await this.$router.currentRoute.value.params + .communityID; this.community = await GetCommunity(this.communityID); }, - getListingsOfCommunityFromAPI: async function(){ - this.communityID = await this.$router.currentRoute.value.params.communityID; + getListingsOfCommunityFromAPI: async function () { + this.communityID = await this.$router.currentRoute.value.params + .communityID; this.items = await GetListingsInCommunity(this.communityID); }, }, beforeMount() { this.getCommunityFromAPI(); //To get the id of the community before mounting the view this.getListingsOfCommunityFromAPI(); - } + }, }; </script> diff --git a/src/components/CommunityComponents/CommunityList.vue b/src/components/CommunityComponents/CommunityList.vue index 045eeadf16730ecd725b4e0c9990fbad0ee3d9ca..859e69d3e7f96c56935f64dd7b16beca2f403188 100644 --- a/src/components/CommunityComponents/CommunityList.vue +++ b/src/components/CommunityComponents/CommunityList.vue @@ -1,21 +1,22 @@ <template> <ul> - <li v-for="(group, index) in groupList" :key="index"> - <group-list-item :group="group" /> + <li v-for="community in communities" :key="community"> + <CommunityListItem :community="community" :member="member" /> </li> </ul> </template> <script> -import GroupListItem from "@/components/CommunityComponents/CommunityListItem.vue"; +import CommunityListItem from "@/components/CommunityComponents/CommunityListItem.vue"; export default { - name: "GroupList", + name: "CommunityList", props: { - groupList: Array, + communities: Array, + member: Boolean, }, components: { - GroupListItem, + CommunityListItem, }, }; </script> diff --git a/src/components/CommunityComponents/CommunityListItem.vue b/src/components/CommunityComponents/CommunityListItem.vue index 81d2b7dee530d7eae79f97e954ff19a52936bd34..d75938f456c1ed61aad0ebc89db8e04a2282bc2f 100644 --- a/src/components/CommunityComponents/CommunityListItem.vue +++ b/src/components/CommunityComponents/CommunityListItem.vue @@ -1,46 +1,66 @@ <template> + <CustomFooterModal + @close="this.dialogOpen = false" + :visible="dialogOpen" + :title="community.name" + :message="community.description" + > + <div class="flex justify-center p-2"> + <ColoredButton + v-if="!member" + :text="'Bli med'" + @click="goToJoin(community.communityId)" + /> + <ColoredButton + v-if="member" + :text="'Gå til'" + @click="goToGroup(community.communityId)" + /> + </div> + </CustomFooterModal> <div + @click="toggleDialog()" class="bg-white shadow dark:bg-gray-800 select-none cursor-pointer hover:bg-gray-50 flex items-center p-4" > <div class="h-10 w-10 flex flex-col justify-center items-center mr-4"> - <img alt="groupIMG" src="../../assets/group.png" /> + <UserGroupIcon v-if="!community.image" alt="Felleskapets bilde" /> + <!-- TODO: USE COMMUNITY IMAGE <img alt="Felleskapets bilde" src="@/assets/group.png" /> --> </div> - <div class="flex-1 pl-1"> - <div class="font-medium dark:text-white"> - {{ group.name }} + <div class="flex-1 pl-1 overflow-hidden"> + <div class="font-medium dark:text-white truncate"> + {{ community.name }} </div> </div> - <div class="flex flex-row justify-center"> - <button - @click="goToJoin(group.communityId)" - v-if="!isMember" - class="px-4 py-2 w-24 font-medium tracking-wide text-white capitalize transition-colors duration-200 transform bg-blue-600 rounded-md hover:bg-blue-500 focus:outline-none focus:ring focus:ring-blue-300 focus:ring-opacity-80" - > - Bli med - </button> - <button - v-if="isMember" - @click="goToGroup(group.communityId)" - class="px-4 py-2 w-24 font-medium tracking-wide text-white capitalize transition-colors duration-200 transform bg-blue-600 rounded-md hover:bg-blue-500 focus:outline-none focus:ring focus:ring-blue-300 focus:ring-opacity-80" - > - Gå til - </button> + <div class="flex flex-row justify-center items-center"> + <LockClosedIcon + v-if="community.visibility === 0" + class="max-h-6 max-w-6 shrink m-2" + /> </div> </div> </template> <script> -import { getMyGroups } from "@/utils/apiutil"; +import CustomFooterModal from "@/components/BaseComponents/CustomFooterModal.vue"; +import ColoredButton from "@/components/BaseComponents/ColoredButton.vue"; +import { UserGroupIcon, LockClosedIcon } from "@heroicons/vue/outline"; export default { - name: "GroupListItem", + name: "CommunityListItem", + components: { + CustomFooterModal, + ColoredButton, + UserGroupIcon, + LockClosedIcon, + }, data() { return { - myGroups: [], + dialogOpen: false, }; }, props: { - group: Object, + community: Object, + member: Boolean, }, methods: { goToGroup(id) { @@ -49,15 +69,9 @@ export default { goToJoin(id) { this.$router.push("/community/" + id + "/join"); }, - async getMyGroups() { - this.myGroups = await getMyGroups(); + toggleDialog() { + this.dialogOpen = !this.dialogOpen; }, - isMember(group) { - return this.myGroups.includes(group); - }, - }, - beforeMount() { - this.getMyGroups(); }, }; </script> diff --git a/src/components/CommunityComponents/ItemCard.vue b/src/components/CommunityComponents/ItemCard.vue index 67d01a798800a5ddff31b1452fa48936e6317f4a..4f4b52526a96f32d29ed839245254a5c12228f1e 100644 --- a/src/components/CommunityComponents/ItemCard.vue +++ b/src/components/CommunityComponents/ItemCard.vue @@ -11,7 +11,9 @@ {{ item.address }} </p> <p class="font-bold text-sm" id="title">{{ item.title }}</p> - <p class="text-gray-700 text-xs" id="price">{{ item.pricePerDay }} kr</p> + <p class="text-gray-700 text-xs" id="price"> + {{ item.pricePerDay }} kr + </p> </div> </div> </div> diff --git a/src/utils/apiutil.js b/src/utils/apiutil.js index b3aa02de8b647da5780bc6bafdcf542ecc59a784..c45384cb725f515cb30f17e0104a0b3a02ab9972 100644 --- a/src/utils/apiutil.js +++ b/src/utils/apiutil.js @@ -149,27 +149,27 @@ export function getVisibleGroups() { } export async function GetCommunity(communityID) { - return axios - .get(API_URL + "community/" + communityID, { - headers: tokenHeader(), - }) - .then((response) => { - return response.data; - }) - .catch((error) => { - console.error(error); - }); + return axios + .get(API_URL + "community/" + communityID, { + headers: tokenHeader(), + }) + .then((response) => { + return response.data; + }) + .catch((error) => { + console.error(error); + }); } export async function GetListingsInCommunity(communityID) { - return axios - .get(API_URL + "community/" + communityID + "/listings", { - headers: tokenHeader(), - }) - .then((response) => { - return response.data; - }) - .catch((error) => { - console.error(error); - }); + return axios + .get(API_URL + "community/" + communityID + "/listings", { + headers: tokenHeader(), + }) + .then((response) => { + return response.data; + }) + .catch((error) => { + console.error(error); + }); } diff --git a/src/views/CommunityViews/CommunityHomeView.vue b/src/views/CommunityViews/CommunityHomeView.vue index cabfd1b6ed2ea1e5775868f160484ddd9fa99b06..40886b3feb0816f305ee4a5045f180478677c8bb 100644 --- a/src/views/CommunityViews/CommunityHomeView.vue +++ b/src/views/CommunityViews/CommunityHomeView.vue @@ -1,15 +1,13 @@ <template> - <GroupHome></GroupHome> + <CommunityHome /> </template> <script> -import GroupHome from "@/components/CommunityComponents/CommunityHome"; +import CommunityHome from "@/components/CommunityComponents/CommunityHome.vue"; export default { - name: "GroupHomeView.vue", + name: "CommunityHomeView", components: { - GroupHome, + CommunityHome, }, }; </script> - -<style scoped></style> diff --git a/src/views/CommunityViews/CommunityView.vue b/src/views/CommunityViews/CommunityView.vue index a2279054ac63749bd62f790783e9adefb23edaa7..9fd39f5f305a7592f633795254899fa3cf3883a8 100644 --- a/src/views/CommunityViews/CommunityView.vue +++ b/src/views/CommunityViews/CommunityView.vue @@ -1,56 +1,49 @@ <template> - <div> - <img - class="cursor-pointer h-8 mr-4 mt-4 float-right" - v-if="isLoggedIn" - src="@/assets/newCommunity.png" - alt="Legg til gruppe" + <div v-if="loggedIn"> + <div class="flex flex-row p-4 relative"> + <p class="capitalize font-bold w-full">Mine felleskap</p> + <PlusIcon + class="cursor-pointer max-h-6 max-w-6 float-right grow" @click="$router.push('/createNewGroup')" - /> - </div> - <div> - <div id="myGroups" v-if="isLoggedIn"> - <div class="m-4" >Mine grupper:</div> - <group-list :groupList="myGroups" /> - </div> - <div id="localGroups"> - <div class="m-4">Offentlige grupper:</div> - <group-list :groupList="localGroups" /> + v-if="loggedIn" + alt="Lag ett nytt felleskap" + /> </div> + <CommunityList :communities="myCommunities" :member="true" /> </div> - + <p class="capitalize font-bold w-full p-4">Offentlige felleskap</p> + <CommunityList :communities="publicCommunities" :member="false" /> </template> <script> -import GroupList from "@/components/CommunityComponents/CommunityList.vue"; +import CommunityList from "@/components/CommunityComponents/CommunityList.vue"; import { getMyGroups, getVisibleGroups } from "@/utils/apiutil"; +import { PlusIcon } from "@heroicons/vue/outline"; export default { name: "HomeView", data() { return { - isLoggedIn: false, - myGroups: [], - localGroups: [], + loggedIn: false, + myCommunities: [], + publicCommunities: [], }; }, components: { - GroupList, - }, - methods: { - async getMyGroups() { - this.myGroups = await getMyGroups(); - }, - async getPotentialGroups() { - this.localGroups = await getVisibleGroups(); - }, + CommunityList, + PlusIcon, }, async created() { - await this.getMyGroups(); - await this.getPotentialGroups(); - if(this.$store.state.user.token !== null){ - this.isLoggedIn = true - } - }, + this.publicCommunities = await getVisibleGroups(); + this.loggedIn = this.$store.state.user.token !== null; + if (!this.loggedIn) return; + + this.myCommunities = await getMyGroups(); + + // Remove all of the user's communities from the public communities arrays + this.publicCommunities = this.publicCommunities.filter( + (val) => !this.myCommunities.includes(val) + ); + }, }; </script> diff --git a/tests/unit/apiutil-communityHome-mock.spec.js b/tests/unit/apiutil-communityHome-mock.spec.js index e627100092bd72fc03e951682a4df9d58ecc78e6..4ab75d6469cf79e31546054eebae45ce5976284d 100644 --- a/tests/unit/apiutil-communityHome-mock.spec.js +++ b/tests/unit/apiutil-communityHome-mock.spec.js @@ -1,58 +1,55 @@ -import {GetCommunity, GetListingsInCommunity} from "@/utils/apiutil"; +import { GetCommunity, GetListingsInCommunity } from "@/utils/apiutil"; import axios from "axios"; jest.mock("axios"); describe("testing mocking of apiutil.js", () => { - - it("check that existing group returns correctly", async () => { - - const expectedResponse = { - communityId: 4040, - name: "Fisken i vannet", - description: "For vi som liker fjell fisk", - visibility: 1, - location: "Bergen brygge", - picture: "fish blub blub" - }; - - axios.get.mockImplementation(() => - Promise.resolve({ data: expectedResponse }) - ); - - const communityResponse = await GetCommunity(4040); - expect(communityResponse.name).toBe(expectedResponse.name); - }); - - it("check that existing group returns correct listings", async () => { - - const expectedResponse = { - item1: { - title: "Fiskekurs", - description: "Fisking og sånn", - pricePerDay: 200, - address: "Vannet", - userID: 6, - categoryNames: null, - communityIDs: null - }, - - item2: { - title: "TestFraFrontend", - description: "oslo", - pricePerDay: 500, - address: "oslo", - userID: 1, - categoryNames: null, - communityIDs: null - }, - }; - - axios.get.mockImplementation(() => - Promise.resolve({ data: expectedResponse }) - ); - - const communityItemResponse = await GetListingsInCommunity(4040); - expect(communityItemResponse).toBe(expectedResponse); - }) + it("check that existing group returns correctly", async () => { + const expectedResponse = { + communityId: 4040, + name: "Fisken i vannet", + description: "For vi som liker fjell fisk", + visibility: 1, + location: "Bergen brygge", + picture: "fish blub blub", + }; + + axios.get.mockImplementation(() => + Promise.resolve({ data: expectedResponse }) + ); + + const communityResponse = await GetCommunity(4040); + expect(communityResponse.name).toBe(expectedResponse.name); + }); + + it("check that existing group returns correct listings", async () => { + const expectedResponse = { + item1: { + title: "Fiskekurs", + description: "Fisking og sånn", + pricePerDay: 200, + address: "Vannet", + userID: 6, + categoryNames: null, + communityIDs: null, + }, + + item2: { + title: "TestFraFrontend", + description: "oslo", + pricePerDay: 500, + address: "oslo", + userID: 1, + categoryNames: null, + communityIDs: null, + }, + }; + + axios.get.mockImplementation(() => + Promise.resolve({ data: expectedResponse }) + ); + + const communityItemResponse = await GetListingsInCommunity(4040); + expect(communityItemResponse).toBe(expectedResponse); + }); });