Skip to content
Snippets Groups Projects
Commit 4e07c554 authored by Gilgard's avatar Gilgard
Browse files

Merge branch 'main' into community-member-list

parents f50267bf 8960de10
Branches
No related tags found
1 merge request!32Community member list
Pipeline #176798 passed
Showing
with 838 additions and 120 deletions
...@@ -12,6 +12,7 @@ module.exports = { ...@@ -12,6 +12,7 @@ module.exports = {
parser: "@babel/eslint-parser", parser: "@babel/eslint-parser",
}, },
rules: { rules: {
"linebreak-style": 0,
"no-console": process.env.NODE_ENV === "production" ? "warn" : "off", "no-console": process.env.NODE_ENV === "production" ? "warn" : "off",
"no-debugger": process.env.NODE_ENV === "production" ? "warn" : "off", "no-debugger": process.env.NODE_ENV === "production" ? "warn" : "off",
}, },
......
# This file is a template, and might need editing before it works on your project. image: node:lts
# To contribute improvements to CI/CD templates, please follow the Development guide at:
# https://docs.gitlab.com/ee/development/cicd/templates.html
# This specific template is located at:
# https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Getting-Started.gitlab-ci.yml
# This is a sample GitLab CI/CD configuration file that should run without any modifications. stages:
# It demonstrates a basic 3 stage CI/CD pipeline. Instead of real tests or scripts,
# it uses echo commands to simulate the pipeline execution.
#
# A pipeline is composed of independent jobs that run scripts, grouped into stages.
# Stages run in sequential order, but jobs within stages run in parallel.
#
# For more information, see: https://docs.gitlab.com/ee/ci/yaml/index.html#stages
stages: # List of stages for jobs, and their order of execution
- build - build
- test - test
# - deploy
image: node:16 # These folders are cached between builds
# http://docs.gitlab.com/ce/ci/yaml/README.html#cache
cache: cache:
key: ${CI_COMMIT_REF_SLUG}
paths: paths:
# Default cache directory from https://classic.yarnpkg.com/en/docs/install-ci/#gitlab.
- node_modules/ - node_modules/
# Enables git-lab CI caching. Both .cache and public must be cached, otherwise builds will fail.
- .cache/
- public/
install_dependencies_job: # This job runs in the build stage, which runs first. npm:install:
stage: build stage: build
script:
- echo "Installing dependencies..."
- npm install
- echo "Dependencies installed."
artifacts:
paths:
- node_modules/
lint-test-job: # This job also runs in the test stage.
stage: test # It can run at the same time as unit-test-job (in parallel).
script: script:
- echo "Linting the code..." - npm ci
- npm run lint
- echo "Code-linting complete."
artifacts:
paths:
- node_modules/
unit-test-job: # This job runs in the test stage. test:unit:
stage: test # It only starts when the job in the build stage completes successfully. stage: test
needs: ["npm:install"]
script: script:
- echo "Running unit tests..." - npm ci
- npm run test:unit -- --coverage - npm run test:unit
- echo "Unit tests complete."
artifacts: #test:coverage:
paths: # stage: test
- node_modules/ # needs: ["npm:install"]
# script:
# - ./node_modules/.bin/gatsby info
# rules:
# - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
# - if: $CI_MERGE_REQUEST_ID
#pages:
# stage: deploy
# needs:
# - npm:install
# - test:unit
# - test:gatsby
# script:
# - ./node_modules/.bin/gatsby build --prefix-paths
# artifacts:
# paths:
# - public
# rules:
# - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
<template> <template>
<div>
<NavBar />
<router-view /> <router-view />
</div>
</template> </template>
<script>
import { defineComponent } from "vue";
// Components
import NavBar from "./components/NavBar.vue";
export default defineComponent({
name: "App",
components: {
NavBar,
},
});
</script>
src/assets/additem.png

29.2 KiB

src/assets/messages.png

17.2 KiB

src/assets/notifications.png

24.3 KiB

src/assets/profile.png

38.4 KiB

