summaryrefslogtreecommitdiffstats
path: root/webapp/src/components/AccountModule.vue
diff options
context:
space:
mode:
authorJannik Schönartz2019-02-24 03:16:04 +0100
committerJannik Schönartz2019-02-24 03:16:04 +0100
commitceb166a81c74ca41b7d9099fb5a067c5cfc1827d (patch)
tree8283f2110a0d74ea37c5856ae3fc683cf52b9fdf /webapp/src/components/AccountModule.vue
parent[webapp/groups] rework old tables to new data table (diff)
downloadbas-ceb166a81c74ca41b7d9099fb5a067c5cfc1827d.tar.gz
bas-ceb166a81c74ca41b7d9099fb5a067c5cfc1827d.tar.xz
bas-ceb166a81c74ca41b7d9099fb5a067c5cfc1827d.zip
[account] Add editable user info, change statuscodes, delete account
[server] Add method for updating user info Add method for deleteing user Switch from statuscode 500 to 401 Fixed stauts null exception Validate Email now allows empty email [webapp/AccountPage] Add button to delete the user account (including a dialog) Some order fixes with the info fields User info is now editable
Diffstat (limited to 'webapp/src/components/AccountModule.vue')
-rw-r--r--webapp/src/components/AccountModule.vue148
1 files changed, 128 insertions, 20 deletions
diff --git a/webapp/src/components/AccountModule.vue b/webapp/src/components/AccountModule.vue
index 6844afa..0b3839b 100644
--- a/webapp/src/components/AccountModule.vue
+++ b/webapp/src/components/AccountModule.vue
@@ -2,8 +2,12 @@
{
"en": {
"accountInfo": "Info",
- "name": "Name",
+ "deleteAccount": "Delete Account",
+ "deleteAccountMsg": "Are you sure you want to permnanently delete your account?",
+ "deleteAccountMsg2": "This action cannot be undone",
"email": "E-Mail",
+ "emailError": "E-mail must be valid.",
+ "name": "Name",
"password": "Password",
"passwordConfirm": "Retype password",
"passwordChanged": "Password successfully changed.",
@@ -21,12 +25,17 @@
"passwordRequirement5": "0+ [!\"§$%&/()=?+#*.:,;]",
"passwordRequirements": "Password requirements",
"security": "Security",
- "username": "Username"
+ "username": "Username",
+ "userInfoChanged": "User informations successfully changed."
},
"de": {
"accountInfo": "Info",
- "name": "Name",
+ "deleteAccount": "Account Löschen",
+ "deleteAccountMsg": "Sind sie sicher, dass sie ihren Account entgültig Löschen wollen?",
+ "deleteAccountMsg2": "Diese Aktion kann nicht rückgängig gemacht werden.",
"email": "E-Mail",
+ "emailError": "Keine gültige E-Mail.",
+ "name": "Name",
"password": "Passwort",
"passwordChanged": "Passwort wurde erfolgreich geändert.",
"passwordConfirm": "Passwort wiederholen",
@@ -44,7 +53,8 @@
"passwordRequirement5": "0+ [!\"§$%&/()=?+#*'-_.:,;]",
"passwordRequirements": "Passwort anforderungen",
"security": "Sicherheit",
- "username": "Benutzername"
+ "username": "Benutzername",
+ "userInfoChanged": "Benutzer Informationen wurden erfolgreich geändert"
}
}
</i18n>
@@ -70,7 +80,8 @@
<v-card>
<v-card-text>
<v-layout wrap>
- <v-flex lg4 md6 sm6 xs12 order-lg1 order-xs1>
+
+ <v-flex lg3 md6 sm6 xs12 order-lg2 order-xs2>
<v-layout column>
<div class="info-input">
<div class="body-2 info-heading"><v-icon>account_circle</v-icon><span>{{ $t('username') }}</span></div>
@@ -78,22 +89,43 @@
</div>
</v-layout>
</v-flex>
- <v-flex lg4 md6 sm6 xs12 order-lg2 order-xs2>
+
+ <v-flex lg3 md6 sm6 xs12 order-lg4 order-xs4>
<v-layout column>
<div class="info-input">
<div class="body-2 info-heading"><v-icon>label</v-icon><span>{{ $t('name') }}</span></div>
- <div class="info-text">{{ user.name }}</div>
+ <div v-if="!editInfoMode" class="info-text">{{ user.name }}</div>
+ <v-text-field v-else v-model="infoName"></v-text-field>
</div>
</v-layout>
</v-flex>
- <v-flex lg4 md6 sm6 xs12 order-lg2 order-xs3>
+
+ <v-flex lg3 md6 sm6 xs12 order-lg6 order-xs6>
<v-layout column>
<div class="info-input">
<div class="body-2 info-heading"><v-icon>email</v-icon><span>{{ $t('email') }}</span></div>
- <div class="info-text">{{ user.email }}</div>
+ <div v-if="!editInfoMode" class="info-text">{{ user.email }}</div>
+ <v-text-field v-else v-model="infoEmail" :rules="emailRules" ref="emailField" validate-on-blur></v-text-field>
</div>
</v-layout>
</v-flex>
+
+ <v-flex lg3 md6 sm6 xs12 order-lg7 order-md3 order-sm3 order-xs1 class="text-xs-right">
+ <div class="info-input">
+ <div v-if="!editInfoMode">
+ <v-btn color="primary" flat @click="editInfo" class="info-buttons">
+ <v-icon left>create</v-icon>{{ $t('edit') }}
+ </v-btn>
+ </div>
+ <div v-else>
+ <v-btn color="primary" flat @click="cancelEditInfo" class="info-buttons">{{ $t('cancel') }}</v-btn>
+ <v-btn color="primary" @click="submitInfo" class="info-buttons">
+ <v-icon left>save</v-icon>{{ $t('save') }}
+ </v-btn>
+ </div>
+ </div>
+ </v-flex>
+
</v-layout>
</v-card-text>
</v-card>
@@ -109,7 +141,7 @@
<div class="body-2 info-heading"><v-icon>lock</v-icon><span>{{ $t('password') }}</span></div>
<div v-if="!editPasswordMode" class="info-text">********</div>
<div v-else>
- <v-form class="password-form" ref="passwordForm" v-model="valid" lazy-validation>
+ <v-form ref="passwordForm" v-model="valid" lazy-validation>
<v-text-field
type="password"
v-model="passwordCurrent"
@@ -137,9 +169,9 @@
</v-layout>
</v-flex>
- <v-flex lg4 md6 sm6 xs12 order-lg1 order-xs2>
+ <v-flex lg4 md6 sm6 xs12 order-lg1 order-xs3 v-if="editPasswordMode">
<v-layout column>
- <div class="info-input" v-if="editPasswordMode">
+ <div class="info-input">
<div class="body-2 info-heading"><v-icon>ballot</v-icon><span>{{ $t('passwordRequirements') }}</span></div>
<div class="info-text">{{ $t('passwordRequirement1') }}</div>
<div class="info-text">{{ $t('passwordRequirement2') }}</div>
@@ -150,17 +182,20 @@
</v-layout>
</v-flex>
- <v-flex lg4 xs12 order-lg3 order-xs1 class="text-xs-right">
+ <v-flex v-if="!editPasswordMode" lg8 sm6 xs12 order-lg3 order-sm2 order-xs1 class="text-xs-right">
<div class="info-input">
- <v-btn v-if="!editPasswordMode" color="primary" flat @click="editPassword" class="info-buttons">
+ <v-btn color="primary" flat @click="editPassword" class="info-buttons">
<v-icon left>create</v-icon>{{ $t('edit') }}
</v-btn>
- <div v-else>
+ </div>
+ </v-flex>
+
+ <v-flex v-else lg4 sm12 xs12 order-lg3 order-sm1 order-xs1 class="text-xs-right">
+ <div class="info-input">
<v-btn color="primary" flat @click="cancelEditPassword" class="info-buttons">{{ $t('cancel') }}</v-btn>
<v-btn color="primary" @click="submitPassword" class="info-buttons">
<v-icon left>save</v-icon>{{ $t('save') }}
</v-btn>
- </div>
</div>
</v-flex>
@@ -175,12 +210,42 @@
</div>
</v-card>
+ <v-subheader>{{ $t('delete') }}</v-subheader>
+ <v-card>
+ <div style="display: flex; justify-content: center;">
+ <v-btn color="error" class="button" @click="dialog = true"><v-icon left>delete</v-icon>{{ $t('deleteAccount') }}</v-btn>
+ </div>
+ </v-card>
+
</v-tab-item>
</v-tabs-items>
</v-flex>
</v-layout>
- </v-container>
+ <v-dialog
+ :value="dialog"
+ scrollable
+ max-width="500px"
+ :fullscreen="$vuetify.breakpoint.xsOnly"
+ >
+ <v-card>
+ <v-card-title primary-title class="elevation-3">
+ <div class="headline">{{ $t('deleteAccount') }}</div>
+ </v-card-title>
+ <v-card-text>
+ <div>{{ $t('deleteAccountMsg') }}</div>
+ <span class="grey--text">{{ $t('deleteAccountMsg2') }}</span>
+ </v-card-text>
+ <v-divider></v-divider>
+ <v-card-actions>
+ <v-spacer></v-spacer>
+ <v-btn flat="flat" @click="dialog = false">{{ $t('cancel') }}</v-btn>
+ <v-btn color="error" @click="deleteAccount">{{ $t('delete') }}</v-btn>
+ </v-card-actions>
+ </v-card>
+ </v-dialog>
+
+ </v-container>
</template>
<script>
@@ -190,8 +255,12 @@ export default {
data () {
return {
tab: 0,
+ dialog: false,
valid: true,
user: '',
+ editInfoMode: false,
+ infoName: '',
+ infoEmail: '',
passwordConfirm: '',
passwordCurrent: '',
passwordNew: '',
@@ -201,6 +270,9 @@ export default {
v => !!v || this.$t('passwordEmptyError'),
v => !this.invalidPasswordError || this.$t('passwordInvalidError')
],
+ emailRules: [
+ v => this.$validateEmail(v) || this.$t('emailError')
+ ],
passwordRules: [
v => !!v || this.$t('passwordEmptyError'),
v => v.length >= 8 || this.$t('passwordLengthError'),
@@ -216,9 +288,28 @@ export default {
...mapGetters(['tabsDark', 'tabsColor', 'tabsSliderColor'])
},
methods: {
+ deleteAccount () {
+ this.dialog = false
+ this.$http.delete('/api/users/current').then(response => {
+ this.$http.post('/api/authentication/logout').then(response => {
+ this.$router.push('/login')
+ this.$socket.close()
+ })
+ })
+ },
clearCurrentPasswordErrors () {
this.invalidPasswordError = false
},
+ submitInfo () {
+ if (!this.$refs.emailField.validate()) return
+
+ // Axios request to submit info (username, name, email)
+ this.$http.post('/api/users/current', { name: this.infoName, email: this.infoEmail }).then(response => {
+ this.editInfoMode = false
+ this.getUserData()
+ this.$snackbar({ color: 'success', text: this.$t('userInfoChanged') })
+ })
+ },
submitPassword () {
if (this.$refs.passwordForm.validate()) {
this.$http.post('/api/users/' + this.user.id + '/password', { passwordCurrent: this.passwordCurrent, passwordNew: this.passwordNew }).then(response => {
@@ -234,30 +325,47 @@ export default {
})
}
},
+ editInfo () {
+ this.infoName = this.user.name
+ this.infoEmail = this.user.email
+ this.editInfoMode = true
+ },
editPassword () {
this.editPasswordMode = true
},
+ cancelEditInfo () {
+ this.editInfoMode = false
+ },
cancelEditPassword () {
this.editPasswordMode = false
this.passwordCurrent = ''
this.passwordNew = ''
this.passwordConfirm = ''
},
+ getUserData () {
+ this.$http('/api/users/current').then(response => {
+ this.user = response.data
+ })
+ },
newAlert () {
this.$alert({ type: 'success', text: 'aaaaaaaaaaaaaaaaaaaaaaaaaas das dsad asdpioipoidijoijoawiojdiojijowaijo d o wiadijo oiawio jdi aaaaaaaaaaaaaaaaaaaaaa uo iashdoiuas dhuas hduioash diuash diuash diuash diuh test ' + this.testId })
this.testId++
}
},
created () {
- this.$http('/api/users/current').then(response => {
- this.user = response.data
- })
+ this.getUserData()
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
+.button {
+ margin-top: 20px;
+ margin-bottom: 20px;
+ width: 95%;
+}
+
.info-buttons {
margin: 0;
}