survey changes

This commit is contained in:
supertiger1234 2019-08-03 11:27:36 +01:00
parent d1b68fc47d
commit 124e9a7f22
7 changed files with 377 additions and 127 deletions

View file

@ -97,7 +97,7 @@ export default {
left: 0;
right: 0;
background: rgba(0, 0, 0, 0.781);
z-index: 111111;
z-index: 11111111133451111;
display: flex;
}
.inner {

View file

@ -2,22 +2,30 @@
<div class="drop-down">
<div class="title">{{name}}</div>
<div class="current-select-box" ref="dropDown" @click="dropped = !dropped">
<div class="name" v-if="noneSelect && selectedItem || !noneSelect">{{selectedItem ? selectedItem.name : items[0].name}}</div>
<div class="name" v-if="noneSelect && selectedItem || !noneSelect">
<div class="emoji" v-if="selectedItemSorted.emoji || items[0].emoji" v-html="selectedItem ? selectedItemSorted.emoji : items[0].emoji"></div>
<div class="item-name">{{selectedItem ? selectedItemSorted.name : items[0].name}}</div>
</div>
<div class="name" v-if="noneSelect && !selectedItem">Select</div>
<div class="material-icons">expand_more</div>
</div>
<div class="drop" v-if="dropped">
<div class="drop-container">
<div v-for="(item, index) of items" :key="index" class="item" :class="{selected: selectedItem === item}" @click="itemClick(item)">{{item.name}}</div>
<div v-for="(item, index) of itemEmojified" :key="index" class="item" :class="{selected: selectedItemSorted === item}" @click="itemClick(item)">
<div class="emoji" v-if="item.emoji" v-html="item.emoji"></div>
<div class="name">{{item.name}}</div>
</div>
</div>
</div>
</div>
</template>
<script>
import emojiParser from "@/utils/emojiParser.js";
export default {
props: ['items', 'name', 'selectedItem', 'noneSelect'], // noneSelect: by default, nothing will be selected.
props: ['items', 'name', 'selectedItem', 'noneSelect', 'selectBy'], // noneSelect: by default, nothing will be selected.
data() {
return {
dropped: false
@ -33,13 +41,36 @@ export default {
if (((el !== target) && !el.contains(target)) && this.dropped) {
this.dropped = false;
}
}
},
},
created() {
document.addEventListener('click', this.documentClick);
},
destroyed() {
document.removeEventListener('click', this.documentClick);
},
computed: {
selectedItemSorted() {
let item = null;
if (this.selectBy){
item = this.items.find(i => i[this.selectBy] === this.selectedItem);
} else {
item = this.selectedItem
}
if (item && item.emoji && !item.emoji.startsWith('<img')) {
item.emoji = emojiParser.replaceEmojis(item.emoji)
}
return item
},
itemEmojified(){
return this.items.map(i => {
if (i && i.emoji && !i.emoji.startsWith('<img')) {
i.emoji = emojiParser.replaceEmojis(i.emoji)
}
return i
})
}
}
}
</script>
@ -73,6 +104,10 @@ export default {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
display: flex;
}
.current-select-box .emoji{
margin-right: 5px;
}
.current-select-box .name {
margin: auto;
@ -107,7 +142,15 @@ export default {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
display: flex;
}
.item div {
align-self: center;
}
.item .emoji {
margin-right: 5px;
}
.item:hover {
background: rgb(46, 46, 46);
}
@ -119,3 +162,13 @@ export default {
}
</style>
<style>
.item .emoji img {
width: 20px;
height: 20px;
}
.current-select-box .emoji img {
width: 20px;
height: 20px;
}
</style>

View file

@ -1,38 +1,41 @@
<template>
<div class="survey" >
<div class="title"><i class="material-icons">error</i>Take Survey</div>
<div class="notice">Note: Everyone will be able to see your survey in your profile.</div>
<div class="survey-inner">
<div class="survey-content">
<div class="left">
<!-- name -->
<div class="input">
<div class="input-title">Name</div>
<input type="text" placeholder="Name">
<div class="survey">
<div class="inner-content">
<div class="title"><i class="material-icons">error</i>Take Survey</div>
<div class="notice">Note: Everyone will be able to see your survey in your profile.</div>
<spinner v-if="!loaded"/>
<div class="survey-inner" v-if="loaded">
<div class="survey-content">
<div class="left">
<!-- name -->
<div class="input">
<div class="input-title">Name</div>
<input type="text" placeholder="Name" v-model="items.name">
</div>
<!-- Gender -->
<drop-down class="dropdown" :items="surveyItems.gender" selectBy="name" :selectedItem="items.gender" :noneSelect="true" name="Gender" @change="changeEvent('gender', $event)"/>
<!-- Age -->
<drop-down class="dropdown" :items="surveyItems.age" selectBy="name" :selectedItem="items.age" :noneSelect="true" name="Age" @change="changeEvent('age', $event)"/>
</div>
<div class="right">
<!-- Continent -->
<drop-down class="dropdown" :items="surveyItems.continents" selectBy="name" :selectedItem="items.continent" :noneSelect="true" name="Continent" @change="changeEvent('continent', $event)"/>
<!-- Countries -->
<drop-down class="dropdown" v-if="filterCountries" :items="filterCountries" selectBy="name" :selectedItem="items.country" :noneSelect="true" name="Country" @change="changeEvent('country', $event)"/>
<!-- About me -->
<div class="input">
<div class="input-title">About me</div>
<textarea placeholder="I like cats and dogs." v-model="items.about_me" />
</div>
</div>
<!-- Gender -->
<drop-down class="dropdown" :items="surveyItems.gender" :noneSelect="true" name="Gender"/>
<!-- Age -->
<drop-down class="dropdown" :items="surveyItems.age" :noneSelect="true" name="Age"/>
</div>
<div class="right">
<!-- Continent -->
<drop-down class="dropdown" :items="surveyItems.continents" :noneSelect="true" name="Continent"/>
<!-- Countries -->
<drop-down class="dropdown" :items="surveyItems.countries" :noneSelect="true" name="Country"/>
<!-- About me -->
<div class="input">
<div class="input-title">About me</div>
<textarea placeholder="I like cats and dogs." />
</div>
</div>
<div class="survey-warning" v-if="surveyErrorMessage">{{ surveyErrorMessage }}</div>
<div class="survey-valid" v-if="surveyValidMessage">{{ surveyValidMessage }}</div>
</div>
<div class="survey-warning" v-if="surveyErrorMessage">{{ surveyErrorMessage }}</div>
<div class="survey-valid" v-if="surveyValidMessage">{{ surveyValidMessage }}</div>
<div class="button" @click="surveySubmitButton">Save</div>
</div>
<div class="button" v-if="loaded" @click="surveySubmitButton">Save</div>
</div>
</template>
@ -40,22 +43,20 @@
import DropDown from './../ServerSettingsPanels/DropDownMenu';
import surveyItems from "@/utils/surveyItems.js";
import userService from "@/services/userService.js";
import Spinner from '@/components/Spinner';
export default {
components: { DropDown },
components: { DropDown, Spinner },
data() {
return {
surveyItems: surveyItems,
surveyErrorMessage: null,
surveyValidMessage: null,
loaded: false,
items: {
about_me: null,
name: null,
},
// selected: {
// name: "",
// gender: null,
// age: null,
// continent: null,
// country: null,
// about_me: ""
// }
};
},
computed: {
@ -63,67 +64,57 @@ export default {
},
async mounted() {
const { ok, error, result } = await userService.getSurvey();
if (ok) {
if (!ok) {
if (error.response === undefined) {
return;
}
this.loaded = true;
return;
}
this.previousLoaded = true;
this.$set(this, 'items', Object.assign({}, this.items, result.data.result))
this.loaded = true;
},
methods: {
changeEvent(name, item) {
if (name === 'continent'){
this.$set(this.items, 'country', null)
}
this.$set(this.items, name, item.name);
},
async surveySubmitButton() {
this.surveyValidMessage = null;
this.surveyErrorMessage = null;
//checks if all drop boxes are not null.
for (let item in this.selected) {
if (this.selected[item] === null && item !== "country") {
this.surveyErrorMessage =
"Make sure you select / fill in all fields!";
return;
}
}
//checks if all values are not null
if (
this.selected.name.trim() === "" ||
this.selected.about_me.trim() === ""
) {
this.surveyErrorMessage = "Make sure you select / fill in all fields!";
return;
}
this.surveyValidMessage = "Saving...";
//gets the country index after unfiltering.
let countryIndex = undefined;
if (this.filterCountry[this.selected.country]) {
const selectedCountryName = this.filterCountry[this.selected.country]
.name;
countryIndex = this.surveyItems.countries.findIndex(
el => el.name == selectedCountryName
);
}
if (this.selected.name && this.selected.name.length > 100) {
if (this.items.name && this.items.name.length > 100) {
this.surveyErrorMessage = "Name must be less that 100 characters.";
this.surveyValidMessage = null;
return;
}
if (this.selected.about_me && this.selected.about_me.length > 500) {
if (this.items.about_me && this.items.about_me.length > 500) {
this.surveyErrorMessage = "About me must be less that 500 characters.";
this.surveyValidMessage = null;
return;
}
const { ok, error, result } = await userService.setSurvey({
name: this.selected.name,
gender: this.selected.gender,
age: this.selected.age,
continent: this.selected.continent,
country: countryIndex,
about_me: this.selected.about_me
});
const { ok, error, result } = await userService.setSurvey(this.items);
if (ok) {
this.surveyValidMessage = "Saved!";
} else {
this.surveyValidMessage = null;
this.surveyErrorMessage = error.response.data.message;
this.surveyErrorMessage = error.response.data.message || error.response.data;
}
}
},
computed: {
filterCountries(){
if (!this.items.continent || this.items.continent === "Rather not say") return null;
const continent = this.surveyItems.continents.find(c => c.name === this.items.continent);
if (!continent) return null;
return [...this.surveyItems.countries.filter(c => c.code === continent.code), ...[{emoji: "😶",name: 'Rather not say', code: 'no'}]];
}
}
};
</script>
@ -132,7 +123,7 @@ export default {
.notice {
color: grey;
font-size: 15px;
margin-top: 20px;
margin-top: 10px;
margin-left: 30px;
user-select: none;
}
@ -144,7 +135,6 @@ export default {
.survey {
height: 100%;
overflow: auto;
align-items: center;
width: 100%;
}
@ -159,6 +149,12 @@ export default {
height: 100%;
}
.inner-content {
display: flex;
flex-direction: column;
overflow: auto;
width: 100%;
}
.survey-content {
display: flex;
@ -207,7 +203,7 @@ export default {
.title {
margin-top: 30px;
margin-top: 20px;
display: flex;
align-content: center;
align-items: center;
@ -253,4 +249,10 @@ textarea {
textarea:hover {
background: rgba(0, 0, 0, 0.401);
}
@media (max-width: 764px) {
.survey-content{
flex-direction: column;
}
}
</style>

View file

@ -15,15 +15,35 @@
<div class="uesrname-tag">
<div class="username">{{user.username}}</div>
<div class="tag">#{{user.tag}}</div>
</div>
<div class="actions" v-if="uniqueID !== selfUniqueID">
<div class="action-buttons">
<div class="button" v-if="this.relationshipStatus === null" @click="AddFriendButton"><div class="material-icons">person_add</div><div>Add Friend</div></div>
<div class="button" v-if="this.relationshipStatus === 0" @click="RemoveFriendButton"><div class="material-icons">hourglass_empty</div><div>Request Sent</div></div>
<div class="button green" v-if="this.relationshipStatus === 1" @click="AcceptFriendButton"><div class="material-icons">check</div><div>Accept Friend</div></div>
<div class="button" v-if="this.relationshipStatus === 2" @click="openChat"><div class="material-icons">message</div><div>Message</div></div>
<div class="button warn" v-if="this.relationshipStatus === 2" @click="RemoveFriendButton"><div class="material-icons">person_add_disabled</div><div>Remove Friend</div></div>
<div class="button warn"><div class="material-icons">block</div><div>Block</div></div>
</div>
</div>
<div class="button" v-if="uniqueID !== selfUniqueID">Add Friend</div>
</div>
<div class="badges" v-if="user.badges && filteredBadges.length">
<div class="title">Badges</div>
<div class="badges-list">
<div class="badge" v-for="(badge, index) of filteredBadges" v-bind:style="{ 'border-color': badges[badge].color }" :key="index">
<img class="icon" :src="badges[badge].icon"/>
<div class="name">{{badges[badge].name}}</div>
<div class="scrollable">
<div class="badges" v-if="user.badges && filteredBadges.length">
<div class="title">Badges</div>
<div class="badges-list">
<div class="badge" v-for="(badge, index) of filteredBadges" v-bind:style="{ 'border-color': badges[badge].color }" :key="index">
<img class="icon" :src="badges[badge].icon"/>
<div class="name">{{badges[badge].name}}</div>
</div>
</div>
</div>
<div class="about-me" v-if="aboutMe">
<div class="title">About Me</div>
<div class="about-item" v-for="(aboutItem) of aboutMe" :key="aboutItem.name" :class="{infoAboutMe: aboutItem.key === 'About me'}">
<div class="key">{{aboutItem.key}}: </div>
<div class="emoji" v-if="aboutItem.emoji" v-html="aboutItem.emoji"></div>
<div class="name" v-if="aboutItem.key === 'About me'" v-html="formatAboutMe(aboutItem.name)"></div>
<div class="name" v-else>{{aboutItem.name}}</div>
</div>
</div>
</div>
@ -53,30 +73,6 @@ export default {
badges
};
},
computed: {
filteredBadges() {
if (!this.user.badges) return;
return this.user.badges.filter(b => this.badges[b])
},
selfUniqueID() {
return this.$store.getters.user.uniqueID;
},
uniqueID() {
return this.$store.getters.popouts.userInformationPopoutID;
},
relationshipStatus() {
const userUniqueID = this.$store.getters.popouts.userInformationPopoutID;
const allFriend = this.$store.getters.user.friends;
if (!allFriend[userUniqueID]) return null;
return allFriend[userUniqueID].status;
}
},
async mounted() {
const { ok, error, result } = await userService.get(this.uniqueID);
if (ok) {
this.user = result.data.user;
}
},
methods: {
backgroundClickEvent(event) {
if (event.target.classList.contains("drop-background")) {
@ -112,8 +108,55 @@ export default {
},
formatAboutMe(string) {
return messageFormatter(string);
},
capitalize(s){
if (typeof s !== 'string') return ''
return s.charAt(0).toUpperCase() + s.slice(1)
}
},
async mounted() {
const { ok, error, result } = await userService.get(this.uniqueID);
if (ok) {
this.user = result.data.user;
}
},
computed: {
aboutMe(){
const about_me = this.user.about_me
if (!about_me) return null;
if (about_me._id) delete about_me._id;
const arr = [];
for (let index in about_me) {
console.log(index)
const item = {key: this.capitalize(index.replace('_', " ")), name: about_me[index]};
if (item.name && item.name.length && item.name !== "Rather not say"){
if (surveyItems.constants[index]){
const i = surveyItems[surveyItems.constants[index]].find(i => i.name === item.name);
item.emoji = i ? this.emojiParse(i.emoji) : undefined;
}
arr.push(item)
}
}
return arr
},
filteredBadges() {
if (!this.user.badges) return;
return this.user.badges.filter(b => this.badges[b])
},
selfUniqueID() {
return this.$store.getters.user.uniqueID;
},
uniqueID() {
return this.$store.getters.popouts.userInformationPopoutID;
},
relationshipStatus() {
const userUniqueID = this.$store.getters.popouts.userInformationPopoutID;
const allFriend = this.$store.getters.user.friends;
if (!allFriend[userUniqueID]) return null;
return allFriend[userUniqueID].status;
}
},
};
</script>
<style scoped>
@ -137,8 +180,7 @@ export default {
color: white;
display: flex;
flex-direction: row;
overflow: auto;
background: rgba(0, 0, 0, 0.553);
background: rgba(22, 22, 22, 0.853);
border-radius: 10px;
}
@ -152,7 +194,18 @@ export default {
width: 100%;
align-items: center;
padding: 10px;
padding-top: 30px;
overflow: auto;
}
.scrollable {
margin-top: 5px;
display: flex;
flex-direction: column;
width: 100%;
align-items: center;
overflow: auto;
}
.scrollable::-webkit-scrollbar {
width: 3px;
}
.profile {
display: flex;
@ -163,6 +216,10 @@ export default {
align-items: center;
align-content: center;
padding-bottom: 10px;
flex-shrink: 0;
background: rgba(41, 41, 41, 0.697);
padding-top: 30px;
border-radius: 5px;
}
.uesrname-tag {
@ -179,30 +236,65 @@ export default {
}
.button {
background: rgb(23, 151, 255);
padding: 8px;
padding: 8px;
align-self: center;
border-radius: 5px;
user-select: none;
cursor: default;
transition: 0.3s;
position: relative;
z-index: 1;
cursor: pointer;
}
.button::after{
content: '';
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
background: rgb(51, 163, 255);
z-index: -1;
border-radius: 5px;
opacity: 0.8;
transition: 0.3s;
}
.button.green::after {
background: rgb(0, 200, 84);
}
.button:hover::after {
opacity: 1;
}
.badges{
display: flex;
flex-direction: column;
width: 100%;
margin-top: 10px;
margin-top: 3px;
border-bottom: solid 1px rgba(255, 255, 255, 0.733);
padding-bottom: 10px;
user-select: none;
cursor: default;
flex-shrink: 0
}
.badges .title {
.actions {
display: flex;
flex-direction: column;
width: 100%;
margin-top: 10px;
user-select: none;
cursor: default;
flex-shrink: 0
}
.title {
font-size: 20px;
margin-bottom: 3px;
}
.badges-list{
display: flex;
margin-top: 5px;
flex-wrap: wrap;
flex-shrink: 0
}
.badge {
border: solid 1px white;
@ -210,6 +302,7 @@ export default {
border-radius: 5px;
margin: 3px;
display: flex;
flex-shrink: 0
}
.badge div {
@ -222,7 +315,89 @@ export default {
width: 20px;
}
@media (max-width: 815px) {
.about-me{
display: flex;
flex-direction: column;
width: 100%;
margin-top: 10px;
margin-bottom: 5px;
border-bottom: solid 1px rgba(255, 255, 255, 0.733);
padding-bottom: 10px;
cursor: default;
flex-shrink: 0
}
</style>
.about-item{
display: flex;
align-items: center;
background: rgba(47, 47, 47, 0.37);
margin: 2px;
border-radius: 5px;
padding: 10px;
flex-shrink: 0
}
.about-item .key {
color: rgb(0, 153, 255);
}
.about-item .name {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.about-item div {
align-self: center;
margin-right: 5px;
}
.infoAboutMe {
height: initial;
flex-direction: column;
}
.infoAboutMe .key {
align-self: flex-start;
margin-bottom: 5px;
}
.infoAboutMe .name {
align-self: center;
width: 100%;
word-wrap: break-word;
word-break: break-word;
white-space: pre-wrap;
text-overflow: none;
margin-right: 0;
}
.action-buttons {
display: flex;
align-self: center;
}
.action-buttons .button {
font-size: 12px;
text-align: center;
margin: 2px;
display: flex;
flex-direction: row;
}
.action-buttons .button .material-icons {
margin-right: 5px;
font-size: 18px;
}
.action-buttons .button div {
align-self: center;
}
.action-buttons .button.warn::after {
background: rgb(255, 53, 53);
border-radius: 5px;
}
@media (max-width: 352px) {
.box {
width: 100%;
}
}
</style>
<style>
.emoji img {
height: 20px;
width: 20px;
}
</style>

View file

@ -108,6 +108,7 @@ export default {
<style scoped>
.username{
width: 201px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}

View file

@ -14,6 +14,18 @@
const config = [
{
version: 5.6,
title: "Redesigned survey + user pop-out",
shortTitle: "",
date: "03/08/2019",
headColor: "rgba(79, 98, 255, 0.77)",
new: [
"Re-coded the survey. Note: since the survey is recoded, you will need to reselect some of the options.",
"Remove '13 or under' option in the survey.",
"Redesigned user information pop-out which now shows the badges for developer, creator and more."
],
},
{
version: 5.6,
title: "Bug fixes and redesigns",

View file

@ -1,4 +1,11 @@
export default {
constants: {
gender: 'gender',
age: 'age',
continent: 'continents',
country: 'countries'
},
gender: [
{ emoji: "👦🏻", name: "Male", code:"M" },
{ emoji: "👧🏼", name: "Female", code:"F"},