<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>
<!-- Select Group -->
<div class="mb-6">
<label
class="block mb-2 text-sm font-medium text-gray-900 dark:text-gray-400"
>Gruppe</label
>
<select
v-model="v$.item.selectGroup.$model"
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 Group
</option>
<option
v-for="group in groups"
:key="group"
class="text-gray-900 text-sm"
>
{{ group }}
</option>
</select>
<!-- error message for select box -->
<div
class="text-red"
v-for="(error, index) of v$.item.selectGroup.$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>
<!-- Address -->
<div class="mb-6" :class="{ error: v$.item.address.$errors.length }">
<label
class="block mb-2 text-sm font-medium text-gray-900 dark:text-gray-300"
>Adresse</label
>
<input
type="text"
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.address.$model"
id="adress"
required
/>
<!-- error message for address-->
<div
class="text-red"
v-for="(error, index) of v$.item.address.$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 { parseUserFromToken } from "@/utils/token-utils";
import { postNewItem } from "@/utils/apiutil";
import {
required,
helpers,
maxLength,
between,
minLength,
} from "@vuelidate/validators";
export default {
name: "AddNewItem",
setup() {
return { v$: useVuelidate() };
},
validations() {
return {
item: {
title: {
required: helpers.withMessage(
() => "Tittelen kan ikke være tom",
required
),
max: helpers.withMessage(
() => `Tittelen kan inneholde max 50 tegn`,
maxLength(50)
),
},
description: {
required: helpers.withMessage(
() => "Beskrivelsen kan ikke være tom",
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),
},
selectGroup: {
required: helpers.withMessage(() => `Velg en gruppe`, required),
},
address: {
required: helpers.withMessage(
() => "Addressen kan ikke være tom",
required
),
max: helpers.withMessage(
() => `Addressen kan inneholde max 50 tegn`,
maxLength(50)
),
},
},
};
},
data() {
return {
item: {
title: "",
description: "",
address: "",
price: "",
category: "",
select: null,
type: "",
images: [],
userId: -1,
selectGroup: null,
},
//Kategorier skal legges inn ved api/hente fra db, her må det endres etterhvert
categories: ["Hage", "Kjøkken", "Musikk", "Annet"],
groups: [4040, 4041],
};
},
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...");
this.checkUser();
console.log("Tittel: " + this.item.title);
console.log("Kategori: " + this.item.select);
console.log("Beskrivelse: " + this.item.description);
console.log("Addressen: " + this.item.address);
console.log("Pris: " + this.item.price);
console.log("bilder: " + this.item.images);
console.log("gruppe: " + this.item.selectGroup);
const itemInfo = {
title: this.item.title,
description: this.item.description,
pricePerDay: this.item.price,
address: this.item.address,
userID: this.item.userId,
categoryNames: [],
communityIDs: [this.item.selectGroup],
};
console.log(itemInfo);
const postRequest = await postNewItem(itemInfo);
console.log("posted: " + postRequest);
}
},
checkUser: async function () {
let user = parseUserFromToken(this.$store.state.user.token);
this.item.userId = parseInt(user.accountId);
console.log("id: " + this.item.userId);
},
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>
<template> <template>
<div class="flex justify-center"> <div class="flex justify-center">
<router-link to="/" class="m-6">Logg inn</router-link> <router-link to="/login" class="m-6">Logg inn</router-link>
<router-link to="/register" class="m-6">Registrer deg</router-link> <router-link to="/register" class="m-6">Registrer deg</router-link>
<router-link to="/about" class="m-6">Om BoCo</router-link> <router-link to="/about" class="m-6">Om BoCo</router-link>
<div @click="logout" class="m-6 cursor-pointer"><p>Logout</p></div>
</div> </div>
</template> </template>
<script> <script>
export default { export default {
name: "HelloWorld", name: "HomeComponent",
data: () => ({}), data: () => ({}),
methods: {
logout() {
this.$store.commit("logout");
},
},
}; };
</script> </script>
<template> <template>
<div class="App"> <div class="App">
<div id="logoField" class="flex justify-center m-6">
<img src="../assets/logo3.svg" alt="BoCo logo" />
</div>
<div <div
id="emailField" id="emailField"
class="m-6" class="m-6"
...@@ -73,7 +69,7 @@ ...@@ -73,7 +69,7 @@
<div id="buttonsField" class="m-6"> <div id="buttonsField" class="m-6">
<div class="align-items: flex-end; mb-6"> <div class="align-items: flex-end; mb-6">
<div class="ml-3 text-sm"> <div class="ml-3 text-sm">
<router-link to="about" class="text-blue-600" <router-link to="/resetPassword" class="text-blue-600"
>Glemt passord</router-link >Glemt passord</router-link
> >
</div> </div>
...@@ -102,7 +98,6 @@ ...@@ -102,7 +98,6 @@
import useVuelidate from "@vuelidate/core"; import useVuelidate from "@vuelidate/core";
import { required, email, helpers } from "@vuelidate/validators"; import { required, email, helpers } from "@vuelidate/validators";
import { doLogin } from "@/utils/apiutil"; import { doLogin } from "@/utils/apiutil";
import { parseUserFromToken } from "@/utils/token-utils";
export default { export default {
name: "LoginForm.vue", name: "LoginForm.vue",
...@@ -110,7 +105,6 @@ export default { ...@@ -110,7 +105,6 @@ export default {
setup() { setup() {
return { v$: useVuelidate() }; return { v$: useVuelidate() };
}, },
validations() { validations() {
return { return {
user: { user: {
...@@ -160,12 +154,7 @@ export default { ...@@ -160,12 +154,7 @@ export default {
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("/");
let user = parseUserFromToken(loginResponse.token);
console.log(user);
let id = user.accountId;
console.log(id);
this.$router.push("/profile/" + id);
} else { } else {
console.log("Something went wrong"); console.log("Something went wrong");
} }
......
<template>
<div>This is a message page</div>
</template>
<script>
export default {
name: "MessagesForm",
};
</script>
<style scoped></style>
<template>
<nav class="flex items-center justify-between bg-white h-20 shadow-2xl">
<div class="logo">
<img
class="m-2 cursor-pointer h-16"
src="../assets/logo3.svg"
alt="BoCo logo"
@click="$router.push('/')"
/>
</div>
<ul class="flex">
<li>
<img
class="m-6 cursor-pointer h-8"
src="../assets/additem.png"
alt="Legg til"
@click="$router.push('/addNewItem')"
/>
</li>
<li>
<img
class="m-6 cursor-pointer h-8"
src="../assets/messages.png"
alt="Meldinger"
@click="$router.push('/messages')"
/>
</li>
<li>
<img
class="m-6 cursor-pointer h-8"
src="../assets/profile.png"
alt="Profil"
@click="loadProfile"
/>
</li>
</ul>
</nav>
</template>
<script>
import { parseUserFromToken } from "@/utils/token-utils";
export default {
name: "NavBar.vue",
methods: {
async loadProfile() {
if (this.$store.state.user.token !== null) {
let user = parseUserFromToken(this.$store.state.user.token);
console.log(user);
let id = user.accountId;
console.log(id);
await this.$router.push("/profile/" + id);
} else {
await this.$router.push("/login");
}
},
},
};
</script>
<style scoped></style>
<template> <template>
<div> <div
<v-col align="center" justify="space-around" class="mt-16"> class="w-full max-w-sm p-6 m-auto bg-white rounded-md shadow-md dark:bg-gray-800"
<v-img >
max-width="45%" <div id="logoField" class="flex justify-center m-6">
:src="require('../assets/logo3.svg')" <img src="../assets/logo3.svg" alt="BoCo logo" />
align="center" </div>
<div
id="firstPasswordField"
:class="{ error: v$.user.password.$errors.length }"
>
<label
for="password"
class="block text-sm text-gray-800 dark:text-gray-200"
>Nytt passord</label
>
<input
type="password"
v-model="v$.user.password.$model"
class="block w-full px-4 py-2 mt-2 text-gray-700 bg-white border rounded-md dark:bg-gray-800 dark:text-gray-300 dark:border-gray-600 focus:border-blue-400 dark:focus:border-blue-300 focus:ring-blue-300 focus:outline-none focus:ring focus:ring-opacity-40"
/> />
</v-col> <!-- error message -->
<div v-for="(error, index) of v$.user.password.$errors" :key="index">
<div
class="text-red-600 text-sm"
v-show="showError"
id="passwordErrorId"
>
{{ error.$message }}
</div>
</div>
</div>
<v-form ref="form" v-model="valid" lazy-validation class="mt-8"> <div
<v-text-field id="secondPasswordField"
v-model="user.password" class="mt-4"
:rules="[rules.required, rules.min]" :class="{ error: v$.user.rePassword.$errors.length }"
:type="'password'" >
name="input-10-1" <div class="flex items-center justify-between">
label="Passord" <label
counter for="rePassword"
></v-text-field> class="block text-sm text-gray-800 dark:text-gray-200"
>Gjenta nytt passord</label
>
</div>
<v-text-field <input
v-model="user.rePassword" type="password"
:rules="[rules.required, rules.min, rules.passwordConfirmation]" v-model="v$.user.rePassword.$model"
:type="'password'" class="block w-full px-4 py-2 mt-2 text-gray-700 bg-white border rounded-md dark:bg-gray-800 dark:text-gray-300 dark:border-gray-600 focus:border-blue-400 dark:focus:border-blue-300 focus:ring-blue-300 focus:outline-none focus:ring focus:ring-opacity-40"
name="input-10-1" />
label="Confirm Password" <!-- error message -->
counter <div v-for="(error, index) of v$.user.rePassword.$errors" :key="index">
></v-text-field> <div
class="text-red-600 text-sm"
v-show="showError"
id="rePasswordErrorId"
>
{{ error.$message }}
</div>
</div>
</div>
<v-col justify="space-around" align="center"> <div id="buttonsField" class="mt-6">
<v-btn <button
:disabled="!valid"
color="success"
class="mb-4 mt-4"
width="50%"
height="40px"
@click="setNewPassword" @click="setNewPassword"
class="w-full px-4 py-2 tracking-wide text-white transition-colors duration-200 transform bg-gray-700 rounded-md hover:bg-gray-600 focus:outline-none focus:bg-gray-600"
> >
Endre passord Endre passord
</v-btn> </button>
</v-col> </div>
</v-form>
</div> </div>
</template> </template>
<script> <script>
import useVuelidate from "@vuelidate/core";
import { required, minLength, sameAs } from "@vuelidate/validators";
import { doNewPassword } from "@/utils/apiutil";
import { mapState } from "vuex";
export default { export default {
name: "NewPasswordForm.vue", name: "NewPasswordForm.vue",
setup() {
return { v$: useVuelidate() };
},
validations() {
return {
user: {
password: {
required,
minLength: minLength(8),
},
rePassword: {
required,
minLength: minLength(8),
sameAs: sameAs(this.user.password),
},
},
};
},
data() { data() {
return { return {
user: { user: {
...@@ -54,18 +107,39 @@ export default { ...@@ -54,18 +107,39 @@ export default {
rePassword: "", rePassword: "",
}, },
valid: true, showError: false,
rules: {
required: (value) => !!value || "Feltet er påkrevd",
min: (v) => v.length >= 8 || "Minimum 8 tegn",
passwordConfirmation: (v) =>
v === this.user.password || "Passordene må være like",
},
}; };
}, },
computed: mapState({
token: (state) => state.user.token,
}),
methods: { methods: {
async setNewPassword() {}, async setNewPassword() {
this.showError = true;
this.v$.user.$touch();
if (this.v$.user.$invalid) {
console.log("Invalid, exiting...");
return;
}
const newPasswordInfo = {
token: this.token,
newPassword: this.password,
};
const newPasswordResponse = doNewPassword(newPasswordInfo);
if (newPasswordResponse.newPasswordSet === true) {
console.log("New password set");
await this.$router.push("/endre");
} else if (newPasswordResponse.newPasswordSet === false) {
console.log("Couldn't set new password");
} else {
console.log("Something went wrong");
}
},
validate() { validate() {
this.$refs.form.validate(); this.$refs.form.validate();
}, },
......
<template>
<div>This is a notification page</div>
</template>
<script>
export default {
name: "NotificationsForm",
};
</script>
<style scoped></style>
<template>
<div class="resetPassword">
<div
id="emailField"
class="m-6"
:class="{ error: v$.email.$errors.length }"
>
<div class="mb-6">
<label
for="email"
class="block mb-2 text-sm font-medium text-gray-900 dark:text-gray-300"
>E-post</label
>
<input
type="email"
id="email"
class="bg-gray-50 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"
placeholder="eksempel@eksempel.no"
v-model="v$.email.$model"
required
/>
<!-- error message -->
<div v-for="(error, index) of v$.email.$errors" :key="index">
<div
class="text-red-600 text-sm"
v-show="showError"
id="emailErrorId"
>
{{ error.$message }}
</div>
</div>
</div>
</div>
<button
@click="sendHome"
class="flex justify-center align-items: flex-end; 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 w-full sm:w-auto px-5 py-2.5 text-center dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800"
>
Send e-post
</button>
</div>
</template>
<script>
import useVuelidate from "@vuelidate/core";
import { required, email, helpers } from "@vuelidate/validators";
export default {
name: "ResetPassword.vue",
data() {
return {
showError: false,
email: "",
};
},
setup() {
return { v$: useVuelidate() };
},
validations() {
return {
email: {
required,
email: helpers.withMessage(`E-posten er ugyldig`, email),
},
};
},
methods: {
sendHome() {
this.showError = true;
this.v$.email.$touch();
if (this.v$.email.$invalid) {
console.log("Ugyldig, avslutter...");
return;
} else {
this.$router.push("/");
}
},
},
validate() {
this.$refs.form.validate();
},
};
</script>
...@@ -4,6 +4,19 @@ import HomeView from "../views/HomeView.vue"; ...@@ -4,6 +4,19 @@ import HomeView from "../views/HomeView.vue";
import LoginView from "../views/LoginView.vue"; import LoginView from "../views/LoginView.vue";
import NewPasswordView from "../views/NewPasswordView"; import NewPasswordView from "../views/NewPasswordView";
/**
* Guards routes. If token is null, no user is logged in and only the
* login page and the register page will be accessible.
*/
function guardRoute(to, from, next) {
let isAuthenticated = store.state.user.token != null;
if (isAuthenticated) {
next(); // allow to enter route
} else {
next("/login"); // go to '/login';
}
}
const routes = [ const routes = [
{ {
path: "/", //Endre før push path: "/", //Endre før push
...@@ -19,18 +32,12 @@ const routes = [ ...@@ -19,18 +32,12 @@ const routes = [
path: "/profile/:id", path: "/profile/:id",
name: "profile", name: "profile",
component: () => import("../views/ProfileView.vue"), component: () => import("../views/ProfileView.vue"),
beforeEnter: () => { beforeEnter: guardRoute,
if (store.state.user.token == null) router.push("login");
},
}, },
{ {
path: "/register", path: "/register",
name: "register", name: "register",
// route level code-splitting component: () => import("../views/RegisterView.vue"),
// this generates a separate chunk (register.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () =>
import(/* webpackChunkName: "register" */ "../views/RegisterView.vue"),
}, },
{ {
path: "/login", path: "/login",
...@@ -41,12 +48,18 @@ const routes = [ ...@@ -41,12 +48,18 @@ const routes = [
path: "/newPassword", path: "/newPassword",
name: "newPassword", name: "newPassword",
component: NewPasswordView, component: NewPasswordView,
beforeEnter: guardRoute,
}, },
{ {
path: "/searchItemList", path: "/searchItemList",
name: "searchItemList", name: "searchItemList",
component: () => import("../views/SearchItemListView.vue"), component: () => import("../views/SearchItemListView.vue"),
}, },
{
path: "/resetPassword",
name: "resetPassword",
component: () => import("../views/ResetPasswordView.vue"),
},
{ {
path: "/createNewGroup", path: "/createNewGroup",
name: "createNewGroup", name: "createNewGroup",
...@@ -56,6 +69,25 @@ const routes = [ ...@@ -56,6 +69,25 @@ const routes = [
path: "/group/:id/memberlist", path: "/group/:id/memberlist",
name: "memberlist", name: "memberlist",
component: () => import("../views/MemberListView.vue"), component: () => import("../views/MemberListView.vue"),
beforeEnter: guardRoute,
},
{
path: "/addNewItem",
name: "addNewItem",
component: () => import("../views/AddNewItemView.vue"),
beforeEnter: guardRoute,
},
{
path: "/notifications",
name: "notifications",
component: () => import("../views/NotificationView.vue"),
beforeEnter: guardRoute,
},
{
path: "/messages",
name: "messages",
component: () => import("../views/MessagesView.vue"),
beforeEnter: guardRoute,
}, },
]; ];
......
...@@ -84,3 +84,26 @@ export function getAverageRating(userid) { ...@@ -84,3 +84,26 @@ export function getAverageRating(userid) {
console.error(error); console.error(error);
}); });
} }
export function doNewPassword() {
//m
//add newPasswordInfo to input
const auth = { newPasswordSet: false };
//return axios
//.post(API_URL + "newPassword", newPasswordInfo)
//.then((response) => {auth.newPasswordSet = true;return auth;})
//.catch((error) => {console.log(error);return auth;});
return auth; //remove after axios is added
}
export function postNewItem(itemInfo) {
return axios
.post(API_URL + "listing", itemInfo)
.then((response) => {
console.log("prøver: " + response.data);
return response;
})
.catch((error) => {
console.log(error.response);
return error;
});
}
<template> <template>
<div class="about"> <div>This is an about page</div>
<h1>This is an about page</h1>
</div>
</template> </template>
<script>
import { defineComponent } from "vue";
// Components
export default defineComponent({
name: "HomeView",
components: {},
});
</script>
<template>
<AddNewItem></AddNewItem>
</template>
<script>
import AddNewItem from "@/components/AddNewItem";
export default {
name: "AddNewItemView.vue",
components: {
AddNewItem,
},
};
</script>
<style scoped></style>
<template> <template>
<HelloWorld /> <Home />
</template> </template>
<script> <script>
import { defineComponent } from "vue"; import { defineComponent } from "vue";
// Components // Components
import HelloWorld from "../components/HelloWorld.vue"; import Home from "../components/HomeComponent.vue";
export default defineComponent({ export default defineComponent({
name: "HomeView", name: "HomeView",
components: { components: {
HelloWorld, Home,
}, },
}); });
</script> </script>
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment