You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
341 lines
12 KiB
341 lines
12 KiB
<template>
|
|
<!-- eslint-disable vue/no-use-v-if-with-v-for,vue/no-confusing-v-for-v-if -->
|
|
<v-card outlined class="rounded-xl px-3">
|
|
<v-card-title> {{ $t("Locations") }}</v-card-title>
|
|
<v-card-subtitle class="mt-0">
|
|
<v-card outlined class="d-flex flex-row justify-space-between align-center px-3" style="border-radius: 12px"
|
|
height="36" width="100%" :ripple="false" @click="dialog = true">
|
|
<div style="color: #9c9c9c">{{ $t(searchBarTitle) }}</div>
|
|
<v-img height="25" max-width="25" contain :src="require('~/assets/svg/search.svg')"></v-img>
|
|
</v-card>
|
|
</v-card-subtitle>
|
|
<v-card-text class="ml-n4 mt-n3">
|
|
<v-list>
|
|
<v-list-group :value="!regionChecked.indexOf(region.id)" v-for="region in locations.slice(0, 8)"
|
|
:key="region.id" no-action class="my-n3">
|
|
<template v-slot:activator>
|
|
<v-list-item-title>{{ region.region }}</v-list-item-title>
|
|
</template>
|
|
<template v-slot:prependIcon>
|
|
<v-checkbox dense hide-details v-model="regionChecked" :value="region.id" @click.stop="
|
|
() => {
|
|
clickRegion(region.id);
|
|
}
|
|
"></v-checkbox>
|
|
</template>
|
|
<v-list>
|
|
<v-list-group class="ml-5" :value="!countryChecked.indexOf(country.id)"
|
|
v-for="country in region.countries" :key="country.id" no-action>
|
|
<template v-slot:activator>
|
|
<v-list-item-title>{{ country.country }}</v-list-item-title>
|
|
</template>
|
|
<template v-slot:prependIcon>
|
|
<v-checkbox dense hide-details v-model="countryChecked" :value="country.id" @click.stop="
|
|
() => {
|
|
clickCountry(region.id, country.id);
|
|
}
|
|
"></v-checkbox>
|
|
</template>
|
|
<v-list-item v-for="(city, i) in country.cities" :key="i">
|
|
<v-list-item-title class="ml-5">
|
|
<v-checkbox dense hide-details v-model="cityChecked" :value="city.id" :label="city.city"
|
|
@click.stop=""></v-checkbox>
|
|
</v-list-item-title>
|
|
</v-list-item>
|
|
</v-list-group>
|
|
</v-list>
|
|
</v-list-group>
|
|
</v-list>
|
|
</v-card-text>
|
|
<v-card-text>
|
|
<v-btn outlined class="rounded-xl remove-upper tw-border-primary-2 tw-text-primary-1 mt-n10"
|
|
style="padding: 10px auto" width="100%" @click="dialog = true">
|
|
{{ $t("See more") }}
|
|
</v-btn>
|
|
</v-card-text>
|
|
|
|
<v-dialog @click:outside="text = ''" v-model="dialog" width="644" height="618" class="rounded-xl">
|
|
<v-card class="rounded-xl pa-4" width="100%" height="100%">
|
|
<v-card-title>
|
|
<v-row no-gutters class="d-flex justify-space-between">
|
|
<div class="ml-n3">{{ $t("Select Location") }}</div>
|
|
<v-img :src="require('~/assets/svg/X.svg')" max-width="24" max-height="24" contain @click="dialog = false">
|
|
</v-img>
|
|
</v-row>
|
|
</v-card-title>
|
|
<v-card-subtitle class="mt-5">
|
|
<v-text-field outlined dense v-model="text" class="rounded-xl" :label="$t('Find Country/City ...')">
|
|
<template v-slot:append>
|
|
<v-img height="25" width="25" class="mt-n1" contain :src="require('~/assets/svg/search.svg')"></v-img>
|
|
</template>
|
|
</v-text-field>
|
|
</v-card-subtitle>
|
|
<v-card-text>
|
|
<v-list>
|
|
<v-list-group :value="
|
|
!regionChecked.indexOf(region.id) ||
|
|
(regionChild[i] > 0 &&
|
|
regionChild[i] < locations[i].countries.length)
|
|
" v-for="(region, i) in locations.slice(0, 8)" :key="region.id" no-action class="my-n3" v-if="
|
|
regionChild[i] > 0 ||
|
|
region.region.toLowerCase().includes(text.toLowerCase())
|
|
">
|
|
<template v-slot:activator>
|
|
<v-list-item-title>{{ region.region }}</v-list-item-title>
|
|
</template>
|
|
<template v-slot:prependIcon>
|
|
<v-checkbox dense hide-details v-model="regionChecked" :value="region.id" @click.stop="
|
|
() => {
|
|
clickRegion(region.id);
|
|
}
|
|
"></v-checkbox>
|
|
</template>
|
|
<v-list>
|
|
<v-list-group class="ml-5" :value="
|
|
!countryChecked.indexOf(country.id) ||
|
|
(countryChild[i][j] > 0 &&
|
|
countryChild[i][j] <
|
|
locations[i].countries[j].cities.length)
|
|
" v-for="(country, j) in region.countries" :key="country.id" no-action v-if="
|
|
countryChild[i][j] > 0 ||
|
|
country.country.toLowerCase().includes(text.toLowerCase())
|
|
">
|
|
<template v-slot:activator>
|
|
<v-list-item-title>{{ country.country }}</v-list-item-title>
|
|
</template>
|
|
<template v-slot:prependIcon>
|
|
<v-checkbox dense hide-details v-model="countryChecked" :value="country.id" @click.stop="
|
|
() => {
|
|
clickCountry(region.id, country.id);
|
|
}
|
|
"></v-checkbox>
|
|
</template>
|
|
|
|
<v-list-item v-for="city in country.cities" :key="city.id" v-if="
|
|
city.city.toLowerCase().includes(text.toLowerCase()) ||
|
|
text == ''
|
|
">
|
|
<v-list-item-title class="ml-5">
|
|
<v-checkbox dense hide-details v-model="cityChecked" :value="city.id" :label="city.city"
|
|
@click.stop=""></v-checkbox>
|
|
</v-list-item-title>
|
|
</v-list-item>
|
|
</v-list-group>
|
|
</v-list>
|
|
</v-list-group>
|
|
</v-list>
|
|
</v-card-text>
|
|
</v-card>
|
|
</v-dialog>
|
|
</v-card>
|
|
</template>
|
|
|
|
<script>
|
|
export default {
|
|
props: ["locations", "searchBarTitle", "searchBarWidth"],
|
|
|
|
data() {
|
|
return {
|
|
regionChecked: [],
|
|
countryChecked: [],
|
|
cityChecked: [],
|
|
regionChild: [],
|
|
countryChild: [],
|
|
locationMapping: {},
|
|
dialog: false,
|
|
text: "",
|
|
};
|
|
},
|
|
created() {
|
|
this.countryChild = new Array(this.locations.length);
|
|
for (let i = 0; i < this.locations.length; i++) {
|
|
let regionId = this.locations[i].id;
|
|
this.locationMapping[regionId] = {};
|
|
this.countryChild[i] = [];
|
|
|
|
this.regionChild[i] = this.locations[i].countries.length;
|
|
for (let j = 0; j < this.locations[i].countries.length; j++) {
|
|
let countryId = this.locations[i].countries[j].id;
|
|
this.locationMapping[regionId][countryId] = [];
|
|
if (this.locations[i].countries[j].cities != null) {
|
|
this.countryChild[i][j] =
|
|
this.locations[i].countries[j].cities.length;
|
|
for (
|
|
let k = 0;
|
|
k < this.locations[i].countries[j].cities.length;
|
|
k++
|
|
) {
|
|
let cityId = this.locations[i].countries[j].cities[k].id;
|
|
this.locationMapping[regionId][countryId].push(cityId);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (
|
|
this.$route.query.region &&
|
|
typeof this.$route.query.region == "object"
|
|
) {
|
|
this.$route.query.region.map((c) => {
|
|
this.regionChecked.push(parseInt(c));
|
|
});
|
|
} else if (
|
|
this.$route.query.region &&
|
|
typeof this.$route.query.region == "string"
|
|
) {
|
|
this.$route.query.region.split(",").map((c) => {
|
|
this.regionChecked.push(parseInt(c));
|
|
});
|
|
}
|
|
if (
|
|
this.$route.query.country &&
|
|
typeof this.$route.query.country == "object"
|
|
) {
|
|
this.$route.query.country.map((c) => {
|
|
this.countryChecked.push(parseInt(c));
|
|
});
|
|
} else if (
|
|
this.$route.query.country &&
|
|
typeof this.$route.query.country == "string"
|
|
) {
|
|
this.$route.query.country.split(",").map((c) => {
|
|
this.countryChecked.push(parseInt(c));
|
|
});
|
|
}
|
|
if (this.$route.query.city && typeof this.$route.query.city == "object") {
|
|
this.$route.query.city.map((c) => {
|
|
this.cityChecked.push(parseInt(c));
|
|
});
|
|
} else if (
|
|
this.$route.query.city &&
|
|
typeof this.$route.query.city == "string"
|
|
) {
|
|
this.$route.query.city.split(",").map((c) => {
|
|
this.cityChecked.push(parseInt(c));
|
|
});
|
|
}
|
|
},
|
|
watch: {
|
|
regionChecked() {
|
|
this.$emit("selectRegion", this.regionChecked);
|
|
},
|
|
countryChecked(to, from) {
|
|
this.$emit("selectCountry", this.countryChecked);
|
|
},
|
|
cityChecked() {
|
|
this.$emit("selectCity", this.cityChecked);
|
|
},
|
|
text() {
|
|
// countryChild //
|
|
let locationsLen = this.$props.locations.length;
|
|
for (let i = 0; i < locationsLen; i++) {
|
|
let countryLen = this.$props.locations[i].countries.length;
|
|
for (let j = 0; j < countryLen; j++) {
|
|
let cityNum = 0;
|
|
let cityLen = this.$props.locations[i].countries[j].cities.length;
|
|
for (let k = 0; k < cityLen; k++) {
|
|
let cityString =
|
|
this.$props.locations[i].countries[j].cities[k].city;
|
|
if (cityString.toLowerCase().includes(this.text.toLowerCase()))
|
|
cityNum++;
|
|
}
|
|
this.countryChild[i][j] = cityNum;
|
|
}
|
|
}
|
|
|
|
// regionChild //
|
|
locationsLen = this.$props.locations.length;
|
|
for (let i = 0; i < locationsLen; i++) {
|
|
let countryNum = 0;
|
|
let countryLen = this.$props.locations[i].countries.length;
|
|
for (let j = 0; j < countryLen; j++) {
|
|
let countryString = this.$props.locations[i].countries[j].country;
|
|
if (
|
|
this.countryChild[i][j] > 0 ||
|
|
countryString.toLowerCase().includes(this.text.toLowerCase())
|
|
)
|
|
countryNum++;
|
|
}
|
|
this.regionChild[i] = countryNum;
|
|
}
|
|
},
|
|
},
|
|
methods: {
|
|
clickRegion(clickRegionId) {
|
|
if (this.regionChecked.includes(clickRegionId)) {
|
|
// add
|
|
let countaryList = this.locationMapping[clickRegionId];
|
|
for (const [country, cities] of Object.entries(countaryList)) {
|
|
if (!this.countryChecked.includes(parseInt(country))) {
|
|
this.countryChecked.push(parseInt(country));
|
|
|
|
for (let i = 0; i < cities.length; i++) {
|
|
let cityId = cities[i];
|
|
if (!this.cityChecked.includes(cityId)) {
|
|
this.cityChecked.push(cityId);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
// delete
|
|
let countryList = this.locationMapping[clickRegionId];
|
|
for (const [country, cities] of Object.entries(countryList)) {
|
|
let countryId = parseInt(country);
|
|
let idxCountry = this.countryChecked.indexOf(countryId);
|
|
if (idxCountry > -1) {
|
|
this.countryChecked.splice(idxCountry, 1);
|
|
for (let i = 0; i < cities.length; i++) {
|
|
let cityId = cities[i];
|
|
let idxCity = this.cityChecked.indexOf(cityId);
|
|
if (idxCity > -1) {
|
|
this.cityChecked.splice(idxCity, 1);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
clickCountry(regionid, clickCountryId) {
|
|
if (this.countryChecked.includes(clickCountryId)) {
|
|
// add
|
|
let cityList = this.locationMapping[regionid][clickCountryId];
|
|
for (let i = 0; i < cityList.length; i++) {
|
|
let cityId = cityList[i];
|
|
if (!this.cityChecked.includes(cityId)) this.cityChecked.push(cityId);
|
|
}
|
|
} else {
|
|
// delete
|
|
let cityList = this.locationMapping[regionid][clickCountaryId];
|
|
for (let i = 0; i < cityList.length; i++) {
|
|
let cityId = cityList[i];
|
|
let idx = this.cityChecked.indexOf(cityId);
|
|
if (idx > -1) this.cityChecked.splice(idx, 1);
|
|
}
|
|
}
|
|
},
|
|
},
|
|
};
|
|
</script>
|
|
|
|
<style scoped lang="scss">
|
|
:deep() {
|
|
.v-text-field__details {
|
|
display: none !important;
|
|
}
|
|
|
|
.v-input__append-inner {
|
|
margin-top: 12px !important;
|
|
}
|
|
|
|
.v-input--selection-controls__input {
|
|
i {
|
|
color: #f5cda8 !important;
|
|
}
|
|
}
|
|
|
|
.v-label {
|
|
color: #232323 !important;
|
|
margin-left: 20px;
|
|
}
|
|
}
|
|
</style>
|