WIP Refactor general api login

This commit is contained in:
Björn Fromme
2019-09-27 11:46:55 +02:00
parent 6079340162
commit ef14ae5863
20 changed files with 475 additions and 547 deletions
@@ -45,7 +45,7 @@ Vue.filter('date', (value) => {
}); });
// Store // Store
import store from './_store'; import store from './store';
// Initialize vue app // Initialize vue app
new Vue({ new Vue({
@@ -65,7 +65,7 @@ new Vue({
Watchlist, Watchlist,
HotelList, HotelList,
BackLink, BackLink,
MyEp: () => import('./myep/components/App.vue'), MyEp: () => import('./myep/App.vue'),
FacebookPixel FacebookPixel
}, },
data () { data () {
@@ -355,8 +355,7 @@ new Vue({
} }
}, },
created () { created () {
this.$store.commit('initConfig'); this.$store.dispatch('init');
this.$store.commit('initWatchlist');
EventBus.$on('ajaxContentLoaded', () => { EventBus.$on('ajaxContentLoaded', () => {
Vue.nextTick(() => { Vue.nextTick(() => {
this.initContentsliders(); this.initContentsliders();
@@ -1,249 +0,0 @@
import Vue from 'vue'
import Vuex from 'vuex'
import axios from 'axios'
import AddressStore from './myep/stores/address'
import CrmDataStore from './myep/stores/crmdata'
import TeamerStore from './myep/stores/teamer'
import EventsStore from './myep/stores/events'
import NewsletterStore from './myep/stores/newsletter'
Vue.use(Vuex);
export default new Vuex.Store({
modules: {
address: AddressStore,
crmdata: CrmDataStore,
teamer: TeamerStore,
events: EventsStore,
newsletter: NewsletterStore
},
state: {
config: {},
watchlist: [],
loading: false,
authToken: sessionStorage.getItem('token'),
loggedIn: !!sessionStorage.getItem('token'),
isTeamer: JSON.parse(sessionStorage.getItem('isTeamer')),
memberId: JSON.parse(sessionStorage.getItem('memberId')),
memberName: sessionStorage.getItem('memberName'),
countries: [],
abilities: [],
timeFrames: [],
jobProfiles: [],
message: {
text: '',
class: ''
}
},
mutations: {
initConfig (state) {
const configElement = document.getElementById('appconfig');
state.config = JSON.parse(configElement.innerHTML);
axios.defaults.baseURL = state.config.myEpApiBaseUrl;
},
initWatchlist (state, list = null) {
if (list) {
sessionStorage.setItem('watchlist', JSON.stringify(list));
} else if (!sessionStorage.getItem('watchlist')) {
sessionStorage.setItem('watchlist', JSON.stringify({ id: null, items: [] }));
}
state.watchlist = JSON.parse(sessionStorage.getItem('watchlist'));
},
watchlistToggle (state, uid) {
let list = state.watchlist.items;
let watchlistIndex = list.indexOf(uid);
if (watchlistIndex === -1) {
list.push(uid)
} else {
list.splice(watchlistIndex, 1)
}
state.watchlist.items = list;
sessionStorage.setItem('watchlist', JSON.stringify(state.watchlist));
if (state.loggedIn) {
const client = axios.create({
headers: {
'X-Auth-Token': state.authToken
}
});
client.put('/api/watchlists/' + state.watchlist.id, state.watchlist);
}
},
loginSuccess (state, token) {
state.loggedIn = true;
state.authToken = token;
sessionStorage.setItem('token', token);
},
loginFailure (state) {
state.loggedIn = false;
},
logout (state) {
state.loggedIn = false;
state.isTeamer = false;
state.teamerId = null;
state.authToken = null;
state.watchlist = { id: null, items: [] };
sessionStorage.removeItem('token');
sessionStorage.removeItem('isTeamer');
sessionStorage.removeItem('memberId');
sessionStorage.removeItem('memberName');
sessionStorage.removeItem('watchlist');
},
alert (state, payload) {
state.message.text = payload.message;
state.message.class = payload.class;
},
isTeamer (state) {
state.isTeamer = true;
sessionStorage.setItem('isTeamer', JSON.stringify(true));
},
setMember (state, member) {
state.memberId = member.id;
state.memberName = member.name;
sessionStorage.setItem('memberId', member.id);
sessionStorage.setItem('memberName', member.name);
},
loadingBegin (state) {
state.loading = true;
state.message.text = '';
state.message.class = '';
},
loadingFinish (state) {
state.loading = false;
},
setCountries (state, countries) {
state.countries = countries;
},
setAbilities (state, abilities) {
state.abilities = abilities;
},
setTimeFrames (state, timeFrames) {
state.timeFrames = timeFrames;
},
setJobProfiles (state, jobProfiles) {
state.jobProfiles = jobProfiles;
}
},
actions: {
login({ commit }, credentials) {
commit('loadingBegin');
const formData = new FormData();
formData.append('_username', credentials.email);
formData.append('_password', credentials.password);
return axios({
url: '/api/login',
data: formData,
method: 'post',
withCredentials: true
}).then((response) => {
let memberId = parseInt(response.data.member_id);
commit('setMember', { id: memberId, name: response.data.member_name });
if (response.data.watchlist) {
commit('initWatchlist', response.data.watchlist);
}
if (response.data.is_teamer) {
commit('isTeamer');
}
commit('loginSuccess', response.data.token);
commit('loadingFinish');
}).catch((error) => {
commit('loginFailure');
commit('alert', {
message: 'Der Login ist fehlgeschlagen :(',
class: 'alert-danger'
});
commit('loadingFinish');
throw error;
});
},
logout({ commit, state }) {
commit('loadingBegin');
return axios({
url: '/api/logout',
headers: {
'x-auth-token': state.authToken
}
}).then(() => {
commit('logout');
commit('loadingFinish');
}).catch((error) => {
commit('alert', {
message: 'Der Logout ist fehlgeschlagen :(',
class: 'alert-danger'
});
commit('loadingFinish');
throw error;
});
},
resetPassword({ commit }, email) {
commit('loadingBegin');
const formData = new FormData();
formData.append('email', email);
return axios({
url: '/api/reset-password',
data: formData,
method: 'post'
}).then((response) => {
commit('loadingFinish');
return response;
}).catch((error) => {
commit('loadingFinish');
throw error;
});
},
register({ commit }, userData) {
commit('loadingBegin');
return axios({
url: '/api/addresses',
data: userData,
method: 'post'
}).then((response) => {
commit('loadingFinish');
return response;
}).catch((error) => {
commit('loadingFinish');
throw error;
});
},
loadSelectableValues ({ commit }) {
axios({
url: '/api/countries',
}).then((response) => {
commit('setCountries', response.data['hydra:member']);
});
axios({
url: '/api/teamer-abilities',
}).then((response) => {
commit('setAbilities', response.data['hydra:member']);
});
axios({
url: '/api/timeframes',
}).then((response) => {
commit('setTimeFrames', response.data['hydra:member']);
});
axios({
url: '/api/teamer-job-profiles',
}).then((response) => {
commit('setJobProfiles', response.data['hydra:member']);
});
}
},
getters: {
watchlistCount: state => {
return state.watchlist.items.length;
},
onWatchlist: (state) => (uid) => {
return state.watchlist.items.indexOf(uid) !== -1;
},
authToken: state => {
return state.authToken;
},
isTeamer: state => {
return state.isTeamer;
},
teamerId: state => {
return state.teamerId;
}
}
});
@@ -24,7 +24,7 @@
}, },
methods: { methods: {
toggleWatchlist () { toggleWatchlist () {
this.$store.commit('watchlistToggle', this.uid); this.$store.dispatch('watchlistToggle', this.uid);
EventBus.$emit('watchlistToggle'); EventBus.$emit('watchlistToggle');
} }
}, },
@@ -8,30 +8,30 @@
<label for="gender" class="control-label"> <label for="gender" class="control-label">
Gender: Gender:
</label> </label>
<select id="gender" v-model="address.gender" class="form-control"> <select id="gender" v-model="userData.gender" class="form-control">
<option value="W">W</option> <option value="w">W</option>
<option value="M">M</option> <option value="m">M</option>
<option value="D">D</option> <option value="d">D</option>
</select> </select>
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="title" class="control-label"> <label for="title" class="control-label">
Titel: Titel:
</label> </label>
<input id="title" type="text" v-model="address.title" class="form-control"> <input id="title" type="text" v-model="userData.title" class="form-control">
</div> </div>
<div class="form-group" :class="{'has-error': formErrors.name }"> <div class="form-group" :class="{'has-error': formErrors.lastName }">
<label for="name" class="control-label"> <label for="name" class="control-label">
Name: Name:
</label> </label>
<input id="name" type="text" v-model="address.name" class="form-control"> <input id="name" type="text" v-model="userData.lastName" class="form-control">
<span class="help-block">{{ formErrors.name }}</span> <span class="help-block">{{ formErrors.lastName }}</span>
</div> </div>
<div class="form-group" :class="{'has-error': formErrors.firstName }"> <div class="form-group" :class="{'has-error': formErrors.firstName }">
<label for="firstName" class="control-label"> <label for="firstName" class="control-label">
Vorname: Vorname:
</label> </label>
<input id="firstName" type="text" v-model="address.firstName" class="form-control"> <input id="firstName" type="text" v-model="userData.firstName" class="form-control">
<span class="help-block">{{ formErrors.firstName }}</span> <span class="help-block">{{ formErrors.firstName }}</span>
</div> </div>
<div class="form-group"> <div class="form-group">
@@ -46,28 +46,28 @@
<label for="street" class="control-label"> <label for="street" class="control-label">
Straße: Straße:
</label> </label>
<input id="street" type="text" v-model="address.street" class="form-control"> <input id="street" type="text" v-model="userData.street" class="form-control">
<span class="help-block">{{ formErrors.street }}</span> <span class="help-block">{{ formErrors.street }}</span>
</div> </div>
<div class="form-group" :class="{'has-error': formErrors.zipCode }"> <div class="form-group" :class="{'has-error': formErrors.zipCode }">
<label for="zipCode" class="control-label"> <label for="zipCode" class="control-label">
PLZ: PLZ:
</label> </label>
<input id="zipCode" type="text" v-model="address.zipCode" class="form-control"> <input id="zipCode" type="text" v-model="userData.zipCode" class="form-control">
<span class="help-block">{{ formErrors.zipCode }}</span> <span class="help-block">{{ formErrors.zipCode }}</span>
</div> </div>
<div class="form-group" :class="{'has-error': formErrors.city }"> <div class="form-group" :class="{'has-error': formErrors.city }">
<label for="city" class="control-label"> <label for="city" class="control-label">
Stadt: Stadt:
</label> </label>
<input id="city" type="text" v-model="address.city" class="form-control"> <input id="city" type="text" v-model="userData.city" class="form-control">
<span class="help-block">{{ formErrors.city }}</span> <span class="help-block">{{ formErrors.city }}</span>
</div> </div>
<div class="form-group" :class="{'has-error': formErrors.country }"> <div class="form-group" :class="{'has-error': formErrors.country }">
<label for="country" class="control-label"> <label for="country" class="control-label">
Land: Land:
</label> </label>
<select id="country" v-model="address.country" class="form-control"> <select id="country" v-model="userData.country" class="form-control">
<option v-for="country in $store.state.countries" <option v-for="country in $store.state.countries"
:value="country['code']">{{ country['name'] }}</option> :value="country['code']">{{ country['name'] }}</option>
</select> </select>
@@ -77,20 +77,20 @@
<label for="email" class="control-label"> <label for="email" class="control-label">
E-Mail: E-Mail:
</label> </label>
<input id="email" type="text" v-model="address.email" class="form-control"> <input id="email" type="text" v-model="userData.email" class="form-control">
<span class="help-block">{{ formErrors.email }}</span> <span class="help-block">{{ formErrors.email }}</span>
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="phone" class="control-label"> <label for="phone" class="control-label">
Telefon: Telefon:
</label> </label>
<input id="phone" type="text" v-model="address.phonePrivate" class="form-control"> <input id="phone" type="text" v-model="userData.phonePrivate" class="form-control">
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="mobile" class="control-label"> <label for="mobile" class="control-label">
Mobil: Mobil:
</label> </label>
<input id="mobile" type="text" v-model="address.phoneMobile" class="form-control"> <input id="mobile" type="text" v-model="userData.phoneMobile" class="form-control">
</div> </div>
</div> </div>
<div class="col-xs-12"> <div class="col-xs-12">
@@ -107,22 +107,24 @@
<script> <script>
import Vue from 'vue' import Vue from 'vue'
import $ from 'jquery' import { mapState } from 'vuex'
import $ from 'jquery'
import flatpickr from 'flatpickr' import flatpickr from 'flatpickr'
import { German } from 'flatpickr/dist/l10n/de' import { German } from 'flatpickr/dist/l10n/de'
import EventBus from '../../_bus'
export default { export default {
data () { data () {
return { return {
picker: null, picker: null,
address: {},
formErrors: {} formErrors: {}
} }
}, },
created () { created () {
this.initFormErrors(); this.initFormErrors();
this.fetchAddress(); this.$store.dispatch('address/load')
.then(() => {
this.picker.setDate(new Date(this.userData.dateOfBirth), true);
});
}, },
mounted () { mounted () {
Vue.nextTick(() => { Vue.nextTick(() => {
@@ -131,15 +133,15 @@
locale: German, locale: German,
inline: true, inline: true,
onChange: (selectedDates) => { onChange: (selectedDates) => {
this.address.dateOfBirth = flatpickr.formatDate(selectedDates[0], 'Y-m-d') this.userData.dateOfBirth = flatpickr.formatDate(selectedDates[0], 'Y-m-d')
} }
}); });
}); })
}, },
methods: { methods: {
initFormErrors () { initFormErrors () {
this.formErrors = { this.formErrors = {
name: null, lastName: null,
firstName: null, firstName: null,
dateOfBirth: null, dateOfBirth: null,
email: null, email: null,
@@ -150,19 +152,9 @@
country: null country: null
} }
}, },
fetchAddress () {
this.$store.dispatch('address/load')
.then((data) => {
this.address = data;
this.picker.setDate(new Date(this.address.dateOfBirth), true);
})
.finally(() => {
EventBus.$emit('scrollTo', '#myep-main');
});
},
saveAddress () { saveAddress () {
this.initFormErrors(); this.initFormErrors();
this.$store.dispatch('address/save', this.address) this.$store.dispatch('address/save', this.userData)
.catch(error => { .catch(error => {
this.$store.commit('alert', { this.$store.commit('alert', {
message: 'Bitte überprüfe deine Eingaben.', message: 'Bitte überprüfe deine Eingaben.',
@@ -170,18 +162,13 @@
}); });
const violations = error.response.data['violations']; const violations = error.response.data['violations'];
for (let violation of violations) { for (let violation of violations) {
this.formErrors[violation.propertyPath] = violation.message; this.formErrors[violation.property_path] = violation.message;
} }
})
.finally(() => {
EventBus.$emit('scrollTo', '#myep-main');
}); });
} }
}, },
computed: { computed: {
loading () { ...mapState(['loading', 'userData'])
return this.$store.state.loading;
}
} }
} }
</script> </script>
@@ -16,36 +16,34 @@
<router-link :to="{ name: 'newsletter' }" tag="li" active-class="active" :class="{ disabled: loading }"><a>Newsletter</a></router-link> <router-link :to="{ name: 'newsletter' }" tag="li" active-class="active" :class="{ disabled: loading }"><a>Newsletter</a></router-link>
<router-link :to="{ name: 'profile' }" tag="li" active-class="active" :class="{ disabled: loading }"><a>Mein Profil</a></router-link> <router-link :to="{ name: 'profile' }" tag="li" active-class="active" :class="{ disabled: loading }"><a>Mein Profil</a></router-link>
<router-link :to="{ name: 'events' }" tag="li" active-class="active" :class="{ disabled: loading }"><a>Reise-Historie</a></router-link> <router-link :to="{ name: 'events' }" tag="li" active-class="active" :class="{ disabled: loading }"><a>Reise-Historie</a></router-link>
<router-link :to="{ name: 'teamer' }" tag="li" active-class="active" :class="{ disabled: loading }" v-if="$store.getters.isTeamer"><a>Teamer</a></router-link> <router-link :to="{ name: 'teamer' }" tag="li" active-class="active" :class="{ disabled: loading }" v-if="isTeamer"><a>Teamer</a></router-link>
</ul> </ul>
<ul class="nav navbar-nav navbar-right"> <ul class="nav navbar-nav navbar-right">
<li :class="{ disabled: loading }"><a href="#" @click.prevent="logout()">Logout</a></li> <li :class="{ disabled: loading }"><a href="#" @click.prevent="logout()">Logout</a></li>
</ul> </ul>
</div> </div>
</nav> </nav>
<div class="row" v-if="$store.state.message.text"> <div class="row" v-if="alert.message">
<div class="col-xs-12"> <div class="col-xs-12">
<div class="alert alert-dismissable" :class="$store.state.message.class"> <div class="alert alert-dismissable" :class="alert.class">
<button type="button" class="close" data-dismiss="alert" aria-label="Close"> <button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">&times;</span> <span aria-hidden="true">&times;</span>
</button> </button>
{{ $store.state.message.text }} {{ alert.message }}
</div> </div>
</div> </div>
</div> </div>
<div class="row" v-show="loading"> <div class="loader" v-show="loading">
<div class="col-xs-12"> <img :src="config.loaderUrl" alt="">
<img :src="$store.state.config.loaderUrl" alt="">
</div>
</div> </div>
<router-view></router-view> <router-view></router-view>
</div> </div>
</template> </template>
<script> <script>
import store from '../../_store' import { mapGetters, mapState } from 'vuex'
import router from '../_router' import store from '../store'
import EventBus from '../../_bus' import router from '../router'
export default { export default {
store, store,
@@ -55,31 +53,46 @@
this.$store.dispatch('logout') this.$store.dispatch('logout')
.then(() => { .then(() => {
this.$router.push({ name: 'login' }) this.$router.push({ name: 'login' })
}).catch(error => {
}); });
} }
}, },
computed: { computed: {
isLoggedIn () { ...mapState(['config', 'loading', 'alert']),
return this.$store.state.loggedIn; ...mapGetters(['isLoggedIn', 'isTeamer'])
},
loaderUrl () {
return this.$store.state.config.loaderUrl;
},
loading () {
return this.$store.state.loading;
}
}, },
created () { mounted () {
this.$store.dispatch('loadSelectableValues'); this.$store.dispatch('initSession')
EventBus.$on('forcedLogout', () => { .then(()=> {
this.$router.push({ name: 'login' }) if (this.isLoggedIn) {
}); this.$router.push({ name: 'address' })
}
})
} }
} }
</script> </script>
<style scoped> <style scoped lang="scss">
.nav-disabled { .nav-disabled {
opacity: 0.5; opacity: 0.5;
} }
#app {
position: relative;
}
.loader {
position: absolute;
top: 0;
left: 0;
z-index: 10;
width: 100%;
height: 100%;
background-color: rgba(255, 255, 255, 0.85);
img {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
}
</style> </style>
@@ -44,7 +44,7 @@
</template> </template>
<script> <script>
import EventBus from '../../_bus' import { mapState } from 'vuex'
export default { export default {
data () { data () {
@@ -62,14 +62,12 @@
this.$store.dispatch('crmdata/load') this.$store.dispatch('crmdata/load')
.then((data) => { .then((data) => {
this.crmData = data; this.crmData = data;
}).finally(() => { }).catch(error => {
EventBus.$emit('scrollTo', '#myep-main');
}); });
}, },
saveSelections () { saveSelections () {
this.$store.dispatch('crmdata/save', this.crmData) this.$store.dispatch('crmdata/save', this.crmData)
.finally(() => { .catch(error => {
EventBus.$emit('scrollTo', '#myep-main');
}); });
}, },
hasVisibleSelections (group) { hasVisibleSelections (group) {
@@ -88,9 +86,7 @@
} }
}, },
computed: { computed: {
loading () { ...mapState(['loading'])
return this.$store.state.loading;
}
} }
} }
</script> </script>
@@ -42,9 +42,9 @@
</template> </template>
<script> <script>
import { mapState } from 'vuex'
import dayjs from 'dayjs' import dayjs from 'dayjs'
import 'dayjs/locale/de' import 'dayjs/locale/de'
import EventBus from '../../_bus'
export default { export default {
data () { data () {
@@ -67,8 +67,7 @@
this.$store.dispatch('events/load') this.$store.dispatch('events/load')
.then((events) => { .then((events) => {
this.events = events; this.events = events;
}).finally(() => { }).catch(error => {
EventBus.$emit('scrollTo', '#myep-main');
}); });
}, },
formatBookingDate (date) { formatBookingDate (date) {
@@ -78,11 +77,11 @@
return dayjs(date).format('DD.MM.YYYY'); return dayjs(date).format('DD.MM.YYYY');
}, },
getDownloadUrl (event, type) { getDownloadUrl (event, type) {
return this.$store.state.config.myEpApiBaseUrl return this.config.myEpApiBaseUrl
+ '/api/events/' + '/api/events/'
+ event.id + event.id
+ '/' + type + '?token=' + '/' + type + '?token='
+ this.$store.getters.authToken; + this.authToken;
}, },
calculateBalance (event) { calculateBalance (event) {
if (!event.preis || !event.zahlung) { if (!event.preis || !event.zahlung) {
@@ -99,9 +98,7 @@
} }
}, },
computed: { computed: {
loading () { ...mapState(['config', 'loading', 'authToken'])
return this.$store.state.loading;
}
} }
} }
</script> </script>
@@ -42,7 +42,7 @@
</template> </template>
<script> <script>
import EventBus from '../../_bus' import { mapState, mapGetters } from 'vuex'
export default { export default {
data () { data () {
@@ -79,8 +79,6 @@
}).then(() => { }).then(() => {
this.$router.push({ name: 'address' }); this.$router.push({ name: 'address' });
}).catch(error => { }).catch(error => {
}).finally(() => {
EventBus.$emit('scrollTo', '#myep-main');
}); });
}, },
resetPassword () { resetPassword () {
@@ -107,15 +105,12 @@
}); });
} }
}).catch(error => { }).catch(error => {
}).finally(() => {
EventBus.$emit('scrollTo', '#myep-main');
}); });
} }
}, },
computed: { computed: {
loading () { ...mapState(['loading']),
return this.$store.state.loading; ...mapGetters(['isLoggedIn']),
},
loginMode () { loginMode () {
return this.mode === 'login'; return this.mode === 'login';
} }
@@ -0,0 +1,42 @@
<template>
<div class="form-wrapper form--border" id="myep-main" v-show="!loading">
<h1>Newsletter</h1>
<div class="row">
<div class="col-xs-12">
<p v-html="statusMessage"></p>
<button type="submit" class="button" :disabled="loading" @click.prevent="toggleReqistration()">
{{ userData.newsletter ? 'Abmelden' : 'Anmelden' }}
</button>
</div>
</div>
</div>
</template>
<script>
import { mapState } from 'vuex'
export default {
methods: {
toggleReqistration () {
this.userData.newsletter = !this.userData.newsletter;
const data = {
id: this.userData.id,
email: this.userData.email,
registration: this.userData.newsletter
};
this.$store.dispatch('newsletter/registration', data)
.catch(error => {
});
}
},
computed: {
...mapState(['loading', 'userData']),
statusMessage () {
let message = 'Du bist aktuell';
message += this.userData.newsletter ? ' ' : ' <strong>nicht</strong> ';
message += 'zum Newsletter angemeldet.';
return message;
}
}
}
</script>
@@ -65,7 +65,7 @@
</template> </template>
<script> <script>
import EventBus from '../../_bus' import { mapState} from 'vuex'
export default { export default {
data () { data () {
@@ -103,8 +103,6 @@
this.formErrors[violation.propertyPath] = violation.message; this.formErrors[violation.propertyPath] = violation.message;
} }
} }
}).finally(() => {
EventBus.$emit('scrollTo', '#myep-main');
}); });
}, },
initFormData () { initFormData () {
@@ -129,9 +127,7 @@
this.initFormErrors(); this.initFormErrors();
}, },
computed: { computed: {
loading () { ...mapState(['loading'])
return this.$store.state.loading;
}
} }
} }
</script> </script>
@@ -6,10 +6,10 @@
<div class="col-xs-12 col-md-6"> <div class="col-xs-12 col-md-6">
<h4>Fährst du Ski oder Board?</h4> <h4>Fährst du Ski oder Board?</h4>
<div class="form-group"> <div class="form-group">
<div class="checkbox" v-for="ability of $store.state.abilities"> <div class="checkbox" v-for="ability of abilities">
<label> <label>
<input type="checkbox" class="form-control" v-model="teamerData.abilities" <input type="checkbox" class="form-control" v-model="userData.abilities"
:value="ability['@id']" /> :value="ability.id" />
<span class="cr"><i class="cr-icon glyphicon glyphicon-ok"></i></span> <span class="cr"><i class="cr-icon glyphicon glyphicon-ok"></i></span>
{{ ability['title'] }} {{ ability['title'] }}
</label> </label>
@@ -17,10 +17,10 @@
</div> </div>
<h4>Mögliche Jobprofile</h4> <h4>Mögliche Jobprofile</h4>
<div class="form-group"> <div class="form-group">
<div class="checkbox" v-for="jobProfile of $store.state.jobProfiles"> <div class="checkbox" v-for="jobProfile of jobProfiles">
<label> <label>
<input type="checkbox" class="form-control" v-model="teamerData.jobProfiles" <input type="checkbox" class="form-control" v-model="userData.jobProfiles"
:value="jobProfile['@id']" /> :value="jobProfile.id" />
<span class="cr"><i class="cr-icon glyphicon glyphicon-ok"></i></span> <span class="cr"><i class="cr-icon glyphicon glyphicon-ok"></i></span>
{{ jobProfile['title'] }} {{ jobProfile['title'] }}
</label> </label>
@@ -30,7 +30,7 @@
<div class="form-group"> <div class="form-group">
<div class="checkbox"> <div class="checkbox">
<label> <label>
<input type="checkbox" class="form-control" v-model="teamerData.wantsToLead"/> <input type="checkbox" class="form-control" v-model="userData.wantsToLead"/>
<span class="cr"><i class="cr-icon glyphicon glyphicon-ok"></i></span> <span class="cr"><i class="cr-icon glyphicon glyphicon-ok"></i></span>
Ich möchte eine Fahrtenleitung übernehmen. Ich möchte eine Fahrtenleitung übernehmen.
</label> </label>
@@ -40,7 +40,7 @@
<label for="status" class="control-label"> <label for="status" class="control-label">
Status: Status:
</label> </label>
<select id="status" v-model="teamerData.seniority" class="form-control"> <select id="status" v-model="userData.seniority" class="form-control">
<option v-for="status in this.status" :value="status.value">{{ status.label }}</option> <option v-for="status in this.status" :value="status.value">{{ status.label }}</option>
</select> </select>
</div> </div>
@@ -48,7 +48,7 @@
<label for="jacketsize" class="control-label"> <label for="jacketsize" class="control-label">
Jackengröße: Jackengröße:
</label> </label>
<select id="jacketsize" v-model="teamerData.jacketSize" class="form-control"> <select id="jacketsize" v-model="userData.jacketSize" class="form-control">
<option v-for="size of this.sizes" :value="size">{{ size }}</option> <option v-for="size of this.sizes" :value="size">{{ size }}</option>
</select> </select>
</div> </div>
@@ -56,22 +56,22 @@
<label for="jacketsize" class="control-label"> <label for="jacketsize" class="control-label">
Wünsche: Wünsche:
</label> </label>
<textarea class="xxlarge form-control" cols="30" rows="3" v-model="teamerData.notes"></textarea> <textarea class="xxlarge form-control" cols="30" rows="3" v-model="userData.notes"></textarea>
</div> </div>
</div> </div>
<div class="col-xs-12 col-md-6"> <div class="col-xs-12 col-md-6">
<h4>Verfügbarkeiten</h4> <h4>Verfügbarkeiten</h4>
<div class="checkbox" v-for="timeFrame in $store.state.timeFrames"> <div class="checkbox" v-for="timeFrame in timeFrames">
<label> <label>
<input type="checkbox" class="form-control" v-model="teamerData.availableTimeframes" <input type="checkbox" class="form-control" v-model="userData.availableTimeframes"
:value="timeFrame['@id']"/> :value="timeFrame.id"/>
<span class="cr"><i class="cr-icon glyphicon glyphicon-ok"></i></span> <span class="cr"><i class="cr-icon glyphicon glyphicon-ok"></i></span>
{{ timeFrame | period }} {{ timeFrame | period }}
</label> </label>
</div> </div>
<div class="checkbox"> <div class="checkbox">
<label> <label>
<input type="checkbox" class="form-control" v-model="teamerData.monthLong"/> <input type="checkbox" class="form-control" v-model="userData.monthLong"/>
<span class="cr"><i class="cr-icon glyphicon glyphicon-ok"></i></span> <span class="cr"><i class="cr-icon glyphicon glyphicon-ok"></i></span>
Ich habe Zeit und würde gerne über einen Monat am Stück in eine Destination. Ich habe Zeit und würde gerne über einen Monat am Stück in eine Destination.
</label> </label>
@@ -92,7 +92,7 @@
</template> </template>
<script> <script>
import EventBus from '../../_bus' import { mapState } from 'vuex'
import dayjs from 'dayjs' import dayjs from 'dayjs'
import 'dayjs/locale/de' import 'dayjs/locale/de'
@@ -103,25 +103,16 @@
status: [ status: [
{ value: 'jr', label: 'Neuteamer' }, { value: 'jr', label: 'Neuteamer' },
{ value: 'sr', label: 'Bestandsteamer' } { value: 'sr', label: 'Bestandsteamer' }
], ]
teamerData () {
return {}
}
} }
}, },
methods: { methods: {
fetchTeamerData () { fetchTeamerData () {
this.$store.dispatch('teamer/load') this.$store.dispatch('teamer/loadSelectableValues');
.then((data) => {
this.teamerData = data;
}).finally(() => {
EventBus.$emit('scrollTo', '#myep-main');
});
}, },
saveTeamerData () { saveTeamerData () {
this.$store.dispatch('teamer/save', this.teamerData) this.$store.dispatch('teamer/save', this.teamerData)
.finally(() => { .catch(error => {
EventBus.$emit('scrollTo', '#myep-main');
}); });
} }
}, },
@@ -129,9 +120,10 @@
this.fetchTeamerData(); this.fetchTeamerData();
}, },
computed: { computed: {
loading () { ...mapState(['userData', 'loading']),
return this.$store.state.loading; ...mapState('teamer', [
} 'abilities', 'jobProfiles', 'timeFrames'
])
}, },
filters: { filters: {
period (timeFrame) { period (timeFrame) {
@@ -1,61 +0,0 @@
<template>
<div class="form-wrapper form--border" id="myep-main" v-show="!loading">
<h1>Newsletter</h1>
<div class="row">
<div class="col-xs-12">
<p v-html="statusMessage"></p>
<button type="submit" class="button" :disabled="loading" @click.prevent="toggleReqistration()">
{{ address.newsletter ? 'Abmelden' : 'Anmelden' }}
</button>
</div>
</div>
</div>
</template>
<script>
import EventBus from '../../_bus'
export default {
data () {
return {
address: {}
}
},
created () {
this.fetchAddress();
},
methods: {
fetchAddress () {
this.$store.dispatch('address/load')
.then((data) => {
this.address = data;
}).finally(() => {
EventBus.$emit('scrollTo', '#myep-main');
});
},
toggleReqistration () {
this.address.newsletter = !this.address.newsletter;
const data = {
id: this.address.id,
email: this.address.email,
registration: this.address.newsletter
};
this.$store.dispatch('newsletter/registration', data)
.finally(() => {
EventBus.$emit('scrollTo', '#myep-main');
});
}
},
computed: {
loading () {
return this.$store.state.loading;
},
statusMessage () {
let message = 'Du bist aktuell';
message += this.address.newsletter ? ' ' : ' <strong>nicht</strong> ';
message += 'zum Newsletter angemeldet.';
return message;
}
}
}
</script>
@@ -1,60 +0,0 @@
import EventBus from '../../_bus';
import axios from 'axios';
export default {
namespaced: true,
state: {},
actions: {
load ({ commit, rootState }) {
commit('loadingBegin', null, { root: true });
const client = axios.create({
headers: {
'X-Auth-Token': rootState.authToken
}
});
return client.get('/api/teamers/' + rootState.memberId)
.then((response) => {
commit('loadingFinish', null, { root: true });
return response.data;
}).catch((error) => {
commit('loadingFinish', null, { root: true });
commit('alert', {
message: 'Es ist ein Fehler aufgetreten :(',
class: 'alert-danger'
}, { root: true });
commit('logout', null, { root: true });
EventBus.$emit('forcedLogout');
throw error;
});
},
save ({ commit, rootState }, data) {
commit('loadingBegin', null, { root: true });
const client = axios.create({
headers: {
'X-Auth-Token': rootState.authToken
}
});
return client.put('/api/teamers/' + rootState.memberId, data)
.then(() => {
commit('loadingFinish', null, { root: true });
commit('alert', {
message: 'Die Änderungen wurden gespeichert',
class: 'alert-success'
}, { root: true });
}).catch((error) => {
commit('loadingFinish', null, { root: true });
commit('alert', {
message: 'Es ist ein Fehler aufgetreten :(',
class: 'alert-danger'
}, { root: true });
commit('logout', null, { root: true });
EventBus.$emit('forcedLogout');
throw error;
});
}
}
}
@@ -1,30 +1,28 @@
import Vue from 'vue'; import Vue from 'vue';
import VueRouter from 'vue-router'; import VueRouter from 'vue-router';
import store from './../_store'; import store from '../store';
Vue.use(VueRouter); Vue.use(VueRouter);
const guard = (to, from, next) => { const guard = (to, from, next) => {
if (store.state.loading) { if (store.state.loading) {
next(false); next(false);
} else if (store.state.loggedIn) { } else if (store.getters.isLoggedIn === false) {
if (to.meta.requiresTeamer && !store.getters.isTeamer) {
next(false);
} else {
next();
}
} else {
next({ name: 'login' }); next({ name: 'login' });
} else if (to.meta.requiresTeamer && store.getters.isTeamer === false) {
next(false);
} else {
next();
} }
}; };
import Address from './components/Address.vue' import Address from '../myep/Address'
import Events from './components/Events.vue' import Events from '../myep/Events'
import Login from './components/Login.vue' import Login from '../myep/Login'
import CrmData from './components/CrmData.vue' import CrmData from '../myep/CrmData'
import Teamer from './components/Teamer.vue' import Teamer from '../myep/Teamer'
import Newsletter from './components/Newsletter.vue' import Newsletter from '../myep/Newsletter'
import Registration from './components/Registration' import Registration from '../myep/Registration'
export default new VueRouter({ export default new VueRouter({
routes: [ routes: [
@@ -33,7 +31,7 @@ export default new VueRouter({
path: '/', path: '/',
component: Login, component: Login,
beforeEnter (from, to, next) { beforeEnter (from, to, next) {
if (!store.state.loggedIn) { if (store.getters.isLoggedIn === false) {
next(); next();
} else { } else {
next({ name: 'address' }); next({ name: 'address' });
@@ -45,7 +43,7 @@ export default new VueRouter({
path: '/register', path: '/register',
component: Registration, component: Registration,
beforeEnter (from, to, next) { beforeEnter (from, to, next) {
if (!store.state.loggedIn) { if (store.getters.isLoggedIn === false) {
next(); next();
} else { } else {
next({ name: 'address' }); next({ name: 'address' });
@@ -87,5 +85,8 @@ export default new VueRouter({
path: '*', path: '*',
redirect: { name: 'login' } redirect: { name: 'login' }
} }
] ],
scrollBehavior (to, from, savedPosition) {
return { selector: '#myep-main', offset: { x: 0, y: 160 } }
}
}); });
@@ -0,0 +1,208 @@
import Vue from 'vue'
import Vuex from 'vuex'
import axios from 'axios'
import AddressStore from './modules/address'
import CrmDataStore from './modules/crmdata'
import TeamerStore from './modules/teamer'
import EventsStore from './modules/events'
import NewsletterStore from './modules/newsletter'
Vue.use(Vuex);
const defaultUserData = {
isTeamer: false,
email: '',
firstName: '',
lastName: '',
gender: '',
dateOfBirth: null,
street: '',
zipCode: '',
city: '',
phoneMobile: '',
phonePrivate: '',
newsletter: false
};
export default new Vuex.Store({
modules: {
address: AddressStore,
crmdata: CrmDataStore,
teamer: TeamerStore,
events: EventsStore,
newsletter: NewsletterStore
},
state: {
config: {},
watchlist: [],
loading: false,
authToken: null,
userData: defaultUserData,
countries: [],
alert: {
message: '',
class: ''
}
},
mutations: {
initSession (state) {
const authToken = sessionStorage.getItem('token');
if (authToken) {
state.authToken = authToken;
}
},
initConfig (state) {
const configElement = document.getElementById('appconfig');
state.config = JSON.parse(configElement.innerHTML);
axios.defaults.baseURL = state.config.myEpApiBaseUrl;
},
initWatchlist (state) {
if (!sessionStorage.getItem('watchlist')) {
sessionStorage.setItem('watchlist', JSON.stringify([]));
}
state.watchlist = JSON.parse(sessionStorage.getItem('watchlist'));
},
setWatchlist (state, list) {
state.watchlist = list;
sessionStorage.setItem('watchlist', JSON.stringify(state.watchlist));
},
setUserData (state, data) {
state.userData = data;
},
login (state, token) {
state.authToken = token;
sessionStorage.setItem('token', token);
},
logout (state) {
state.authToken = null;
state.watchlist = [];
state.userData = defaultUserData;
sessionStorage.removeItem('token');
sessionStorage.removeItem('watchlist');
},
alert (state, payload) {
state.alert = payload;
},
loadingBegin (state) {
state.loading = true;
state.alert = { message: '', class: ''};
},
loadingFinish (state) {
state.loading = false;
},
setCountries (state, countries) {
state.countries = countries;
}
},
actions: {
init({ commit }) {
commit('initConfig');
commit('initWatchlist');
},
initSession({ commit, dispatch }) {
commit('initSession');
return dispatch('loadSelectableValues')
},
login({ commit, dispatch }, credentials) {
commit('loadingBegin');
return axios({
url: '/api/login_check',
method: 'post',
data: {
username: credentials.email,
password: credentials.password
}
}).then(response => {
commit('login', response.data.token);
}).catch(error => {
commit('logout');
commit('alert', {
message: 'Der Login ist fehlgeschlagen :(',
class: 'alert-danger'
});
throw error;
}).finally(() => {
commit('loadingFinish');
});
},
logout({ commit, state }) {
commit('loadingBegin');
const client = axios.create({
headers: {
'Authorization': 'Bearer ' + state.authToken,
}
});
return client({
url: '/api/logout'
}).then(() => {
commit('logout');
}).catch(error => {
commit('alert', {
message: 'Der Logout ist fehlgeschlagen :(',
class: 'alert-danger'
});
throw error;
}).finally(() => {
commit('loadingFinish');
});
},
resetPassword({ commit }, email) {
commit('loadingBegin');
return axios({
url: '/api/reset-password',
data: { email: email },
method: 'post'
}).then(response => {
return response;
}).catch(error => {
throw error;
}).finally(() => {
commit('loadingFinish');
});
},
register({ commit }, userData) {
commit('loadingBegin');
return axios({
url: '/api/register',
data: userData,
method: 'post'
}).then(response => {
return response;
}).catch(error => {
throw error;
}).finally(() => {
commit('loadingFinish');
});
},
loadSelectableValues ({ commit }) {
commit('loadingBegin');
return axios({
url: '/api/countries',
}).then(response => {
commit('setCountries', response.data);
}).finally(() => {
commit('loadingFinish');
});
},
watchlistToggle ({ commit, state }, uid) {
let list = state.watchlist;
let watchlistIndex = list.indexOf(uid);
if (watchlistIndex === -1) {
list.push(uid)
} else {
list.splice(watchlistIndex, 1)
}
commit('setWatchlist', list);
if (!!state.authToken) {
axios.put('/api/watchlist', list)
}
},
},
getters: {
watchlistCount: state => state.watchlist.length,
onWatchlist: (state) => (uid) => state.watchlist.indexOf(uid) !== -1,
isLoggedIn: state => !!state.authToken,
isTeamer: state => state.userData.isTeamer,
}
});
@@ -1,4 +1,3 @@
import EventBus from '../../_bus';
import axios from 'axios'; import axios from 'axios';
export default { export default {
@@ -10,23 +9,24 @@ export default {
const client = axios.create({ const client = axios.create({
headers: { headers: {
'X-Auth-Token': rootState.authToken 'Authorization': 'Bearer ' + rootState.authToken,
} }
}); });
return client.get('/api/addresses') return client.get('/api/address')
.then((response) => { .then(response => {
commit('loadingFinish', null, { root: true }); commit('setUserData', response.data, { root: true });
return response.data['hydra:member'][0]; if (response.data.watchlist) {
}).catch((error) => { commit('setWatchlist', response.data.watchlist, { root: true });
commit('loadingFinish', null, { root: true }); }
}).catch(() => {
commit('alert', { commit('alert', {
message: 'Es ist ein Fehler aufgetreten :(', message: 'Es ist ein Fehler aufgetreten :(',
class: 'alert-danger' class: 'alert-danger'
}, { root: true }); }, { root: true });
commit('logout', null, { root: true }); commit('logout', null, { root: true });
EventBus.$emit('forcedLogout'); }).finally(() => {
throw error; commit('loadingFinish', null, { root: true });
}); });
}, },
save ({ commit, rootState }, data) { save ({ commit, rootState }, data) {
@@ -34,25 +34,25 @@ export default {
const client = axios.create({ const client = axios.create({
headers: { headers: {
'X-Auth-Token': rootState.authToken 'Authorization': 'Bearer ' + rootState.authToken,
} }
}); });
return client.put('/api/addresses/' + data.id, data) return client.put('/api/address', data)
.then(() => { .then(() => {
commit('loadingFinish', null, { root: true });
commit('alert', { commit('alert', {
message: 'Die Änderungen wurden gespeichert', message: 'Die Änderungen wurden gespeichert',
class: 'alert-success' class: 'alert-success'
}, { root: true }); }, { root: true });
}) })
.catch((error) => { .catch(error => {
commit('loadingFinish', null, { root: true });
commit('alert', { commit('alert', {
message: 'Es ist ein Fehler aufgetreten :(', message: 'Es ist ein Fehler aufgetreten :(',
class: 'alert-danger' class: 'alert-danger'
}, { root: true }); }, { root: true });
throw error; throw error;
}).finally(() => {
commit('loadingFinish', null, { root: true });
}); });
} }
} }
@@ -1,4 +1,3 @@
import EventBus from '../../_bus';
import axios from 'axios'; import axios from 'axios';
export default { export default {
@@ -10,14 +9,14 @@ export default {
const client = axios.create({ const client = axios.create({
headers: { headers: {
'X-Auth-Token': rootState.authToken 'Authorization': 'Bearer ' + rootState.authToken
} }
}); });
return client.get('/api/crm-selections') return client.get('/api/crm-selections')
.then((response) => { .then((response) => {
commit('loadingFinish', null, { root: true }); commit('loadingFinish', null, { root: true });
return response.data['hydra:member'][0]; return response.data;
}).catch((error) => { }).catch((error) => {
commit('loadingFinish', null, { root: true }); commit('loadingFinish', null, { root: true });
commit('alert', { commit('alert', {
@@ -25,7 +24,6 @@ export default {
class: 'alert-danger' class: 'alert-danger'
}, { root: true }); }, { root: true });
commit('logout', null, { root: true }); commit('logout', null, { root: true });
EventBus.$emit('forcedLogout');
throw error; throw error;
}); });
}, },
@@ -34,7 +32,7 @@ export default {
const client = axios.create({ const client = axios.create({
headers: { headers: {
'X-Auth-Token': rootState.authToken 'Authorization': 'Bearer ' + rootState.authToken
} }
}); });
@@ -52,7 +50,6 @@ export default {
class: 'alert-danger' class: 'alert-danger'
}, { root: true }); }, { root: true });
commit('logout', null, { root: true }); commit('logout', null, { root: true });
EventBus.$emit('forcedLogout');
throw error; throw error;
}); });
} }
@@ -10,14 +10,14 @@ export default {
const client = axios.create({ const client = axios.create({
headers: { headers: {
'X-Auth-Token': rootState.authToken 'Authorization': 'Bearer ' + rootState.authToken
} }
}); });
return client.get('/api/events') return client.get('/api/events')
.then((response) => { .then((response) => {
commit('loadingFinish', null, { root: true }); commit('loadingFinish', null, { root: true });
return response.data['hydra:member']; return response.data;
}).catch((error) => { }).catch((error) => {
commit('loadingFinish', null, { root: true }); commit('loadingFinish', null, { root: true });
commit('alert', { commit('alert', {
@@ -10,20 +10,18 @@ export default {
const client = axios.create({ const client = axios.create({
headers: { headers: {
'X-Auth-Token': rootState.authToken 'Authorization': 'Bearer ' + rootState.authToken
} }
}); });
return client.put('/api/newsletters/' + data.id, data) return client.put('/api/newsletter', data)
.then(() => { .then(() => {
commit('loadingFinish', null, { root: true });
commit('alert', { commit('alert', {
message: 'Die Änderungen wurden gespeichert', message: 'Die Änderungen wurden gespeichert',
class: 'alert-success' class: 'alert-success'
}, { root: true }); }, { root: true });
}) })
.catch((error) => { .catch((error) => {
commit('loadingFinish', null, { root: true });
commit('alert', { commit('alert', {
message: 'Es ist ein Fehler aufgetreten :(', message: 'Es ist ein Fehler aufgetreten :(',
class: 'alert-danger' class: 'alert-danger'
@@ -31,6 +29,8 @@ export default {
commit('logout', null, { root: true }); commit('logout', null, { root: true });
EventBus.$emit('forcedLogout'); EventBus.$emit('forcedLogout');
throw error; throw error;
}).finally(() => {
commit('loadingFinish', null, { root: true });
}); });
} }
} }
@@ -0,0 +1,75 @@
import EventBus from '../../_bus';
import axios from 'axios';
export default {
namespaced: true,
state: {
abilities: [],
timeFrames: [],
jobProfiles: []
},
mutations: {
setAbilities (state, abilities) {
state.abilities = abilities;
},
setTimeFrames (state, timeFrames) {
state.timeFrames = timeFrames;
},
setJobProfiles (state, jobProfiles) {
state.jobProfiles = jobProfiles;
}
},
actions: {
save ({ commit, rootState }, data) {
commit('loadingBegin', null, { root: true });
const client = axios.create({
headers: {
'Authorization': 'Bearer ' + rootState.authToken
}
});
return client.put('/api/teamer/', data)
.then(() => {
commit('alert', {
message: 'Die Änderungen wurden gespeichert',
class: 'alert-success'
}, { root: true });
}).catch(error => {
commit('alert', {
message: 'Es ist ein Fehler aufgetreten :(',
class: 'alert-danger'
}, { root: true });
commit('logout', null, { root: true });
EventBus.$emit('forcedLogout');
throw error;
}).finally(() => {
commit('loadingFinish', null, { root: true });
});
},
loadSelectableValues ({ commit, rootState }) {
commit('loadingBegin', null, { root: true });
const client = axios.create({
headers: {
'Authorization': 'Bearer ' + rootState.authToken
}
});
return client.get('/api/teamer-data')
.then(response => {
commit('setAbilities', response.data.abilities);
commit('setTimeFrames', response.data.timeFrames);
commit('setJobProfiles', response.data.jobProfiles);
}).catch(error => {
}).finally(() => {
commit('loadingFinish', null, { root: true });
});
}
},
getters: {
abilities: state => state.abilities,
jobProfiles: state => state.jobProfiles,
timeFrames: state => state.timeFrames
}
}