168 lines
5.4 KiB
Vue
168 lines
5.4 KiB
Vue
<template>
|
|
<div class="flex min-h-full w-full items-center justify-center p-20">
|
|
<div class="card justify-items-center">
|
|
<img :alt="t('alt')" src="/images/hutopymedia/loginpage/hutopylogin.svg" />
|
|
<div class="flex flex-col gap-10">
|
|
<h1 class="login-text text-center text-2xl font-bold ">
|
|
{{ t('title') }}
|
|
</h1>
|
|
|
|
<v-form @submit.prevent="handleRegister">
|
|
<div class="flex flex-col gap-4">
|
|
<v-text-field v-model="name" :label="t('name')" required></v-text-field>
|
|
|
|
<v-text-field v-model="email" :label="t('email')" type="email" required></v-text-field>
|
|
|
|
<v-text-field v-model="password" :label="t('password')" :type="showPassword ? 'text' : 'password'" required
|
|
:hint="t('passwordRequirements')">
|
|
<template v-slot:append-inner>
|
|
<v-icon @click="showPassword = !showPassword" class="visibility-toggle" size="small"
|
|
:icon="showPassword ? mdiEyeOff : mdiEye" />
|
|
</template>
|
|
</v-text-field>
|
|
|
|
<v-text-field v-model="confirmPassword" :label="t('confirmPassword')"
|
|
:type="showConfirmPassword ? 'text' : 'password'" required>
|
|
<template v-slot:append-inner>
|
|
<v-icon @click="showConfirmPassword = !showConfirmPassword" class="visibility-toggle" size="small"
|
|
:icon="showConfirmPassword ? mdiEyeOff : mdiEye" />
|
|
</template>
|
|
</v-text-field>
|
|
|
|
<v-btn type="submit" color="primary" block :loading="isLoading">
|
|
{{ t('register') }}
|
|
</v-btn>
|
|
|
|
<div class="mt-4 text-center">
|
|
{{ t('alreadyHaveAccount') }}
|
|
<router-link to="/login" class="text-blue-500">
|
|
{{ t('signIn') }}
|
|
</router-link>
|
|
</div>
|
|
</div>
|
|
</v-form>
|
|
</div>
|
|
</div>
|
|
|
|
<v-snackbar v-model="errorSnackBar" color="error">
|
|
{{ errorMessage }}
|
|
</v-snackbar>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { ref } from 'vue';
|
|
import { useClient } from '@/plugins/api.js';
|
|
import { useAuthStore } from '@/stores/authStore.js';
|
|
import { useI18n } from 'vue-i18n';
|
|
import { useRouter } from 'vue-router';
|
|
import { mdiEye, mdiEyeOff } from '@mdi/js';
|
|
|
|
const { t } = useI18n();
|
|
const router = useRouter();
|
|
const authStore = useAuthStore();
|
|
const clientApi = useClient();
|
|
|
|
const name = ref('');
|
|
const email = ref('');
|
|
const password = ref('');
|
|
const confirmPassword = ref('');
|
|
const isLoading = ref(false);
|
|
const errorSnackBar = ref(false);
|
|
const errorMessage = ref('');
|
|
const showPassword = ref(false);
|
|
const showConfirmPassword = ref(false);
|
|
|
|
async function handleRegister() {
|
|
if (password.value !== confirmPassword.value) {
|
|
errorMessage.value = t('passwordsDoNotMatch');
|
|
errorSnackBar.value = true;
|
|
return;
|
|
}
|
|
|
|
isLoading.value = true;
|
|
|
|
try {
|
|
// Register the user
|
|
const response = await clientApi.post('api/users/register', {
|
|
name: name.value,
|
|
email: email.value.trim(),
|
|
password: password.value
|
|
});
|
|
|
|
// If registration is successful, log them in
|
|
await authStore.login(email.value, password.value);
|
|
|
|
// Redirect to home or welcome page
|
|
await router.push('/landing');
|
|
} catch (error) {
|
|
console.error('Registration failed:', error);
|
|
errorMessage.value = error.response?.data?.message || t('registrationFailed');
|
|
errorSnackBar.value = true;
|
|
} finally {
|
|
isLoading.value = false;
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style scoped>
|
|
.visibility-toggle {
|
|
@apply cursor-pointer;
|
|
@apply transition-opacity duration-300;
|
|
@apply opacity-60 hover:opacity-100;
|
|
@apply z-10;
|
|
}
|
|
|
|
/* Override Vuetify's default padding to accommodate our icon */
|
|
:deep(.v-field__append-inner) {
|
|
padding-inline-start: 0;
|
|
}
|
|
</style>
|
|
|
|
<i18n>
|
|
{
|
|
"en": {
|
|
"title": "Create your account",
|
|
"alt": "Hutopy Registration",
|
|
"name": "Full Name",
|
|
"email": "Email",
|
|
"password": "Password",
|
|
"confirmPassword": "Confirm Password",
|
|
"passwordRequirements": "Password must be at least 8 characters",
|
|
"register": "Register",
|
|
"alreadyHaveAccount": "Already have an account?",
|
|
"signIn": "Sign in",
|
|
"passwordsDoNotMatch": "Passwords do not match",
|
|
"registrationFailed": "Registration failed. Please try again."
|
|
},
|
|
"fr": {
|
|
"title": "Créer votre compte",
|
|
"alt": "Inscription Hutopy",
|
|
"name": "Nom complet",
|
|
"email": "Email",
|
|
"password": "Mot de passe",
|
|
"confirmPassword": "Confirmer le mot de passe",
|
|
"passwordRequirements": "Le mot de passe doit comporter au moins 8 caractères",
|
|
"register": "S'inscrire",
|
|
"alreadyHaveAccount": "Vous avez déjà un compte?",
|
|
"signIn": "Se connecter",
|
|
"passwordsDoNotMatch": "Les mots de passe ne correspondent pas",
|
|
"registrationFailed": "L'inscription a échoué. Veuillez réessayer."
|
|
},
|
|
"es": {
|
|
"title": "Crea tu cuenta",
|
|
"alt": "Registro de Hutopy",
|
|
"name": "Nombre completo",
|
|
"email": "Correo electrónico",
|
|
"password": "Contraseña",
|
|
"confirmPassword": "Confirmar contraseña",
|
|
"passwordRequirements": "La contraseña debe tener al menos 8 caracteres",
|
|
"register": "Registrarse",
|
|
"alreadyHaveAccount": "¿Ya tienes una cuenta?",
|
|
"signIn": "Iniciar sesión",
|
|
"passwordsDoNotMatch": "Las contraseñas no coinciden",
|
|
"registrationFailed": "El registro falló. Por favor, inténtelo de nuevo."
|
|
}
|
|
}
|
|
</i18n>
|