replace user setting's select by location select component

This commit is contained in:
mahula 2023-04-25 10:59:17 +02:00
parent e2667a1a98
commit 6aeef477fc
2 changed files with 123 additions and 57 deletions

View File

@ -0,0 +1,118 @@
<template>
<div>
<label class="ds-input-label">
{{ `${$t('settings.data.labelCity')}` }}
<span v-if="locationName">{{ `- ${locationName}` }}</span>
</label>
<ds-select
id="city"
v-model="currentValue"
:options="cities"
icon="map-marker"
:icon-right="null"
:placeholder="$t('settings.data.labelCity') + ' …'"
:loading="loadingGeo"
@input.native="handleCityInput"
/>
<base-button
v-if="locationName !== ''"
icon="close"
ghost
size="small"
style="position: relative; display: inline-block; right: -94%; top: -48px; width: 29px"
@click.native="clearLocationName"
></base-button>
</div>
</template>
<script>
import { queryLocations } from '~/graphql/location'
let timeout
export default {
name: 'LocationSelect',
props: {
value: {
required: true,
},
},
async created() {
const result = await this.requestGeoData(this.locationName)
await this.$nextTick(() => {
this.currentValue = result || this.locationName
})
},
data() {
return {
currentValue: this.value,
loadingGeo: false,
cities: [],
}
},
computed: {
locationName() {
return typeof this.value === 'object' ? this.value.value : this.value
},
},
watch: {
currentValue() {
if (this.currentValue !== this.value) {
this.$emit('input', this.currentValue)
}
},
value() {
if (this.value !== this.currentValue) {
this.currentValue = this.value
}
},
},
methods: {
handleCityInput(event) {
clearTimeout(timeout)
timeout = setTimeout(
() => this.requestGeoData(event.target ? event.target.value.trim() : ''),
500,
)
},
processLocationsResult(places) {
if (!places.length) {
return []
}
const result = []
places.forEach((place) => {
result.push({
label: place.place_name,
value: place.place_name,
id: place.id,
})
})
return result
},
async requestGeoData(value) {
if (value === '') {
this.cities = []
return
}
this.loadingGeo = true
const place = encodeURIComponent(value)
const lang = this.$i18n.locale()
const {
data: { queryLocations: result },
} = await this.$apollo.query({ query: queryLocations(), variables: { place, lang } })
this.cities = this.processLocationsResult(result)
this.loadingGeo = false
return this.cities.find((city) => city.value === value)
},
clearLocationName(event) {
event.target.value = ''
this.$emit('input', event.target.value)
},
},
}
</script>

View File

@ -11,20 +11,7 @@
: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"
/>
<ds-text class="location-hint" color="softer">
{{ $t('settings.data.labelCityHint') }}
</ds-text>
<location-select model="locationName"/>
<!-- eslint-enable vue/use-v-on-exact -->
<ds-input
id="about"
@ -45,13 +32,14 @@
<script>
import { mapGetters, mapMutations } from 'vuex'
import UniqueSlugForm from '~/components/utils/UniqueSlugForm'
import LocationSelect from '~/components/Select/LocationSelect'
import { updateUserMutation } from '~/graphql/User'
import { queryLocations } from '~/graphql/location'
let timeout
export default {
name: 'NewsFeed',
components: {
LocationSelect
},
data() {
return {
cities: [],
@ -121,52 +109,12 @@ export default {
this.loadingData = false
}
},
handleCityInput(value) {
clearTimeout(timeout)
timeout = setTimeout(() => this.requestGeoData(value), 500)
},
processLocationsResult(places) {
if (!places.length) {
return []
}
const result = []
places.forEach((place) => {
result.push({
label: place.place_name,
value: place.place_name,
id: place.id,
})
})
return result
},
async requestGeoData(e) {
const value = e.target ? e.target.value.trim() : ''
if (value === '') {
this.cities = []
return
}
this.loadingGeo = true
const place = encodeURIComponent(value)
const lang = this.$i18n.locale()
const {
data: { queryLocations: res },
} = await this.$apollo.query({ query: queryLocations(), variables: { place, lang } })
this.cities = this.processLocationsResult(res)
this.loadingGeo = false
},
},
}
</script>
<style lang="scss">
// .settings-form {
// >
.location-hint {
margin-top: -$space-x-small - $space-xxx-small - $space-xxx-small;
}
// }
</style>