Skip to content
Snippets Groups Projects
Commit b9a238f5 authored by Zara Mudassar's avatar Zara Mudassar
Browse files

Merge remote-tracking branch 'origin/main'

parents 68200bef ce6de1ce
No related branches found
No related tags found
1 merge request!23Navbar
<template>
<div class="m-6">
<!-- Component heading -->
<div class="flex justify-center">
<p class="text-4xl mb-6 mt-6">Utleie</p>
</div>
<!-- Title -->
<div class="mb-6" :class="{ error: v$.item.title.$errors.length }">
<label
class="block mb-2 text-sm font-medium text-gray-900 dark:text-gray-300"
id="titleLabel"
>Tittel</label
>
<input
type="text"
id="title"
class="bg-gray-200 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 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"
v-model="v$.item.title.$model"
required
/>
<!-- error message for title-->
<div
class="text-red"
v-for="(error, index) of v$.item.title.$errors"
:key="index"
>
<div class="text-red-600 text-sm">
{{ error.$message }}
</div>
</div>
</div>
<!-- Select category -->
<div class="mb-6">
<label
class="block mb-2 text-sm font-medium text-gray-900 dark:text-gray-400"
id="selectCategoryLabel"
>Kategori</label
>
<select
v-model="v$.item.select.$model"
id="categories"
class="bg-gray-200 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 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"
>
<option class="text-gray-400" value="" disabled selected>
Select a category
</option>
<option
v-for="category in categories"
:key="category"
class="text-gray-900 text-sm"
>
{{ category }}
</option>
</select>
<!-- error message for select box -->
<div
class="text-red"
v-for="(error, index) of v$.item.select.$errors"
:key="index"
>
<div class="text-red-600 text-sm">
{{ error.$message }}
</div>
</div>
</div>
<!-- price -->
<div class="mb-6" :class="{ error: v$.item.price.$errors.length }">
<label
class="block mb-2 text-sm font-medium text-gray-900 dark:text-gray-300"
id="priceLabel"
>Pris</label
>
<input
type="number"
v-model="v$.item.price.$model"
id="price"
class="bg-gray-200 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 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
/>
<!-- error message for price -->
<div
class="text-red"
v-for="(error, index) of v$.item.price.$errors"
:key="index"
>
<div class="text-red-600 text-sm">
{{ error.$message }}
</div>
</div>
</div>
<!-- Description -->
<div class="mb-6" :class="{ error: v$.item.description.$errors.length }">
<label
class="block mb-2 text-sm font-medium text-gray-900 dark:text-gray-400"
id="descriptionLabel"
>Beskrivelse</label
>
<textarea
id="description"
rows="4"
v-model="v$.item.description.$model"
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
></textarea>
<!-- error message for description -->
<div
class="text-red"
v-for="(error, index) of v$.item.description.$errors"
:key="index"
>
<div class="text-red-600 text-sm">
{{ error.$message }}
</div>
</div>
</div>
<!-- Images -->
<div>
<label
class="block mb-2 text-sm font-medium text-gray-900 dark:text-gray-400"
id="imageLabel"
>
Bilder
</label>
<input
type="file"
ref="file"
style="display: none"
@change="addImage"
multiple
accept="image/png, image/jpeg"
/>
<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"
>
Velg bilde
</button>
<div v-for="image in item.images" :key="image" class="m-2">
<img :src="image" class="w-2/5 inline" alt="Bilde av gjenstanden" />
</div>
</div>
<!-- Save item button -->
<div class="flex justify-center">
<button
@click="saveClicked"
class="content-center text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm sm:w-auto px-5 py-2.5 text-center dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800"
id="saveButton"
>
Lagre
</button>
</div>
</div>
</template>
<script>
import useVuelidate from "@vuelidate/core";
import {
required,
helpers,
maxLength,
between,
minLength,
} from "@vuelidate/validators";
export default {
name: "AddNewItem",
setup() {
return { v$: useVuelidate() };
},
validations() {
return {
item: {
title: {
required,
max: helpers.withMessage(
() => `Tittelen kan inneholde max 50 tegn`,
maxLength(50)
),
},
description: {
required,
max: helpers.withMessage(
() => `Beskrivelsen kan inneholde max 200 tegn`,
maxLength(200)
),
min: helpers.withMessage(
() => `Beskrivelsen kan ikke være tom`,
minLength(0)
),
},
price: {
required,
between: helpers.withMessage(
() => `Leieprisen kan ikke være større enn 25000`,
between(0, 25000)
),
},
select: {
required: helpers.withMessage(() => `Velg en kategori`, required),
},
},
};
},
data() {
return {
item: {
title: "",
description: "",
price: "",
category: "",
select: null,
type: "",
images: [],
},
//Kategorier skal legges inn ved api/hente fra db, her må det endres etterhvert
categories: ["Hage", "Kjøkken", "Musikk", "Annet"],
};
},
methods: {
checkValidation: function () {
console.log("sjekker validering");
this.v$.item.$touch();
if (this.v$.item.$invalid) {
console.log("Invalid, avslutter...");
return false;
}
console.log("validert!");
return true;
},
async saveClicked() {
console.log("Attempting to save item");
if (this.checkValidation()) {
console.log("validert, videre...");
console.log("Tittel: " + this.item.title);
console.log("Kategori: " + this.item.select);
console.log("Beskrivelse: " + this.item.description);
console.log("Pris: " + this.item.price);
console.log("bilder: " + this.item.images);
}
},
addImage: function (event) {
console.log(event.target.files);
this.item.images.push(URL.createObjectURL(event.target.files[0]));
console.log("antall bilder: " + this.item.images.length);
},
},
};
</script>
...@@ -158,18 +158,17 @@ export default { ...@@ -158,18 +158,17 @@ export default {
if (loginResponse.isLoggedIn === false) { if (loginResponse.isLoggedIn === false) {
this.message = "Feil e-post/passord"; this.message = "Feil e-post/passord";
this.$store.commit("logout"); this.$store.commit("logout");
} } else if (loginResponse.isLoggedIn === true) {
else if (loginResponse.isLoggedIn === true) {
this.$store.commit("saveToken", loginResponse.token); this.$store.commit("saveToken", loginResponse.token);
await this.$router.push("/endre");
} let user = parseUserFromToken(loginResponse.token);
else { console.log(user);
let id = user.accountId;
console.log(id);
this.$router.push("/profile/" + id);
} else {
console.log("Something went wrong"); console.log("Something went wrong");
} }
let user = parseUserFromToken();
let id = user.account_id;
this.$router.push("/profile/" + id);
}, },
validate() { validate() {
......
...@@ -74,7 +74,7 @@ ...@@ -74,7 +74,7 @@
alt="Profile picture" alt="Profile picture"
/> />
<h5 class="mb-1 text-xl font-medium text-gray-900 dark:text-white"> <h5 class="mb-1 text-xl font-medium text-gray-900 dark:text-white">
{{ user.first_name }} {{ user.last_name }} {{ user.firstName }} {{ user.lastName }}
</h5> </h5>
<div> <div>
<rating-component :rating="renterRating" :ratingType="'Leietaker'" /> <rating-component :rating="renterRating" :ratingType="'Leietaker'" />
...@@ -94,8 +94,8 @@ ...@@ -94,8 +94,8 @@
<script> <script>
import RatingComponent from "@/components/UserProfileComponents/RatingComponent.vue"; import RatingComponent from "@/components/UserProfileComponents/RatingComponent.vue";
import { parseUserFromToken } from "@/utils/token-utils"; import { parseCurrentUser } from "@/utils/token-utils";
import { getUser /* getRenterRating, getOwnerRating */ } from "@/utils/apiutil"; import { getUser, getRenterRating, getOwnerRating } from "@/utils/apiutil";
import router from "@/router"; import router from "@/router";
export default { export default {
...@@ -106,8 +106,8 @@ export default { ...@@ -106,8 +106,8 @@ export default {
currentUser: {}, currentUser: {},
id: -1, id: -1,
isCurrentUser: false, isCurrentUser: false,
renterRating: 0, //getRenterRating(this.userID), renterRating: -1, //getRenterRating(this.userID),
ownerRating: 0, //getOwnerRating(this.userID), ownerRating: -1, //getOwnerRating(this.userID),
dropdown: false, dropdown: false,
}; };
}, },
...@@ -116,19 +116,16 @@ export default { ...@@ -116,19 +116,16 @@ export default {
}, },
methods: { methods: {
async getUser() { async getUser() {
this.currentUser = parseUserFromToken(); this.currentUser = parseCurrentUser();
this.id = router.currentRoute.value.params.id; this.id = router.currentRoute.value.params.id;
if (this.id == this.currentUser.account_id) { if (this.id == this.currentUser.account_id) {
this.isCurrentUser = true; this.isCurrentUser = true;
this.user = this.currentUser; this.user = this.currentUser;
return; return;
} }
let getuser = await getUser(this.id); this.user = await getUser(this.id);
this.user = { this.renterRating = getRenterRating(this.id);
account_id: getuser.userID, this.ownerRating = getOwnerRating(this.id);
first_name: getuser.firstName,
last_name: getuser.lastName,
};
}, },
getProfilePicture() { getProfilePicture() {
/* if (this.user.picture != "") { /* if (this.user.picture != "") {
......
<template> <template>
<ul class="flex justify-center"> <ul v-if="compRating != -1" class="flex justify-center">
<li> <li>
<p class="ml-2 text-sm font-medium text-gray-500 dark:text-gray-400"> <p class="ml-2 text-sm font-medium text-gray-500 dark:text-gray-400">
{{ ratingType }}:&nbsp; {{ ratingType }}:&nbsp;
...@@ -23,6 +23,18 @@ ...@@ -23,6 +23,18 @@
</p> </p>
</li> </li>
</ul> </ul>
<ul v-else class="flex justify-center">
<li>
<p class="ml-2 text-sm font-medium text-gray-500 dark:text-gray-400">
{{ ratingType }}:&nbsp;
</p>
</li>
<li>
<p class="ml-2 text-sm font-medium text-gray-500 dark:text-gray-400">
Rating ikke tilgjengelig
</p>
</li>
</ul>
</template> </template>
<script> <script>
......
...@@ -43,7 +43,6 @@ const routes = [ ...@@ -43,7 +43,6 @@ const routes = [
component: NewPasswordView, component: NewPasswordView,
}, },
{ {
path: "/searchItemList", path: "/searchItemList",
name: "searchItemList", name: "searchItemList",
component: () => import("../views/SearchItemListView.vue"), component: () => import("../views/SearchItemListView.vue"),
...@@ -52,7 +51,11 @@ const routes = [ ...@@ -52,7 +51,11 @@ const routes = [
path: "/createNewGroup", path: "/createNewGroup",
name: "createNewGroup", name: "createNewGroup",
component: () => import("../views/CreateNewGroupView.vue"), component: () => import("../views/CreateNewGroupView.vue"),
},
{
path: "/addNewItem",
name: "addNewItem",
component: () => import("../views/AddNewItemView.vue"),
}, },
]; ];
......
...@@ -4,7 +4,7 @@ import { tokenHeader } from "./token-utils"; ...@@ -4,7 +4,7 @@ import { tokenHeader } from "./token-utils";
const API_URL = process.env.VUE_APP_BASEURL; const API_URL = process.env.VUE_APP_BASEURL;
export function doLogin(loginRequest) { export function doLogin(loginRequest) {
const auth = {isLoggedIn: false, token: ""}; const auth = { isLoggedIn: false, token: "" };
return axios return axios
.post(API_URL + "login/authentication", loginRequest) .post(API_URL + "login/authentication", loginRequest)
.then((response) => { .then((response) => {
...@@ -48,7 +48,7 @@ export async function getUser(userid) { ...@@ -48,7 +48,7 @@ export async function getUser(userid) {
export function getRenterRating(userid) { export function getRenterRating(userid) {
return axios return axios
.get(API_URL + "users/" + userid + "", { .get(API_URL + "rating/" + userid + "/as_owner", {
headers: tokenHeader(), headers: tokenHeader(),
}) })
.then((response) => { .then((response) => {
...@@ -61,7 +61,7 @@ export function getRenterRating(userid) { ...@@ -61,7 +61,7 @@ export function getRenterRating(userid) {
export function getOwnerRating(userid) { export function getOwnerRating(userid) {
return axios return axios
.get(API_URL + "users/" + userid + "", { .get(API_URL + "rating/" + userid + "/as_renter", {
headers: tokenHeader(), headers: tokenHeader(),
}) })
.then((response) => { .then((response) => {
......
...@@ -6,7 +6,11 @@ export function tokenHeader() { ...@@ -6,7 +6,11 @@ export function tokenHeader() {
return { Authorization: token }; return { Authorization: token };
} }
export function parseUserFromToken() { export function parseCurrentUser() {
let token = store.state.user.token; let token = store.state.user.token;
return jwt_decode(token); return jwt_decode(token);
} }
export function parseUserFromToken(token) {
return jwt_decode(token);
}
<template>
<AddNewItem></AddNewItem>
</template>
<script>
import AddNewItem from "@/components/AddNewItem";
export default {
name: "AddNewItemView.vue",
components: {
AddNewItem,
},
};
</script>
<style scoped></style>
import { shallowMount } from "@vue/test-utils";
import AddNewItem from "@/components/AddNewItem.vue";
describe("addNewItem elements rendering", () => {
it("renders all labels", () => {
const wrapper = shallowMount(AddNewItem);
expect(wrapper.find("#titleLabel").text()).toMatch("Tittel");
expect(wrapper.find("#selectCategoryLabel").text()).toMatch("Kategori");
expect(wrapper.find("#priceLabel").text()).toMatch("Pris");
expect(wrapper.find("#descriptionLabel").text()).toMatch("Beskrivelse");
expect(wrapper.find("#imageLabel").text()).toMatch("Bilde");
});
it("Tests setting values of input field", async () => {
const wrapper = shallowMount(AddNewItem);
const titleInput = wrapper.find("#title");
await titleInput.setValue("Dyson");
expect(titleInput.element.value).toBe("Dyson");
const selectedCategory = wrapper.find("#categories");
await selectedCategory.setValue("Hage");
expect(selectedCategory.element.value).toBe("Hage");
const priceInput = wrapper.find("#price");
await priceInput.setValue(500);
expect(priceInput.element.value).toBe("500");
const descriptionInput = wrapper.find("#description");
await descriptionInput.setValue("Dette er en støvsuer fra Dyson");
expect(descriptionInput.element.value).toBe(
"Dette er en støvsuer fra Dyson"
);
});
});
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