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.
432 lines
18 KiB
432 lines
18 KiB
<template>
|
|
<div
|
|
:class="['searchDialog tw-overflow-auto tw-fixed tw-top-0 tw-bottom-0 tw-left-0 tw-right-0 tw-w-full tw-h-full tw-z-10 tw-bg-white tw-transition-all tw-duration-300 tw-delay-75 tw-ease-in-out tw-border-0 tw-border-t tw-border-neutral-200',searchDialogActive ? 'tw-translate-y-0' : 'tw-translate-y-full']">
|
|
<div class="tw-px-[20px]">
|
|
<div class="tw-flex tw-justify-end tw-my-[15px]">
|
|
<v-btn @click="closeDialog" icon>
|
|
<img src="@/assets/svg/X.svg" />
|
|
</v-btn>
|
|
</div>
|
|
<!-- v2.0 -->
|
|
<div
|
|
class="tw-grid tw-grid-cols-2 tw-border-solid tw-border-[1px] tw-border-neutrals-200 tw-rounded-[14px] tw-mb-[16px] md:tw-mb-[20px]">
|
|
<button
|
|
:class="['tw-py-[11px] tw-rounded-[14px] tw-transition-all tw-duration-100 tw-delay-75 tw-ease-in-out',type == 'exhibition' ? 'tw-bg-primary-default tw-text-white':'tw-bg-white tw-text-primary-default']"
|
|
@click="type = 'exhibition'">{{
|
|
$t('Exhibition')
|
|
}}</button>
|
|
<button
|
|
:class="['tw-py-[11px] tw-rounded-[14px] tw-transition-all tw-duration-300 tw-ease-in-out',type == 'service' ? 'tw-bg-primary-default tw-text-white':'tw-bg-white tw-text-primary-default']"
|
|
@click="type = 'service'">{{ $t('Service')
|
|
}}</button>
|
|
</div>
|
|
|
|
<input type="search" v-model="searchQuery"
|
|
class="tw-text-[16px] tw-rounded-[16px] tw-w-full tw-h-[48px] tw-border-solid tw-border-[1px] tw-border-neutrals-200 tw-outline-none tw-px-[20px] tw-py-[15px] tw-mb-[20px] md:tw-mb-[25px] focus:tw-border-primary-default"
|
|
@focus="show= true" @blur="show= false" @keyup.enter="search" />
|
|
|
|
<!-- v2.0 -->
|
|
<div v-if="type=='exhibition'">
|
|
<div>
|
|
<!-- <div class="tw-mb-[30px]">
|
|
<div class="tw-body-4 tw-font-bold tw-text-black tw-mb-[10px] md:tw-mb-[20px]">{{ $t('History') }}
|
|
</div>
|
|
<div class="tw-flex tw-flex-wrap">
|
|
<nuxt-link :to="localePath(`/exhibition?q=${servicesSearch}`)"
|
|
class="tw-mr-[16px] tw-mb-[10px] tw-px-[16px] tw-py-[7px] tw-border-solid tw-border-[1px] tw-rounded-[12px] tw-border-x-secondary-default tw-text-secondary-default"
|
|
v-for="(servicesSearch, idx) in servicesSearchs" :key="idx">
|
|
{{ servicesSearch }}
|
|
</nuxt-link>
|
|
</div>
|
|
</div> -->
|
|
<Transition name="bounce">
|
|
<div class="tw-mb-[30px]" v-show="show">
|
|
<div class="tw-body-4 tw-font-bold tw-text-black tw-mb-[10px] md:tw-mb-[20px]">{{ $t('Popular search') }}
|
|
</div>
|
|
<div class="tw-flex tw-flex-wrap">
|
|
<nuxt-link :to="localePath(`/exhibition?q=${servicesLocation}`)" @click.native="closeDialog()"
|
|
class="tw-mr-[16px] tw-mb-[10px] tw-px-[16px] tw-py-[7px] tw-border-solid tw-border-[1px] tw-rounded-[12px] tw-border-x-secondary-default tw-text-secondary-default hover:tw-border-transparent hover:tw-bg-secondary-default hover:tw-text-white"
|
|
v-for="(servicesLocation, idx) in populars.search" :key="idx">
|
|
{{ servicesLocation }}
|
|
</nuxt-link>
|
|
</div>
|
|
</div>
|
|
</Transition>
|
|
</div>
|
|
<div class="tabs tw-flex tw-mb-[20px]">
|
|
<button
|
|
:class="['tw-transition-all tw-duration-300 tw-ease-in-out tw-mr-[30px] tab',tabs == 'exhibitionsCategories' ? 'active tw-text-black tw-font-bold':'tw-text-neutrals-500']"
|
|
@click="tabs = 'exhibitionsCategories'">{{
|
|
$t('Exhibition Categories')
|
|
}}</button>
|
|
<button
|
|
:class="['tw-transition-all tw-duration-300 tw-ease-in-out tab',tabs == 'location' ? 'active tw-text-black tw-font-bold':'tw-text-neutrals-500']"
|
|
@click="tabs = 'location'">{{ $t('Location')
|
|
}}</button>
|
|
</div>
|
|
|
|
<div v-if="tabs=='exhibitionsCategories'">
|
|
<div class="customMenuLink tw-relative tw-flex tw-justify-start tw-items-center tw-z-10">
|
|
<div class="customDropMenu exhibition tw-w-full tw-overflow-hidden">
|
|
<div class="tw-relative tw-grid tw-grid-cols-[210px_auto] tw-h-[344px] md:tw-grid-cols-[3fr_2fr]">
|
|
<div
|
|
class="tw-list-none tw-overflow-y-auto tw-h-auto tw-break-inside-avoid tw-flex tw-flex-col tw-pr-[20px]">
|
|
<template v-if="exhibitionsCategoryList.length>0">
|
|
<div v-for="(item,index) in exhibitionsCategoryList" :key="index" @click="exhibitionActiveIndex=index"
|
|
:class="['exhibitionDropdownLink tw-block tw-w-full tw-body-4 tw-font-normal tw-mb-[20px] tw-pr-[20px] hover:tw-text-primary-default',exhibitionActiveIndex == index ? 'tw-text-primary-default active':'tw-text-neutrals-900']">
|
|
{{
|
|
$t(item.CategoryName)
|
|
}}</div></template>
|
|
</div>
|
|
<div class="tw-overflow-x-hidden tw-overflow-y-auto" v-if="exhibitionsCategoryList.length>0">
|
|
<div class="tw-list-none tw-flex tw-flex-col tw-flex-wrap tw-px-[20px]">
|
|
<div class="tw-list-none tw-mb-[20px] tw-w-full">
|
|
<nuxt-link
|
|
:to="localePath(`/exhibition?category=${exhibitionsCategoryList[exhibitionActiveIndex].CategoryID}`)"
|
|
@click.native="closeDialog()"
|
|
class="tw-block tw-body-4 tw-font-normal tw-text-neutral-800 hover:tw-text-primary-default">{{
|
|
$t('All')}}</nuxt-link>
|
|
</div>
|
|
<template v-if="exhibitionsCategoryList[
|
|
exhibitionActiveIndex
|
|
].SubCategoryList && exhibitionsCategoryList[
|
|
exhibitionActiveIndex
|
|
].SubCategoryList.length>0">
|
|
<div v-for="(sub,index) in exhibitionsCategoryList[exhibitionActiveIndex].SubCategoryList" :key="index"
|
|
class="tw-list-none tw-mb-[20px] tw-w-full">
|
|
<nuxt-link :to="localePath(`/exhibition?subcategory=${sub.CategoryID}`)" @click.native="closeDialog()"
|
|
class="tw-block tw-body-4 tw-font-normal tw-text-neutral-800 hover:tw-text-primary-default">{{
|
|
sub.CategoryName }}</nuxt-link>
|
|
</div></template>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div v-if="tabs=='location'">
|
|
<div class="customMenuLink tw-relative tw-flex tw-justify-start tw-items-center tw-z-10">
|
|
<div class="customDropMenu exhibition tw-w-full tw-overflow-hidden">
|
|
<div class="tw-relative tw-grid tw-grid-cols-[120px_auto] tw-h-[344px] md:tw-grid-cols-[1fr_3fr]">
|
|
<div class="tw-list-none tw-overflow-y-auto tw-h-auto tw-break-inside-avoid tw-flex tw-flex-col">
|
|
<div v-for="(item,index) in exhibitionsLocations" :key="index" @click="locationActiveIndex=index"
|
|
:class="['exhibitionDropdownLink tw-block tw-w-full tw-body-4 tw-font-normal tw-mb-[20px] tw-pr-[20px] hover:tw-text-primary-default',locationActiveIndex == index ? 'tw-text-primary-default active':'tw-text-neutrals-900']">
|
|
{{
|
|
$t(item.region)
|
|
}}</div>
|
|
</div>
|
|
<div class="tw-ml-[20px] tw-overflow-x-hidden tw-overflow-y-auto">
|
|
<ul class="tw-list-none tw-flex tw-flex-col tw-flex-wrap">
|
|
<li class="tw-list-none tw-mb-[20px]">
|
|
<nuxt-link :to="localePath(`/exhibition?region=${exhibitionsLocations[locationActiveIndex].id}`)"
|
|
@click.native="closeDialog()"
|
|
class="tw-block tw-body-4 tw-font-normal tw-text-neutral-800 hover:tw-text-primary-default">{{
|
|
$t('All')}}</nuxt-link>
|
|
</li>
|
|
<li v-for="(countries,index) in exhibitionsLocations[locationActiveIndex].countries" :key="index"
|
|
class="tw-list-none tw-mb-[20px]">
|
|
<nuxt-link :to="localePath(`/exhibition?country=${countries.id}`)" @click.native="closeDialog()"
|
|
class="tw-block tw-body-4 tw-font-normal tw-text-neutral-800 hover:tw-text-primary-default">{{
|
|
countries.country }}</nuxt-link>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<!-- <v-card flat width="100%" height="100%" class="d-flex"
|
|
:height="$vuetify.breakpoint.smAndUp ? '700px' : '448px'">
|
|
<v-card flat width="33%" class="d-flex flex-column overflow-y-auto"
|
|
:height="$vuetify.breakpoint.smAndUp ? '700px' : '448px'">
|
|
<v-card flat width="100%"
|
|
:class="$vuetify.breakpoint.smOnly ? 'ps-3 pb-3 pt-3 text-size-14 d-flex align-center' : 'ps-3 pb-3 pt-3 text-size-12 d-flex align-center'"
|
|
v-for="i in exhibitionsLocations.length" :key="i" @click.stop="
|
|
locationsIdx = i - 1;
|
|
countriesIdx = 0;
|
|
">
|
|
<v-spacer :class="locationsIdx === i - 1 ? 'primary--text' : ''">
|
|
{{ exhibitionsLocations[i - 1].region }}
|
|
</v-spacer>
|
|
<v-icon :color="locationsIdx === i - 1 ? 'primary' : ''" class="me-6">mdi-chevron-right</v-icon>
|
|
</v-card>
|
|
</v-card>
|
|
<v-card flat width="33%" class="d-flex flex-column overflow-y-auto"
|
|
:height="$vuetify.breakpoint.smAndUp ? '700px' : '448px'">
|
|
<v-card flat width="100%"
|
|
:class="$vuetify.breakpoint.smOnly ? 'ps-3 pb-3 pt-3 text-size-14' : 'ps-3 pb-3 pt-3 text-size-12'"
|
|
@click="localeRegion(exhibitionsLocations[locationsIdx].id)">
|
|
{{ $t('All') }}
|
|
</v-card>
|
|
<v-card flat width="100%"
|
|
:class="$vuetify.breakpoint.smOnly ? 'ps-3 pb-3 pt-3 text-size-14 d-flex align-center' : 'ps-3 pb-3 pt-3 text-size-12 d-flex align-center'"
|
|
v-for="j in exhibitionsLocations[locationsIdx].countries
|
|
.length" :key="j" @click="countriesIdx = j - 1">
|
|
<v-spacer :class="countriesIdx === j - 1 ? 'primary--text' : ''">
|
|
{{
|
|
exhibitionsLocations[locationsIdx].countries[j - 1].country
|
|
}}
|
|
</v-spacer>
|
|
<v-icon :color="countriesIdx === j - 1 ? 'primary' : ''"
|
|
:class="$vuetify.breakpoint.smOnly ? 'me-6' : 'me-2'">mdi-chevron-right</v-icon>
|
|
</v-card>
|
|
</v-card>
|
|
<v-card flat width="34%" class="d-flex flex-column overflow-y-auto"
|
|
v-if="exhibitionsLocations[locationsIdx].countries.length != 0"
|
|
:height="$vuetify.breakpoint.smAndUp ? '700px' : '448px'">
|
|
<v-card width="100%"
|
|
:class="$vuetify.breakpoint.smOnly ? 'ps-3 pb-3 pt-3 text-size-14' : 'ps-3 pb-3 pt-3 text-size-12'" flat
|
|
color="transparent"
|
|
@click="localeCountry(exhibitionsLocations[locationsIdx].countries[countriesIdx].id)">
|
|
{{ $t('All') }}
|
|
</v-card>
|
|
<v-card v-for="k in exhibitionsLocations[locationsIdx].countries[
|
|
countriesIdx
|
|
].cities.length" :key="k" width="100%"
|
|
:class="$vuetify.breakpoint.smOnly ? 'ps-3 pb-3 pt-3 text-size-14' : 'ps-3 pb-3 pt-3 text-size-12'" flat
|
|
color="transparent" @click="localeCity(exhibitionsLocations[locationsIdx].countries[
|
|
countriesIdx
|
|
].cities[k - 1].id)">
|
|
{{
|
|
exhibitionsLocations[locationsIdx].countries[countriesIdx].cities[k - 1].city
|
|
}}
|
|
</v-card>
|
|
</v-card>
|
|
</v-card> -->
|
|
</div>
|
|
</div>
|
|
<div v-if="type=='service'">
|
|
<div>
|
|
<!-- <div class="tw-mb-[30px]">
|
|
<div class="tw-body-4 tw-font-bold tw-text-black tw-mb-[10px] md:tw-mb-[20px]">{{ $t('History') }}
|
|
</div>
|
|
<div class="tw-flex tw-flex-wrap">
|
|
<nuxt-link :to="localePath(`/exhibition?q=${servicesSearch}`)"
|
|
class="tw-mr-[16px] tw-mb-[10px] tw-px-[16px] tw-py-[7px] tw-border-solid tw-border-[1px] tw-rounded-[12px] tw-border-x-secondary-default tw-text-secondary-default"
|
|
v-for="(servicesSearch, idx) in servicesSearchs" :key="idx">
|
|
{{ servicesSearch }}
|
|
</nuxt-link>
|
|
</div>
|
|
</div> -->
|
|
<div class="tw-mb-[30px]">
|
|
<div class="tw-body-4 tw-font-bold tw-text-black tw-mb-[10px] md:tw-mb-[20px]">{{ $t('Popular search') }}
|
|
</div>
|
|
<div class="tw-flex tw-flex-wrap">
|
|
<nuxt-link :to="localePath(`/service?q=${servicesLocation}`)" @click.native="closeDialog()"
|
|
class="tw-mr-[16px] tw-mb-[10px] tw-px-[16px] tw-py-[7px] tw-border-solid tw-border-[1px] tw-rounded-[12px] tw-border-x-secondary-default tw-text-secondary-default hover:tw-border-transparent hover:tw-bg-secondary-default hover:tw-text-white"
|
|
v-for="(servicesLocation, idx) in populars.service" :key="idx">
|
|
{{ servicesLocation }}
|
|
</nuxt-link>
|
|
</div>
|
|
</div>
|
|
<div>
|
|
<div class="tw-body-4 tw-font-bold tw-text-black tw-mb-[10px] md:tw-mb-[20px]">{{ $t('Location') }} </div>
|
|
<div class="tw-flex tw-flex-wrap">
|
|
<nuxt-link :to="localePath(`/service?q=${servicesLocation}`)" @click.native="closeDialog()"
|
|
class="tw-mr-[16px] tw-mb-[10px] tw-px-[16px] tw-py-[7px] tw-border-solid tw-border-[1px] tw-rounded-[12px] tw-border-x-secondary-default tw-text-secondary-default hover:tw-border-transparent hover:tw-bg-secondary-default hover:tw-text-white"
|
|
v-for="(servicesLocation, idx) in servicesLocations" :key="idx">
|
|
{{ servicesLocation }}
|
|
</nuxt-link>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
export default {
|
|
name: 'SearchDialog',
|
|
props: {
|
|
exhibitionsCategoryList: {
|
|
type: Array,
|
|
required: true,
|
|
default: () => []
|
|
},
|
|
exhibitionsLocations: {
|
|
type: Array,
|
|
required: true,
|
|
default: () => []
|
|
},
|
|
exhibitionsCategories: {
|
|
type: Array,
|
|
required: true,
|
|
default: () => []
|
|
},
|
|
servicesSearchs: {
|
|
type: Array,
|
|
required: true,
|
|
default: () => []
|
|
},
|
|
servicesLocations: {
|
|
type: Array,
|
|
required: true,
|
|
default: () => []
|
|
},
|
|
exhibitionsKeywords: {
|
|
type: Array,
|
|
default: () => []
|
|
},
|
|
populars: {
|
|
type: Object,
|
|
default: () => { }
|
|
}
|
|
},
|
|
data() {
|
|
return {
|
|
type: 'exhibition',
|
|
tabs: 'exhibitionsCategories',
|
|
searchQuery: '',
|
|
locationsIdx: 0,
|
|
countriesIdx: 0,
|
|
categoriesIdx: 0,
|
|
exhibitionActiveIndex: 0,
|
|
locationActiveIndex: 0,
|
|
show: false,
|
|
}
|
|
},
|
|
computed: {
|
|
searchDialogActive: {
|
|
get() {
|
|
return this.$store.getters.getSearchDialogStatus
|
|
},
|
|
}
|
|
},
|
|
methods: {
|
|
closeDialog() {
|
|
this.$store.dispatch('toggleSearchDialog', false);
|
|
this.type = 'exhibition';
|
|
this.tabs = 'exhibitionsCategories';
|
|
this.searchQuery = '';
|
|
this.locationsIdx = 0;
|
|
this.countriesIdx = 0;
|
|
this.categoriesIdx = 0;
|
|
this.exhibitionActiveIndex = 0;
|
|
this.locationActiveIndex = 0;
|
|
},
|
|
search() {
|
|
this.$emit('loaading', true);
|
|
this.$router.push(this.localePath(`/${this.type}?q=${this.searchQuery}`))
|
|
this.closeDialog()
|
|
},
|
|
localeRegion(id) {
|
|
this.$router.push(this.localePath(`/exhibition?region=${id}`))
|
|
this.closeDialog()
|
|
},
|
|
localeCountry(id) {
|
|
this.$router.push(this.localePath(`/exhibition?country=${id}`))
|
|
this.closeDialog()
|
|
},
|
|
localeCity(id) {
|
|
this.$router.push(this.localePath(`/exhibition?city=${id}`))
|
|
this.closeDialog()
|
|
},
|
|
localeCategory(id) {
|
|
this.$router.push(this.localePath(`/exhibition?category=${id}`))
|
|
this.closeDialog()
|
|
},
|
|
localeSubcategory(id) {
|
|
this.$router.push(this.localePath(`/exhibition?subcategory=${id}`))
|
|
this.closeDialog()
|
|
}
|
|
}
|
|
};
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
:deep() {
|
|
.v-btn--outlined {
|
|
border: 1px solid #E5E5E5;
|
|
}
|
|
|
|
}
|
|
|
|
input[type="search"] {
|
|
background-image: url('~/assets/svg/icon-search-small.svg');
|
|
background-position: right 20px center;
|
|
background-size: 24px;
|
|
background-repeat: no-repeat;
|
|
}
|
|
|
|
.searchDialog {
|
|
min-height: 100vh !important;
|
|
min-height: -webkit-fill-available !important;
|
|
|
|
@media (min-width: 768px) {
|
|
min-height: max-content !important;
|
|
}
|
|
}
|
|
|
|
.nuxt-link-active {
|
|
color: #232323;
|
|
text-decoration: none;
|
|
}
|
|
|
|
.custom-control:focus {
|
|
outline: none !important;
|
|
}
|
|
|
|
.v-dialog__content {
|
|
z-index: 4 !important;
|
|
}
|
|
|
|
.v-dialog__content--active {
|
|
z-index: 4 !important;
|
|
}
|
|
|
|
.tabs {
|
|
.tab {
|
|
position: relative;
|
|
padding-bottom: 15px;
|
|
|
|
&.active {
|
|
&::after {
|
|
position: absolute;
|
|
bottom: 0;
|
|
left: 0;
|
|
right: 0;
|
|
margin: 0 auto;
|
|
content: '';
|
|
display: block;
|
|
width: 44px;
|
|
height: 3px;
|
|
background-color: #f48800;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
.exhibitionDropdownLink {
|
|
&.active {
|
|
background-image: url('@/assets/svg/icon-arrow.svg');
|
|
background-position: right top;
|
|
background-size: 16px;
|
|
background-repeat: no-repeat;
|
|
}
|
|
}
|
|
|
|
.bounce-enter-active {
|
|
animation: bounce-in 0.3s ease-out;
|
|
}
|
|
|
|
.bounce-leave-active {
|
|
animation: bounce-in 0.3s cubic-bezier(1, 0.5, 0.8, 1) reverse;
|
|
}
|
|
|
|
@keyframes bounce-in {
|
|
0% {
|
|
opacity: 0;
|
|
transform: translateY(-10px);
|
|
}
|
|
|
|
50% {
|
|
opacity: 0.5;
|
|
transform: translateY(-5px);
|
|
}
|
|
|
|
100% {
|
|
opacity: 1;
|
|
transform: translateY(0);
|
|
}
|
|
}
|
|
</style>
|