Skip to content

Commit 7724d00

Browse files
committed
image upload, location update
1 parent 81cae36 commit 7724d00

File tree

1 file changed

+132
-42
lines changed

1 file changed

+132
-42
lines changed

frontend/src/views/app/Settings.vue

Lines changed: 132 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<div class="w-full md:w-auto md:mx-16 lg:mx-32 relative md:flex items-start h-auto md:mb-16 lg:mb-32">
66
<section class="w-full md:max-w-xs md:shadow-md md:rounded-md">
77
<div class="w-full md:hidden h-1 bg-white-matcha"></div>
8-
<div class="text-wrap bg-white-matcha recommendation-card w-full sm:rounded-md"
8+
<div class="text-wrap bg-white-matcha recommendation-card w-full sm:rounded-t-md"
99
v-bind:style="{
1010
'background-repeat': 'no-repeat',
1111
'background-position': 'center center',
@@ -14,7 +14,7 @@
1414
<!-- <h1 class="absolute bottom-0 w-full text-center pb-8 text-4xl text-white-matcha capitalize">-->
1515
<!-- {{this.$store.getters.getLoggedInUser.first_name}} {{this.$store.getters.getLoggedInUser.last_name}}</h1>-->
1616
</div>
17-
<div class="px-8 pb-2 md:pt-2 md:pt-4 md:py-0 md:px-0 w-full">
17+
<div class="px-8 pb-2 md:pt-2 md:py-4 md:py-0 md:px-0 w-full">
1818
<h1 class="text-4xl md:text-2xl md:font-bold text-gray-matcha text-center md:text-left md:px-8 font-bold md:font-normal mt-4 md:mb-1 md:mt-0">Settings</h1>
1919
<MenuButton v-on:click.native="showSetting('account')" v-bind:class="{'md:px-8':true, 'md:bg-gray-200': getShow === 'account'}" v-bind:text="'Account'"></MenuButton>
2020
<hr class="bg-gray-300 w-full md:hidden">
@@ -44,53 +44,78 @@
4444
v-bind:type="'password'"
4545
v-bind:currentValuePassed="''"></AccountInput>
4646
</section>
47-
<section v-if="getShow === 'profile'" class="profile-section flex flex-col items-start z-10 absolute bg-white-matcha px-8 pb-4 w-full top-0 left-0 h-screen md:ml-4 md:relative md:shadow-md md:rounded-md">
47+
<section v-if="getShow === 'profile'" class="overflow-scroll profile-section 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">
4848
<SectionHeader v-bind:name="'profile'" v-on:click.native="closeSetting()"></SectionHeader>
49-
<div>
50-
<h1 class="inline-block mr-4">I am</h1>
51-
<DropdownDisplayChoice
52-
class="inline-block"
53-
v-on:saveSingleChoice="saveSingleChoice"
54-
v-bind:name="'gender'"
55-
v-bind:starting-option="this.$store.getters.getLoggedInUser.gender"
56-
v-bind:options="['male', 'female', 'other']"></DropdownDisplayChoice>
49+
<div class="pb-4">
50+
<div class="px-8">
51+
<h1 class="inline-block mr-4 font-bold text-gray-matcha">I am</h1>
52+
<DropdownDisplayChoice
53+
class="inline-block"
54+
v-on:saveSingleChoice="saveSingleChoice"
55+
v-bind:name="'gender'"
56+
v-bind:starting-option="this.$store.getters.getLoggedInUser.gender"
57+
v-bind:options="['male', 'female', 'other']"></DropdownDisplayChoice>
58+
</div>
59+
<div class="px-8 mt-4">
60+
<h1 class="inline-block mr-4 font-bold text-gray-matcha">Sexuality</h1>
61+
<DropdownDisplayChoice
62+
class="inline-block"
63+
v-on:saveSingleChoice="saveSingleChoice"
64+
v-bind:name="'gender'"
65+
v-bind:starting-option="this.$store.getters.getLoggedInUser.orientation"
66+
v-bind:options="['heterosexual', 'homosexual', 'bisexual', 'other']"></DropdownDisplayChoice>
67+
</div>
68+
<div class="px-8 mt-4">
69+
<h1 class="inline-block mr-3 font-bold text-gray-matcha">Interests</h1>
70+
<DropdownDisplayChoices
71+
class="inline-block"
72+
v-bind:options="[
73+
'swimming', 'wine', 'reading', 'foodie', 'netflix', 'music', 'yoga', 'golf',
74+
'photography', 'baking', 'shopping', 'outdoors', 'art', 'travel', 'hiking',
75+
'running', 'volunteering', 'cycling', 'climbing', 'tea', 'fishing', 'soccer',
76+
'museum', 'dancing', 'surfing', 'karaoke', 'parties', 'diy',
77+
'walking', 'cat lover', 'movies', 'gardening', 'trivia', 'working out',
78+
'cooking', 'gamer', 'brunch', 'blogging', 'picknicking', 'athlete',
79+
'dog lover', 'politics', 'environmentalism', 'instagram', 'spirituality',
80+
'language exchange', 'sports', 'comedy', 'fashion', 'disney', 'vlogging',
81+
'astrology', 'board games', 'craft beer', 'coffee', 'writer',
82+
]"
83+
v-bind:startingOptions="userInterests"
84+
v-bind:min="3"
85+
v-bind:max="10"
86+
v-bind:name="'interests'"
87+
v-on:saveMultipleChoice="saveMultipleChoice"></DropdownDisplayChoices>
88+
</div>
5789
</div>
58-
<div class="mt-4">
59-
<h1 class="inline-block mr-4">Sexuality</h1>
60-
<DropdownDisplayChoice
61-
class="inline-block"
62-
v-on:saveSingleChoice="saveSingleChoice"
63-
v-bind:name="'gender'"
64-
v-bind:starting-option="this.$store.getters.getLoggedInUser.orientation"
65-
v-bind:options="['heterosexual', 'homosexual', 'bisexual', 'other']"></DropdownDisplayChoice>
66-
</div>
67-
<div class="mt-4">
68-
<h1 class="inline-block mr-3">Interests</h1>
69-
<DropdownDisplayChoices
70-
class="inline-block"
71-
v-bind:options="[
72-
'swimming', 'wine', 'reading', 'foodie', 'netflix', 'music', 'yoga', 'golf',
73-
'photography', 'baking', 'shopping', 'outdoors', 'art', 'travel', 'hiking',
74-
'running', 'volunteering', 'cycling', 'climbing', 'tea', 'fishing', 'soccer',
75-
'museum', 'dancing', 'surfing', 'karaoke', 'parties', 'diy',
76-
'walking', 'cat lover', 'movies', 'gardening', 'trivia', 'working out',
77-
'cooking', 'gamer', 'brunch', 'blogging', 'picknicking', 'athlete',
78-
'dog lover', 'politics', 'environmentalism', 'instagram', 'spirituality',
79-
'language exchange', 'sports', 'comedy', 'fashion', 'disney', 'vlogging',
80-
'astrology', 'board games', 'craft beer', 'coffee', 'writer',
81-
]"
82-
v-bind:startingOptions="userInterests"
83-
v-bind:min="3"
84-
v-bind:max="10"
85-
v-bind:name="'interests'"
86-
v-on:saveMultipleChoice="saveMultipleChoice"></DropdownDisplayChoices>
87-
</div>
88-
<div class="mt-4">
90+
<div class="py-4 px-8 border-t border-gray-300 w-full">
8991
<AccountInput
9092
v-bind:name="'Bio'"
9193
v-bind:type="'bio'"
9294
v-bind:currentValuePassed="this.$store.getters.getLoggedInUser.bio"></AccountInput>
9395
</div>
96+
<div class="py-4 px-8 border-t border-gray-300 w-full">
97+
<h1 class="inline-block mr-3 font-bold text-gray-matcha">Location</h1>
98+
<h1 class="onboarding-sub-container-content-button-outline mt-2 px-2 cursor-pointer" v-on:click="updateLocation()">Update current location</h1>
99+
</div>
100+
<div class="py-4 w-full px-8 border-t border-gray-300">
101+
<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>
102+
<div class="auth-sub-container-error mt-8" v-if="image.error">
103+
<h1 class="auth-sub-container-error-message">{{image.error}}</h1>
104+
</div>
105+
<button v-if="this.$store.getters.getLoggedInUser.images.length < 6" class="cursor-pointer relative onboarding-sub-container-upload-button w-32 my-2">
106+
<input class="cursor-pointer opacity-0 absolute top-0 left-0 w-full h-full rounded-md" type="file" v-on:change="selectFile()" ref="file">
107+
<img src="../../assets/onboarding/cloud.png" class="w-8 mx-auto">
108+
</button>
109+
<div v-for="image in this.$store.getters.getLoggedInUser.images" :key="image.id">
110+
<div class="relative overflow-hidden bg-transparent rounded-md w-full" style="padding-bottom: 70%">
111+
<img v-bind:src="image.link" class="absolute object-cover w-full h-full rounded-md">
112+
</div>
113+
<div class="flex justify-between mb-4">
114+
<h1 class="text-red-500 cursor-pointer" v-on:click="deleteImage(image.id)">Delete</h1>
115+
<h1 class="text-purple-matcha cursor-pointer" v-if="!image.is_primary" v-on:click="makePrimaryImage(image.id)">Make primary</h1>
116+
</div>
117+
</div>
118+
</div>
94119
</section>
95120
</div>
96121
</div>
@@ -120,13 +145,69 @@ export default {
120145
data: () => ({
121146
userInterests: [],
122147
show: '',
148+
image: {
149+
error: null,
150+
},
123151
}),
124152
computed: {
125153
getShow() {
126154
return this.show;
127155
},
128156
},
129157
methods: {
158+
async updateLocation() {
159+
navigator.geolocation.getCurrentPosition(
160+
this.locationAllowed,
161+
this.locationDenied,
162+
{ enableHighAccuracy: true },
163+
);
164+
},
165+
async locationAllowed(position) {
166+
const { latitude } = position.coords;
167+
const { longitude } = position.coords;
168+
const locationData = { lat: latitude, lng: longitude, ip: '0.0.0.0' };
169+
await this.$http.put('/profile/edit/geolocation', locationData);
170+
},
171+
async locationDenied() {
172+
let ipRequest = await fetch('https://api.ipify.org?format=json');
173+
ipRequest = await ipRequest.json();
174+
const { ip } = ipRequest;
175+
const locationData = { ip };
176+
await this.$http.put('/profile/edit/geolocation', locationData);
177+
},
178+
async selectFile() {
179+
this.image.error = '';
180+
const allowedTypes = ['image/jpeg', 'image/png', 'image/gif'];
181+
const file = this.$refs.file.files[0];
182+
183+
if (!allowedTypes.includes(file.type)) {
184+
this.image.error = 'Only images allowed';
185+
return;
186+
}
187+
if (file.size > 2000000) {
188+
this.image.error = 'File too large';
189+
return;
190+
}
191+
const formData = new FormData();
192+
formData.append('file[]', file);
193+
if (this.$store.getters.getLoggedInUser.images.length) {
194+
await this.$http.post('/profile/images?is_primary=false', formData);
195+
} else {
196+
await this.$http.post('/profile/images?is_primary=true', formData);
197+
}
198+
const user = await this.$http.get(`/users/${this.$store.getters.getLoggedInUser.id}`);
199+
await this.$store.dispatch('login', user.data);
200+
},
201+
async deleteImage(imageId) {
202+
await this.$http.delete(`/profile/images/${imageId}`);
203+
const user = await this.$http.get(`/users/${this.$store.getters.getLoggedInUser.id}`);
204+
await this.$store.dispatch('login', user.data);
205+
},
206+
async makePrimaryImage(imageId) {
207+
console.log(await this.$http.put(`/profile/images/${imageId}`));
208+
const user = await this.$http.get(`/users/${this.$store.getters.getLoggedInUser.id}`);
209+
await this.$store.dispatch('login', user.data);
210+
},
130211
saveSingleChoice(...args) {
131212
const [key, value] = args;
132213
if (key === 'gender') {
@@ -155,10 +236,16 @@ export default {
155236
}
156237
return imageOther;
157238
}
239+
for (let i = 0; i < this.$store.getters.getLoggedInUser.images.length; i += 1) {
240+
if (this.$store.getters.getLoggedInUser.images[i].is_primary) {
241+
return this.$store.getters.getLoggedInUser.images[i].link;
242+
}
243+
}
158244
return this.$store.getters.getLoggedInUser.images[0].link;
159245
},
160246
},
161247
beforeMount() {
248+
console.log(this.$store.getters.getLoggedInUser);
162249
const tags = this.$store.getters.getLoggedInUser.tags;
163250
for (let i = 0; i < tags.length; i += 1) {
164251
this.userInterests.push(tags[i].name);
@@ -173,4 +260,7 @@ export default {
173260
height: 20rem;
174261
/*box-shadow: inset 0 -8rem 1rem rgba(0, 0, 0, 0.3);*/
175262
}
263+
.profile-section {
264+
height: 34rem;
265+
}
176266
</style>

0 commit comments

Comments
 (0)