mirror of
https://github.com/Ocelot-Social-Community/Ocelot-Social.git
synced 2025-12-13 07:46:06 +00:00
- write tests for userMiddleware - checks the functionality of nodes/locations middleware - refactor to not allow users to update to remove their name debatable whether we want that or not, but we do not allow users to create accounts with no name, so we should be consistent, before we were using neode to validate this, but we have are removing neode from production code, so we must validate ourselves - collate UpdateUser mutations to one
176 lines
4.7 KiB
Vue
176 lines
4.7 KiB
Vue
<template>
|
|
<ds-form v-model="form" :schema="formSchema" @submit="submit">
|
|
<template slot-scope="{ errors }">
|
|
<ds-card :header="$t('settings.data.name')">
|
|
<ds-input
|
|
id="name"
|
|
model="name"
|
|
icon="user"
|
|
:label="$t('settings.data.labelName')"
|
|
:placeholder="$t('settings.data.namePlaceholder')"
|
|
/>
|
|
<ds-input id="slug" model="slug" icon="at" :label="$t('settings.data.labelSlug')" />
|
|
<!-- eslint-disable vue/use-v-on-exact -->
|
|
<ds-select
|
|
id="city"
|
|
model="locationName"
|
|
icon="map-marker"
|
|
:options="cities"
|
|
:label="$t('settings.data.labelCity')"
|
|
:placeholder="$t('settings.data.labelCity')"
|
|
:loading="loadingGeo"
|
|
@input.native="handleCityInput"
|
|
/>
|
|
<!-- eslint-enable vue/use-v-on-exact -->
|
|
<ds-input
|
|
id="bio"
|
|
model="about"
|
|
type="textarea"
|
|
rows="3"
|
|
:label="$t('settings.data.labelBio')"
|
|
:placeholder="$t('settings.data.labelBio')"
|
|
/>
|
|
<template slot="footer">
|
|
<ds-button icon="check" :disabled="errors" type="submit" :loading="loadingData" primary>
|
|
{{ $t('actions.save') }}
|
|
</ds-button>
|
|
</template>
|
|
</ds-card>
|
|
</template>
|
|
</ds-form>
|
|
</template>
|
|
|
|
<script>
|
|
import { mapGetters, mapMutations } from 'vuex'
|
|
import { CancelToken } from 'axios'
|
|
import UniqueSlugForm from '~/components/utils/UniqueSlugForm'
|
|
import { updateUserMutation } from '~/graphql/User'
|
|
|
|
let timeout
|
|
const mapboxToken = process.env.MAPBOX_TOKEN
|
|
|
|
export default {
|
|
data() {
|
|
return {
|
|
axiosSource: null,
|
|
cities: [],
|
|
loadingData: false,
|
|
loadingGeo: false,
|
|
formData: {},
|
|
}
|
|
},
|
|
computed: {
|
|
...mapGetters({
|
|
currentUser: 'auth/user',
|
|
}),
|
|
formSchema() {
|
|
const uniqueSlugForm = UniqueSlugForm({
|
|
apollo: this.$apollo,
|
|
currentUser: this.currentUser,
|
|
translate: this.$t,
|
|
})
|
|
return {
|
|
...uniqueSlugForm.formSchema,
|
|
}
|
|
},
|
|
form: {
|
|
get: function() {
|
|
const { name, slug, locationName, about } = this.currentUser
|
|
return { name, slug, locationName, about }
|
|
},
|
|
set: function(formData) {
|
|
this.formData = formData
|
|
},
|
|
},
|
|
},
|
|
methods: {
|
|
...mapMutations({
|
|
setCurrentUser: 'auth/SET_USER',
|
|
}),
|
|
async submit() {
|
|
this.loadingData = true
|
|
const { name, slug, about } = this.formData
|
|
let { locationName } = this.formData || this.currentUser
|
|
locationName = locationName && (locationName.label || locationName)
|
|
try {
|
|
await this.$apollo.mutate({
|
|
mutation: updateUserMutation(),
|
|
variables: {
|
|
id: this.currentUser.id,
|
|
name,
|
|
slug,
|
|
locationName,
|
|
about,
|
|
},
|
|
update: (store, { data: { UpdateUser } }) => {
|
|
const { name, slug, locationName, about } = UpdateUser
|
|
this.setCurrentUser({
|
|
...this.currentUser,
|
|
name,
|
|
slug,
|
|
locationName,
|
|
about,
|
|
})
|
|
},
|
|
})
|
|
this.$toast.success(this.$t('settings.data.success'))
|
|
} catch (err) {
|
|
this.$toast.error(err.message)
|
|
} finally {
|
|
this.loadingData = false
|
|
}
|
|
},
|
|
handleCityInput(value) {
|
|
clearTimeout(timeout)
|
|
timeout = setTimeout(() => this.requestGeoData(value), 500)
|
|
},
|
|
processCityResults(res) {
|
|
if (!res || !res.data || !res.data.features || !res.data.features.length) {
|
|
return []
|
|
}
|
|
const output = []
|
|
res.data.features.forEach(item => {
|
|
output.push({
|
|
label: item.place_name,
|
|
value: item.place_name,
|
|
id: item.id,
|
|
})
|
|
})
|
|
|
|
return output
|
|
},
|
|
requestGeoData(e) {
|
|
if (this.axiosSource) {
|
|
// cancel last request
|
|
this.axiosSource.cancel()
|
|
}
|
|
|
|
const value = e.target ? e.target.value.trim() : ''
|
|
if (value === '' || value.length < 3) {
|
|
this.cities = []
|
|
return
|
|
}
|
|
this.loadingGeo = true
|
|
this.axiosSource = CancelToken.source()
|
|
|
|
const place = encodeURIComponent(value)
|
|
const lang = this.$i18n.locale()
|
|
|
|
this.$axios
|
|
.get(
|
|
`https://api.mapbox.com/geocoding/v5/mapbox.places/${place}.json?access_token=${mapboxToken}&types=region,place,country&language=${lang}`,
|
|
{
|
|
cancelToken: this.axiosSource.token,
|
|
},
|
|
)
|
|
.then(res => {
|
|
this.cities = this.processCityResults(res)
|
|
})
|
|
.finally(() => {
|
|
this.loadingGeo = false
|
|
})
|
|
},
|
|
},
|
|
}
|
|
</script>
|