Skip to content

Commit ac4373d

Browse files
committed
renamed old slider and create search view
1 parent 882dc7b commit ac4373d

File tree

7 files changed

+249
-37
lines changed

7 files changed

+249
-37
lines changed

frontend/src/components/app/recommendations/Recommendations.vue

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,23 +11,23 @@
1111
v-bind:options="['Closest', 'Furthest', 'Youngest',
1212
'Oldest', 'Most popular', 'Least popular', 'Most common interests', 'Least common interests']"
1313
v-on:saveSort="saveSort"></Sort>
14-
<FilterSlider
14+
<FilterSliderDropdown
1515
v-bind:min="recommendationsAnalysis.age.min"
1616
v-bind:max="recommendationsAnalysis.age.max"
1717
v-bind:name="'age'"
18-
v-on:saveFilter="saveFilter"></FilterSlider>
19-
<FilterSlider
18+
v-on:saveFilter="saveFilter"></FilterSliderDropdown>
19+
<FilterSliderDropdown
2020
v-bind:min="recommendationsAnalysis.distance.min"
2121
v-bind:max="recommendationsAnalysis.distance.max"
2222
v-bind:unit="'km'"
2323
v-bind:name="'distance'"
24-
v-on:saveFilter="saveFilter"></FilterSlider>
25-
<FilterSlider
24+
v-on:saveFilter="saveFilter"></FilterSliderDropdown>
25+
<FilterSliderDropdown
2626
v-bind:min="recommendationsAnalysis.popularity.min"
2727
v-bind:max="recommendationsAnalysis.popularity.max"
2828
v-bind:unit="'pts'"
2929
v-bind:name="'popularity'"
30-
v-on:saveFilter="saveFilter"></FilterSlider>
30+
v-on:saveFilter="saveFilter"></FilterSliderDropdown>
3131
<MultipleFiltersDropdown
3232
v-bind:position="'right'"
3333
v-bind:options="recommendationsAnalysis.uniqueInterests"
@@ -45,7 +45,7 @@
4545
<script>
4646
/* eslint-disable */
4747
import Sort from '@/components/shared/Sort.vue';
48-
import FilterSlider from '@/components/shared/FilterSlider.vue';
48+
import FilterSliderDropdown from '@/components/shared/FilterSliderDropdown.vue';
4949
import RecommendationCard from '@/components/app/recommendations/RecommendationCard.vue';
5050
import MultipleFiltersDropdown from '@/components/shared/MultipleFiltersDropdown.vue';
5151
@@ -54,7 +54,7 @@ export default {
5454
components: {
5555
Sort,
5656
RecommendationCard,
57-
FilterSlider,
57+
FilterSliderDropdown,
5858
MultipleFiltersDropdown,
5959
},
6060
data: () => ({

frontend/src/components/shared/FilterSlider.vue

Lines changed: 10 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,17 @@
11
<template>
22
<!-- eslint-disable max-len -->
3-
<div class="focus:outline-none ml-2 flex-1 sm:flex-none" @focusout="close" tabindex="1">
4-
<div v-bind:class="{'filter-button': true, 'border-gray-matcha': !closed}" @click="toggle">
5-
<h1 v-bind:class="{ 'opacity-50': closed, 'noSelect': true, 'capitalize': true }">{{name}}</h1>
6-
</div>
7-
<div ref="sliderDropdown" v-bind:class="{'slider-dropdown': true, 'hidden': closed}">
8-
<div class="flex mb-4 mt-2">
9-
<h1>
10-
<span class="font-bold">{{this.slider.startMin}} {{this.unit}}</span>
11-
to
12-
<span class="font-bold">{{this.slider.startMax}} {{this.unit}}</span></h1>
3+
<div class="mb-8" ref="sliderDropdown">
4+
<div class="mx-auto flex w-full items-center mb-4 max-w-md">
5+
<div class="w-full flex justify-between">
6+
<h1 class="text-xl text-purple-matcha capitalize">{{ name }}</h1>
7+
<h1 class="text-xl text-purple-matcha">
8+
<span class="">{{this.slider.startMin}} {{this.unit}}</span>
9+
to
10+
<span class="">{{this.slider.startMax}} {{this.unit}}</span></h1>
11+
</div>
1312
</div>
14-
<div ref="slider" class="w-64 mb-4"></div>
13+
<div ref="slider" class="mx-auto w-full mb-4 px-4 max-w-md"></div>
1514
</div>
16-
</div>
1715
</template>
1816

1917
<script>
@@ -23,7 +21,6 @@ import 'nouislider/distribute/nouislider.css';
2321
export default {
2422
props: ['options', 'name', 'unit', 'min', 'max'],
2523
data: () => ({
26-
closed: true,
2724
slider: {
2825
startMin: null,
2926
startMax: null,
@@ -33,21 +30,6 @@ export default {
3330
step: 1,
3431
},
3532
}),
36-
methods: {
37-
toggle() {
38-
this.closed = !this.closed;
39-
if (!this.closed) {
40-
this.$nextTick(function () {
41-
this.$refs.sliderDropdown.focus();
42-
});
43-
}
44-
},
45-
close(event) {
46-
if (!event.currentTarget.contains(event.relatedTarget)) {
47-
this.closed = true;
48-
}
49-
},
50-
},
5133
mounted() {
5234
this.slider.startMin = this.min;
5335
this.slider.startMax = this.max;
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
<template>
2+
<!-- eslint-disable max-len -->
3+
<div class="focus:outline-none ml-2 flex-1 sm:flex-none" @focusout="close" tabindex="1">
4+
<div v-bind:class="{'filter-button': true, 'border-gray-matcha': !closed}" @click="toggle">
5+
<h1 v-bind:class="{ 'opacity-50': closed, 'noSelect': true, 'capitalize': true }">{{name}}</h1>
6+
</div>
7+
<div ref="sliderDropdown" v-bind:class="{'slider-dropdown': true, 'hidden': closed}">
8+
<div class="flex mb-4 mt-2">
9+
<h1>
10+
<span class="font-bold">{{this.slider.startMin}} {{this.unit}}</span>
11+
to
12+
<span class="font-bold">{{this.slider.startMax}} {{this.unit}}</span></h1>
13+
</div>
14+
<div ref="slider" class="w-64 mb-4"></div>
15+
</div>
16+
</div>
17+
</template>
18+
19+
<script>
20+
import noUiSlider from 'nouislider';
21+
import 'nouislider/distribute/nouislider.css';
22+
23+
export default {
24+
props: ['options', 'name', 'unit', 'min', 'max'],
25+
data: () => ({
26+
closed: true,
27+
slider: {
28+
startMin: null,
29+
startMax: null,
30+
min: null,
31+
max: null,
32+
start: null,
33+
step: 1,
34+
},
35+
}),
36+
methods: {
37+
toggle() {
38+
this.closed = !this.closed;
39+
if (!this.closed) {
40+
this.$nextTick(function () {
41+
this.$refs.sliderDropdown.focus();
42+
});
43+
}
44+
},
45+
close(event) {
46+
if (!event.currentTarget.contains(event.relatedTarget)) {
47+
this.closed = true;
48+
}
49+
},
50+
},
51+
mounted() {
52+
this.slider.startMin = this.min;
53+
this.slider.startMax = this.max;
54+
this.slider.min = this.min;
55+
this.slider.max = this.max;
56+
this.slider.start = this.min;
57+
noUiSlider.create(this.$refs.slider, {
58+
start: [this.slider.startMin, this.slider.startMax],
59+
step: this.slider.step,
60+
range: {
61+
min: this.slider.min,
62+
max: this.slider.max,
63+
},
64+
});
65+
this.$refs.slider.noUiSlider.on('update', (values) => {
66+
this.slider.startMin = parseInt(values[0], 10);
67+
this.slider.startMax = parseInt(values[1], 10);
68+
this.$emit('saveFilter', this.name, this.slider.startMin, this.slider.startMax);
69+
});
70+
},
71+
};
72+
</script>
73+
74+
<style>
75+
.noUi-handle {
76+
outline: none;
77+
}
78+
.noUi-handle:focus {
79+
outline: none;
80+
}
81+
</style>
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<template>
2+
<!-- eslint-disable max-len -->
3+
<div class='mx-auto max-w-md mb-4'>
4+
<h1 class="text-xl lg text-purple-matcha capitalize text-left mb-4">{{ name }}</h1>
5+
<div class="h-48 w-auto overflow-scroll rounded-md border border-gray-300 bg-white">
6+
<h1 v-for="(option, index) in options" :key="option + index + option"
7+
v-bind:class="{'sort-dropdown-option': true, 'text-lg': true, 'border-b': index !== options.length - 1, 'capitalize': true,
8+
'font-extrabold': selectedFilters.indexOf(option) !== -1, 'text-gray-matcha': selectedFilters.indexOf(option) !== -1}"
9+
v-on:click="select(option)">
10+
{{option}}
11+
</h1>
12+
</div>
13+
</div>
14+
</template>
15+
16+
<script>
17+
export default {
18+
props: ['options', 'name', 'position'],
19+
data: () => ({
20+
closed: true,
21+
selectedFilters: [],
22+
}),
23+
methods: {
24+
select(option) {
25+
const optionIndex = this.selectedFilters.indexOf(option);
26+
if (optionIndex !== -1) {
27+
this.selectedFilters.splice(optionIndex, 1);
28+
this.$emit('saveFilterMultiple', this.name, this.selectedFilters);
29+
} else {
30+
this.selectedFilters.push(option);
31+
this.$emit('saveFilterMultiple', this.name, this.selectedFilters);
32+
}
33+
},
34+
toggle() {
35+
this.closed = !this.closed;
36+
},
37+
close() {
38+
this.closed = true;
39+
},
40+
},
41+
};
42+
</script>

frontend/src/components/shared/NavBar.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
<router-link to="/accounts/signup" class="navigation-button-logged-in sm:hover:bg-purple-matcha sm:hover:text-white-matcha sm:text-white-matcha sm:py-2 sm:px-8">Get Started</router-link>
2727
</div>
2828
<router-link v-if="loggedIn && currentRoute !== 'Browse'" to="/browse" class="navigation-button-logged-in">Browse</router-link>
29-
<router-link v-if="loggedIn" to="/search" class="navigation-button-logged-in">Search</router-link>
29+
<router-link v-if="loggedIn && currentRoute !== 'Search'" to="/search" class="navigation-button-logged-in">Search</router-link>
3030
<router-link v-if="loggedIn" to="/" class="navigation-button-logged-in">Matches</router-link>
3131
<router-link v-if="loggedIn" to="/" class="navigation-button-logged-in">Profile</router-link>
3232
<router-link v-if="loggedIn" v-on:click.native="logout()" to="/" class="navigation-button-logged-in">Exit</router-link>

frontend/src/router/index.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import ResetPassword from '../views/auth/ResetPassword.vue';
1010
import ResetPasswordError from '../views/auth/ResetPasswordError.vue';
1111
import Onboarding from '../views/app/Onboarding.vue';
1212
import Browse from '../views/app/Browse.vue';
13+
import Search from '../views/app/Search.vue';
1314
import store from '../store/index';
1415

1516
Vue.use(VueRouter);
@@ -102,6 +103,11 @@ const routes = [
102103
beforeEnter: notLoggedInRedirectLogin,
103104
props: true,
104105
},
106+
{
107+
path: '/search',
108+
name: Search,
109+
component: Search,
110+
},
105111
];
106112

107113
const router = new VueRouter({

frontend/src/views/app/Search.vue

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
<template>
2+
<!-- eslint-disable max-len -->
3+
<div class="mx-4 sm:mx-16 lg:mx-32">
4+
<NavBar v-bind:currentRoute="'Search'"></NavBar>
5+
<section v-if="searchSubmitted">results</section>
6+
<section v-if="!searchSubmitted" class="flex flex-col my-8 md:my-12">
7+
<div>
8+
<FilterSlider
9+
v-bind:min="18"
10+
v-bind:max="100"
11+
v-bind:name="'age'"
12+
v-on:saveFilter="saveFilter"></FilterSlider>
13+
<FilterSlider
14+
v-bind:min="18"
15+
v-bind:max="100"
16+
v-bind:name="'distance'"
17+
v-on:saveFilter="saveFilter"></FilterSlider>
18+
<FilterSlider
19+
v-bind:min="18"
20+
v-bind:max="100"
21+
v-bind:name="'popularity'"
22+
v-on:saveFilter="saveFilter"></FilterSlider>
23+
</div>
24+
<div>
25+
<MultipleFilters
26+
v-bind:options="[
27+
'swimming', 'wine', 'reading', 'foodie', 'netflix', 'music', 'yoga', 'golf',
28+
'photography', 'baking', 'shopping', 'outdoors', 'art', 'travel', 'hiking',
29+
'running', 'volunteering', 'cycling', 'climbing', 'tea', 'fishing', 'soccer',
30+
'museum', 'dancing', 'surfing', 'karaoke', 'parties', 'diy',
31+
'walking', 'cat lover', 'movies', 'gardening', 'trivia', 'working out',
32+
'cooking', 'gamer', 'brunch', 'blogging', 'picknicking', 'athlete',
33+
'dog lover', 'politics', 'environmentalism', 'instagram', 'spirituality',
34+
'language exchange', 'sports', 'comedy', 'fashion', 'disney', 'vlogging',
35+
'astrology', 'board games', 'craft beer', 'coffee', 'writer',
36+
]"
37+
v-bind:name="'interests'"
38+
v-on:saveFilterMultiple="saveFilterMultiple"></MultipleFilters>
39+
</div>
40+
<div class="mx-auto w-full max-w-md">
41+
<h1 v-on:click="search()" class="onboarding-sub-container-content-button-outline w-48 text-lg font-normal max-w-full bg-purple-matcha w-full text-white-matcha mx-auto">
42+
Search</h1>
43+
</div>
44+
</section>
45+
</div>
46+
</template>
47+
48+
<script>
49+
/* eslint-disable max-len */
50+
import NavBar from '@/components/shared/NavBar.vue';
51+
import FilterSlider from '@/components/shared/FilterSlider.vue';
52+
import MultipleFilters from '@/components/shared/MultipleFilters.vue';
53+
54+
export default {
55+
props: ['recommendationsFromSettingUp'],
56+
components: {
57+
MultipleFilters,
58+
NavBar,
59+
FilterSlider,
60+
},
61+
data: () => ({
62+
searchSubmitted: false,
63+
filters: {
64+
age: {
65+
min: null,
66+
max: null,
67+
},
68+
distance: {
69+
min: null,
70+
max: null,
71+
},
72+
popularity: {
73+
min: null,
74+
max: null,
75+
},
76+
interests: [],
77+
},
78+
}),
79+
methods: {
80+
saveFilter(...range) {
81+
const [name, min, max] = range;
82+
this.filters[name].min = min;
83+
this.filters[name].max = max;
84+
},
85+
saveFilterMultiple(...multiple) {
86+
const [name, filters] = multiple;
87+
this.filters[name] = filters;
88+
},
89+
search() {
90+
this.searchSubmitted = true;
91+
},
92+
},
93+
};
94+
95+
</script>
96+
97+
<style scoped>
98+
.home {
99+
height: calc(100% - 4rem - 2rem);
100+
}
101+
</style>

0 commit comments

Comments
 (0)