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
4646import MultipleFiltersDropdown from ' @/components/shared/MultipleFiltersDropdown.vue' ;
4747
4848export 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