174 lines
6.6 KiB
Vue
174 lines
6.6 KiB
Vue
<template>
|
|
<DialogWidget ref="dialog" title="register.title" :show-close="true" :buttons="buttons" :modal="true"
|
|
@close="closeDialog" @register="register" width="35em" height="33em" name="RegisterDialog"
|
|
:isTitleTranslated="true">
|
|
<div class="form-content form-stack">
|
|
<div class="form-field">
|
|
<label for="register-email">{{ $t("register.email") }}</label>
|
|
<input id="register-email" type="email" v-model="email" :class="{ 'field-error': emailTouched && !isEmailValid }" />
|
|
<span v-if="emailTouched && !isEmailValid" class="form-error">Bitte eine gültige E-Mail-Adresse eingeben.</span>
|
|
</div>
|
|
<div class="form-field">
|
|
<label for="register-username">{{ $t("register.username") }}</label>
|
|
<input id="register-username" type="text" v-model="username" :class="{ 'field-error': usernameTouched && !isUsernameValid }" />
|
|
<span v-if="usernameTouched && !isUsernameValid" class="form-error">Der Benutzername sollte mindestens 3 Zeichen haben.</span>
|
|
</div>
|
|
<div class="form-field">
|
|
<label for="register-password">{{ $t("register.password") }}</label>
|
|
<input id="register-password" type="password" v-model="password" :class="{ 'field-error': passwordTouched && !isPasswordValid }" />
|
|
<span class="form-hint">Mindestens 8 Zeichen.</span>
|
|
<span v-if="passwordTouched && !isPasswordValid" class="form-error">Das Passwort ist noch zu kurz.</span>
|
|
</div>
|
|
<div class="form-field">
|
|
<label for="register-repeat-password">{{ $t("register.repeatPassword") }}</label>
|
|
<input id="register-repeat-password" type="password" v-model="repeatPassword" :class="{ 'field-error': repeatPasswordTouched && !doPasswordsMatch }" />
|
|
<span v-if="repeatPasswordTouched && !doPasswordsMatch" class="form-error">Die Passwörter stimmen nicht überein.</span>
|
|
</div>
|
|
<SelectDropdownWidget labelTr="settings.personal.label.language" :v-model="language"
|
|
tooltipTr="settings.personal.tooltip.language" :list="languages" :value="language" />
|
|
</div>
|
|
</DialogWidget>
|
|
</template>
|
|
|
|
<script>
|
|
import { mapActions } from 'vuex';
|
|
import apiClient from '@/utils/axios.js';
|
|
import DialogWidget from '@/components/DialogWidget.vue';
|
|
import SelectDropdownWidget from '@/components/form/SelectDropdownWidget.vue';
|
|
import { showApiError, showError } from '@/utils/feedback.js';
|
|
|
|
export default {
|
|
name: 'RegisterDialog',
|
|
components: {
|
|
DialogWidget,
|
|
SelectDropdownWidget,
|
|
},
|
|
data() {
|
|
return {
|
|
email: '',
|
|
username: '',
|
|
password: '',
|
|
repeatPassword: '',
|
|
language: null,
|
|
languages: [],
|
|
emailTouched: false,
|
|
usernameTouched: false,
|
|
passwordTouched: false,
|
|
repeatPasswordTouched: false,
|
|
buttons: [
|
|
{ text: 'register.close', action: 'close' },
|
|
{ text: 'register.register', action: 'register', disabled: !this.canRegister }
|
|
]
|
|
};
|
|
},
|
|
computed: {
|
|
isEmailValid() {
|
|
return /\S+@\S+\.\S+/.test(this.email);
|
|
},
|
|
isUsernameValid() {
|
|
return this.username.trim().length >= 3;
|
|
},
|
|
isPasswordValid() {
|
|
return this.password.length >= 8;
|
|
},
|
|
doPasswordsMatch() {
|
|
return Boolean(this.password) && this.password === this.repeatPassword;
|
|
},
|
|
canRegister() {
|
|
return this.isEmailValid && this.isUsernameValid && this.isPasswordValid && this.doPasswordsMatch && this.language;
|
|
}
|
|
},
|
|
watch: {
|
|
email() {
|
|
this.emailTouched = true;
|
|
},
|
|
username() {
|
|
this.usernameTouched = true;
|
|
},
|
|
password() {
|
|
this.passwordTouched = true;
|
|
},
|
|
repeatPassword() {
|
|
this.repeatPasswordTouched = true;
|
|
},
|
|
canRegister(newValue) {
|
|
this.buttons[1].disabled = !newValue;
|
|
}
|
|
},
|
|
async created() {
|
|
await this.getLanguages();
|
|
await this.getBrowserLanguage();
|
|
},
|
|
methods: {
|
|
...mapActions(['login']),
|
|
async getBrowserLanguage() {
|
|
const browserLanguage = navigator.language || navigator.languages[0];
|
|
let short = '';
|
|
if (browserLanguage.startsWith('de')) {
|
|
short = 'de';
|
|
} else {
|
|
short = 'en';
|
|
}
|
|
const response = await apiClient.post('/api/settings/getparamvalueid', { paramValue: short });
|
|
this.language = response.data.paramValueId;
|
|
},
|
|
open() {
|
|
this.$refs.dialog.open();
|
|
},
|
|
closeDialog() {
|
|
this.$refs.dialog.close();
|
|
},
|
|
async register() {
|
|
if (!this.canRegister) {
|
|
showError(this, 'tr:register.passwordMismatch');
|
|
return;
|
|
}
|
|
|
|
try {
|
|
const response = await apiClient.post('/api/auth/register', {
|
|
email: this.email,
|
|
username: this.username,
|
|
password: this.password,
|
|
language: this.language
|
|
});
|
|
|
|
if (response.status === 201) {
|
|
this.login(response.data);
|
|
this.$refs.dialog.close();
|
|
this.$router.push('/activate');
|
|
} else {
|
|
showError(this, 'tr:register.failure');
|
|
}
|
|
} catch (error) {
|
|
if (error.response && error.response.status === 409) {
|
|
showError(this, `tr:register.${error.response.data.error}`);
|
|
} else {
|
|
console.error('Error registering user:', error);
|
|
showApiError(this, error, 'tr:register.failure');
|
|
}
|
|
}
|
|
},
|
|
async getLanguages() {
|
|
try {
|
|
const response = await apiClient.post('/api/settings/getparamvalues', {
|
|
type: 'language'
|
|
});
|
|
this.languages = response.data.map(item => { return { value: item.id, captionTr: `settings.personal.language.${item.name}` } });
|
|
} catch (err) {
|
|
console.error('Error loading languages:', err);
|
|
}
|
|
}
|
|
}
|
|
};
|
|
</script>
|
|
|
|
<style scoped>
|
|
input[type="email"],
|
|
input[type="text"],
|
|
input[type="password"],
|
|
select {
|
|
width: 100%;
|
|
box-sizing: border-box;
|
|
}
|
|
</style>
|