diff --git a/webapp/graphql/User.js b/webapp/graphql/User.js index 27b3785ae..dbc1997af 100644 --- a/webapp/graphql/User.js +++ b/webapp/graphql/User.js @@ -134,3 +134,11 @@ export const unfollowUserMutation = i18n => { } ` } + +export const checkSlugAvailableQuery = gql` + query($slug: String!) { + User(slug: $slug) { + slug + } + } +` diff --git a/webapp/locales/de.json b/webapp/locales/de.json index 5b83821f5..496d3f21b 100644 --- a/webapp/locales/de.json +++ b/webapp/locales/de.json @@ -151,11 +151,17 @@ "data": { "name": "Deine Daten", "labelName": "Dein Name", + "labelSlug": "Dein eindeutiger Benutzername", "namePlaceholder": "Petra Lustig", "labelCity": "Deine Stadt oder Region", "labelBio": "Über dich", "success": "Deine Daten wurden erfolgreich aktualisiert!" }, + "validation": { + "slug": { + "alreadyTaken": "Dieser Benutzername ist schon vergeben." + } + }, "security": { "name": "Sicherheit", "change-password": { diff --git a/webapp/locales/en.json b/webapp/locales/en.json index 39220d318..660a2b1ee 100644 --- a/webapp/locales/en.json +++ b/webapp/locales/en.json @@ -152,11 +152,17 @@ "data": { "name": "Your data", "labelName": "Your Name", + "labelSlug": "Your unique user name", "namePlaceholder": "Femanon Funny", "labelCity": "Your City or Region", "labelBio": "About You", "success": "Your data was successfully updated!" }, + "validation": { + "slug": { + "alreadyTaken": "This user name is already taken." + } + }, "security": { "name": "Security", "change-password": { diff --git a/webapp/pages/settings/index.vue b/webapp/pages/settings/index.vue index 5c99f4b8b..d79c00e2f 100644 --- a/webapp/pages/settings/index.vue +++ b/webapp/pages/settings/index.vue @@ -8,6 +8,16 @@ :label="$t('settings.data.labelName')" :placeholder="$t('settings.data.namePlaceholder')" /> + + + {{ $t('settings.validation.slug.alreadyTaken') }} + @@ -42,6 +59,8 @@ import gql from 'graphql-tag' import { mapGetters, mapMutations } from 'vuex' import { CancelToken } from 'axios' +import { checkSlugAvailableQuery } from '~/graphql/User.js' +import { debounce } from 'lodash' let timeout const mapboxToken = process.env.MAPBOX_TOKEN @@ -60,9 +79,10 @@ const query = gql` */ const mutation = gql` - mutation($id: ID!, $name: String, $locationName: String, $about: String) { - UpdateUser(id: $id, name: $name, locationName: $locationName, about: $about) { + mutation($id: ID!, $slug: String, $name: String, $locationName: String, $about: String) { + UpdateUser(id: $id, slug: $slug, name: $name, locationName: $locationName, about: $about) { id + slug name locationName about @@ -78,6 +98,7 @@ export default { loadingData: false, loadingGeo: false, formData: {}, + slugAvailable: true, } }, computed: { @@ -86,21 +107,30 @@ export default { }), form: { get: function() { - const { name, locationName, about } = this.currentUser - return { name, locationName, about } + const { name, slug, locationName, about } = this.currentUser + return { name, slug, locationName, about } }, set: function(formData) { this.formData = formData }, }, }, + created() { + this.validateSlug = debounce(async () => { + const variables = { slug: this.formData.slug } + const { + data: { User }, + } = await this.$apollo.query({ query: checkSlugAvailableQuery, variables }) + this.slugAvailable = User && !User[0] + }, 500) + }, methods: { ...mapMutations({ setCurrentUser: 'auth/SET_USER', }), async submit() { this.loadingData = true - const { name, about } = this.formData + const { name, slug, about } = this.formData let { locationName } = this.formData || this.currentUser locationName = locationName && (locationName['label'] || locationName) try { @@ -109,14 +139,16 @@ export default { variables: { id: this.currentUser.id, name, + slug, locationName, about, }, update: (store, { data: { UpdateUser } }) => { - const { name, locationName, about } = UpdateUser + const { name, slug, locationName, about } = UpdateUser this.setCurrentUser({ ...this.currentUser, name, + slug, locationName, about, })