From 119e05e6334ef57c89cffe3987d12f7f41ecb8fc Mon Sep 17 00:00:00 2001 From: Eliot Berriot <contact@eliotberriot.com> Date: Sat, 24 Feb 2018 14:34:28 +0100 Subject: [PATCH] Signup form --- front/src/components/auth/Login.vue | 3 + front/src/components/auth/Signup.vue | 137 +++++++++++++++++++++++++++ front/src/router/index.js | 6 ++ front/src/store/instance.js | 10 +- 4 files changed, 155 insertions(+), 1 deletion(-) create mode 100644 front/src/components/auth/Signup.vue diff --git a/front/src/components/auth/Login.vue b/front/src/components/auth/Login.vue index f84ad9295b..2cf6d5f6db 100644 --- a/front/src/components/auth/Login.vue +++ b/front/src/components/auth/Login.vue @@ -32,6 +32,9 @@ > </div> <button :class="['ui', {'loading': isLoading}, 'button']" type="submit">Login</button> + <router-link class="ui right floated basic button" :to="{path: '/signup'}"> + Create an account + </router-link> </form> </div> </div> diff --git a/front/src/components/auth/Signup.vue b/front/src/components/auth/Signup.vue new file mode 100644 index 0000000000..13b723d201 --- /dev/null +++ b/front/src/components/auth/Signup.vue @@ -0,0 +1,137 @@ +<template> + <div class="main pusher"> + <div class="ui vertical stripe segment"> + <div class="ui small text container"> + <h2>Create a funkwhale account</h2> + <form + v-if="$store.state.instance.settings.users.registration_enabled.value" + :class="['ui', {'loading': isLoadingInstanceSetting}, 'form']" + @submit.prevent="submit()"> + <div v-if="errors.length > 0" class="ui negative message"> + <div class="header">We cannot create your account</div> + <ul class="list"> + <li v-for="error in errors">{{ error }}</li> + </ul> + </div> + <div class="field"> + <label>Username</label> + <input + ref="username" + required + type="text" + autofocus + placeholder="Enter your username" + v-model="username"> + </div> + <div class="field"> + <label>Email</label> + <input + ref="email" + required + type="email" + placeholder="Enter your email" + v-model="email"> + </div> + <div class="field"> + <label>Password</label> + <div class="ui action input"> + <input + required + :type="passwordInputType" + placeholder="Enter your password" + v-model="password"> + <span @click="showPassword = !showPassword" title="Show/hide password" class="ui icon button"> + <i class="eye icon"></i> + </span> + </div> + </div> + <button :class="['ui', 'green', {'loading': isLoading}, 'button']" type="submit">Create my account</button> + </form> + <p v-else>Registration is currently disabled on this instance, please try again later.</p> + </div> + </div> + </div> +</template> + +<script> +import axios from 'axios' +import logger from '@/logging' + +export default { + name: 'login', + props: { + next: {type: String, default: '/'} + }, + data () { + return { + username: '', + email: '', + password: '', + isLoadingInstanceSetting: true, + errors: [], + isLoading: false, + showPassword: false + } + }, + created () { + let self = this + this.$store.dispatch('instance/fetchSettings', { + callback: function () { + self.isLoadingInstanceSetting = false + } + }) + }, + methods: { + submit () { + var self = this + self.isLoading = true + this.errors = [] + var payload = { + username: this.username, + password1: this.password, + password2: this.password, + email: this.email + } + return axios.post('auth/registration/', payload).then(response => { + logger.default.info('Successfully created account') + self.$router.push({ + name: 'profile', + params: { + username: this.username + }}) + }, error => { + self.errors = this.getErrors(error.response) + self.isLoading = false + }) + }, + getErrors (response) { + let errors = [] + if (response.status !== 400) { + errors.push('An unknown error occured, ensure your are connected to the internet and your funkwhale instance is up and running') + return errors + } + for (var field in response.data) { + if (response.data.hasOwnProperty(field)) { + response.data[field].forEach(e => { + errors.push(e) + }) + } + } + return errors + } + }, + computed: { + passwordInputType () { + if (this.showPassword) { + return 'text' + } + return 'password' + } + } + +} +</script> + +<!-- Add "scoped" attribute to limit CSS to this component only --> +<style scoped> +</style> diff --git a/front/src/router/index.js b/front/src/router/index.js index ea8854bbe4..c1d03e0594 100644 --- a/front/src/router/index.js +++ b/front/src/router/index.js @@ -3,6 +3,7 @@ import Router from 'vue-router' import PageNotFound from '@/components/PageNotFound' import Home from '@/components/Home' import Login from '@/components/auth/Login' +import Signup from '@/components/auth/Signup' import Profile from '@/components/auth/Profile' import Settings from '@/components/auth/Settings' import Logout from '@/components/auth/Logout' @@ -38,6 +39,11 @@ export default new Router({ component: Login, props: (route) => ({ next: route.query.next || '/library' }) }, + { + path: '/signup', + name: 'signup', + component: Signup + }, { path: '/logout', name: 'logout', diff --git a/front/src/store/instance.js b/front/src/store/instance.js index a0071f0961..dd20a8b1d7 100644 --- a/front/src/store/instance.js +++ b/front/src/store/instance.js @@ -6,6 +6,11 @@ export default { namespaced: true, state: { settings: { + users: { + registration_enabled: { + value: true + } + }, raven: { front_enabled: { value: false @@ -23,7 +28,7 @@ export default { }, actions: { // Send a request to the login URL and save the returned JWT - fetchSettings ({commit}) { + fetchSettings ({commit}, {callback}) { return axios.get('instance/settings/').then(response => { logger.default.info('Successfully fetched instance settings') let sections = {} @@ -34,6 +39,9 @@ export default { sections[e.section][e.name] = e }) commit('settings', sections) + if (callback) { + callback() + } }, response => { logger.default.error('Error while fetching settings', response.data) }) -- GitLab