diff --git a/src/components/BaseComponents/TripleDotButton.vue b/src/components/BaseComponents/TripleDotButton.vue new file mode 100644 index 0000000000000000000000000000000000000000..5205015a39798c6af46dae4b99af4f6fbb826172 --- /dev/null +++ b/src/components/BaseComponents/TripleDotButton.vue @@ -0,0 +1,24 @@ +<template> + <button + id="dropdownDefault" + data-dropdown-toggle="dropdown" + class="w-10 h-10 text-gray-500 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-700 focus:outline-none focus:ring-4 focus:ring-gray-200 dark:focus:ring-gray-700 rounded-lg float-right text-sm p-1.5" + type="button" + > + <svg + class="w-6 h-6" + fill="currentColor" + viewBox="0 0 20 20" + xmlns="http://www.w3.org/2000/svg" + > + <path + d="M10 6a2 2 0 110-4 2 2 0 010 4zM10 12a2 2 0 110-4 2 2 0 010 4zM10 18a2 2 0 110-4 2 2 0 010 4z" + ></path> + </svg> + </button> +</template> +<script> +export default { + name: "TripleDotButton", +}; +</script> diff --git a/src/components/CommunityComponents/NewCommunityForm.vue b/src/components/CommunityComponents/NewCommunityForm.vue index bfa39aaa8d7c3b3136319565e476ea82d2751191..a64b9f927e1292b6ec346428052b6062ae9b1e62 100644 --- a/src/components/CommunityComponents/NewCommunityForm.vue +++ b/src/components/CommunityComponents/NewCommunityForm.vue @@ -1,28 +1,10 @@ <template> <div - class=" - md:ring-1 - ring-gray-300 - rounded-xl - overflow-hidden - mx-auto - mb-auto - max-w-md - w-full - p-4 - " + class="md:ring-1 ring-gray-300 rounded-xl overflow-hidden mx-auto mb-auto max-w-md w-full p-4" > <!-- Component heading --> <div - class=" - text-xl - md:text-2xl - font-medium - text-center text-gray-600 - dark:text-gray-200 - mt-4 - mb-10 - " + class="text-xl md:text-2xl font-medium text-center text-gray-600 dark:text-gray-200 mt-4 mb-10" > Opprett ny gruppe </div> @@ -36,25 +18,7 @@ > <div class="form-check"> <input - class=" - form-check-input - appearance-none - rounded-full - h-4 - w-4 - border border-gray-300 - bg-white - checked:bg-primary-medium checked:border-primary-medium - focus:outline-none - transition - duration-200 - mt-1 - align-top - bg-no-repeat bg-center bg-contain - float-left - mr-2 - cursor-pointer - " + class="form-check-input appearance-none rounded-full h-4 w-4 border border-gray-300 bg-white checked:bg-primary-medium checked:border-primary-medium focus:outline-none transition duration-200 mt-1 align-top bg-no-repeat bg-center bg-contain float-left mr-2 cursor-pointer" type="radio" name="flexRadioDefault" id="flexRadioOpen" @@ -72,25 +36,7 @@ </div> <div class="form-check"> <input - class=" - form-check-input - appearance-none - rounded-full - h-4 - w-4 - border border-gray-300 - bg-white - checked:bg-primary-medium checked:border-primary-medium - focus:outline-none - transition - duration-200 - mt-1 - align-top - bg-no-repeat bg-center bg-contain - float-left - mr-2 - cursor-pointer - " + class="form-check-input appearance-none rounded-full h-4 w-4 border border-gray-300 bg-white checked:bg-primary-medium checked:border-primary-medium focus:outline-none transition duration-200 mt-1 align-top bg-no-repeat bg-center bg-contain float-left mr-2 cursor-pointer" type="radio" name="flexRadioDefault" id="flexRadioPrivate" @@ -117,25 +63,7 @@ <input type="text" id="title" - class=" - block - w-full - px-4 - py-2 - mt-2 - text-gray-700 - placeholder-gray-500 - bg-white - border - rounded-md - dark:bg-gray-800 dark:border-gray-600 dark:placeholder-gray-400 - focus:border-primary-light - dark:focus:border-primary-light - focus:ring-opacity-40 - focus:outline-none - focus:ring - focus:ring-primary-light - " + class="block w-full px-4 py-2 mt-2 text-gray-700 placeholder-gray-500 bg-white border rounded-md dark:bg-gray-800 dark:border-gray-600 dark:placeholder-gray-400 focus:border-primary-light dark:focus:border-primary-light focus:ring-opacity-40 focus:outline-none focus:ring focus:ring-primary-light" v-model="v$.group.name.$model" required /> @@ -161,25 +89,7 @@ > <input type="text" - class=" - block - w-full - px-4 - py-2 - mt-2 - text-gray-700 - placeholder-gray-500 - bg-white - border - rounded-md - dark:bg-gray-800 dark:border-gray-600 dark:placeholder-gray-400 - focus:border-primary-light - dark:focus:border-primary-light - focus:ring-opacity-40 - focus:outline-none - focus:ring - focus:ring-primary-light - " + class="block w-full px-4 py-2 mt-2 text-gray-700 placeholder-gray-500 bg-white border rounded-md dark:bg-gray-800 dark:border-gray-600 dark:placeholder-gray-400 focus:border-primary-light dark:focus:border-primary-light focus:ring-opacity-40 focus:outline-none focus:ring focus:ring-primary-light" v-model="v$.group.place.$model" required /> @@ -207,25 +117,7 @@ id="description" rows="4" v-model="v$.group.description.$model" - class=" - block - w-full - px-4 - py-2 - mt-2 - text-gray-700 - placeholder-gray-500 - bg-white - border - rounded-md - dark:bg-gray-800 dark:border-gray-600 dark:placeholder-gray-400 - focus:border-primary-light - dark:focus:border-primary-light - focus:ring-opacity-40 - focus:outline-none - focus:ring - focus:ring-primary-light - " + class="block w-full px-4 py-2 mt-2 text-gray-700 placeholder-gray-500 bg-white border rounded-md dark:bg-gray-800 dark:border-gray-600 dark:placeholder-gray-400 focus:border-primary-light dark:focus:border-primary-light focus:ring-opacity-40 focus:outline-none focus:ring focus:ring-primary-light" required ></textarea> @@ -264,21 +156,7 @@ <!--<div class="text-error uppercase text-center">Midlertidig fjernet</div> --> <button @click="$refs.file.click()" - class=" - text-black - bg-gray-200 - hover:bg-grey-800 - focus:ring-4 focus:outline-none focus:ring-grey-300 - font-medium - rounded-lg - text-sm - sm:w-auto - px-5 - py-2.5 - text-center - dark:bg-grey-600 dark:hover:bg-grey-700 dark:focus:ring-grey-800 - disabled:opacity-50 - " + class="text-black bg-gray-200 hover:bg-grey-800 focus:ring-4 focus:outline-none focus:ring-grey-300 font-medium rounded-lg text-sm sm:w-auto px-5 py-2.5 text-center dark:bg-grey-600 dark:hover:bg-grey-700 dark:focus:ring-grey-800 disabled:opacity-50" :disabled="imageAdded" > Velg bilde @@ -432,7 +310,6 @@ export default { console.log(id); console.log(API_URL + "images/" + id); that.group.image = API_URL + "images/" + id; - }; fileReader.readAsArrayBuffer(image); this.imageThere = true; diff --git a/src/components/UserProfileComponents/UserItems.vue b/src/components/UserProfileComponents/UserItems.vue index 29deba9c6990b348a41796de1ba1f3d1d46d6a6e..b20cc54235d7912027965299414328313fdd1162 100644 --- a/src/components/UserProfileComponents/UserItems.vue +++ b/src/components/UserProfileComponents/UserItems.vue @@ -1,6 +1,6 @@ <template> <div id="headline" class="text-xl md:text-2xl text-primary-light font-medium"> - Dine gjenstander + Mine gjenstander </div> <!-- Search field --> <div class="relative" id="searchComponent"> @@ -25,7 +25,6 @@ @change="searchWritten" /> </div> - <div class="absolute inset-x-0 px-5 py-3"> <!-- ItemCards --> <div class="flex items-center justify-center w-screen"> @@ -34,7 +33,63 @@ 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" /> + <div class="cardContainer" id="item" v-for="item in visibleItems" :key="item"> + <ItemCard class="ItemCard w-fit h-fit" :item="item" /> + + <TripleDotButton class="DotButton" @click="openDotMenu(item)"> + </TripleDotButton> + + <div + v-show="item.toggle" + class="options z-10 w-44 text-base list-none bg-white rounded divide-y divide-gray-100 shadow dark:bg-gray-700" + > + <ul + class="py-1 absolute bg-white ring-1 ring-gray-300 rounded-xl" + aria-labelledby="dropdownDefault" + > + <li> + <button + to="/user/userItems" + class="block py-2 px-4 text-sm text-gray-700 hover:bg-gray-100 dark:hover:bg-gray-600 dark:text-gray-200 dark:hover:text-white" + > + Rediger gjenstand + </button> + </li> + <li> + <button + @click="goToDeleteItem(item.listingID)" + class="block py-2 px-4 text-sm text-error-medium hover:bg-gray-100 dark:hover:bg-gray-600 dark:text-gray-200 dark:hover:text-white" + > + Slett gjenstand + </button> + </li> + </ul> + </div> + </div> + + <CustomFooterModal + @close="this.readyToDelete = false" + :visible="readyToDelete" + :title="'Sikker på at du vil slette annonsen?'" + :message="''" + > + <div class="flex justify-center p-2"> + <ColoredButton + id="#cancelDeleteButton" + :text="'Avbryt'" + @click="cancelDelete" + class="bg-gray-500 m-2" + ></ColoredButton> + + <ColoredButton + id="confirmDeleteButton" + @click="deleteItem" + :text="'Slett'" + class="m-2 bg-error-medium" + > + </ColoredButton> + </div> + </CustomFooterModal> </div> <!-- Shows items based on search field input --> @@ -42,7 +97,60 @@ 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" /> + <div class="cardContainer" v-for="item in searchedItems" :key="item"> + <ItemCard class="ItemCard" :item="item" /> + <TripleDotButton class="DotButton" @click="openDotMenu(item)"> </TripleDotButton> + + <div + v-show="item.toggle" + class="options z-10 w-44 text-base list-none bg-white rounded divide-y divide-gray-100 shadow dark:bg-gray-700" + > + <ul + class="py-1 absolute bg-white ring-1 ring-gray-300 rounded-xl" + aria-labelledby="dropdownDefault" + > + <li> + <button + to="/user/userItems" + class="block py-2 px-4 text-sm text-gray-700 hover:bg-gray-100 dark:hover:bg-gray-600 dark:text-gray-200 dark:hover:text-white" + > + Rediger gjenstand + </button> + </li> + <li> + <button + @click="goToDeleteItem(item.listingID)" + class="block py-2 px-4 text-sm text-error-medium hover:bg-gray-100 dark:hover:bg-gray-600 dark:text-gray-200 dark:hover:text-white" + > + Slett gjenstand + </button> + </li> + </ul> + </div> + </div> + <CustomFooterModal + @close="this.readyToDelete = false" + :visible="readyToDelete" + :title="'Sikker på at du vil slette annonsen?'" + :message="''" + > + <div class="flex justify-center p-2"> + <ColoredButton + id="#cancelDeleteButton" + :text="'Avbryt'" + @click="cancelDelete" + class="bg-gray-500 m-2" + ></ColoredButton> + + <ColoredButton + id="confirmDeleteButton" + @click="deleteItem" + :text="'Slett'" + class="m-2 bg-error-medium" + > + </ColoredButton> + </div> + </CustomFooterModal> </div> </div> <!-- pagination --> @@ -58,15 +166,23 @@ </div> </template> <script> +import TripleDotButton from "@/components/BaseComponents/TripleDotButton.vue"; import { GetUserListings, getItemPictures } from "@/utils/apiutil"; +import ColoredButton from "@/components/BaseComponents/ColoredButton.vue"; + +import UserService from "@/services/user.service"; import ItemCard from "@/components/ItemComponents/ItemCard.vue"; import PaginationTemplate from "@/components/BaseComponents/PaginationTemplate"; +import CustomFooterModal from "@/components/BaseComponents/CustomFooterModal.vue"; export default { name: "UserItems", components: { ItemCard, + TripleDotButton, PaginationTemplate, + CustomFooterModal, + ColoredButton, }, data() { return { @@ -77,10 +193,14 @@ export default { address: "", title: "", pricePerDay: 0, + toggle: false, }, + chosenItem: null, showItems: true, showSearchedItems: false, search: "", + readyToDelete: false, + dropdown: false, //Variables connected to pagination currentPage: 0, pageSize: 12, @@ -102,15 +222,30 @@ export default { }, }, methods: { + openDotMenu(item){ + if(item.toggle == false){ + for(var i = 0; i<this.visibleItems.length; i++){ + this.visibleItems[i].toggle = false; + } + item.toggle = true; + } + else{ + item.toggle = false; + } + }, getUserListingsFromAPI: async function () { this.items = await GetUserListings(); for (var i = 0; i < this.items.length; i++) { + this.items[i].toggle = false; let images = await getItemPictures(this.items[i].listingID); if (images.length > 0) { this.items[i].img = images[0].picture; } } }, + cancelDelete() { + this.readyToDelete = false; + }, //Pagination updatePage(pageNumber) { this.currentPage = pageNumber; @@ -127,6 +262,16 @@ export default { this.updatePage(this.currentPage - 1); } }, + goToDeleteItem(item) { + console.log("Halllllo: " + item) + this.chosenItem = item; + this.readyToDelete = true; + }, + async deleteItem() { + console.log("HEI " + this.chosenItem); + await UserService.setListingToDeleted(this.chosenItem); + this.$router.go(0); + }, searchWritten: function () { //This method triggers when search input field is changed if (this.search.length > 0) { @@ -150,5 +295,18 @@ export default { display: block; margin-top: 10px; margin-bottom: 10px; + margin-left: 20px; +} +.cardContainer{ + position: relative; +} +.DotButton{ + position: absolute; + right: 40px; + bottom: 10px } +.options{ + position: absolute; +} + </style> diff --git a/src/services/user.service.js b/src/services/user.service.js index b8f10603ecbd21ebfe0eec3b7e7d2227b025ffad..e2bf48bd4b19f07b3b5f2de07544d1d05a0fc020 100644 --- a/src/services/user.service.js +++ b/src/services/user.service.js @@ -27,6 +27,17 @@ class UserService { .catch((err) => console.error(err)); } + async setListingToDeleted(listingId) { + return await axios + .put(API_URL + "listing/" + listingId, { + headers: tokenHeader(), + }) + .then((res) => { + return res.data; + }) + .catch((err) => console.error(err)); + } + async getRenterHistory() { return await axios .get(API_URL + "user/profile/rent/history", { diff --git a/src/utils/apiutil.js b/src/utils/apiutil.js index f33d6db9f3ce03cac2a5b9d6dc149c41b1949912..88717abceb23d9a2537ab240708f7bdaaf669b19 100644 --- a/src/utils/apiutil.js +++ b/src/utils/apiutil.js @@ -328,15 +328,15 @@ export function postNewRating(ratingInfo) { export function postNewImageCommunity(image) { return axios - .post(API_URL + "images", image, { - headers: {...tokenHeader(), "Content-Type": "image/png"}, - }) - .then((response) => { - console.log(response.data); - return response.data; - }) - .catch((error) => { - console.log(error); - return error; - }); + .post(API_URL + "images", image, { + headers: { ...tokenHeader(), "Content-Type": "image/png" }, + }) + .then((response) => { + console.log(response.data); + return response.data; + }) + .catch((error) => { + console.log(error); + return error; + }); } diff --git a/src/views/HelpView.vue b/src/views/HelpView.vue index 56f7e0e267f102c5493e80579c7c9c11cf9aed45..585749da03358203863f9f07e23a64c86fec264d 100644 --- a/src/views/HelpView.vue +++ b/src/views/HelpView.vue @@ -114,13 +114,14 @@ export default { { question: "Hvordan kan jeg bli med i en gruppe?", answer: - "På hovedsiden vil alle offentlige og lukkede grupper vises. Når du trykker på ønsket gruppe vil du få muligheten til å bli med/sende medlemsforespørsel.", + "På hovedsiden vil alle offentlige og lukkede grupper vises. Når du trykker på ønsket gruppe vil du få muligheten til å bli med/sende medlemsforespørsel.", toggle: false, }, { - question: "Hva vil jeg ha tilgang til ved å logge inn/opprette en bruker?", + question: + "Hva vil jeg ha tilgang til ved å logge inn/opprette en bruker?", answer: - "Uten å være logget inn vil du kunne se alle grupper, og også se gjenstander som ligger ute til lån i offentlige grupper. For å kunne låne en gjenstand må du være med i gruppen gjenstanden ligger i, og for dette må du være innlogget. Du må også være innlogget for å sende medlemsforespørsel i lukkede grupper.", + "Uten å være logget inn vil du kunne se alle grupper, og også se gjenstander som ligger ute til lån i offentlige grupper. For å kunne låne en gjenstand må du være med i gruppen gjenstanden ligger i, og for dette må du være innlogget. Du må også være innlogget for å sende medlemsforespørsel i lukkede grupper.", toggle: false, }, ],