bemarket/src/components/market/SearchPanel.vue
2022-03-10 15:30:55 +08:00

449 lines
9.4 KiB
Vue

<template>
<div class="searchPanel">
<div class="filter-header">
<img class="icon"
@click = "hideFilter"
alt="filter header"
src="data:image/svg+xml,%3csvg width='12' height='20' viewBox='0 0 12 20' fill='none' xmlns='http://www.w3.org/2000/svg'%3e %3cpath d='M10.5 19L1.5 10L10.5 1' stroke='white' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' /%3e %3c/svg%3e">
</div>
<div class="root">
<div class="header">
<span class="label">FILTERS</span>
<button class="button" @click="onClickClearAll">CLEAR ALL</button>
</div>
<div class="content">
<div class="one-block" v-for="data in currentFilterData" :key="data.title">
<check-list v-if="data.type === 'check'" :title="data.title" :items="data.datas"></check-list>
<slider-section v-else-if="data.type === 'slider'" :title="data.title" :value-min="data.valueMin" :value-max="data.valueMax" :cfg="data.cfg"></slider-section>
<range-input v-else-if="data.type==='range'" :title="data.title" :value-min="data.valueMin" :value-max="data.valueMax"></range-input>
</div>
</div>
</div>
<div class="filter-btn">
<button class="general-btn btnApply"><span>Apply Filter</span></button>
</div>
</div>
</template>
<script lang="ts">
import { Component, Prop, Vue } from 'vue-property-decorator'
import FilterItem from '@/components/market/filters/FilterItem.vue'
import SelectSection from '@/components/market/filters/SelectSection.vue'
import RangeSlider, { ISliderCfg } from '@/components/market/filters/RangeSlider.vue'
import CheckList, { ICheckData } from '@/components/market/filters/CheckList.vue'
import SliderSection from '@/components/market/filters/SliderSection.vue'
import RangeInput from '@/components/market/filters/RangeSection.vue'
export interface IFilterCfg {
title: string
type: string
datas?: ICheckData[]
cfg?: ISliderCfg
valueMin?: number
valueMax?: number
}
@Component({
name: 'SearchPanel',
components: {
RangeInput,
SliderSection,
CheckList,
RangeSlider,
SelectSection,
FilterItem
}
})
export default class extends Vue {
@Prop() private nftType: number
private heroFilterData: IFilterCfg[] = [
{
title: 'CLASS',
type: 'check',
datas: [
{
title: 'Attacker',
id: 'attacker',
checked: false
},
{
title: 'Defender',
id: 'defender',
checked: false
},
{
title: 'Supporter',
id: 'supporter',
checked: false
}
]
},
{
title: 'HERO',
type: 'check',
datas: [
{
title: 'Aoi',
id: 'aoi',
checked: false
},
{
title: 'yamada',
id: 'yamada',
checked: false
},
{
title: 'lazar',
id: 'lazar',
checked: false
},
{
title: 'hill',
id: 'hill',
checked: false
},
{
title: 'kurosawa',
id: 'kurosawa',
checked: false
},
{
title: 'canoe',
id: 'canoe',
checked: false
},
{
title: 'miffy',
id: 'miffy',
checked: false
},
{
title: 'dragonscale',
id: 'dragonscale',
checked: false
},
{
title: 'astral',
id: 'astral',
checked: false
},
{
title: 'mariana',
id: 'mariana',
checked: false
}
]
},
{
title: 'LEVEL',
type: 'slider',
valueMin: 1,
valueMax: 6,
cfg: {
min: 1,
max: 10,
masks: {
1: 'L1',
10: 'L10'
}
}
},
{
title: 'PRICE RANGE (WBNB)',
type: 'range',
valueMin: undefined,
valueMax: 5
}
]
private weaponFilterData: IFilterCfg[] = [
{
title: 'WEAPON',
type: 'check',
datas: [
{
title: 'Assault Rifle',
id: 'assault rifle',
checked: false
},
{
title: 'Dragon Firethrower',
id: 'dragon firethrower',
checked: false
},
{
title: 'Frost Machine Gun',
id: 'frost machine gun',
checked: false
},
{
title: 'Lightning',
id: 'lightning',
checked: false
},
{
title: 'Shotgun',
id: 'shotgun',
checked: false
},
{
title: 'Single Shot Rocket Launcher',
id: 'single shot rocket launcher',
checked: false
},
{
title: 'Sniper Rifle',
id: 'sniper rifle',
checked: false
}
]
},
{
title: 'LEVEL',
type: 'slider',
valueMin: 1,
valueMax: 6,
cfg: {
min: 1,
max: 10,
masks: {
1: 'L1',
10: 'L10'
}
}
},
{
title: 'PRICE RANGE (WBNB)',
type: 'range',
valueMin: undefined,
valueMax: 5
}
]
private chipFilterData: IFilterCfg[] = [
{
title: 'QUALITY',
type: 'check',
datas: [
{
title: 'green',
id: 'green',
checked: false
},
{
title: 'blue',
id: 'blue',
checked: false
},
{
title: 'orange',
id: 'orange',
checked: false
},
{
title: 'purple',
id: 'purple',
checked: false
}
]
},
{
title: 'PRICE RANGE (WBNB)',
type: 'range',
valueMin: undefined,
valueMax: 5
}
]
get currentFilterData(): IFilterCfg[] {
switch (this.nftType) {
case 0:
return this.heroFilterData
case 1:
return this.weaponFilterData
case 2:
return this.chipFilterData
default:
return this.heroFilterData
}
}
onClickClearAll() {
const currentDatas = this.currentFilterData
for (const data of currentDatas) {
switch (data.type) {
case 'check':
for (const _d of data.datas!) {
_d.checked = false
}
break
case 'slider':
data.valueMin = data.cfg!.min
data.valueMax = data.cfg!.max
break
case 'range':
data.valueMin = undefined
data.valueMax = undefined
break
}
}
this.$forceUpdate()
}
hideFilter() {
this.$emit('filter-show', false)
}
}
</script>
<style lang="scss" scoped>
.searchPanel {
display: flex;
flex-direction: column;
width: 20.875em;
max-width: 100%;
padding: 2.5em;
box-sizing: border-box;
.root{
display: flex;
flex-direction: column;
cursor: default;
.header{
display: flex;
flex-direction: row;
padding: 0.75em 0;
border-bottom: 1px solid #51529D;
width: 100%;
.label{
display: flex;
flex: 1;
font-size: 0.875em;
color: white;
}
.button{
display: flex;
background: none;
border: none;
outline: none;
font-weight: bold;
font-size: 0.875em;
color: #46E0F4;
cursor: pointer;
}
}
}
.content{
display: flex;
flex-direction: column;
width: 100%;
}
}
.filter-btn {
display: none;
}
.filter-header {
display: none;
}
@media (max-width: 767px) {
.searchPanel{
position: fixed;
top: 0;
left: 0;
right: 0;
height: 100vh;
z-index: 26;
background-color: black;
overflow-y: scroll;
display: none;
.root {
margin-bottom: 140px;
margin-top: 76px;
}
}
.filter-btn{
width: 100vw;
max-width: 100%;
background: #130933;
position: fixed;
bottom: 0;
right: 0;
font-size: 16px;
display: flex;
z-index: 10;
transition: transform linear .2s,opacity linear .2s;
box-sizing: border-box;
flex-direction: column;
}
.btnApply {
line-height: inherit;
padding: 20px 0;
margin: 40px 24px 45px;
height: 55px;
span {
font-size: 1.125em;
}
}
.filter-header {
width: 100vw;
max-width: 100%;
background: #130933;
position: fixed;
top: 0;
right: 0;
display: flex;
z-index: 10;
transition: transform linear .2s,opacity linear .2s;
box-sizing: border-box;
flex-direction: column;
font-size: 20px;
font-weight: bold;
color: white;
padding: 22.5px 24px 33px 24px;
.icon {
margin-right: 25px;
width: 12px;
}
}
}
.el-slider {
.el-slider__input {
margin-top: 0;
}
.el-slider__runway {
height: 32px;
margin-top: 0;
margin-bottom: 0 !important;
background-color: #FFFFFF;
border: 1px solid #DCDFE6;
.el-slider__bar {
height: 31px;
}
.el-slider__button-wrapper {
top: 0;
height: 32px;
.el-slider__button {
width: 4px;
height: 31px;
border-radius: 0;
background: #FFFFFF;
border: solid 2px #0068A5;
}
}
.el-slider__stop {
width: 1px;
height: 31px;
border-radius: 0;
background-color: #DCDFE6;
}
.el-slider__marks-text {
color: #717171;
margin-top: 0;
transform: translateX(-115%);
}
}
}
</style>