Files
yourpart3/frontend/src/dialogues/auth/RegisterDialog.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>