Skip to content

Commit ef5b09c

Browse files
authored
Merge pull request #407 from Seluj78/257-loading-icons
2 parents 4c3e868 + ce9dccd commit ef5b09c

File tree

13 files changed

+130
-48
lines changed

13 files changed

+130
-48
lines changed

frontend/src/components/app/users/User.vue

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
<template>
22
<!-- eslint-disable max-len -->
33
<div class="sm:mx-16 lg:mx-32">
4-
<section class="mx-auto">
4+
<div v-if="!user" class="mx-auto flex items-center justify-center mt-32">
5+
<img class="h-36" src="../../../assets/loading.svg">
6+
</div>
7+
<section v-else class="mx-auto">
58
<div v-on:click="goBack()" class="sort-button py-0 ml-auto rounded-md text-lg w-20 md:w-16 mr-4 sm:mr-0 mb-4">
69
<h1 class="noSelect">←</h1>
710
</div>
8-
<div v-if="user" class="md:flex md:items-start">
11+
<div class="md:flex md:items-start">
912
<UserImages v-bind:images="user.images" v-bind:gender="user.gender" class="md:w-7/12 md:order-2 sm:rounded-t md:rounded-r-md md:rounded-l-none"></UserImages>
1013
<UserProfile class="md:w-5/12 md:order-1 md:overflow-scroll md:border-b md:border-l md:rounded-l-md" v-bind:user="user"></UserProfile>
1114
</div>

frontend/src/components/shared/FilterSlider.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
<div class="mb-8" ref="sliderDropdown">
44
<div class="mx-auto flex w-full items-center mb-4 max-w-md">
55
<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">
6+
<h1 class="text-base text-purple-matcha capitalize">{{ name }}</h1>
7+
<h1 class="text-base text-purple-matcha">
88
<span class="">{{this.slider.startMin}}<span v-if="oneHandle"> {{this.unit}}</span></span>
99
<span v-if="!oneHandle"> to </span>
1010
<span v-if="!oneHandle" class="">{{this.slider.startMax}} {{this.unit}}</span></h1>

frontend/src/components/shared/MultipleFilters.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<h1 class="text-md text-left opacity-50 mb-4">{{ info }}</h1>
66
<div class="h-48 w-auto overflow-scroll rounded-md border border-gray-300 bg-white">
77
<h1 v-for="(option, index) in options" :key="option + index + option"
8-
v-bind:class="{'sort-dropdown-option': true, 'text-lg': true, 'border-b': index !== options.length - 1, 'capitalize': true,
8+
v-bind:class="{'sort-dropdown-option': true, 'text-base': true, 'border-b': index !== options.length - 1, 'capitalize': true,
99
'font-extrabold': selectedFilters.indexOf(option) !== -1, 'text-gray-matcha': selectedFilters.indexOf(option) !== -1}"
1010
v-on:click="select(option)">
1111
{{option}}

frontend/src/views/app/Browse.vue

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
<!-- eslint-disable max-len -->
33
<div class="mx-4 sm:mx-16 lg:mx-32">
44
<section class="mx-auto">
5+
<div v-if="!recommendationsAnalysisDone" class="flex items-center justify-center mt-32">
6+
<img class="h-36" src="../../assets/loading.svg">
7+
</div>
58
<Recommendations
69
v-if="recommendationsAnalysisDone"
710
v-bind:title="'Potential matches'"

frontend/src/views/app/History.vue

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
<template>
22
<!-- eslint-disable max-len -->
33
<div class="mx-4 sm:mx-16 lg:mx-32">
4-
<section class="mx-auto mt-4">
4+
<div v-if="!historyFetched" class="mx-auto flex items-center justify-center mt-32">
5+
<img class="h-36" src="../../assets/loading.svg">
6+
</div>
7+
<section v-else class="mx-auto mt-4">
58
<div class="flex items-center justify-center md:justify-start w-full mb-4">
69
<h1
710
class="text-3xl sm:text-5xl my-4 inline-block text-center leading-none onboarding-sub-container-content-heading">
@@ -55,6 +58,7 @@ export default {
5558
},
5659
recommendationsAnalysisDone: false,
5760
filteredCount: null,
61+
historyFetched: false,
5862
}),
5963
methods: {
6064
async fetchUsers(request) {
@@ -108,6 +112,7 @@ export default {
108112
}
109113
}
110114
}
115+
this.historyFetched = true;
111116
this.recommendationsAnalysisDone = true;
112117
},
113118
browseAgain() {
@@ -120,6 +125,7 @@ export default {
120125
this.recommendationsAnalysis.popularity.max = null;
121126
this.recommendationsAnalysis.interests = [];
122127
this.recommendationsAnalysisDone = false;
128+
this.historyFetched = false;
123129
},
124130
updateHistory(...args) {
125131
const [key, value] = args;

frontend/src/views/app/Matches.vue

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
<template>
22
<!-- eslint-disable max-len -->
33
<div class="mx-4 sm:mx-16 lg:mx-32">
4+
<div v-if="!fetchingDone" class="mx-auto flex items-center justify-center mt-32">
5+
<img class="h-36" src="../../assets/loading.svg">
6+
</div>
47
<section v-if="fetchingDone" class="mx-auto relative md:flex md:items-start md:justify-center">
58
<div class="md:w-full md:max-w-xs md:shadow-md md:rounded-md md:p-8 md:flex md:flex-col md:justify-start">
69
<div class="mt-8 sm:mt-0">

frontend/src/views/app/Search.vue

Lines changed: 44 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
<template>
22
<!-- eslint-disable max-len -->
33
<div class="mx-4 sm:mx-16 lg:mx-32">
4+
<div v-if="!recommendationsAnalysisDone && !sliderValuesFetched" class="mx-auto flex items-center justify-center mt-32">
5+
<img class="h-36" src="../../assets/loading.svg">
6+
</div>
47
<section v-if="recommendationsAnalysisDone" class="mx-auto">
58
<div class="sort-button rounded-md text-lg lg:text-2xl w-24 ml-auto" v-on:click="searchAgain()">
69
<h1 class="noSelect capitalize">←</h1>
@@ -13,30 +16,30 @@
1316
<section v-on:click="setError(null)"
1417
v-if="!recommendationsAnalysisDone && sliderValuesFetched"
1518
class="flex flex-col my-8 md:my-12">
16-
<div><img src="../../assets/search.png" class="w-20 mb-4 mx-auto"></div>
17-
<div>
18-
<FilterSlider
19-
v-bind:min="sliders.age.min"
20-
v-bind:max="sliders.age.max"
21-
v-bind:name="'age'"
22-
v-on:save-filter="saveFilter"></FilterSlider>
23-
<FilterSlider
24-
v-bind:min="1"
25-
v-bind:max="2000"
26-
v-bind:unit="'km'"
27-
v-bind:oneHandle="true"
28-
v-bind:name="'distance'"
29-
v-on:save-filter="saveFilter"></FilterSlider>
30-
<FilterSlider
31-
v-bind:min="sliders.popularity.min"
32-
v-bind:max="sliders.popularity.max"
33-
v-bind:unit="'pts'"
34-
v-bind:name="'popularity'"
35-
v-on:save-filter="saveFilter"></FilterSlider>
36-
</div>
37-
<div>
38-
<MultipleFilters
39-
v-bind:options="[
19+
<div><img src="../../assets/search.png" class="w-20 mb-4 mx-auto"></div>
20+
<div>
21+
<FilterSlider
22+
v-bind:min="sliders.age.min"
23+
v-bind:max="sliders.age.max"
24+
v-bind:name="'age'"
25+
v-on:save-filter="saveFilter"></FilterSlider>
26+
<FilterSlider
27+
v-bind:min="1"
28+
v-bind:max="2000"
29+
v-bind:unit="'km'"
30+
v-bind:oneHandle="true"
31+
v-bind:name="'distance'"
32+
v-on:save-filter="saveFilter"></FilterSlider>
33+
<FilterSlider
34+
v-bind:min="sliders.popularity.min"
35+
v-bind:max="sliders.popularity.max"
36+
v-bind:unit="'pts'"
37+
v-bind:name="'popularity'"
38+
v-on:save-filter="saveFilter"></FilterSlider>
39+
</div>
40+
<div>
41+
<MultipleFilters
42+
v-bind:options="[
4043
'swimming', 'wine', 'reading', 'foodie', 'netflix', 'music', 'yoga', 'golf',
4144
'photography', 'baking', 'shopping', 'outdoors', 'art', 'travel', 'hiking',
4245
'running', 'volunteering', 'cycling', 'climbing', 'tea', 'fishing', 'soccer',
@@ -47,14 +50,17 @@
4750
'language exchange', 'sports', 'comedy', 'fashion', 'disney', 'vlogging',
4851
'astrology', 'board games', 'craft beer', 'coffee', 'writer',
4952
]"
50-
v-bind:name="'interests'"
51-
v-bind:info="'If no selected, all are accounted.'"
52-
v-on:save-filter-multiple="saveFilterMultiple"></MultipleFilters>
53-
</div>
53+
v-bind:name="'interests'"
54+
v-bind:info="'If no selected, all are accounted.'"
55+
v-on:save-filter-multiple="saveFilterMultiple"></MultipleFilters>
56+
</div>
5457
<div class="auth-sub-container-error mx-auto max-w-md" v-if="error"><h1 class="auth-sub-container-error-message">{{ error }}</h1></div>
5558
<div class="mx-auto w-full max-w-md">
56-
<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">
59+
<h1 v-if="!submitted" 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">
5760
Search</h1>
61+
<div v-else class="flex items-center justify-center mt-4">
62+
<img class="h-12" src="../../assets/loading.svg">
63+
</div>
5864
</div>
5965
</section>
6066
</div>
@@ -103,6 +109,7 @@ export default {
103109
},
104110
recommendationsAnalysisDone: false,
105111
error: null,
112+
submitted: false,
106113
}),
107114
methods: {
108115
saveFilter(...range) {
@@ -122,15 +129,21 @@ export default {
122129
const sliderRangesRequest = await this.$http.get('/search/values');
123130
const values = sliderRangesRequest.data.search_minmax;
124131
this.sliders.age.min = values.min_age;
132+
this.filters.age.min = values.min_age;
125133
if (this.sliders.age.min < 18) {
126134
this.sliders.age.min = 18;
135+
this.filters.age.min = 18;
127136
}
128137
this.sliders.age.max = values.max_age;
138+
this.filters.age.max = values.max_age;
129139
this.sliders.popularity.min = values.min_score;
140+
this.filters.popularity.min = values.min_score;
130141
this.sliders.popularity.max = values.max_score;
142+
this.filters.popularity.max = values.max_score;
131143
this.sliderValuesFetched = true;
132144
},
133145
async search() {
146+
this.submitted = true;
134147
const searchRequest = await this.$http.post('/search', {
135148
min_age: this.filters.age.min,
136149
max_age: this.filters.age.max,
@@ -154,6 +167,7 @@ export default {
154167
}
155168
this.recommendations = searchRequest.data.search_results;
156169
if (this.recommendations.length === 0) {
170+
this.submitted = false;
157171
this.setError('0 profiles found. Please, try expanding your search criteria.');
158172
return;
159173
}
@@ -169,6 +183,7 @@ export default {
169183
this.recommendations[i].interests.push(interests[j].name);
170184
}
171185
}
186+
this.submitted = false;
172187
this.recommendationsAnalysisDone = true;
173188
this.scrollToTop();
174189
},

frontend/src/views/app/Settings.vue

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
<template>
22
<!-- eslint-disable max-len -->
33
<div class="w-full md:w-auto md:mx-16 lg:mx-32 relative md:flex items-start h-auto md:mb-16">
4-
<section class="w-auto md:max-w-xss md:shadow-md md:rounded-md">
4+
<div v-if="!settingsFetched" class="mx-auto flex items-center justify-center mt-32">
5+
<img class="h-36" src="../../assets/loading.svg">
6+
</div>
7+
<section v-if="settingsFetched" class="w-auto md:max-w-xss md:shadow-md md:rounded-md">
58
<div class="w-full md:hidden h-1 bg-white-matcha"></div>
69
<div class="md:border-b profile-card text-wrap p-16 md:py-8 flex flex-col w-full md:rounded-t-md">
710
<div class="mx-auto overflow-hidden w-48 h-48 md:w-24 md:h-24 rounded-full">
@@ -26,7 +29,7 @@
2629
<MenuButton v-on:click.native="showSetting('profile')" v-bind:class="{'md:px-8':true, 'md:bg-purple-200': getShow === 'profile'}" v-bind:text="'Profile'"></MenuButton>
2730
</div>
2831
</section>
29-
<section v-if="getShow === 'account'" class="flex flex-col items-center z-10 absolute bg-white-matcha px-8 md:pb-8 w-full top-0 left-0 h-full md:h-auto md:ml-4 md:relative md:shadow-md md:rounded-md">
32+
<section v-if="getShow === 'account' && settingsFetched" class="flex flex-col items-center z-10 absolute bg-white-matcha px-8 md:pb-8 w-full top-0 left-0 h-full md:h-auto md:ml-4 md:relative md:shadow-md md:rounded-md">
3033
<SectionHeader v-bind:name="'account'" v-on:click.native="closeSetting()"></SectionHeader>
3134
<AccountInput
3235
v-bind:name="'First Name'"
@@ -49,7 +52,7 @@
4952
v-bind:type="'password'"
5053
v-bind:currentValuePassed="''"></AccountInput>
5154
</section>
52-
<section v-if="getShow === 'profile'" class="flex flex-col items-start z-10 absolute bg-white-matcha w-full top-0 left-0 md:ml-4 md:relative md:shadow-md md:rounded-md">
55+
<section v-if="getShow === 'profile' && settingsFetched" class="flex flex-col items-start z-10 absolute bg-white-matcha w-full top-0 left-0 md:ml-4 md:relative md:shadow-md md:rounded-md">
5356
<div class="px-8 w-full">
5457
<SectionHeader class="mx-auto" v-bind:name="'profile'" v-on:click.native="closeSetting()"></SectionHeader>
5558
</div>
@@ -104,18 +107,24 @@
104107
<div class="text-center px-8 py-8 border-t border-gray-300 w-full">
105108
<h1 class="inline-block mr-3 font-bold text-gray-matcha leading-none">Location</h1>
106109
<h1 class="text-md font-normal opacity-50 text-gray-matcha mx-auto pb-2 max-w-sm">If you refused sharing location, it will be approximated from your computer address </h1>
107-
<h1 v-if="!locationUpdateSuccess" class="mx-auto onboarding-sub-container-content-button-outline max-w-sm border font-normal mt-2 px-2 cursor-pointer" v-on:click="updateLocation()">Update current location</h1>
108-
<h1 v-else class="mx-auto onboarding-sub-container-content-button-outline max-w-sm border font-normal mt-2 px-2 cursor-pointer text-green-500">Success</h1>
110+
<h1 v-if="!locationUpdateSuccess && !fetching" class="mx-auto onboarding-sub-container-content-button-outline max-w-sm border font-normal mt-2 px-2 cursor-pointer" v-on:click="updateLocation()">Update current location</h1>
111+
<h1 v-if="locationUpdateSuccess && !fetching" class="mx-auto onboarding-sub-container-content-button-outline max-w-sm border font-normal mt-2 px-2 cursor-pointer text-green-500">Success</h1>
112+
<div v-if="fetching" class="mx-auto flex items-center justify-center mt-4">
113+
<img class="h-12" src="../../assets/loading.svg">
114+
</div>
109115
</div>
110116
<div class="text-center py-8 w-full px-8 border-t border-gray-300">
111117
<h1 class="font-bold text-gray-matcha">Images<span class="text-md font-normal ml-2 opacity-50 text-gray-matcha">{{this.$store.getters.getLoggedInUser.images.length}} / 5</span></h1>
112118
<div class="auth-sub-container-error mt-8" v-if="image.error">
113119
<h1 class="auth-sub-container-error-message">{{image.error}}</h1>
114120
</div>
115-
<button v-if="this.$store.getters.getLoggedInUser.images.length < 6" class="overflow-hidden relative onboarding-sub-container-content-button-outline border w-full max-w-sm my-4">
121+
<button v-if="this.$store.getters.getLoggedInUser.images.length < 5 && !fetchingImages" class="overflow-hidden relative onboarding-sub-container-content-button-outline border w-full max-w-sm my-4">
116122
<input style="padding-left: 100%;" class="cursor-pointer opacity-0 absolute top-0 left-0 w-full h-full rounded-md" type="file" v-on:change="selectFile()" ref="file">
117123
<img src="../../assets/onboarding/cloudPurple.png" class="w-8 mx-auto">
118124
</button>
125+
<div v-if="fetchingImages" class="mx-auto flex items-center justify-center mt-4">
126+
<img class="h-12" src="../../assets/loading.svg">
127+
</div>
119128
<ProfileImage
120129
v-for="image in this.$store.getters.getLoggedInUser.images"
121130
:key="image.id"
@@ -157,6 +166,9 @@ export default {
157166
error: null,
158167
},
159168
locationUpdateSuccess: false,
169+
settingsFetched: false,
170+
fetching: false,
171+
fetchingImages: false,
160172
}),
161173
computed: {
162174
getShow() {
@@ -165,6 +177,7 @@ export default {
165177
},
166178
methods: {
167179
async updateLocation() {
180+
this.fetching = true;
168181
navigator.geolocation.getCurrentPosition(
169182
this.locationAllowed,
170183
this.locationDenied,
@@ -176,6 +189,7 @@ export default {
176189
const { longitude } = position.coords;
177190
const locationData = { lat: latitude, lng: longitude, ip: '0.0.0.0' };
178191
await this.$http.put('/profile/edit/geolocation', locationData);
192+
this.fetching = false;
179193
this.locationUpdateSuccess = true;
180194
setTimeout(() => {
181195
this.locationUpdateSuccess = false;
@@ -187,13 +201,15 @@ export default {
187201
const { ip } = ipRequest;
188202
const locationData = { ip };
189203
await this.$http.put('/profile/edit/geolocation', locationData);
204+
this.fetching = false;
190205
this.locationUpdateSuccess = true;
191206
setTimeout(() => {
192207
this.locationUpdateSuccess = false;
193208
}, 3000);
194209
},
195210
async selectFile() {
196211
this.image.error = '';
212+
this.fetchingImages = true;
197213
const allowedTypes = ['image/jpeg', 'image/png', 'image/gif'];
198214
const file = this.$refs.file.files[0];
199215
@@ -214,6 +230,7 @@ export default {
214230
}
215231
const user = await this.$http.get(`/users/${this.$store.getters.getLoggedInUser.id}`);
216232
await this.$store.dispatch('login', user.data);
233+
this.fetchingImages = false;
217234
},
218235
async deleteImage(...args) {
219236
const [imageId] = args;
@@ -288,6 +305,7 @@ export default {
288305
}
289306
const userViewsReceivedRequest = await this.$http.get('/history/viewed/me');
290307
this.userViewsReceived = userViewsReceivedRequest.data.viewed_me.length;
308+
this.settingsFetched = true;
291309
},
292310
};
293311
</script>

frontend/src/views/auth/ForgotPassword.vue

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,17 @@
1010
<h1 class="auth-sub-container-content-heading">Forgot password?</h1>
1111
<h1 class="text-sm text-gray-matcha text-center">Enter your email and we will send you a link, so you can log in again</h1>
1212
</div>
13-
<div class="auth-sub-container-content mt-4" v-if="!forgotPasswordEmailSent">
14-
<ValidationObserver v-slot="{ handleSubmit, invalid }">
13+
<div class="auth-sub-container-content mt-4 w-full" v-if="!forgotPasswordEmailSent">
14+
<ValidationObserver v-slot="{ handleSubmit, invalid }" class="w-full">
1515
<form @submit.prevent="handleSubmit(onSubmit)">
1616
<ValidationProvider name="Email" rules="required|email|max:50" v-slot="{errors}">
1717
<input type="email" placeholder="Email" v-model="formData.email" class="matcha-input">
1818
<span class="matcha-input-error">{{ errors[0] }}</span>
1919
</ValidationProvider>
20-
<input type="submit" :disabled="invalid" value="Send reset link" v-bind:class="{'auth-sub-container-content-submit-button': true, 'opacity-50': invalid, 'cursor-pointer': !invalid}">
20+
<input v-if="!submitted" type="submit" :disabled="invalid" value="Send reset link" v-bind:class="{'auth-sub-container-content-submit-button': true, 'opacity-50': invalid, 'cursor-pointer': !invalid}">
21+
<div v-else class="flex items-center justify-center mt-4">
22+
<img class="h-12" src="../../assets/loading.svg">
23+
</div>
2124
</form>
2225
</ValidationObserver>
2326
</div>
@@ -47,15 +50,19 @@ export default {
4750
happened: false,
4851
message: '',
4952
},
53+
submitted: false,
5054
}),
5155
methods: {
5256
async onSubmit() {
5357
try {
58+
this.submitted = true;
5459
this.clearError();
5560
await this.sendResetPasswordLink();
5661
this.forgotPasswordEmailSent = true;
62+
this.submitted = false;
5763
} catch (error) {
5864
this.displayError(this.$errorMessenger(error));
65+
this.submitted = false;
5966
}
6067
},
6168
async sendResetPasswordLink() {

0 commit comments

Comments
 (0)