Skip to content

Commit 4a58da0

Browse files
committed
receive sort,filter info, perform operations and re render results
1 parent 2f35765 commit 4a58da0

File tree

1 file changed

+113
-20
lines changed

1 file changed

+113
-20
lines changed

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

Lines changed: 113 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -6,34 +6,34 @@
66
<Sort
77
v-bind:position="'left'"
88
v-bind:options="['Closest', 'Furthest', 'Youngest', 'Oldest', 'Most popular', 'Least popular', 'Most common interests', 'Least common interests']"
9-
v-on:sort="sort"></Sort>
9+
v-on:saveSort="saveSort"></Sort>
1010
<FilterSlider
1111
v-bind:min="recommendationsAnalysis.age.min"
1212
v-bind:max="recommendationsAnalysis.age.max"
1313
v-bind:name="'age'"
14-
v-on:filter="filter"></FilterSlider>
14+
v-on:saveFilter="saveFilter"></FilterSlider>
1515
<FilterSlider
1616
v-bind:min="recommendationsAnalysis.distance.min"
1717
v-bind:max="recommendationsAnalysis.distance.max"
1818
v-bind:unit="'km'"
1919
v-bind:name="'distance'"
20-
v-on:filter="filter"></FilterSlider>
20+
v-on:saveFilter="saveFilter"></FilterSlider>
2121
<FilterSlider
2222
v-bind:min="recommendationsAnalysis.popularity.min"
2323
v-bind:max="recommendationsAnalysis.popularity.max"
2424
v-bind:unit="'pts'"
25-
v-bind:name="'fame'"
26-
v-on:filter="filter"></FilterSlider>
25+
v-bind:name="'popularity'"
26+
v-on:saveFilter="saveFilter"></FilterSlider>
2727
<MultipleFiltersDropdown
2828
v-bind:position="'right'"
2929
v-bind:options="recommendationsAnalysis.uniqueInterests"
3030
v-bind:name="'interests'"
31-
v-on:filter="filter"></MultipleFiltersDropdown>
31+
v-on:saveFilterMultiple="saveFilterMultiple"></MultipleFiltersDropdown>
3232
</div>
33-
<div class="grid grid-cols-1 md:grid-cols-2 gap-2">
33+
<div ref="recommendationCards" class="grid grid-cols-1 md:grid-cols-2 gap-2">
3434
<RecommendationCard
3535
v-for="(recommendation, index) in recommendations" :key="index"
36-
v-bind:recommendation="recommendation" v-bind:index="index + 1"></RecommendationCard>
36+
v-bind:recommendation="recommendation"></RecommendationCard>
3737
</div>
3838
</section>
3939
</template>
@@ -46,39 +46,132 @@ import RecommendationCard from '@/components/app/recommendations/RecommendationC
4646
import MultipleFiltersDropdown from '@/components/shared/MultipleFiltersDropdown.vue';
4747
4848
export default {
49-
props: ['title', 'recommendations', 'recommendationsAnalysis'],
49+
props: ['title', 'recommendationsReceived', 'recommendationsAnalysis'],
5050
components: {
5151
Sort,
5252
RecommendationCard,
5353
FilterSlider,
5454
MultipleFiltersDropdown,
5555
},
5656
data: () => ({
57+
recommendations: [],
58+
recommendationsBackup: [],
59+
sorting: 'Closest',
60+
filters: {
61+
age: {
62+
min: null,
63+
max: null,
64+
},
65+
distance: {
66+
min: null,
67+
max: null,
68+
},
69+
popularity: {
70+
min: null,
71+
max: null,
72+
},
73+
interests: [],
74+
},
5775
}),
5876
methods: {
59-
sort(...args) {
77+
saveSort(...args) {
6078
const [by] = args;
79+
this.sorting = by;
80+
},
81+
saveFilter(...range) {
82+
const [name, min, max] = range;
83+
this.filters[name].min = min;
84+
this.filters[name].max = max;
85+
},
86+
saveFilterMultiple(...multiple) {
87+
const [name, filters] = multiple;
88+
this.filters[name] = filters;
89+
},
90+
sort(recommendations, by) {
6191
if (by === 'Closest') {
62-
this.recommendations.sort((a, b) => a.distance - b.distance);
92+
recommendations.sort((a, b) => a.distance - b.distance);
6393
} else if (by === 'Furthest') {
64-
this.recommendations.sort((a, b) => b.distance - a.distance);
94+
recommendations.sort((a, b) => b.distance - a.distance);
6595
} else if (by === 'Youngest') {
66-
this.recommendations.sort((a, b) => a.age - b.age);
96+
recommendations.sort((a, b) => a.age - b.age);
6797
} else if (by === 'Oldest') {
68-
this.recommendations.sort((a, b) => b.age - a.age);
98+
recommendations.sort((a, b) => b.age - a.age);
6999
} else if (by === 'Most popular') {
70-
this.recommendations.sort((a, b) => b.heat_score - a.heat_score);
100+
recommendations.sort((a, b) => b.heat_score - a.heat_score);
71101
} else if (by === 'Least popular') {
72-
this.recommendations.sort((a, b) => a.heat_score - b.heat_score);
102+
recommendations.sort((a, b) => a.heat_score - b.heat_score);
73103
} else if (by === 'Most common interests') {
74-
this.recommendations.sort((a, b) => b.common_interests - a.common_interests);
104+
recommendations.sort((a, b) => b.common_tags.length - a.common_tags.length);
75105
} else if (by === 'Least common interests') {
76-
this.recommendations.sort((a, b) => a.common_interests - b.common_interests);
106+
recommendations.sort((a, b) => a.common_tags.length - b.common_tags.length);
77107
}
78108
},
79-
filter() {
80-
console.log('filter');
109+
filter(recommendations) {
110+
let i = recommendations.length;
111+
while (i--) {
112+
if (!this.meetsFilters(recommendations[i])) {
113+
recommendations.splice(i, 1);
114+
}
115+
}
116+
return recommendations;
117+
},
118+
meetsFilters(recommendation) {
119+
return this.meetsAge(recommendation)
120+
&& this.meetsPopularity(recommendation)
121+
&& this.meetsDistance(recommendation)
122+
&& this.meetsInterests(recommendation);
123+
},
124+
meetsAge(recommendation) {
125+
return recommendation.age >= this.filters.age.min
126+
&& recommendation.age <= this.filters.age.max;
127+
},
128+
meetsPopularity(recommendation) {
129+
return recommendation.heat_score >= this.filters.popularity.min
130+
&& recommendation.heat_score <= this.filters.popularity.max;
131+
},
132+
meetsDistance(recommendation) {
133+
return recommendation.distance >= this.filters.distance.min
134+
&& recommendation.distance <= this.filters.distance.max;
135+
},
136+
meetsInterests(recommendation) {
137+
const recommendationInterests = recommendation.interests;
138+
const filterInterests = this.filters.interests;
139+
for (let i = 0; i < filterInterests.length; i += 1) {
140+
if (recommendationInterests.indexOf(filterInterests[i]) === -1) {
141+
return false;
142+
}
143+
}
144+
return true;
145+
},
146+
},
147+
watch: {
148+
sorting: {
149+
handler() {
150+
let base = this.recommendationsBackup.slice();
151+
base = this.filter(base);
152+
this.sort(base, this.sorting);
153+
this.recommendations = base;
154+
},
81155
},
156+
filters: {
157+
handler() {
158+
let base = this.recommendationsBackup.slice();
159+
base = this.filter(base);
160+
this.sort(base, this.sorting);
161+
this.recommendations = base;
162+
},
163+
deep: true,
164+
}
82165
},
166+
beforeMount() {
167+
this.recommendations = this.recommendationsReceived;
168+
this.recommendationsBackup = this.recommendationsReceived;
169+
this.filters.age.min = this.recommendationsAnalysis.age.min;
170+
this.filters.age.max = this.recommendationsAnalysis.age.max;
171+
this.filters.distance.min = this.recommendationsAnalysis.distance.min;
172+
this.filters.distance.max = this.recommendationsAnalysis.distance.max;
173+
this.filters.popularity.min = this.recommendationsAnalysis.popularity.min;
174+
this.filters.popularity.max = this.recommendationsAnalysis.popularity.max;
175+
}
83176
};
84177
</script>

0 commit comments

Comments
 (0)