Skip to content
Snippets Groups Projects
Commit 1620eba4 authored by henrikburmann's avatar henrikburmann
Browse files

My items added

parent ddf68d07
No related branches found
No related tags found
1 merge request!90My items
Pipeline #180085 passed
<template> <template>
<div v-if="totalPages() > 0"> <div v-if="totalPages() > 0">
<span v-if="showPreviousLink()" <span
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" v-if="showPreviousLink()"
@click="updatePage(currentPage - 1)"> 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 Forrige
</span> </span>
<label class="mx-2">{{ currentPage + 1 }} av {{ totalPages() }}</label> <label class="mx-2">{{ currentPage + 1 }} av {{ totalPages() }}</label>
<span <span
v-if="showNextLink()" 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" 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)"> @click="updatePage(currentPage + 1)"
>
Neste Neste
</span> </span>
</div> </div>
...@@ -17,11 +20,11 @@ ...@@ -17,11 +20,11 @@
<script> <script>
export default { export default {
name: 'paginationTemplate', name: "paginationTemplate",
props: ['items', 'currentPage', 'pageSize'], props: ["items", "currentPage", "pageSize"],
methods: { methods: {
updatePage(pageNumber) { updatePage(pageNumber) {
this.$emit('page:update', pageNumber); this.$emit("page:update", pageNumber);
}, },
totalPages() { totalPages() {
return Math.ceil(this.items.length / this.pageSize); return Math.ceil(this.items.length / this.pageSize);
...@@ -30,8 +33,8 @@ export default { ...@@ -30,8 +33,8 @@ export default {
return this.currentPage == 0 ? false : true; return this.currentPage == 0 ? false : true;
}, },
showNextLink() { showNextLink() {
return this.currentPage == (this.totalPages() - 1) ? false : true; return this.currentPage == this.totalPages() - 1 ? false : true;
} },
} },
} };
</script> </script>
<template> <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 <CommunityHeader
:admin-status="false" :admin-status="false"
:community="community" :community="community"
...@@ -30,35 +30,44 @@ ...@@ -30,35 +30,44 @@
/> />
</div> </div>
<div class="absolute inset-x-0 px-5 py-3"> <div class="absolute inset-x-0 px-5 py-3">
<!-- ItemCards --> <!-- ItemCards -->
<div class="flex items-center justify-center w-screen"> <div class="flex items-center justify-center w-screen">
<!-- Shows items based on pagination --> <!-- Shows items based on pagination -->
<div <div
class="grid grid-flow-row-dense grid-cols-2 md:grid-cols-4 lg:grid-cols-5 w-full" class="grid grid-flow-row-dense grid-cols-2 md:grid-cols-4 lg:grid-cols-5 w-full"
v-if="showItems"> v-if="showItems"
<ItemCard v-for="item in visibleItems" :key="item" :item="item" @click="goToItemInfoPage(item.listingID)" /> >
<ItemCard
v-for="item in visibleItems"
:key="item"
:item="item"
@click="goToItemInfoPage(item.listingID)"
/>
</div> </div>
<!-- Shows items based on search field input --> <!-- Shows items based on search field input -->
<div <div
class="grid grid-flow-row-dense grid-cols-2 md:grid-cols-4 lg:grid-cols-5 w-full place-items-center" 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"> v-if="showSearchedItems"
<ItemCard v-for="item in searchedItems" :key="item" :item="item" @click="goToItemInfoPage(item.listingID)" /> >
<ItemCard
v-for="item in searchedItems"
:key="item"
:item="item"
@click="goToItemInfoPage(item.listingID)"
/>
</div> </div>
</div> </div>
<!-- pagination --> <!-- pagination -->
<div class="flex justify-center" v-if="showItems"> <div class="flex justify-center" v-if="showItems">
<PaginationTemplate <PaginationTemplate
v-bind:items="items" v-bind:items="items"
v-on:page:update="updatePage" v-on:page:update="updatePage"
v-bind:currentPage="currentPage" v-bind:currentPage="currentPage"
v-bind:pageSize="pageSize" v-bind:pageSize="pageSize"
class="mt-10" class="mt-10"
/> />
</div> </div>
</div> </div>
...@@ -113,7 +122,7 @@ export default { ...@@ -113,7 +122,7 @@ export default {
title: "", title: "",
pricePerDay: 0, pricePerDay: 0,
}, },
search: "",
communityID: -1, communityID: -1,
community: {}, community: {},
...@@ -150,13 +159,12 @@ export default { ...@@ -150,13 +159,12 @@ export default {
let res = await getItemPictures(itemid); let res = await getItemPictures(itemid);
return res; return res;
}, },
searchWritten: function (){ searchWritten: function () {
//This method triggers when search input field is changed //This method triggers when search input field is changed
if(this.search.length > 0){ if (this.search.length > 0) {
this.showItems = false; this.showItems = false;
this.showSearchedItems = true; this.showSearchedItems = true;
} } else {
else{
this.showItems = true; this.showItems = true;
this.showSearchedItems = false; this.showSearchedItems = false;
} }
...@@ -168,11 +176,14 @@ export default { ...@@ -168,11 +176,14 @@ export default {
this.updateVisibleTodos(); this.updateVisibleTodos();
}, },
updateVisibleTodos() { updateVisibleTodos() {
this.visibleItems = this.items.slice(this.currentPage * this.pageSize, (this.currentPage * this.pageSize) + this.pageSize); 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 we have 0 visible items, go back a page
if (this.visibleItems.length === 0 && this.currentPage > 0) { if (this.visibleItems.length === 0 && this.currentPage > 0) {
this.updatePage(this.currentPage -1); this.updatePage(this.currentPage - 1);
} }
}, },
}, },
......
...@@ -28,16 +28,20 @@ ...@@ -28,16 +28,20 @@
class="block p-2.5 w-full text-sm text-gray-900 bg-gray-200 rounded-lg border border-gray-300 focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500" class="block p-2.5 w-full text-sm text-gray-900 bg-gray-200 rounded-lg border border-gray-300 focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
required required
></textarea> ></textarea>
</div > </div>
<button id="cancelButton" @click="cancelRent" class="text-primary-medium"> <button id="cancelButton" @click="cancelRent" class="text-primary-medium">
Tilbake Tilbake
</button> </button>
<div id="confirm"> <div id="confirm">
<colored-button id="confirmButton" @click="sendRent" :text="'Send'"></colored-button> <colored-button
id="confirmButton"
@click="sendRent"
:text="'Send'"
></colored-button>
</div> </div>
</div> </div>
<div> <div>
<notification-modal <notification-modal
@click="routeToHome" @click="routeToHome"
:visible="confirmed" :visible="confirmed"
:title="'Vellykket'" :title="'Vellykket'"
...@@ -160,9 +164,7 @@ export default { ...@@ -160,9 +164,7 @@ export default {
}; };
await postNewRent(rent); await postNewRent(rent);
this.$router.push("/");
this.confirmed = true; this.confirmed = true;
}, },
}, },
}; };
......
<template>
<div id = "headline" class = "text-xl md:text-2xl text-gray-600 font-medium w-full">
Dine gjenstander
</div>
<!-- Search field -->
<!-- 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"
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>
<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"
/>
</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"
/>
</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>
</template>
<script>
import { GetUserListings, getItemPictures } from "@/utils/apiutil";
import ItemCard from "@/components/ItemComponents/ItemCard.vue";
import PaginationTemplate from "@/components/BaseComponents/PaginationTemplate";
export default {
name: "UserItems",
components: {
ItemCard,
PaginationTemplate
},
data() {
return {
items: [],
item: {
listingID: 0,
img: "",
address: "",
title: "",
pricePerDay: 0,
},
showItems: true,
showSearchedItems: false,
search: "",
//Variables connected to pagination
currentPage: 0,
pageSize: 12,
visibleItems: [],
};
},
computed: {
searchedItems() {
let filteredItems = [];
filteredItems = this.items.filter(
(p) =>
p.title.toLowerCase().includes(this.search.toLowerCase()) ||
p.address.toLowerCase().includes(this.search.toLowerCase()) ||
p.pricePerDay === Number(this.search)
);
return filteredItems;
},
},
methods: {
getUserListingsFromAPI: async function () {
this.items = await GetUserListings();
for (var i = 0; i < this.items.length; i++) {
let images = await getItemPictures(this.items[i].listingID);
if (images.length > 0) {
this.items[i].img = images[0].picture;
}
}
},
//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);
}
},
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;
}
},
},
async beforeMount() {
await this.getUserListingsFromAPI();
this.updateVisibleTodos();
},
};
</script>
<style>
#headline {
display: block;
margin-top: 10px;
margin-bottom: 10px;
}
</style>
\ No newline at end of file
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
> >
<li> <li>
<router-link <router-link
@click="goToMyItems"
to="" to=""
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" 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"
>Mine gjenstander</router-link >Mine gjenstander</router-link
...@@ -151,6 +152,9 @@ export default { ...@@ -151,6 +152,9 @@ export default {
this.$store.commit("logout"); this.$store.commit("logout");
this.$router.push("/"); this.$router.push("/");
}, },
goToMyItems(){
this.$router.push("/user/userItems");
}
}, },
beforeMount() { beforeMount() {
this.getUser(); this.getUser();
......
...@@ -105,6 +105,11 @@ const routes = [ ...@@ -105,6 +105,11 @@ const routes = [
name: "ItemInfo", name: "ItemInfo",
component: () => import("../views/RentingViews/ItemInfoPageView.vue"), component: () => import("../views/RentingViews/ItemInfoPageView.vue"),
}, },
{
path: "/user/userItems",
name: "UserItems",
component: () => import("../views/UserProfileViews/UserItemsView.vue"),
}
]; ];
const router = createRouter({ const router = createRouter({
......
...@@ -284,3 +284,17 @@ export async function LeaveCommunity(communityID) { ...@@ -284,3 +284,17 @@ export async function LeaveCommunity(communityID) {
return error; return error;
}); });
} }
export async function GetUserListings() {
return axios
.get(API_URL + "listing/userListings", {
headers: tokenHeader(),
})
.then((response) => {
return response.data;
})
.catch((error) => {
console.error(error);
});
}
<template>
<user-items> </user-items>
</template>
<script>
import UserItems from "@/components/UserProfileComponents/UserItems.vue"
export default {
name: "UserItemsView",
components:{
UserItems
}
}
</script>
<style>
</style>
import { mount } from "@vue/test-utils"; import { mount } from "@vue/test-utils";
import NewRent from "@/components/RentingComponents/NewRent.vue" import NewRent from "@/components/RentingComponents/NewRent.vue";
describe("Confirm and send a rent request", () => { describe("Confirm and send a rent request", () => {
let wrapper; let wrapper;
const route = { const route = {
params: { params: {
id: 1 id: 1,
} },
} };
const router = { const router = {
push: jest.fn(), push: jest.fn(),
} };
beforeEach(() => { beforeEach(() => {
wrapper = mount(NewRent, {
wrapper = mount(NewRent, { props: {
props: { newRentBox: {
newRentBox: { title: "Telt",
title: "Telt", listingID: 1,
listingID: 1, fromTime: "2022-09-19",
fromTime: "2022-09-19", toTime: "2022-09-23",
toTime: "2022-09-23", price: 200,
price: 200, renterId: 1,
renterId: 1, isAccepted: false,
isAccepted: false },
} },
}, global: {
global: { mocks: {
mocks: { $route: route,
$route: route, $router: router,
$router: router },
} },
}
});
}); });
});
it("Is instansiated", () => { it("Is instansiated", () => {
expect(wrapper.exists()).toBeTruthy(); expect(wrapper.exists()).toBeTruthy();
}); });
it("Check if fields show correct informations", () => { it("Check if fields show correct informations", () => {
expect(wrapper.find("#rentTitle").text()).toEqual("Telt"); expect(wrapper.find("#rentTitle").text()).toEqual("Telt");
expect(wrapper.find("#fromTime").text()).toMatch("19. September 2022"); expect(wrapper.find("#fromTime").text()).toMatch("19. September 2022");
expect(wrapper.find("#toTime").text()).toMatch("23. September 2022"); expect(wrapper.find("#toTime").text()).toMatch("23. September 2022");
expect(wrapper.find("#price").text()).toEqual("Totaltpris: 200 kr"); expect(wrapper.find("#price").text()).toEqual("Totaltpris: 200 kr");
}); });
}); });
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment