Implement token autentication, Implement account views
This commit is contained in:
parent
669ca7c52b
commit
997c2e9b12
56
basta/src/authentication.js
Normal file
56
basta/src/authentication.js
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
import router from '@/router'
|
||||||
|
import {API_ROOT} from '@/config.js'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
user: {
|
||||||
|
authenticated: false
|
||||||
|
},
|
||||||
|
|
||||||
|
// authentication status
|
||||||
|
authenticated() {
|
||||||
|
return (localStorage.getItem('user') !== null && JSON.parse(localStorage.getItem('user')).data.token !== '')
|
||||||
|
},
|
||||||
|
|
||||||
|
// Send a request to the login URL and save the returned JWT
|
||||||
|
login(creds) {
|
||||||
|
console.log('LOGIN');
|
||||||
|
window.axios.post(API_ROOT.concat('/token-auth/token/create/'), creds)
|
||||||
|
.then((response) => {
|
||||||
|
this.user.authenticated = true;
|
||||||
|
console.log(response);
|
||||||
|
localStorage.setItem('user', JSON.stringify(response));
|
||||||
|
// Redirect to a specified route
|
||||||
|
window.axios.defaults.headers.common = {
|
||||||
|
'Authorization': ('Token ' + JSON.parse(localStorage.getItem('user')).data.auth_token)
|
||||||
|
};
|
||||||
|
location.reload();
|
||||||
|
})
|
||||||
|
.catch(function (error) {
|
||||||
|
console.log(error);
|
||||||
|
alert(error.response.data.non_field_errors[0]);
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
// To log out
|
||||||
|
logout: function (redirect) {
|
||||||
|
window.axios.post(API_ROOT.concat('/token-auth/token/destroy/'),)
|
||||||
|
.then((response) => {
|
||||||
|
this.user.authenticated = false;
|
||||||
|
localStorage.removeItem('user');
|
||||||
|
console.log(response);
|
||||||
|
// Redirect to a specified route
|
||||||
|
window.axios.defaults.headers.common = {
|
||||||
|
'Authorization': '',
|
||||||
|
};
|
||||||
|
location.reload();
|
||||||
|
if (redirect) {
|
||||||
|
router.push({name: 'home'});
|
||||||
|
// router.go(redirect)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(function (error) {
|
||||||
|
console.log(error);
|
||||||
|
alert(error.response.data);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
41
basta/src/components/account/AccountOverview.vue
Normal file
41
basta/src/components/account/AccountOverview.vue
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<b-tabs>
|
||||||
|
<b-tab title="Account Details" active>
|
||||||
|
<account-details :user="user"></account-details>
|
||||||
|
</b-tab>
|
||||||
|
<b-tab title="Food App">
|
||||||
|
<food></food>
|
||||||
|
</b-tab>
|
||||||
|
</b-tabs>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import * as CONFIG from '../../config.js';
|
||||||
|
import AccountDetails from '@/components/account/utils/AccountDetails';
|
||||||
|
import Food from '@/components/account/utils/Food';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "AccountOverview",
|
||||||
|
components: {AccountDetails, Food,},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
user: {},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
window.axios
|
||||||
|
.get(CONFIG.API_ROOT_ACCOUNT.concat('/'))
|
||||||
|
.then((response) => {
|
||||||
|
console.log(response.data);
|
||||||
|
this.user = response.data[0];
|
||||||
|
})
|
||||||
|
.catch(e => console.error(e));
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
51
basta/src/components/account/Activation.vue
Normal file
51
basta/src/components/account/Activation.vue
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
<template>
|
||||||
|
<b-row>
|
||||||
|
<b-col class="justify-content-md-center text-center">
|
||||||
|
<div v-if="activated">
|
||||||
|
<p>Dein Account ist nun aktiviert.</p>
|
||||||
|
<router-link :to="{name: 'home'}">Home</router-link>
|
||||||
|
</div>
|
||||||
|
<div v-else>
|
||||||
|
<p v-if="!error">Account wird aktiviert.</p>
|
||||||
|
<p v-if="error">Leider konnte der Account nicht aktiviert werden.</p>
|
||||||
|
<router-link :to="{name: 'home'}">Home</router-link>
|
||||||
|
</div>
|
||||||
|
</b-col>
|
||||||
|
</b-row>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import * as CONFIG from '../../config'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "Activation",
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
activated: false,
|
||||||
|
error: false,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
let url = CONFIG.API_ROOT.concat('/token-auth/users/activate/');
|
||||||
|
let post_data = {
|
||||||
|
"uid": this.$route.params.uuid,
|
||||||
|
"token": this.$route.params.token,
|
||||||
|
};
|
||||||
|
window.axios
|
||||||
|
.post(url, post_data)
|
||||||
|
.then(response => {
|
||||||
|
this.activated = true;
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.catch(
|
||||||
|
e => {
|
||||||
|
this.error = true;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
84
basta/src/components/account/Login.vue
Normal file
84
basta/src/components/account/Login.vue
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
<template>
|
||||||
|
<div v-if="!isAuthenticated()">
|
||||||
|
<b-row class="justify-content-center text-center ml-md-auto mt-2">
|
||||||
|
<b-col cols="11" sm="10" md="7" lg="5" xl="4" class="border pb-2 pt-2">
|
||||||
|
<h2>Login</h2>
|
||||||
|
<b-form @submit="onSubmit" v-if="show">
|
||||||
|
<b-form-group id="username"
|
||||||
|
label="User Name:"
|
||||||
|
label-for="username">
|
||||||
|
<b-form-input id="username"
|
||||||
|
type="text"
|
||||||
|
v-model="form.username"
|
||||||
|
required
|
||||||
|
placeholder="Enter username">
|
||||||
|
</b-form-input>
|
||||||
|
</b-form-group>
|
||||||
|
<b-form-group id="password"
|
||||||
|
label="Password:"
|
||||||
|
label-for="password">
|
||||||
|
<b-form-input id="password"
|
||||||
|
type="password"
|
||||||
|
v-model="form.password"
|
||||||
|
required
|
||||||
|
placeholder="Enter password">
|
||||||
|
</b-form-input>
|
||||||
|
</b-form-group>
|
||||||
|
<b-button type="submit" variant="primary">Submit</b-button>
|
||||||
|
</b-form>
|
||||||
|
</b-col>
|
||||||
|
<b-col cols="12" class="">
|
||||||
|
<br/>
|
||||||
|
<p>
|
||||||
|
<router-link :to="{name: 'password-reset-mail'}">Passwort vergessen?</router-link>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<router-link :to="{name: 'registration'}">Noch keinen Account?</router-link>
|
||||||
|
</p>
|
||||||
|
</b-col>
|
||||||
|
</b-row>
|
||||||
|
</div>
|
||||||
|
<div v-else>
|
||||||
|
<b-row class="justify-content-center text-center ml-md-auto mt-2">
|
||||||
|
<b-col cols="11" sm="10" md="7" lg="5" xl="4" class="border pb-2 pt-2">
|
||||||
|
Du wurdest erfolgreich eingeloggt.
|
||||||
|
</b-col>
|
||||||
|
</b-row>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import authentication from "../../authentication";
|
||||||
|
import router from '../../router'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "Login",
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
form: {
|
||||||
|
username: '',
|
||||||
|
password: '',
|
||||||
|
},
|
||||||
|
show: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
onSubmit(evt) {
|
||||||
|
evt.preventDefault();
|
||||||
|
authentication.login({"username": this.form.username, "password": this.form.password}, -1);
|
||||||
|
},
|
||||||
|
isAuthenticated: function () {
|
||||||
|
if (authentication.authenticated()) {
|
||||||
|
router.go(-1);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
28
basta/src/components/account/Logout.vue
Normal file
28
basta/src/components/account/Logout.vue
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
<template>
|
||||||
|
<b-row class="justify-content-center text-center ml-md-auto mt-2">
|
||||||
|
<b-col cols="11" sm="10" md="7" lg="5" xl="4" class="border pb-2 pt-2">
|
||||||
|
Du wurdest erfolgreich ausgeloggt.
|
||||||
|
</b-col>
|
||||||
|
</b-row>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import Auth from '../../authentication'
|
||||||
|
import router from '../../router'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "Logout",
|
||||||
|
created() {
|
||||||
|
if (Auth.authenticated()) {
|
||||||
|
Auth.logout();
|
||||||
|
}
|
||||||
|
setTimeout(function () {
|
||||||
|
router.go(-1);
|
||||||
|
}, 3000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
101
basta/src/components/account/PasswordResetConfirmation.vue
Normal file
101
basta/src/components/account/PasswordResetConfirmation.vue
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
<template>
|
||||||
|
<b-row class="justify-content-center text-center ml-md-auto mt-2">
|
||||||
|
<b-col cols="11" sm="10" md="7" lg="5" xl="4" class="border pb-2 pt-2">
|
||||||
|
<h2>Passwort Reset</h2>
|
||||||
|
<p v-if="error">Das Passwort konnte nicht zurück gesetzt werden.</p>
|
||||||
|
<b-form @submit="onSubmit" v-if="show">
|
||||||
|
<b-form-group id="password"
|
||||||
|
label="Password:"
|
||||||
|
label-for="password">
|
||||||
|
<b-form-input id="password"
|
||||||
|
type="password"
|
||||||
|
v-model="form.password"
|
||||||
|
required
|
||||||
|
placeholder="Enter password">
|
||||||
|
</b-form-input>
|
||||||
|
</b-form-group>
|
||||||
|
<b-form-group id="passwordSafety"
|
||||||
|
label-for="passwordSafety">
|
||||||
|
<b-form-input id="passwordSafety"
|
||||||
|
type="password"
|
||||||
|
v-model="form.passwordSafety"
|
||||||
|
required
|
||||||
|
placeholder="Enter password again">
|
||||||
|
</b-form-input>
|
||||||
|
</b-form-group>
|
||||||
|
<div v-if="error" class="error">
|
||||||
|
<p v-for="error in errorMsgs">{{error}}</p>
|
||||||
|
</div>
|
||||||
|
<b-button type="submit" variant="primary">Submit</b-button>
|
||||||
|
</b-form>
|
||||||
|
<div v-if="!show">
|
||||||
|
<p>Passwort wurde erfolgreich zurückgesetzt.</p>
|
||||||
|
<p>Zurück zum
|
||||||
|
<router-link :to="{name: 'login'}">Login</router-link>
|
||||||
|
.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</b-col>
|
||||||
|
</b-row>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import * as CONFIG from "../../config";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "PasswordResetMail",
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
form: {
|
||||||
|
password: '',
|
||||||
|
passwordSafety: ''
|
||||||
|
},
|
||||||
|
show: true,
|
||||||
|
error: false,
|
||||||
|
errorMsgs: []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
onSubmit(evt) {
|
||||||
|
evt.preventDefault();
|
||||||
|
this.errorMsgs = [];
|
||||||
|
let url = CONFIG.API_ROOT.concat('/token-auth/password/reset/confirm/');
|
||||||
|
let post_data = {
|
||||||
|
"new_password": this.form.password,
|
||||||
|
"re_new_password": this.form.passwordSafety,
|
||||||
|
"uid": this.$route.params.uuid,
|
||||||
|
"token": this.$route.params.token,
|
||||||
|
};
|
||||||
|
window.axios
|
||||||
|
.post(url, post_data)
|
||||||
|
.then(response => {
|
||||||
|
this.show = false;
|
||||||
|
this.error = false;
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.catch(
|
||||||
|
e => {
|
||||||
|
this.error = true;
|
||||||
|
console.log(e);
|
||||||
|
if (e.response.data.new_password) {
|
||||||
|
for (const error of e.response.data.new_password) {
|
||||||
|
this.errorMsgs.push(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (e.response.data.non_field_errors) {
|
||||||
|
this.errorMsgs.push(e.response.data.non_field_errors[0]);
|
||||||
|
}
|
||||||
|
console.log(this.errorMsgs)
|
||||||
|
}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.error {
|
||||||
|
font-size: 13px;
|
||||||
|
color: #ff253a;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
77
basta/src/components/account/PasswordResetMail.vue
Normal file
77
basta/src/components/account/PasswordResetMail.vue
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
<template>
|
||||||
|
<b-row class="justify-content-center text-center ml-md-auto mt-2">
|
||||||
|
<b-col cols="11" sm="10" md="7" lg="5" xl="4" class="border pb-2 pt-2">
|
||||||
|
<h2>Passwort Reset</h2>
|
||||||
|
<b-form @submit="onSubmit" v-if="show">
|
||||||
|
<b-form-group id="email"
|
||||||
|
label="Email-Adresse"
|
||||||
|
label-for="email"
|
||||||
|
>
|
||||||
|
<b-form-input id="email"
|
||||||
|
type="email"
|
||||||
|
v-model="form.email"
|
||||||
|
:state="!form.emailErrorVal"
|
||||||
|
required
|
||||||
|
placeholder="Enter email">
|
||||||
|
</b-form-input>
|
||||||
|
<b-form-invalid-feedback id="input1LiveFeedback">
|
||||||
|
<p v-for="error in form.emailError">{{error}}</p>
|
||||||
|
</b-form-invalid-feedback>
|
||||||
|
</b-form-group>
|
||||||
|
<b-button type="submit" variant="primary">Submit</b-button>
|
||||||
|
</b-form>
|
||||||
|
<div v-if="!show">
|
||||||
|
Die E-Mail wurde erfolgreich versandt.
|
||||||
|
<p>Zurück zu
|
||||||
|
<router-link :to="{name: 'home'}">Home</router-link>
|
||||||
|
.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</b-col>
|
||||||
|
</b-row>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import * as CONFIG from "../../config";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "PasswordResetMail",
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
form: {
|
||||||
|
email: '',
|
||||||
|
emailError: '',
|
||||||
|
emailErrorVal: false,
|
||||||
|
},
|
||||||
|
show: true,
|
||||||
|
error: false,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
onSubmit(evt) {
|
||||||
|
evt.preventDefault();
|
||||||
|
this.form.emailErrorVal = false;
|
||||||
|
let url = CONFIG.API_ROOT.concat('/token-auth/password/reset/');
|
||||||
|
let post_data = {
|
||||||
|
"email": this.form.email,
|
||||||
|
};
|
||||||
|
window.axios
|
||||||
|
.post(url, post_data)
|
||||||
|
.then(response => {
|
||||||
|
this.show = false;
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.catch(
|
||||||
|
e => {
|
||||||
|
this.form.emailError = e.response.data.email;
|
||||||
|
this.form.emailErrorVal = true;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
155
basta/src/components/account/Registration.vue
Normal file
155
basta/src/components/account/Registration.vue
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
<template>
|
||||||
|
<b-row class="justify-content-center text-center ml-md-auto mt-2">
|
||||||
|
<b-col cols="11" sm="10" md="7" lg="5" xl="4" class="border pb-2 pt-2">
|
||||||
|
<h2>Registrierung</h2>
|
||||||
|
<p v-if="error">Der Nutzer konnte nicht registriert werden, bitte versuche es erneut.</p>
|
||||||
|
<ul>
|
||||||
|
<li v-for="error in form.passwordError">{{error}}</li>
|
||||||
|
</ul>
|
||||||
|
<b-form @submit="onSubmit" v-if="show">
|
||||||
|
<b-form-group id="username"
|
||||||
|
label="Nutzername"
|
||||||
|
label-for="username">
|
||||||
|
<b-form-input id="username"
|
||||||
|
type="text"
|
||||||
|
v-model="form.username"
|
||||||
|
required
|
||||||
|
placeholder="Enter username">
|
||||||
|
</b-form-input>
|
||||||
|
</b-form-group>
|
||||||
|
<b-form-group id="email"
|
||||||
|
label="Email Adresse"
|
||||||
|
label-for="email"
|
||||||
|
>
|
||||||
|
<b-form-input id="email"
|
||||||
|
type="email"
|
||||||
|
v-model="form.email"
|
||||||
|
:state="!$v.form.email.$invalid"
|
||||||
|
required
|
||||||
|
placeholder="Enter email">
|
||||||
|
</b-form-input>
|
||||||
|
<b-form-invalid-feedback id="input1LiveFeedback">
|
||||||
|
Bitte gebe eine valide E-Mail an.
|
||||||
|
</b-form-invalid-feedback>
|
||||||
|
</b-form-group>
|
||||||
|
<b-form-group id="password"
|
||||||
|
label="Passwort"
|
||||||
|
label-for="password">
|
||||||
|
<b-form-input id="password"
|
||||||
|
type="password"
|
||||||
|
:state="!$v.form.password"
|
||||||
|
v-model="form.password"
|
||||||
|
required
|
||||||
|
placeholder="Enter password">
|
||||||
|
</b-form-input>
|
||||||
|
<b-form-invalid-feedback id="input1LiveFeedback">
|
||||||
|
<ul>
|
||||||
|
<li v-for="error in form.passwordError.$invalid">{{error}}</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
</b-form-invalid-feedback>
|
||||||
|
</b-form-group>
|
||||||
|
<b-form-group id="passwordSafety"
|
||||||
|
label-for="passwordSafety">
|
||||||
|
<b-form-input id="passwordSafety"
|
||||||
|
type="password"
|
||||||
|
v-model="form.passwordSafety"
|
||||||
|
:state="!$v.form.passwordSafety.$invalid"
|
||||||
|
required
|
||||||
|
placeholder="Enter password again">
|
||||||
|
</b-form-input>
|
||||||
|
<b-form-invalid-feedback id="input1LiveFeedback">
|
||||||
|
Die Passwörter müssen identisch sein
|
||||||
|
</b-form-invalid-feedback>
|
||||||
|
</b-form-group>
|
||||||
|
<b-button type="submit" variant="primary" :disabled="$v.form.$invalid">Submit</b-button>
|
||||||
|
</b-form>
|
||||||
|
<div v-if="!show && response">
|
||||||
|
Dein Account wurde erfolgreich angelegt.
|
||||||
|
Bitte bestätige deinen Account über die Aktivierungsmail.
|
||||||
|
</div>
|
||||||
|
<div v-if="!show && !response">
|
||||||
|
Die Account daten werden übermittelt.
|
||||||
|
</div>
|
||||||
|
</b-col>
|
||||||
|
</b-row>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import * as CONFIG from '../../config'
|
||||||
|
import {validationMixin} from "vuelidate"
|
||||||
|
import {required, minLength, sameAs, email} from "vuelidate/lib/validators"
|
||||||
|
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "Registration",
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
form: {
|
||||||
|
username: '',
|
||||||
|
email: '',
|
||||||
|
password: '',
|
||||||
|
passwordError: ['Ein Passwort darf nicht zu ähnlich zum Benutzernamen sein.', ' Ein Passwort muss mindestens 8 Zeichen enthalten.'],
|
||||||
|
passwordSafety: '',
|
||||||
|
},
|
||||||
|
response: false,
|
||||||
|
show: true,
|
||||||
|
error: false,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mixins: [validationMixin],
|
||||||
|
validations: {
|
||||||
|
form: {
|
||||||
|
username: {
|
||||||
|
required,
|
||||||
|
},
|
||||||
|
email: {
|
||||||
|
required,
|
||||||
|
email,
|
||||||
|
},
|
||||||
|
password: {
|
||||||
|
required,
|
||||||
|
minLength: minLength(8),
|
||||||
|
},
|
||||||
|
passwordSafety: {
|
||||||
|
required,
|
||||||
|
sameAsPassword: sameAs('password'),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
onSubmit(evt) {
|
||||||
|
evt.preventDefault();
|
||||||
|
this.show = false;
|
||||||
|
this.error = false;
|
||||||
|
let url = CONFIG.API_ROOT.concat('/token-auth/users/create/');
|
||||||
|
let post_data = {
|
||||||
|
"username": this.form.username,
|
||||||
|
"email": this.form.email,
|
||||||
|
"password": this.form.password,
|
||||||
|
// "re_new_password": this.form.passwordSafety,
|
||||||
|
};
|
||||||
|
window.axios
|
||||||
|
.post(url, post_data)
|
||||||
|
.then(response => {
|
||||||
|
this.error = false;
|
||||||
|
this.response = true;
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.catch(
|
||||||
|
e => {
|
||||||
|
if (e.response.data.password) {
|
||||||
|
this.form.passwordError = e.response.data.password;
|
||||||
|
}
|
||||||
|
this.error = true;
|
||||||
|
this.show = true;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
58
basta/src/components/account/utils/AccountDetails.vue
Normal file
58
basta/src/components/account/utils/AccountDetails.vue
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<div v-if="!showFormular">
|
||||||
|
<b-row class="p-1">
|
||||||
|
<b-col cols="12" sm="12" md="12" lg="8" xl="8" class="p-3 bg-light text-dark">
|
||||||
|
<h3>{{user.username}}</h3>
|
||||||
|
<p><strong>Vorname:</strong> {{ user.first_name }}</p>
|
||||||
|
<p><strong>Nachname:</strong> {{ user.last_name }}</p>
|
||||||
|
<p><strong>E-Mail:</strong> {{ user.email }}</p>
|
||||||
|
<!--<a href="{{ url('change-account') }}">Bearbeiten</a>-->
|
||||||
|
<b-button :pressed.sync="showFormular" variant="primary">{{this.formularButtonLabel}}</b-button>
|
||||||
|
</b-col>
|
||||||
|
<div class="col-12 col-sm-12 col-md-12 col-lg-4 col-xl-4 text-center p-3">
|
||||||
|
<div class="p-3 bg-light text-dark">
|
||||||
|
<p>Date joined: {{ user.date_joined | formatDate}}</p>
|
||||||
|
<p>Last Login: {{ user.last_login | formatDate}}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</b-row>
|
||||||
|
</div>
|
||||||
|
<div v-if="showFormular">
|
||||||
|
<account-formular :user="user"></account-formular>
|
||||||
|
<b-button :pressed.sync="showFormular" variant="primary">{{this.formularButtonLabel}}</b-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import * as CONFIG from '../../../config.js';
|
||||||
|
import AccountFormular from '@/components/account/utils/AccountFormular';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "AccountDetails",
|
||||||
|
components: {AccountFormular},
|
||||||
|
props: ['user'],
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
account: {},
|
||||||
|
showFormular: false,
|
||||||
|
formularButtonLabel: 'Bearbeiten',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
watch: {
|
||||||
|
showFormular: function (newShowFormular) {
|
||||||
|
if (newShowFormular) {
|
||||||
|
this.formularButtonLabel = 'Fertig'
|
||||||
|
} else {
|
||||||
|
this.formularButtonLabel = 'Bearbeiten'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
159
basta/src/components/account/utils/AccountFormular.vue
Normal file
159
basta/src/components/account/utils/AccountFormular.vue
Normal file
@ -0,0 +1,159 @@
|
|||||||
|
<template>
|
||||||
|
<b-row class="justify-content-center text-center ml-md-auto mt-2">
|
||||||
|
<b-col cols="11" sm="10" md="7" lg="5" xl="4" class="border pb-2 pt-2 text-left">
|
||||||
|
<b-form @submit="onSubmit">
|
||||||
|
<b-form-input id="username"
|
||||||
|
type="text"
|
||||||
|
v-model="form.username"
|
||||||
|
required
|
||||||
|
placeholder="Nutzername">
|
||||||
|
</b-form-input>
|
||||||
|
<b-form-input id="firstName"
|
||||||
|
type="text"
|
||||||
|
v-model="form.firstName"
|
||||||
|
placeholder="Vorname">
|
||||||
|
</b-form-input>
|
||||||
|
<b-form-input id="lastName"
|
||||||
|
type="text"
|
||||||
|
v-model="form.lastName"
|
||||||
|
placeholder="Nachname">
|
||||||
|
</b-form-input>
|
||||||
|
<b-form-input id="email"
|
||||||
|
type="email"
|
||||||
|
v-model="form.email"
|
||||||
|
:state="!$v.form.email.$invalid"
|
||||||
|
placeholder="Email Adresse">
|
||||||
|
</b-form-input>
|
||||||
|
<multiselect
|
||||||
|
v-model="form.fakultaet"
|
||||||
|
:options="fakultaetOptions"
|
||||||
|
:multiple="false"
|
||||||
|
:custom-label="optionLabel"
|
||||||
|
track-by="text"
|
||||||
|
placeholder="Fakultät"
|
||||||
|
>
|
||||||
|
</multiselect>
|
||||||
|
<b-form-checkbox id="fakultaetsNews"
|
||||||
|
v-model="form.fakultaetsNews"
|
||||||
|
value=true
|
||||||
|
unchecked-value=false>
|
||||||
|
Fakultätsnachrichten
|
||||||
|
</b-form-checkbox>
|
||||||
|
<multiselect
|
||||||
|
v-model="form.allergens"
|
||||||
|
:options="allergensOptions"
|
||||||
|
:multiple="true"
|
||||||
|
:custom-label="optionLabel"
|
||||||
|
track-by="text"
|
||||||
|
placeholder="Allergene"
|
||||||
|
>
|
||||||
|
</multiselect>
|
||||||
|
<b-button type="submit" variant="primary" :disabled="$v.form.$invalid">Submit</b-button>
|
||||||
|
</b-form>
|
||||||
|
</b-col>
|
||||||
|
</b-row>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import * as CONFIG from '../../../config';
|
||||||
|
import {validationMixin} from "vuelidate";
|
||||||
|
import {required, minLength, sameAs, email} from "vuelidate/lib/validators";
|
||||||
|
import Multiselect from 'vue-multiselect';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "AccountFormular",
|
||||||
|
props: ['user'],
|
||||||
|
components: {Multiselect,},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
form: {
|
||||||
|
username: '',
|
||||||
|
firstName: '',
|
||||||
|
lastName: '',
|
||||||
|
email: '',
|
||||||
|
fakultaet: '',
|
||||||
|
fakultaetsNews: false,
|
||||||
|
allergens: '',
|
||||||
|
},
|
||||||
|
fakultaetOptions: [
|
||||||
|
{value: 1, text: 'SoWi'},
|
||||||
|
{value: 2, text: 'GuK'},
|
||||||
|
{value: 3, text: 'HuWi'},
|
||||||
|
{value: 4, text: 'WIAI'},
|
||||||
|
],
|
||||||
|
allergensOptions: [
|
||||||
|
{value: 1, text: 'Gluten'},
|
||||||
|
{value: 2, text: 'Schwein'},
|
||||||
|
{value: 3, text: 'Rind'},
|
||||||
|
{value: 4, text: 'KA'},
|
||||||
|
],
|
||||||
|
response: false,
|
||||||
|
show: true,
|
||||||
|
error: false,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mixins: [validationMixin],
|
||||||
|
validations: {
|
||||||
|
form: {
|
||||||
|
username: {
|
||||||
|
required,
|
||||||
|
},
|
||||||
|
email: {
|
||||||
|
required,
|
||||||
|
email,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.updateFormular();
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
user: function (newUser) {
|
||||||
|
this.updateFormular();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
updateFormular() {
|
||||||
|
this.form.username = this.user.username;
|
||||||
|
this.form.firstName = this.user.firstName;
|
||||||
|
this.form.lastName = this.user.lastName;
|
||||||
|
this.form.email = this.user.email;
|
||||||
|
},
|
||||||
|
optionLabel(option) {
|
||||||
|
return option.text;
|
||||||
|
},
|
||||||
|
onSubmit(evt) {
|
||||||
|
this.show = false;
|
||||||
|
this.error = false;
|
||||||
|
let url = CONFIG.API_ROOT.concat('/token-auth/users/create/');
|
||||||
|
let post_data = {
|
||||||
|
"username": this.form.username,
|
||||||
|
"email": this.form.email,
|
||||||
|
"password": this.form.password,
|
||||||
|
// "re_new_password": this.form.passwordSafety,
|
||||||
|
};
|
||||||
|
window.axios
|
||||||
|
.post(url, post_data)
|
||||||
|
.then(response => {
|
||||||
|
this.error = false;
|
||||||
|
this.response = true;
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.catch(
|
||||||
|
e => {
|
||||||
|
if (e.response.data.password) {
|
||||||
|
this.form.passwordError = e.response.data.password;
|
||||||
|
}
|
||||||
|
this.error = true;
|
||||||
|
this.show = true;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style src="vue-multiselect/dist/vue-multiselect.min.css"></style>
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
139
basta/src/components/account/utils/Food.vue
Normal file
139
basta/src/components/account/utils/Food.vue
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<h4>Essen</h4>
|
||||||
|
<div class="row p-1">
|
||||||
|
<div v-for="food in foods" class="col col-12 col-sm-12 col-md-12 col-lg-6 col-xl-6 p-2">
|
||||||
|
<b-row class="food border p-2">
|
||||||
|
<b-col cols="4" class="image">
|
||||||
|
<a v-if="food.image" :href="food.image.thumb">
|
||||||
|
<img :src="food.image.thumb" class="media-object" alt="Bild" width="100%">
|
||||||
|
</a>
|
||||||
|
<a v-else :href="defaultImageUrl">
|
||||||
|
<img :src="defaultImageUrl" class="media-object"
|
||||||
|
alt="Bild" width="100%">
|
||||||
|
</a>
|
||||||
|
</b-col>
|
||||||
|
<b-col cols="4" class="title-rating">
|
||||||
|
<b-row>
|
||||||
|
<b-col cols="12">
|
||||||
|
<h5>{{food.name}}</h5>
|
||||||
|
</b-col>
|
||||||
|
</b-row>
|
||||||
|
<b-row>
|
||||||
|
<b-col cols="12">
|
||||||
|
<div v-if="food.rating">
|
||||||
|
Rating: {{food.rating}}
|
||||||
|
</div>
|
||||||
|
</b-col>
|
||||||
|
</b-row>
|
||||||
|
</b-col>
|
||||||
|
<b-col cols="4" class="comment">
|
||||||
|
<div v-if="food.comment">
|
||||||
|
<h5>{{food.comment.title}}</h5>
|
||||||
|
<div class="">
|
||||||
|
<p>{{food.comment.description}}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</b-col>
|
||||||
|
</b-row>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import * as CONFIG from '../../../config.js'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "Food",
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
images: [],
|
||||||
|
ratings: [],
|
||||||
|
comments: [],
|
||||||
|
foods: [],
|
||||||
|
defaultImageUrl: '',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
window.axios
|
||||||
|
.get(CONFIG.API_ROOT_ACCOUNT.concat('/food/ratings/'))
|
||||||
|
.then((response) => {
|
||||||
|
this.ratings = response.data;
|
||||||
|
this.mergeArrays();
|
||||||
|
})
|
||||||
|
.catch(e => console.error(e));
|
||||||
|
|
||||||
|
window.axios
|
||||||
|
.get(CONFIG.API_ROOT_ACCOUNT.concat('/food/images/'))
|
||||||
|
.then((response) => {
|
||||||
|
this.images = response.data;
|
||||||
|
this.mergeArrays();
|
||||||
|
})
|
||||||
|
.catch(e => console.error(e));
|
||||||
|
|
||||||
|
window.axios
|
||||||
|
.get(CONFIG.API_ROOT_ACCOUNT.concat('/food/comments/'))
|
||||||
|
.then((response) => {
|
||||||
|
this.comments = response.data;
|
||||||
|
this.mergeArrays();
|
||||||
|
})
|
||||||
|
.catch(e => console.error(e));
|
||||||
|
axios.get(CONFIG.API_ROOT_FOOD.concat('/meals/images/default'))
|
||||||
|
.then(response => {
|
||||||
|
this.defaultImageUrl = response.data.image;
|
||||||
|
})
|
||||||
|
.catch(e => {
|
||||||
|
console.error(e)
|
||||||
|
});
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
mergeArrays: function () {
|
||||||
|
this.foods = [];
|
||||||
|
let food_ids = [];
|
||||||
|
let foods = {};
|
||||||
|
|
||||||
|
if (this.images.length > 0) {
|
||||||
|
for (const image of this.images) {
|
||||||
|
food_ids.push(image.food.id);
|
||||||
|
foods[image.food.id] = {};
|
||||||
|
foods[image.food.id]['name'] = image.food.name;
|
||||||
|
foods[image.food.id]['image'] = image.image;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (this.ratings.length > 0) {
|
||||||
|
for (const rating of this.ratings) {
|
||||||
|
food_ids.push(rating.food.id);
|
||||||
|
if (!foods[rating.food.id]) {
|
||||||
|
foods[rating.food.id] = {};
|
||||||
|
}
|
||||||
|
foods[rating.food.id]['name'] = rating.food.name;
|
||||||
|
foods[rating.food.id]['rating'] = rating.rating;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (this.comments.length > 0) {
|
||||||
|
for (const comment of this.comments) {
|
||||||
|
food_ids.push(comment.food.id);
|
||||||
|
if (!foods[comment.food.id]) {
|
||||||
|
foods[comment.food.id] = {};
|
||||||
|
}
|
||||||
|
foods[comment.food.id]['name'] = comment.food.name;
|
||||||
|
foods[comment.food.id]['comment'] = {};
|
||||||
|
foods[comment.food.id]['comment']['title'] = comment.title;
|
||||||
|
foods[comment.food.id]['comment']['description'] = comment.description;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (const key in foods) {
|
||||||
|
this.foods.push(foods[key]);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.food {
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
Reference in New Issue
Block a user