New client more misc (#8902)

* View party now opens member modal

* Clicking member in header opens member detail modal

* Began sticky header

* Added sleep

* Removed extra inbox and added name styles

* Lint fixes

* Added member filter

* Added task counts

* Updated quest start modal

* Updated members modal style

* Fixed editing party

* Updated tavern

* Updated my guilds

* More guild styles

* Many challenge styles and fixes

* Fixed notification menu display

* Added initial styles to groupplans

* Added syncing with inbox

* Fixed lint

* Added new edit profile layout

* Added initial achievement layout

* Began adding new stats layout

* Removed duplicate:

* fix(CI): attempt to address Travis Mongo connection issue

* fix(CI): don't strand us in Mongo shell

* Travis updates

* Try percise
This commit is contained in:
Keith Holliday
2017-07-29 16:08:36 -06:00
committed by GitHub
parent c6c0e3660b
commit c5e0bcfb0e
39 changed files with 961 additions and 856 deletions

View File

@@ -2,6 +2,7 @@ language: node_js
node_js: node_js:
- '6' - '6'
sudo: required sudo: required
dist: precise
services: services:
- mongodb - mongodb
addons: addons:
@@ -19,7 +20,7 @@ install:
before_script: before_script:
- npm run test:build - npm run test:build
- cp config.json.example config.json - cp config.json.example config.json
- if [ $REQUIRES_SERVER ]; then until nc -z localhost 27017; do echo Waiting for MongoDB; sleep 1; done; export DISPLAY=:99; fi - sleep 15
script: script:
- npm run $TEST - npm run $TEST
- if [ $COVERAGE ]; then ./node_modules/.bin/lcov-result-merger 'coverage/**/*.info' | ./node_modules/coveralls/bin/coveralls.js; fi - if [ $COVERAGE ]; then ./node_modules/.bin/lcov-result-merger 'coverage/**/*.info' | ./node_modules/coveralls/bin/coveralls.js; fi

View File

@@ -9,7 +9,8 @@
app-menu app-menu
.container-fluid .container-fluid
app-header app-header
router-view div(:class='{sticky: user.preferences.stickyHeader}')
router-view
app-footer app-footer
</template> </template>
@@ -35,6 +36,7 @@ export default {
}, },
computed: { computed: {
...mapState(['isUserLoggedIn']), ...mapState(['isUserLoggedIn']),
...mapState({user: 'user.data'}),
isStaticPage () { isStaticPage () {
return this.$route.meta.requiresLogin === false ? true : false; return this.$route.meta.requiresLogin === false ? true : false;
}, },

View File

@@ -1,13 +1,13 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="76" height="88" viewBox="0 0 76 88"> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="70" height="76" viewBox="0 0 70 76">
<defs> <defs>
<path id="a" d="M38 0L0 17.64C0 52.924 4.62 72.88 38 88c33.38-15.12 38-35.077 38-70.36L38 0z"/> <path id="a" d="M35 0L0 15.235C0 45.705 4.255 62.941 35 76c30.745-13.059 35-30.294 35-60.765L35 0z"/>
</defs> </defs>
<g fill="none" fill-rule="evenodd"> <g fill-rule="evenodd">
<g> <g>
<use fill="#C3C0C7" xlink:href="#a"/> <use fill="#C3C0C7" xlink:href="#a"/>
<path stroke="#F9F9F9" stroke-width="10" d="M36.975 5.037l4.857 2.255 13.063 6.064 13.062 6.064 3.028 1.405c-.168 17.685-1.8 28.545-5.99 37.422-4.69 9.939-12.968 17.548-26.995 24.24-14.027-6.692-22.306-14.301-26.996-24.24-4.189-8.877-5.821-19.737-5.99-37.422L38 5.513l-1.025-.476z"/> <path stroke="#F9F9F9" stroke-width="10" d="M35 5.453L5.02 18.503c.182 14.831 1.675 23.961 5.417 31.396C14.674 58.32 22.197 64.81 35 70.545 47.803 64.81 55.326 58.32 59.563 49.9c3.742-7.435 5.235-16.565 5.418-31.395l-2.445-1.065L38.473 6.965l-4.442-1.934.969.422z"/>
<path stroke="#C3C0C7" stroke-width="6" d="M37.39 3.025a191742500.733 191742500.733 0 0 1 18.347 8.517l13.062 6.064 4.196 1.947c-.102 18.718-1.747 30.131-6.19 39.548-5 10.593-13.865 18.622-28.805 25.597-14.94-6.975-23.805-15.004-28.805-25.597-4.443-9.417-6.088-20.83-6.19-39.548L38 3.308l-.61-.283z"/> <path stroke="#C3C0C7" stroke-width="6" d="M35 3.272L3.007 17.198c.111 15.9 1.621 25.609 5.643 33.6C13.205 59.848 21.31 66.734 35 72.733c13.691-6 21.795-12.885 26.35-21.935 4.022-7.991 5.532-17.7 5.643-33.6l-3.66-1.593L39.272 5.131l-4.85-2.111.579.252z"/>
</g> </g>
<path fill="#F9F9F9" d="M26 51.001V56h24v-4.999C50 46.334 42.002 44 38 44c-3.998 0-12 2.334-12 7.001zM38.009 29A6.008 6.008 0 0 0 32 35.001C32 38.312 34.692 41 38.009 41A5.99 5.99 0 0 0 44 35.001 5.991 5.991 0 0 0 38.009 29"/> <path fill="#F9F9F9" d="M27 40.667V44h16v-3.333C43 37.557 37.668 36 35 36c-2.666 0-8 1.556-8 4.667zM35.006 26A4.005 4.005 0 0 0 31 30c0 2.208 1.795 4 4.006 4A3.993 3.993 0 0 0 39 30c0-2.207-1.781-4-3.994-4"/>
</g> </g>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -1,9 +1,10 @@
<template lang="pug"> <template lang="pug">
#app-header.row #app-header.row(:class='{sticky: user.preferences.stickyHeader}')
members-modal(:group='user.party', :hide-badge="true")
member-details(:member="user", @click="$router.push({name: 'avatar'})") member-details(:member="user", @click="$router.push({name: 'avatar'})")
.view-party(v-if="user.party && user.party._id") .view-party(v-if="user.party && user.party._id")
// TODO button should open the party members modal // TODO button should open the party members modal
router-link.btn.btn-primary(:active-class="''", :to="{name: 'party'}") {{ $t('viewParty') }} button.btn.btn-primary(@click='openPartyModal()') {{ $t('viewParty') }}
.party-members.d-flex(v-if="partyMembers && partyMembers.length > 1") .party-members.d-flex(v-if="partyMembers && partyMembers.length > 1")
member-details( member-details(
v-for="(member, $index) in partyMembers", v-for="(member, $index) in partyMembers",
@@ -36,6 +37,12 @@
position: relative; position: relative;
} }
.sticky {
position: fixed !important;
width: 100%;
z-index: 1;
}
.no-party, .party-members { .no-party, .party-members {
flex-grow: 1; flex-grow: 1;
} }
@@ -77,11 +84,13 @@
import { mapGetters, mapActions } from 'client/libs/store'; import { mapGetters, mapActions } from 'client/libs/store';
import MemberDetails from './memberDetails'; import MemberDetails from './memberDetails';
import createPartyModal from './groups/createPartyModal'; import createPartyModal from './groups/createPartyModal';
import membersModal from './groups/membersModal';
export default { export default {
components: { components: {
MemberDetails, MemberDetails,
createPartyModal, createPartyModal,
membersModal,
}, },
data () { data () {
return { return {
@@ -105,6 +114,9 @@ export default {
this.expandedMember = memberId; this.expandedMember = memberId;
} }
}, },
openPartyModal () {
this.$root.$emit('show::modal', 'members-modal');
},
}, },
created () { created () {
if (this.user.party && this.user.party._id) this.getPartyMembers(); if (this.user.party && this.user.party._id) this.getPartyMembers();

View File

@@ -184,10 +184,6 @@ div
} }
} }
.item-notifications {
margin-left: 33.5px;
}
.item-user .edit-avatar { .item-user .edit-avatar {
h3 { h3 {
color: $gray-10; color: $gray-10;

View File

@@ -30,9 +30,9 @@
.col-4.sidebar.standard-page .col-4.sidebar.standard-page
.acitons .acitons
div(v-if='!isMember && !isLeader') div(v-if='!isMember && !isLeader')
button.btn.btn-success(v-once) {{$t('joinChallenge')}} button.btn.btn-success(v-once, @click='joinChallenge()') {{$t('joinChallenge')}}
div(v-if='isMember') div(v-if='isMember')
button.btn.btn-danger(v-once) {{$t('leaveChallenge')}} button.btn.btn-danger(v-once, @click='leaveChallenge()') {{$t('leaveChallenge')}}
div(v-if='isLeader') div(v-if='isLeader')
button.btn.btn-success(v-once) {{$t('addTask')}} button.btn.btn-success(v-once) {{$t('addTask')}}
div(v-if='isLeader') div(v-if='isLeader')
@@ -122,6 +122,8 @@
</style> </style>
<script> <script>
import findIndex from 'lodash/findIndex';
import { mapState } from 'client/libs/store'; import { mapState } from 'client/libs/store';
import closeChallengeModal from './closeChallengeModal'; import closeChallengeModal from './closeChallengeModal';
import Column from '../tasks/column'; import Column from '../tasks/column';
@@ -146,22 +148,7 @@ export default {
memberIcon, memberIcon,
calendarIcon, calendarIcon,
}), }),
challenge: { challenge: {},
// _id: 1,
// title: 'I am the Night! (Official TAKE THIS Challenge June 2017)',
// memberCount: 5261,
// endDate: '2017-04-04',
// tags: ['Habitica Official', 'Tag'],
// prize: 10,
// description: 'Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium.',
// counts: {
// habit: 0,
// dailies: 2,
// todos: 2,
// rewards: 0,
// },
// author: 'SabreCat',
},
}; };
}, },
computed: { computed: {
@@ -170,7 +157,8 @@ export default {
return this.user.challenges.indexOf(this.challenge._id) !== -1; return this.user.challenges.indexOf(this.challenge._id) !== -1;
}, },
isLeader () { isLeader () {
return true; if (!this.leader) return false;
return this.user._id === this.leader.id;
}, },
}, },
mounted () { mounted () {
@@ -181,10 +169,15 @@ export default {
this.challenge = await this.$store.dispatch('challenges:getChallenge', {challengeId: this.challengeId}); this.challenge = await this.$store.dispatch('challenges:getChallenge', {challengeId: this.challengeId});
}, },
async joinChallenge () { async joinChallenge () {
// this.challenge = this.$store.dispatch('challenges:joinChallenge', {challengeId: this.challengeId}); this.user.challenges.push(this.challengeId);
await this.$store.dispatch('challenges:joinChallenge', {challengeId: this.challengeId});
}, },
async leaveChallenge () { async leaveChallenge () {
// this.challenge = this.$store.dispatch('challenges:leaveChallenge', {challengeId: this.challengeId}); let index = findIndex(this.user.challenges, (challengeId) => {
return challengeId === this.challengeId;
});
this.user.challenges.splice(index, 1);
await this.$store.dispatch('challenges:leaveChallenge', {challengeId: this.challengeId});
}, },
closeChallenge () { closeChallenge () {
this.$root.$emit('show::modal', 'close-challenge-modal'); this.$root.$emit('show::modal', 'close-challenge-modal');

View File

@@ -8,11 +8,12 @@
span span
.svg-icon.member-icon(v-html="icons.memberIcon") .svg-icon.member-icon(v-html="icons.memberIcon")
span {{challenge.memberCount}} span {{challenge.memberCount}}
span // @TODO: Add in V2
.svg-icon.calendar-icon(v-html="icons.calendarIcon") span
span .svg-icon.calendar-icon(v-html="icons.calendarIcon")
strong End Date: span
span {{challenge.endDate}} strong End Date:
span {{challenge.endDate}}
div.tags div.tags
span.tag(v-for='tag in challenge.tags') {{tag}} span.tag(v-for='tag in challenge.tags') {{tag}}
.col-6.prize-section .col-6.prize-section
@@ -23,28 +24,28 @@
.row.description .row.description
.col-12 .col-12
| {{challenge.description}} | {{challenge.description}}
.container.well-wrapper(v-if='challenge.counts') .container.well-wrapper
.well.row .well.row
.col-3 .col-3
.count-details .count-details
.svg-icon.habit-icon(v-html="icons.habitIcon") .svg-icon.habit-icon(v-html="icons.habitIcon")
span.count {{challenge.counts.habit}} span.count {{challenge.tasksOrder.habits.length}}
div {{$t('habit')}} div {{$t('habit')}}
.col-3 .col-3
.count-details .count-details
.svg-icon.daily-icon(v-html="icons.dailyIcon") .svg-icon.daily-icon(v-html="icons.dailyIcon")
span.count {{challenge.counts.dailies}} span.count {{challenge.tasksOrder.dailys.length}}
div {{$t('daily')}} div {{$t('daily')}}
.col-3 .col-3
.count-details .count-details
.svg-icon.todo-icon(v-html="icons.todoIcon") .svg-icon.todo-icon(v-html="icons.todoIcon")
span.count {{challenge.counts.todos}} span.count {{challenge.tasksOrder.todos.length}}
div {{$t('todo')}} div {{$t('todo')}}
.col-3 .col-3
.count-details .count-details
.svg-icon.reward-icon(v-html="icons.rewardIcon") .svg-icon.reward-icon(v-html="icons.rewardIcon")
span.count {{challenge.counts.rewards}} span.count {{challenge.tasksOrder.rewards.length}}
div {{$t('reward')}} div {{$t('reward')}}
</template> </template>
<style lang='scss' scoped> <style lang='scss' scoped>
@@ -53,8 +54,9 @@
.card { .card {
background-color: $white; background-color: $white;
box-shadow: 0 2px 2px 0 $gray-600, 0 1px 4px 0 $gray-600; box-shadow: 0 2px 2px 0 $gray-600, 0 1px 4px 0 $gray-600;
padding: 1em; padding: 2em;
height: 372px; height: 325px;
margin-bottom: 1em;
.gem { .gem {
width: 32px; width: 32px;
@@ -98,7 +100,6 @@
.prize-section { .prize-section {
text-align: right; text-align: right;
padding-right: 2em; padding-right: 2em;
padding-top: 1em;
} }
.description { .description {
@@ -116,6 +117,8 @@
text-align: center; text-align: center;
padding: 2em; padding: 2em;
border-radius: 4px; border-radius: 4px;
margin-left: .2em;
margin-right: .2em;
.svg-icon { .svg-icon {
display: inline-block; display: inline-block;

View File

@@ -1,5 +1,4 @@
<template lang="pug"> <template lang="pug">
div
b-modal#challenge-modal(:title="$t('createChallenge')", size='lg') b-modal#challenge-modal(:title="$t('createChallenge')", size='lg')
form(@submit.stop.prevent="submit") form(@submit.stop.prevent="submit")
.form-group .form-group

View File

@@ -11,11 +11,11 @@
span.dropdown-label {{ $t('sortBy') }} span.dropdown-label {{ $t('sortBy') }}
b-dropdown(:text="$t('sort')", right=true) b-dropdown(:text="$t('sort')", right=true)
b-dropdown-item(v-for='sortOption in sortOptions', :key="sortOption.value", @click='sort(sortOption.value)') {{sortOption.text}} b-dropdown-item(v-for='sortOption in sortOptions', :key="sortOption.value", @click='sort(sortOption.value)') {{sortOption.text}}
button.btn.btn-secondary.create-challenge-button button.btn.btn-secondary.create-challenge-button(@click='createChallenge()')
.svg-icon.positive-icon(v-html="icons.positiveIcon") .svg-icon.positive-icon(v-html="icons.positiveIcon")
span(v-once, @click='createChallenge()') {{$t('createChallenge')}} span(v-once) {{$t('createChallenge')}}
.row .row
.col-6(v-for='challenge in challenges') .col-6(v-for='challenge in challenges', v-if='!memberOf(challenge)')
challenge-item(:challenge='challenge') challenge-item(:challenge='challenge')
</template> </template>
@@ -41,6 +41,8 @@
</style> </style>
<script> <script>
import { mapState } from 'client/libs/store';
import bDropdown from 'bootstrap-vue/lib/components/dropdown'; import bDropdown from 'bootstrap-vue/lib/components/dropdown';
import bDropdownItem from 'bootstrap-vue/lib/components/dropdown-item'; import bDropdownItem from 'bootstrap-vue/lib/components/dropdown-item';
import Sidebar from './sidebar'; import Sidebar from './sidebar';
@@ -71,7 +73,13 @@ export default {
// @TODO: do we need to load groups for filters still? // @TODO: do we need to load groups for filters still?
}, },
computed: {
...mapState({user: 'user.data'}),
},
methods: { methods: {
memberOf (challenge) {
return this.user.challenges.indexOf(challenge._id) !== -1;
},
updateSearch () { updateSearch () {
}, },

View File

@@ -11,19 +11,19 @@
span.dropdown-label {{ $t('sortBy') }} span.dropdown-label {{ $t('sortBy') }}
b-dropdown(:text="$t('sort')", right=true) b-dropdown(:text="$t('sort')", right=true)
b-dropdown-item(v-for='sortOption in sortOptions', :key="sortOption.value", @click='sort(sortOption.value)') {{sortOption.text}} b-dropdown-item(v-for='sortOption in sortOptions', :key="sortOption.value", @click='sort(sortOption.value)') {{sortOption.text}}
button.btn.btn-secondary.create-challenge-button button.btn.btn-secondary.create-challenge-button(@click='createChallenge()')
.svg-icon.positive-icon(v-html="icons.positiveIcon") .svg-icon.positive-icon(v-html="icons.positiveIcon")
span(v-once, @click='createChallenge()') {{$t('createChallenge')}} span(v-once) {{$t('createChallenge')}}
.row .row
.no-challenges.text-center.col-md-6.offset-3(v-if='challenges.length === 0') .no-challenges.text-center.col-md-6.offset-3(v-if='filteredChallenges.length === 0')
.svg-icon(v-html="icons.challengeIcon") .svg-icon(v-html="icons.challengeIcon")
h2(v-once) {{$t('noChallengeTitle')}} h2(v-once) {{$t('noChallengeTitle')}}
p(v-once) {{$t('challengeDescription1')}} p(v-once) {{$t('challengeDescription1')}}
p(v-once) {{$t('challengeDescription2')}} p(v-once) {{$t('challengeDescription2')}}
.row .row
.col-6(v-for='challenge in challenges') .col-6(v-for='challenge in filteredChallenges')
challenge-item(:challenge='challenge') challenge-item(:challenge='challenge')
</template> </template>
@@ -63,6 +63,8 @@
</style> </style>
<script> <script>
import { mapState } from 'client/libs/store';
import bDropdown from 'bootstrap-vue/lib/components/dropdown'; import bDropdown from 'bootstrap-vue/lib/components/dropdown';
import bDropdownItem from 'bootstrap-vue/lib/components/dropdown-item'; import bDropdownItem from 'bootstrap-vue/lib/components/dropdown-item';
import Sidebar from './sidebar'; import Sidebar from './sidebar';
@@ -86,45 +88,27 @@ export default {
challengeIcon, challengeIcon,
positiveIcon, positiveIcon,
}), }),
challenges: [ challenges: [],
// {
// _id: 1,
// title: 'I am the Night! (Official TAKE THIS Challenge June 2017)',
// memberCount: 5261,
// endDate: '2017-04-04',
// tags: ['Habitica Official', 'Tag'],
// prize: 10,
// description: 'Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium.',
// counts: {
// habit: 0,
// dailies: 2,
// todos: 2,
// rewards: 0,
// },
// },
// {
// _id: 2,
// title: '30-Day Money Cleanse 💰',
// memberCount: 112,
// endDate: '2017-04-05',
// tags: ['Owned', 'Tag'],
// prize: 10,
// description: 'Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa.',
// counts: {
// habit: 0,
// dailies: 2,
// todos: 30,
// rewards: 0,
// },
// },
],
sortOptions: [], sortOptions: [],
}; };
}, },
mounted () { mounted () {
this.loadchallanges(); this.loadchallanges();
}, },
computed: {
...mapState({user: 'user.data'}),
filteredChallenges () {
return this.challenges.filter((challenge) => {
let isMember = this.memberOf(challenge);
// @TODO: Other filters
return isMember;
});
},
},
methods: { methods: {
memberOf (challenge) {
return this.user.challenges.indexOf(challenge._id) !== -1;
},
updateSearch () { updateSearch () {
}, },

View File

@@ -4,9 +4,9 @@
input.form-control.search(type="text", :placeholder="$t('search')", v-model='searchTerm') input.form-control.search(type="text", :placeholder="$t('search')", v-model='searchTerm')
form form
h3(v-once) {{ $t('filter') }} h2(v-once) {{ $t('filter') }}
.form-group .form-group
h5 Category h3 Category
.form-check( .form-check(
v-for="group in categoryOptions", v-for="group in categoryOptions",
:key="group.key", :key="group.key",
@@ -16,7 +16,7 @@
span.custom-control-indicator span.custom-control-indicator
span.custom-control-description(v-once) {{ $t(group.label) }} span.custom-control-description(v-once) {{ $t(group.label) }}
.form-group .form-group
h5 Membership h3 Membership
.form-check( .form-check(
v-for="group in roleOptions", v-for="group in roleOptions",
:key="group.key", :key="group.key",
@@ -26,7 +26,7 @@
span.custom-control-indicator span.custom-control-indicator
span.custom-control-description(v-once) {{ $t(group.label) }} span.custom-control-description(v-once) {{ $t(group.label) }}
.form-group .form-group
h5 Guild Size h3 Ownership
.form-check( .form-check(
v-for="group in guildSizeOptions", v-for="group in guildSizeOptions",
:key="group.key", :key="group.key",
@@ -65,34 +65,6 @@ export default {
label: 'comicsHobbies', label: 'comicsHobbies',
key: 'comics_hobbies', key: 'comics_hobbies',
}, },
{
label: 'diyCrafts',
key: 'diy_crafts',
},
{
label: 'education',
key: 'education',
},
{
label: 'foodCooking',
key: 'food_cooking',
},
{
label: 'healthFitness',
key: 'health_fitness',
},
{
label: 'music',
key: 'music',
},
{
label: 'relationship',
key: 'relationship',
},
{
label: 'scienceTech',
key: 'science_tech ',
},
], ],
roleFilters: [], roleFilters: [],
roleOptions: [ roleOptions: [

View File

@@ -4,14 +4,21 @@ div
.row .row
// .col-md-2 // .col-md-2
// @TODO: Implement when we pull avatars .svg-icon(v-html="icons.like") // @TODO: Implement when we pull avatars .svg-icon(v-html="icons.like")
.col-md-12(v-for="(msg, index) in chat", :key="msg.id")
.hr
.col-md-12(v-for="(msg, index) in chat", :key="msg.id", v-if='chat')
// @TODO: is there a different way to do these conditionals? This creates an infinite loop
//.hr(v-if='displayDivider(msg)')
.hr-middle(v-once) {{ msg.timestamp }}
.card .card
.card-block .card-block
h3.leader {{msg.user}} h3.leader {{msg.user}}
p {{msg.timestamp | timeAgo}} p {{msg.timestamp | timeAgo}}
.text {{msg.text}} .text {{msg.text}}
hr hr
.action(v-once, @click='like(msg)', :class='{active: msg.likes[user._id]}') .action(v-once, @click='like(msg)', v-if='msg.likes', :class='{active: msg.likes[user._id]}')
.svg-icon(v-html="icons.like") .svg-icon(v-html="icons.like")
span(v-if='!msg.likes[user._id]') {{ $t('like') }} span(v-if='!msg.likes[user._id]') {{ $t('like') }}
span(v-if='msg.likes[user._id]') {{ $t('liked') }} span(v-if='msg.likes[user._id]') {{ $t('liked') }}
@@ -32,6 +39,28 @@ div
<style lang="scss" scoped> <style lang="scss" scoped>
@import '~client/assets/scss/colors.scss'; @import '~client/assets/scss/colors.scss';
.hr {
width: 100%;
height: 20px;
border-bottom: 1px solid $gray-500;
text-align: center;
margin: 2em 0;
}
.hr-middle {
font-size: 16px;
font-weight: bold;
font-family: 'Roboto Condensed';
line-height: 1.5;
text-align: center;
color: $gray-200;
background-color: $gray-700;
padding: .2em;
margin-top: .2em;
display: inline-block;
width: 100px;
}
.card { .card {
margin-bottom: 1em; margin-bottom: 1em;
} }
@@ -91,18 +120,32 @@ export default {
}), }),
copyingMessage: {}, copyingMessage: {},
messages: [], messages: [],
currentDayDividerDisplay: moment().day(),
}; };
}, },
filters: { filters: {
timeAgo (value) { timeAgo (value) {
return moment(value).fromNow(); return moment(value).fromNow();
}, },
date (value) {
// @TODO: Add user preference
return moment(value).toDate();
},
}, },
computed: { computed: {
...mapState({user: 'user.data'}), ...mapState({user: 'user.data'}),
}, },
methods: { methods: {
displayDivider (message) {
if (this.currentDayDividerDisplay !== moment(message.timestamp).day()) {
this.currentDayDividerDisplay = moment(message.timestamp).day();
return true;
}
return false;
},
likeCount (message) { likeCount (message) {
if (!message.likes) return 0;
return Object.keys(message.likes).length; return Object.keys(message.likes).length;
}, },
async like (message) { async like (message) {

View File

@@ -6,10 +6,11 @@
strong(v-once) {{$t('name')}}* strong(v-once) {{$t('name')}}*
b-form-input(type="text", :placeholder="$t('newGuildPlaceHolder')", v-model="newGuild.name") b-form-input(type="text", :placeholder="$t('newGuildPlaceHolder')", v-model="newGuild.name")
.form-group(v-if='newGuild.id') .form-group(v-if='newGuild.id && members.length > 0')
label label
strong(v-once) {{$t('guildLeader')}}* strong(v-once) {{$t('guildLeader')}}*
b-form-select(v-model="newGuild.newLeader" :options="members") select.form-control(v-model="newGuild.newLeader")
option(v-for='member in members', :value="member._id") {{ member.profile.name }}
.form-group .form-group
label label
@@ -229,7 +230,7 @@ export default {
}, },
], ],
showCategorySelect: false, showCategorySelect: false,
members: ['one', 'two'], members: [],
creatingParty: true, creatingParty: true,
inviteMembers: false, inviteMembers: false,
newMemberToInvite: { newMemberToInvite: {
@@ -261,6 +262,8 @@ export default {
this.newGuild.privacy = editingGroup.privacy; this.newGuild.privacy = editingGroup.privacy;
if (editingGroup.description) this.newGuild.description = editingGroup.description; if (editingGroup.description) this.newGuild.description = editingGroup.description;
this.newGuild.id = editingGroup._id; this.newGuild.id = editingGroup._id;
this.newGuild.newLeader = editingGroup.leader._id;
this.getMembers();
}); });
}, },
computed: { computed: {
@@ -274,6 +277,14 @@ export default {
}, },
}, },
methods: { methods: {
async getMembers () {
if (!this.newGuild.id) return;
let members = await this.$store.dispatch('members:getGroupMembers', {
groupId: this.newGuild.id,
includeAllPublicFields: true,
});
this.members = members;
},
addMemberToInvite () { addMemberToInvite () {
// @TODO: determine type // @TODO: determine type
this.membersToInvite.push(this.newMemberToInvite); this.membersToInvite.push(this.newMemberToInvite);
@@ -323,6 +334,8 @@ export default {
if (this.newGuild.id) { if (this.newGuild.id) {
await this.$store.dispatch('guilds:update', {group: this.newGuild}); await this.$store.dispatch('guilds:update', {group: this.newGuild});
// @TODO: this doesn't work because of the async resource
// if (updatedGroup.type === 'party') this.$store.state.party = {data: updatedGroup};
} else { } else {
await this.$store.dispatch('guilds:create', {group: this.newGuild}); await this.$store.dispatch('guilds:create', {group: this.newGuild});
} }

View File

@@ -1,134 +1,166 @@
<template lang="pug"> <template lang="pug">
.standard-page div
div(v-if='activePage === PAGES.CREATE_GROUP')
h2.text-center {{ $t('createAGroup') }}
.col-xs-12
.col-md-12.form-horizontal
.form-group
label.control-label(for='new-group-name') {{ $t('newGroupName', {groupType: 'text'}) }}
input.form-control#new-group-name.input-medium.option-content(required, type='text', :placeholder="$t('newGroupName', {groupType: 'text'})", v-model='newGroup.name')
.form-group
label(for='new-group-description') {{ $t('description') }}
textarea.form-control#new-group-description.option-content(cols='3', :placeholder="$t('description')", v-model='newGroup.description')
.form-group(v-if='type === "guild"')
.radio
label
input(type='radio', name='new-group-privacy', value='public', v-model='newGroup.privacy')
| {{ $t('public') }}
.radio
label
input(type='radio', name='new-group-privacy', value='private', v-model='newGroup.privacy')
| {{ $t('inviteOnly') }}
br
input.btn.btn-default(type='submit', :disabled='!newGroup.privacy && !newGroup.name', :value="$t('create')")
span.gem-cost {{ '4 ' + $t('gems') }}
p
small {{ $t('gemCost') }}
.form-group
.checkbox
label
input(type='checkbox', v-model='newGroup.leaderOnly.challenges')
| {{ $t('leaderOnlyChallenges') }}
.form-group(v-if='type === "party"')
input.btn.btn-default.form-control(type='submit', :value="$t('create')")
br
br
.row
.col-sm-6.col-sm-offset-3
a.btn.btn-primary.btn-lg.btn-block(@click="createGroup()", :disabled="!newGroupIsReady") {{ $t('create') }}
div(v-if='activePage === PAGES.UPGRADE_GROUP')
h2.text-center {{ $t('upgradeTitle') }}
.row.text-center
.col-6.col-offset-3
a.purchase.btn.btn-primary(@click='upgradeGroup(PAYMENTS.STRIPE)') {{ $t('card') }}
a.purchase(@click='upgradeGroup(PAYMENTS.AMAZON)')
img(src='https://payments.amazon.com/gp/cba/button', :alt="$t('amazonPayments')")
// @TODO: Add paypal
.row
.col-md-6.col-md-offset-3
br
.text-center {{ $t('groupSubscriptionPrice') }}
div(v-if='activePage === PAGES.BENEFITS') div(v-if='activePage === PAGES.BENEFITS')
h2.text-center {{ $t('groupBenefitsTitle') }} .header
.row(style="font-size: 2rem;") h1.text-center Need more for your Group?
.col-md-6.col-md-offset-3.text-center {{ $t('groupBenefitsDescription') }} .row
.row.row-margin .col-6.offset-3.text-center {{ $t('groupBenefitsDescription') }}
.col-md-4 .container.benefits
h2 {{ $t('teamBasedTasks') }} .row
div .col-4
// shared tasks .box
h3 h2 {{ $t('teamBasedTasks') }}
span.glyphicon.glyphicon-ok-circle(style='margin-right: 1.5rem;') p Set up an easily-viewed shared task list for the group. Assign tasks to your fellow group members, or let them claim their own tasks to make it clear what everyone is working on!
| {{ $t('groupBenefitOneTitle') }}
span {{ $t('groupBenefitOneDescription') }}
div
// assign tasks
h3
span.glyphicon.glyphicon-ok-circle(style='margin-right: 1.5rem;')
| {{ $t('groupBenefitTwoTitle') }}
span {{ $t('groupBenefitTwoDescription') }}
div
// claim tasks
h3
span.glyphicon.glyphicon-ok-circle(style='margin-right: 1.5rem;')
| {{ $t('groupBenefitThreeTitle') }}
span {{ $t('groupBenefitThreeDescription') }}
div
// mark tasks
h3
span.glyphicon.glyphicon-ok-circle(style='margin-right: 1.5rem;')
| {{ $t('groupBenefitFourTitle') }}
span {{ $t('groupBenefitFourDescription') }}
div
// group managers
h3
span.glyphicon.glyphicon-ok-circle(style='margin-right: 1.5rem;')
| {{ $t('groupBenefitEightTitle') }}
span {{ $t('groupBenefitEightDescription') }}
.col-md-4 .col-4
h2 {{ $t('specializedCommunication') }} .box
div h2 Group Management Controls
// chat privately p Use task approvals to verify that a task that was really completed, add Group Managers to share responsibilities, and enjoy a private group chat for all team members.
h3
span.glyphicon.glyphicon-ok-circle(style='margin-right: 1.5rem;')
| {{ $t('groupBenefitFiveTitle') }}
span {{ $t('groupBenefitFiveDescription') }}
div
h3
span.glyphicon.glyphicon-ok-circle(style='margin-right: 1.5rem;')
| {{ $t('groupBenefitMessageLimitTitle') }}
span {{ $t('groupBenefitMessageLimitDescription') }}
.col-md-4
h2 {{ $t('funExtras') }}
div
// free subscription
h3
span.glyphicon.glyphicon-ok-circle(style='margin-right: 1.5rem;')
| {{ $t('groupBenefitSixTitle') }}
span {{ $t('groupBenefitSixDescription') }}
div
// exclusive mount
h3
span.glyphicon.glyphicon-ok-circle(style='margin-right: 1.5rem;')
| {{ $t('groupBenefitSevenTitle') }}
br .col-4
br .box
.row h2 In-Game Benefits
.col-sm-6.col-sm-offset-3 p Group members get an exclusive Jackalope Mount, as well as full subscription benefits, including special monthly equipment sets and the ability to buy gems with gold.
a.btn.btn-primary.btn-lg.btn-block(ui-sref="options.social.newGroup") {{ $t('createAGroup') }}
.row .container.payment-options
.col-md-6.col-md-offset-3 h1.text-center.purple-header Are you ready to upgrade?
br .row
.text-center {{ $t('groupSubscriptionPrice') }} .col-6.offset-3.text-center
.purple-box
.dollar $
.number 9
.name Group Owner Subscription
.plus +
.dollar $
.number 3
.name Each Individual Group Member
.box
h3 Choose your payment method
.box.payment-button(@click='createGroup(PAYMENTS.STRIPE)')
p Credit Card
p Powered by Stripe
.box.payment-button(@click='createGroup(PAYMENTS.AMAZON)')
| Amazon Pay
.standard-page(v-if='activePage === PAGES.CREATE_GROUP')
h1.text-center {{ $t('createAGroup') }}
.col-6.offset-3
.form-group
label.control-label(for='new-group-name') Name
input.form-control#new-group-name.input-medium.option-content(required, type='text', placeholder="Name", v-model='newGroup.name')
.form-group
label(for='new-group-description') {{ $t('description') }}
textarea.form-control#new-group-description.option-content(cols='3', :placeholder="$t('description')", v-model='newGroup.description')
.form-group(v-if='type === "guild"')
.radio
label
input(type='radio', name='new-group-privacy', value='public', v-model='newGroup.privacy')
| {{ $t('public') }}
.radio
label
input(type='radio', name='new-group-privacy', value='private', v-model='newGroup.privacy')
| {{ $t('inviteOnly') }}
// @TODO Does it cost gems for a group plan?
.form-group
input.btn.btn-default(type='submit', :disabled='!newGroup.privacy && !newGroup.name', :value="$t('create')")
span.gem-cost {{ '4 ' + $t('gems') }}
p
small {{ $t('gemCost') }}
.form-group
.checkbox
label
input(type='checkbox', v-model='newGroup.leaderOnly.challenges')
| {{ $t('leaderOnlyChallenges') }}
.form-group(v-if='type === "party"')
input.btn.btn-default.form-control(type='submit', :value="$t('create')")
.form-group
button.btn.btn-primary.btn-lg.btn-block(@click="upgrade()", :disabled="!newGroupIsReady") {{ $t('create') }}
</template> </template>
<style lang="scss" scoped>
.header {
margin-bottom: 3em;
background-color: #4f2a93;
color: #fff;
padding: 2em;
height: 356px;
h1 {
font-size: 48px;
color: #fff;
}
}
.benefits {
margin-top: -12em;
}
.box {
border-radius: 2px;
background-color: #ffffff;
box-shadow: 0 2px 2px 0 rgba(26, 24, 29, 0.16), 0 1px 4px 0 rgba(26, 24, 29, 0.12);
padding: 2em;
text-align: center;
}
.purple-header {
color: #6133b4;
font-size: 48px;
margin-top: 1em;
}
.payment-options {
margin-bottom: 4em;
.purple-box {
background-color: #4f2a93;
color: #fff;
padding: .5em;
border-radius: 8px;
width: 200px;
height: 200px;
.dollar {
margin-left: 1.2em;
}
.number {
font-size: 60px;
}
.name {
width: 120px;
margin-left: .3em;
}
.plus {
width: 100%;
text-align: center;
}
div {
display: inline-block;
}
}
.box, .purple-box {
display: inline-block;
vertical-align: bottom;
}
.payment-button {
width: 200px;
height: 80px;
margin-bottom: .5em;
padding: .5em;
display: block;
}
}
</style>
<script> <script>
export default { export default {
data () { data () {
@@ -142,6 +174,7 @@ export default {
AMAZON: 'amazon', AMAZON: 'amazon',
STRIPE: 'stripe', STRIPE: 'stripe',
}, },
paymentMethod: '',
newGroup: { newGroup: {
type: 'guild', type: 'guild',
privacy: 'private', privacy: 'private',
@@ -155,7 +188,7 @@ export default {
}; };
}, },
mounted () { mounted () {
this.activePage = this.PAGES.CREATE_GROUP; this.activePage = this.PAGES.BENEFITS;
}, },
computed: { computed: {
newGroupIsReady () { newGroupIsReady () {
@@ -167,18 +200,19 @@ export default {
this.activePage = page; this.activePage = page;
window.scrollTo(0, 0); window.scrollTo(0, 0);
}, },
createGroup () { createGroup (paymentType) {
this.changePage(this.PAGES.UPGRADE_GROUP); this.paymentMethod = paymentType;
this.changePage(this.PAGES.CREATE_GROUP);
}, },
upgradeGroup (paymentType) { upgrade () {
// let subscriptionKey = 'group_monthly'; // @TODO: Get from content API? // let subscriptionKey = 'group_monthly'; // @TODO: Get from content API?
if (paymentType === this.PAYMENTS.STRIPE) { if (this.paymentMethod === this.PAYMENTS.STRIPE) {
// Payments.showStripe({ // Payments.showStripe({
// subscription: subscriptionKey, // subscription: subscriptionKey,
// coupon: null, // coupon: null,
// groupToCreate: this.newGroup // groupToCreate: this.newGroup
// }); // });
} else if (paymentType === this.PAYMENTS.AMAZON) { } else if (this.paymentMethod === this.PAYMENTS.AMAZON) {
// Payments.amazonPayments.init({ // Payments.amazonPayments.init({
// type: 'subscription', // type: 'subscription',
// subscription: subscriptionKey, // subscription: subscriptionKey,

View File

@@ -2,7 +2,8 @@
.row(v-if="group") .row(v-if="group")
group-form-modal group-form-modal
invite-modal invite-modal
.clearfix.col-8 start-quest-modal(:group='this.group')
.col-8.standard-page
.row .row
.col-6.title-details .col-6.title-details
h1 {{group.name}} h1 {{group.name}}
@@ -10,9 +11,12 @@
span.float-left(v-once, v-if='group.leader.profile') : {{group.leader.profile.name}} span.float-left(v-once, v-if='group.leader.profile') : {{group.leader.profile.name}}
.col-6 .col-6
.row.icon-row .row.icon-row
.col-4(v-bind:class="{ 'offset-8': isParty }") .col-4.offset-4(v-bind:class="{ 'offset-8': isParty }")
members-modal(:group='group', v-if='isMember') .item-with-icon(@click="showMemberModal()")
.col-6(v-if='!isParty') .svg-icon.shield(v-html="icons.goldGuildBadgeIcon")
span.number {{group.memberCount}}
div(v-once) {{ $t('members') }}
.col-4(v-if='!isParty')
.item-with-icon .item-with-icon
.svg-icon.gem(v-html="icons.gem") .svg-icon.gem(v-html="icons.gem")
span.number {{group.memberCount}} span.number {{group.memberCount}}
@@ -24,8 +28,6 @@
textarea(:placeholder="$t('chatPlaceHolder')", v-model='newMessage') textarea(:placeholder="$t('chatPlaceHolder')", v-model='newMessage')
button.btn.btn-secondary.send-chat.float-right(v-once, @click='sendMessage()') {{ $t('send') }} button.btn.btn-secondary.send-chat.float-right(v-once, @click='sendMessage()') {{ $t('send') }}
.hr
.hr-middle(v-once) {{ $t('today') }}
chat-message(:chat.sync='group.chat', :group-id='group._id', group-name='group.name') chat-message(:chat.sync='group.chat', :group-id='group._id', group-name='group.name')
@@ -43,11 +45,11 @@
.button-container .button-container
button.btn.btn-primary(v-once, @click='showInviteModal()') {{$t('invite')}} button.btn.btn-primary(v-once, @click='showInviteModal()') {{$t('invite')}}
.button-container .button-container
button.btn.btn-primary(v-once, v-if='!isLeader') {{$t('messageGuildLeader')}} // @TODO: V2 button.btn.btn-primary(v-once, v-if='!isLeader') {{$t('messageGuildLeader')}}
.button-container .button-container
button.btn.btn-primary(v-once, v-if='isMember && !isParty') {{$t('donateGems')}} // @TODO: V2 button.btn.btn-primary(v-once, v-if='isMember && !isParty') {{$t('donateGems')}}
.section-header .section-header(v-if='isParty')
.row .row
.col-10 .col-10
h3(v-once) {{ $t('questDetailsTitle') }} h3(v-once) {{ $t('questDetailsTitle') }}
@@ -63,7 +65,6 @@
h4(v-once) {{ $t('yourNotOnQuest') }} h4(v-once) {{ $t('yourNotOnQuest') }}
p(v-once) {{ $t('questDescription') }} p(v-once) {{ $t('questDescription') }}
button.btn.btn-secondary(v-once, @click="openStartQuestModal()") {{ $t('startAQuest') }} button.btn.btn-secondary(v-once, @click="openStartQuestModal()") {{ $t('startAQuest') }}
owned-quests-modal(:group='this.group')
.row.quest-active-section(v-if='isParty && onPendingQuest && !onActiveQuest') .row.quest-active-section(v-if='isParty && onPendingQuest && !onActiveQuest')
h2 Pending quest h2 Pending quest
button.btn.btn-secondary(v-once, @click="questForceStart()") {{ $t('begin') }} button.btn.btn-secondary(v-once, @click="questForceStart()") {{ $t('begin') }}
@@ -79,7 +80,8 @@
div(:class="'quest_' + questData.key + '_' + key") div(:class="'quest_' + questData.key + '_' + key")
.col-10 .col-10
strong {{value.text()}} strong {{value.text()}}
.collect-progress-bar .grey-progress-bar
.collect-progress-bar(:style="{width: (group.quest.progress.collect[key] / value.count) * 100 + '%'}")
strong {{group.quest.progress.collect[key]}} / {{value.count}} strong {{group.quest.progress.collect[key]}} / {{value.count}}
.boss-info(v-if='questData.boss') .boss-info(v-if='questData.boss')
.row .row
@@ -89,7 +91,8 @@
span.float-right(v-once) {{ $t('participants') }} span.float-right(v-once) {{ $t('participants') }}
.row .row
.col-12 .col-12
.boss-health-bar .grey-progress-bar
.boss-health-bar(:style="{width: (group.quest.progress.hp / questData.boss.hp) * 100 + '%'}")
.row.boss-details .row.boss-details
.col-6 .col-6
span.float-left span.float-left
@@ -137,7 +140,7 @@
.toggle-down(@click="sections.challenges = !sections.challenges", v-if="!sections.challenges") .toggle-down(@click="sections.challenges = !sections.challenges", v-if="!sections.challenges")
.svg-icon(v-html="icons.downIcon") .svg-icon(v-html="icons.downIcon")
.section(v-if="sections.challenges") .section(v-if="sections.challenges")
group-challenges(:groupId='groupId') group-challenges(:groupId='searchId')
div.text-center div.text-center
button.btn.btn-primary(class='btn-danger', v-if='isMember') {{ $t('leave') }} button.btn.btn-primary(class='btn-danger', v-if='isMember') {{ $t('leave') }}
</template> </template>
@@ -145,6 +148,10 @@
<style lang="scss" scoped> <style lang="scss" scoped>
@import '~client/assets/scss/colors.scss'; @import '~client/assets/scss/colors.scss';
h1 {
color: $purple-200;
}
.button-container { .button-container {
margin-bottom: 1em; margin-bottom: 1em;
@@ -158,11 +165,27 @@
background-color: #ffffff; background-color: #ffffff;
box-shadow: 0 2px 2px 0 rgba(26, 24, 29, 0.16), 0 1px 4px 0 rgba(26, 24, 29, 0.12); box-shadow: 0 2px 2px 0 rgba(26, 24, 29, 0.16), 0 1px 4px 0 rgba(26, 24, 29, 0.12);
padding: 1em; padding: 1em;
text-align: center;
.svg-icon.shield, .svg-icon.gem {
width: 40px;
margin: 0 auto;
}
.number {
font-size: 22px;
font-weight: bold;
}
}
.item-with-icon:hover {
cursor: pointer;
} }
.sidebar { .sidebar {
background-color: $gray-600; background-color: $gray-600;
padding-top: 2em; padding-top: 2em;
padding-bottom: 2em;
} }
.card { .card {
@@ -196,11 +219,6 @@
padding: .5em; padding: .5em;
} }
.svg-icon.shield, .svg-icon.gem {
width: 40px;
margin-right: 1em;
}
.title-details { .title-details {
padding-top: 1em; padding-top: 1em;
padding-left: 1em; padding-left: 1em;
@@ -226,26 +244,8 @@
} }
} }
.hr { .toggle-up .svg-icon, .toggle-down .svg-icon {
width: 100%; width: 25px;
height: 20px;
border-bottom: 1px solid $gray-500;
text-align: center;
margin: 2em 0;
}
.hr-middle {
font-size: 16px;
font-weight: bold;
font-family: 'Roboto Condensed';
line-height: 1.5;
text-align: center;
color: $gray-200;
background-color: $gray-700;
padding: .2em;
margin-top: .2em;
display: inline-block;
width: 100px;
} }
span.action { span.action {
@@ -275,6 +275,7 @@
.svg-icon { .svg-icon {
height: 30px; height: 30px;
width: 30px; width: 30px;
margin: 0 auto;
margin-bottom: 2em; margin-bottom: 2em;
} }
} }
@@ -336,18 +337,25 @@
margin-bottom: .5em; margin-bottom: .5em;
} }
.grey-progress-bar {
width: 100%;
height: 15px;
background-color: #e1e0e3;
}
.collect-progress-bar { .collect-progress-bar {
background-color: #24cc8f; background-color: #24cc8f;
height: 15px; height: 15px;
width: 80%;
} }
</style> </style>
<script> <script>
import groupUtilities from 'client/mixins/groupsUtilities'; import groupUtilities from 'client/mixins/groupsUtilities';
import styleHelper from 'client/mixins/styleHelper';
import { mapState } from 'client/libs/store'; import { mapState } from 'client/libs/store';
import membersModal from './membersModal'; import membersModal from './membersModal';
import ownedQuestsModal from './ownedQuestsModal'; import startQuestModal from './startQuestModal';
import quests from 'common/script/content/quests'; import quests from 'common/script/content/quests';
import percent from 'common/script/libs/percent'; import percent from 'common/script/libs/percent';
import groupFormModal from './groupFormModal'; import groupFormModal from './groupFormModal';
@@ -372,14 +380,15 @@ import informationIcon from 'assets/svg/information.svg';
import questBackground from 'assets/svg/quest-background-border.svg'; import questBackground from 'assets/svg/quest-background-border.svg';
import upIcon from 'assets/svg/up.svg'; import upIcon from 'assets/svg/up.svg';
import downIcon from 'assets/svg/down.svg'; import downIcon from 'assets/svg/down.svg';
import goldGuildBadgeIcon from 'assets/svg/gold-guild-badge.svg';
export default { export default {
mixins: [groupUtilities], mixins: [groupUtilities, styleHelper],
props: ['groupId'], props: ['groupId'],
components: { components: {
membersModal, membersModal,
memberModal, memberModal,
ownedQuestsModal, startQuestModal,
bCollapse, bCollapse,
bCard, bCard,
bTooltip, bTooltip,
@@ -393,6 +402,7 @@ export default {
}, },
data () { data () {
return { return {
searchId: null,
group: null, group: null,
icons: Object.freeze({ icons: Object.freeze({
like: likeIcon, like: likeIcon,
@@ -406,8 +416,8 @@ export default {
questBackground, questBackground,
upIcon, upIcon,
downIcon, downIcon,
goldGuildBadgeIcon,
}), }),
questData: {},
selectedQuest: {}, selectedQuest: {},
sections: { sections: {
quest: true, quest: true,
@@ -475,16 +485,19 @@ export default {
bossHpPercent () { bossHpPercent () {
return percent(this.group.quest.progress.hp, this.questData.boss.hp); return percent(this.group.quest.progress.hp, this.questData.boss.hp);
}, },
questData () {
if (!this.group.quest) return {};
return quests.quests[this.group.quest.key];
},
}, },
created () { created () {
this.searchId = this.groupId;
if (this.isParty) { if (this.isParty) {
this.groupId = 'party'; this.searchId = 'party';
// @TODO: Set up from old client. Decide what we need and what we don't // @TODO: Set up from old client. Decide what we need and what we don't
// Check Desktop notifs // Check Desktop notifs
// Mark Chat seen // Mark Chat seen
// Load members
// Load invites // Load invites
// Load challenges
// Load group tasks for group plan // Load group tasks for group plan
// Load approvals for group plan // Load approvals for group plan
} }
@@ -495,6 +508,9 @@ export default {
$route: 'fetchGuild', $route: 'fetchGuild',
}, },
methods: { methods: {
showMemberModal () {
this.$root.$emit('show::modal', 'members-modal');
},
async sendMessage () { async sendMessage () {
let response = await this.$store.dispatch('chat:postChat', { let response = await this.$store.dispatch('chat:postChat', {
groupId: this.group._id, groupId: this.group._id,
@@ -511,12 +527,11 @@ export default {
this.$root.$emit('show::modal', 'invite-modal'); this.$root.$emit('show::modal', 'invite-modal');
}, },
async fetchGuild () { async fetchGuild () {
let group = await this.$store.dispatch('guilds:getGroup', {groupId: this.groupId}); let group = await this.$store.dispatch('guilds:getGroup', {groupId: this.searchId});
if (this.isParty) { if (this.isParty) {
this.$store.party = group; this.$store.party = group;
this.group = this.$store.party; this.group = this.$store.party;
this.checkForAchievements(); this.checkForAchievements();
this.questData = quests.quests[this.group.quest.key];
return; return;
} }
this.group = group; this.group = group;
@@ -527,7 +542,7 @@ export default {
} }
}, },
openStartQuestModal () { openStartQuestModal () {
this.$root.$emit('show::modal', 'owned-quests-modal'); this.$root.$emit('show::modal', 'start-quest-modal');
}, },
// inviteOrStartParty (group) { // inviteOrStartParty (group) {
// Analytics.track({'hitType':'event','eventCategory':'button','eventAction':'click','eventLabel':'Invite Friends'}); // Analytics.track({'hitType':'event','eventCategory':'button','eventAction':'click','eventLabel':'Invite Friends'});
@@ -625,7 +640,7 @@ export default {
}); });
if (hasQuests) { if (hasQuests) {
this.$root.$emit('show::modal', 'owned-quests-modal'); this.$root.$emit('show::modal', 'start-quest-modal');
return; return;
} }
// $rootScope.$state.go('options.inventory.quests'); // $rootScope.$state.go('options.inventory.quests');

View File

@@ -1,10 +1,5 @@
<template lang="pug"> <template lang="pug">
div div
.item-with-icon(@click="$root.$emit('show::modal','members-modal')")
.svg-icon.shield(v-html="icons.goldGuildBadgeIcon")
span.number {{group.memberCount}}
div(v-once) {{ $t('members') }}
b-modal#members-modal(:title="$t('createGuild')", size='lg') b-modal#members-modal(:title="$t('createGuild')", size='lg')
.header-wrap(slot="modal-header") .header-wrap(slot="modal-header")
.row .row
@@ -40,7 +35,7 @@ div
b-dropdown-item(@click='sort(option.value)') b-dropdown-item(@click='sort(option.value)')
.svg-icon(v-html="icons.removeIcon") .svg-icon(v-html="icons.removeIcon")
| {{$t('removeManager2')}} | {{$t('removeManager2')}}
.row-fluid.gradient .row.gradient(v-if='members.length > 3')
b-modal#remove-member(:title="$t('confirmRemoveMember')") b-modal#remove-member(:title="$t('confirmRemoveMember')")
button(@click='confirmRemoveMember(member)', v-once) {{$t('remove')}} button(@click='confirmRemoveMember(member)', v-once) {{$t('remove')}}
@@ -73,6 +68,7 @@ div
#members-modal_modal_body { #members-modal_modal_body {
padding: 0; padding: 0;
max-height: 450px;
.col-8 { .col-8 {
margin-left: 0; margin-left: 0;
@@ -89,29 +85,19 @@ div
.gradient { .gradient {
background-image: linear-gradient(to bottom, rgba(255, 255, 255, 0), #ffffff); background-image: linear-gradient(to bottom, rgba(255, 255, 255, 0), #ffffff);
height: 200px; height: 50px;
width: 100%; width: 100%;
position: absolute; position: absolute;
bottom: 0px; bottom: 0px;
margin-left: -15px;
} }
} }
.item-with-icon { .dropdown-menu .svg-icon {
border-radius: 2px; width: 20px;
background-color: #ffffff; display: inline-block;
box-shadow: 0 2px 2px 0 rgba(26, 24, 29, 0.16), 0 1px 4px 0 rgba(26, 24, 29, 0.12); vertical-align: bottom;
padding: 1em; margin-right: .5em;
text-align: center;
}
.svg-icon.shield, .svg-icon.gem {
width: 40px;
margin-right: 1em;
}
.number {
font-size: 22px;
font-weight: bold;
} }
</style> </style>
@@ -127,7 +113,7 @@ import starIcon from 'assets/members/star.svg';
import goldGuildBadgeIcon from 'assets/svg/gold-guild-badge.svg'; import goldGuildBadgeIcon from 'assets/svg/gold-guild-badge.svg';
export default { export default {
props: ['group'], props: ['group', 'hideBadge'],
components: { components: {
bModal, bModal,
bDropdown, bDropdown,

View File

@@ -42,6 +42,11 @@
.no-guilds-wrapper { .no-guilds-wrapper {
width: 400px; width: 400px;
margin: 0 auto; margin: 0 auto;
.svg-icon {
width: 60px;
margin: 0 auto;
}
} }
} }
</style> </style>

View File

@@ -1,54 +0,0 @@
<template lang="pug">
div
b-modal#owned-quests-modal(title="Which quest do you want to start?", size='md', hide-footer=true)
.row.content
.quest(v-for='(value, key, index) in user.items.quests', :class="'inventory_quest_scroll_' + key", @click='selectQuest(key)')
button.btn.btn-primary(@click='confirm()') Confirm
start-quest-modal(:group='group', :selectedQuest='selectedQuest')
</template>
<style lang='scss' scoped>
@import '~client/assets/scss/colors.scss';
.content {
padding: 2em;
.quest {
margin-right: 1em;
margin-bottom: 1em;
display: inline-block;
}
}
</style>
<script>
import { mapState } from 'client/libs/store';
import bModal from 'bootstrap-vue/lib/components/modal';
import startQuestModal from './startQuestModal';
export default {
props: ['group'],
components: {
bModal,
startQuestModal,
},
data () {
return {
selectedQuest: {},
};
},
computed: {
...mapState({user: 'user.data'}),
},
methods: {
selectQuest (quest) {
this.selectedQuest = quest;
},
confirm () {
this.$root.$emit('show::modal', 'start-quest-modal');
this.$root.$emit('hide::modal', 'owned-quests-modal');
},
},
};
</script>

View File

@@ -14,8 +14,8 @@
.col-md-2.cta-container .col-md-2.cta-container
button.btn.btn-danger(v-if='isMember && displayLeave' @click='leave()', v-once) {{ $t('leave') }} button.btn.btn-danger(v-if='isMember && displayLeave' @click='leave()', v-once) {{ $t('leave') }}
button.btn.btn-success(v-if='!isMember' @click='join()', v-once) {{ $t('join') }} button.btn.btn-success(v-if='!isMember' @click='join()', v-once) {{ $t('join') }}
div.item-with-icon(v-if='displayGemBank') div.item-with-icon.gem-bank(v-if='displayGemBank')
.svg-icon(v-html="icons.gem") .svg-icon.gem(v-html="icons.gem")
span.count {{ guild.balance }} span.count {{ guild.balance }}
div.guild-bank(v-if='displayGemBank', v-once) {{$t('guildBank')}} div.guild-bank(v-if='displayGemBank', v-once) {{$t('guildBank')}}
.row .row
@@ -29,7 +29,7 @@
@import '~client/assets/scss/colors.scss'; @import '~client/assets/scss/colors.scss';
.card { .card {
height: 260px; height: 160px;
border-radius: 4px; border-radius: 4px;
background-color: $white; background-color: $white;
box-shadow: 0 2px 2px 0 rgba($black, 0.15), 0 1px 4px 0 rgba($black, 0.1); box-shadow: 0 2px 2px 0 rgba($black, 0.15), 0 1px 4px 0 rgba($black, 0.1);
@@ -44,14 +44,13 @@
.cta-container { .cta-container {
margin: 0 auto; margin: 0 auto;
margin-top: 4em;
button {
margin-top: 2.5em;
}
} }
.item-with-icon { .item-with-icon {
.svg-icon {
height: 37px;
}
.count { .count {
font-size: 20px; font-size: 20px;
height: 37px; height: 37px;
@@ -62,6 +61,8 @@
.shield { .shield {
width: 70px; width: 70px;
margin: 0 auto;
margin-top: 2em;
} }
.guild-bank { .guild-bank {
@@ -73,13 +74,23 @@
.member-count { .member-count {
position: relative; position: relative;
top: -3.6em; top: -3.6em;
left: -.1em; font-size: 22px;
font-size: 28px;
font-weight: bold; font-weight: bold;
font-family: 'Roboto Condensed';
line-height: 1.2; line-height: 1.2;
text-align: center; text-align: center;
color: #b36213; color: #b36213;
margin-top: 2.1em;
}
.gem-bank {
margin-top: 2em;
.gem {
width: 25px;
display: inline-block;
vertical-align: bottom;
margin-right: .8em;
}
} }
} }
</style> </style>

View File

@@ -4,9 +4,9 @@
input.form-control.search(type="text", :placeholder="$t('search')", v-model='searchTerm') input.form-control.search(type="text", :placeholder="$t('search')", v-model='searchTerm')
form form
h3(v-once) {{ $t('filter') }} h2(v-once) {{ $t('filter') }}
.form-group .form-group
h5 Category h3 Category
.form-check( .form-check(
v-for="group in categoryOptions", v-for="group in categoryOptions",
:key="group.key", :key="group.key",
@@ -16,7 +16,7 @@
span.custom-control-indicator span.custom-control-indicator
span.custom-control-description(v-once) {{ $t(group.label) }} span.custom-control-description(v-once) {{ $t(group.label) }}
.form-group .form-group
h5 Role h3 Role
.form-check( .form-check(
v-for="group in roleOptions", v-for="group in roleOptions",
:key="group.key", :key="group.key",
@@ -26,7 +26,7 @@
span.custom-control-indicator span.custom-control-indicator
span.custom-control-description(v-once) {{ $t(group.label) }} span.custom-control-description(v-once) {{ $t(group.label) }}
.form-group .form-group
h5 Guild Size h3 Guild Size
.form-check( .form-check(
v-for="group in guildSizeOptions", v-for="group in guildSizeOptions",
:key="group.key", :key="group.key",

View File

@@ -1,23 +1,33 @@
<template lang="pug"> <template lang="pug">
b-modal#start-quest-modal(title="Empty", size='md', hide-footer=true, v-if='questData') b-modal#start-quest-modal(title="Empty", size='md', :hide-footer="true", :hide-header="true")
.quest-image(:class="'quest_' + questData.key") .left-panel.content
h2 {{questData.text()}} h3.text-center Quests
//- span by: Keith Holliday @TODO: Add author .row
p {{questData.notes()}} .col-4.quest-col(v-for='(value, key, index) in user.items.quests', @click='selectQuest(key)', :class="{selected: key === selectedQuest}")
div.quest-details .quest-wrapper
div(v-if=' questData.collect') .quest(:class="'inventory_quest_scroll_' + key")
Strong {{$t('collect')}}: &nbsp; .row
span(v-for="(value, key, index) in questData.collect") .col-10.offset-1.text-center
| {{$t('collectionItems', { number: questData.collect[key].count, items: questData.collect[key].text() })}} span.description Cant find a quest to start? Try checking out the Quest Shop in the Market for new releases!
div div(v-if='questData')
Strong {{$t('collect')}}: &nbsp; .quest-image(:class="'quest_' + questData.key")
span h2.text-center {{questData.text()}}
.svg-icon(v-html="icons.difficultyStarIcon") //- span by: Keith Holliday @TODO: Add author
div p(v-html="questData.notes()")
div.quest-details
div(v-if=' questData.collect')
Strong {{$t('collect')}}: &nbsp;
span(v-for="(value, key, index) in questData.collect")
| {{$t('collectionItems', { number: questData.collect[key].count, items: questData.collect[key].text() })}}
div
Strong {{$t('difficulty')}}: &nbsp;
span
.svg-icon.difficulty-star(v-html="icons.difficultyStarIcon")
div.text-center
button.btn.btn-primary(@click='questInit()') {{$t('inviteToPartyOrQuest')}} button.btn.btn-primary(@click='questInit()') {{$t('inviteToPartyOrQuest')}}
div div.text-center
p {{$t('inviteInformation')}} p {{$t('inviteInformation')}}
.side-panel .side-panel(v-if='questData')
h4.text-center {{$t('rewards')}} h4.text-center {{$t('rewards')}}
.box .box
.svg-icon.rewards-icon(v-html="icons.starIcon") .svg-icon.rewards-icon(v-html="icons.starIcon")
@@ -47,6 +57,7 @@
.quest-image { .quest-image {
margin: 0 auto; margin: 0 auto;
margin-bottom: 1em; margin-bottom: 1em;
margin-top: 1.5em;
} }
.quest-details { .quest-details {
@@ -59,12 +70,49 @@
margin: 1em 0; margin: 1em 0;
} }
.left-panel {
background: #4e4a57;
color: $white;
position: absolute;
height: 460px;
width: 320px;
top: 2.5em;
left: -22em;
z-index: -1;
padding: 2em;
h3 {
color: $white;
}
.selected .quest-wrapper {
border: solid 1.5px #9a62ff;
}
.quest-wrapper:hover {
cursor: pointer;
}
.quest-col .quest-wrapper {
background: $white;
padding: .7em;
margin-bottom: 1em;
border-radius: 3px;
}
.description {
text-align: center;
color: #a5a1ac;
font-size: 12px;
}
}
.side-panel { .side-panel {
background: #edecee; background: #edecee;
position: absolute; position: absolute;
height: 460px; height: 460px;
width: 320px; width: 320px;
top: -1.8em; top: 2.5em;
left: 35em; left: 35em;
z-index: -1; z-index: -1;
padding-top: 1em; padding-top: 1em;
@@ -101,9 +149,16 @@
padding: 1em; padding: 1em;
} }
} }
.difficulty-star {
width: 20px;
display: inline-block;
vertical-align: bottom;
}
</style> </style>
<script> <script>
import { mapState } from 'client/libs/store';
import bModal from 'bootstrap-vue/lib/components/modal'; import bModal from 'bootstrap-vue/lib/components/modal';
import quests from 'common/script/content/quests'; import quests from 'common/script/content/quests';
@@ -118,12 +173,13 @@ import goldIcon from 'assets/svg/gold.svg';
import difficultyStarIcon from 'assets/svg/difficulty-star.svg'; import difficultyStarIcon from 'assets/svg/difficulty-star.svg';
export default { export default {
props: ['group', 'selectedQuest'], props: ['group'],
components: { components: {
bModal, bModal,
}, },
data () { data () {
return { return {
selectedQuest: {},
icons: Object.freeze({ icons: Object.freeze({
copy: copyIcon, copy: copyIcon,
greyBadge: greyBadgeIcon, greyBadge: greyBadgeIcon,
@@ -137,12 +193,20 @@ export default {
shareUserIdShown: false, shareUserIdShown: false,
}; };
}, },
mounted () {
let questKeys = Object.keys(this.user.items.quests);
this.selectedQuest = questKeys[0];
},
computed: { computed: {
...mapState({user: 'user.data'}),
questData () { questData () {
return quests.quests[this.selectedQuest]; return quests.quests[this.selectedQuest];
}, },
}, },
methods: { methods: {
selectQuest (quest) {
this.selectedQuest = quest;
},
async questInit () { async questInit () {
let key = this.selectedQuest; let key = this.selectedQuest;
// Analytics.updateUser({'partyID': party._id, 'partySize': party.memberCount}); // Analytics.updateUser({'partyID': party._id, 'partySize': party.memberCount});

View File

@@ -9,26 +9,25 @@
.col-12 .col-12
h3(v-once) {{ $t('welcomeToTavern') }} h3(v-once) {{ $t('welcomeToTavern') }}
textarea(:placeholder="$t('chatPlaceHolder')", v-model='newMessage') .row
autocomplete(:text='newMessage', v-on:select="selectedAutocomplete") textarea(:placeholder="$t('chatPlaceHolder')", v-model='newMessage')
button.btn.btn-secondary.send-chat.float-right(v-once, @click='sendMessage()') {{ $t('send') }} autocomplete(:text='newMessage', v-on:select="selectedAutocomplete")
button.btn.btn-secondary.send-chat.float-right(v-once, @click='sendMessage()') {{ $t('send') }}
.container.community-guidelines(v-if='communityGuidelinesAccepted') .container.community-guidelines(v-if='!communityGuidelinesAccepted')
.row .row
div.col-8(v-once) {{ $t('communityGuidelinesIntro') }} div.col-8(v-once) {{ $t('communityGuidelinesIntro') }}
div.col-4 div.col-4
button.btn.btn-info(@click='acceptCommunityGuidelines()', v-once) {{ $t('acceptCommunityGuidelines') }} button.btn.btn-info(@click='acceptCommunityGuidelines()', v-once) {{ $t('acceptCommunityGuidelines') }}
.hr .row
.hr-middle(v-once) {{ $t('today') }} chat-message(:chat.sync='group.chat', :group-id='group._id', group-name='group.name')
chat-message(:chat.sync='group.chat', :group-id='group._id', group-name='group.name')
.col-md-4.sidebar .col-md-4.sidebar
.section .section
.grassy-meadow-backdrop .grassy-meadow-backdrop
.sleep .sleep.below-header-sections
strong(v-once) {{ $t('sleepDescription') }} strong(v-once) {{ $t('sleepDescription') }}
ul ul
li(v-once) {{ $t('sleepBullet1') }} li(v-once) {{ $t('sleepBullet1') }}
@@ -38,75 +37,76 @@
button.btn.btn-secondary.pause-button(v-if='!user.preferences.sleep', @click='toggleSleep()', v-once) {{ $t('pauseDailies') }} button.btn.btn-secondary.pause-button(v-if='!user.preferences.sleep', @click='toggleSleep()', v-once) {{ $t('pauseDailies') }}
button.btn.btn-secondary.pause-button(v-if='user.preferences.sleep', @click='toggleSleep()', v-once) {{ $t('unpauseDailies') }} button.btn.btn-secondary.pause-button(v-if='user.preferences.sleep', @click='toggleSleep()', v-once) {{ $t('unpauseDailies') }}
.section-header .below-header-sections
.row .section-header
.col-10 .row
h3(v-once) {{ $t('staffAndModerators') }} .col-10
.col-2 h3(v-once) {{ $t('staffAndModerators') }}
.toggle-up(@click="sections.staff = !sections.staff", v-if="sections.staff") .col-2
.svg-icon(v-html="icons.upIcon") .toggle-up(@click="sections.staff = !sections.staff", v-if="sections.staff")
.toggle-down(@click="sections.staff = !sections.staff", v-if="!sections.staff") .svg-icon(v-html="icons.upIcon")
.svg-icon(v-html="icons.downIcon") .toggle-down(@click="sections.staff = !sections.staff", v-if="!sections.staff")
.section.row(v-if="sections.staff") .svg-icon(v-html="icons.downIcon")
.col-3.staff(v-for='user in staff', :class='{staff: user.type === "Staff", moderator: user.type === "Moderator", bailey: user.name === "It\'s Bailey"}') .section.row(v-if="sections.staff")
.title {{user.name}} .col-3.staff(v-for='user in staff', :class='{staff: user.type === "Staff", moderator: user.type === "Moderator", bailey: user.name === "It\'s Bailey"}')
.type {{user.type}} .title {{user.name}}
.type {{user.type}}
.section-header .section-header
.row .row
.col-10 .col-10
h3(v-once) {{ $t('helpfulLinks') }} h3(v-once) {{ $t('helpfulLinks') }}
.col-2 .col-2
.toggle-up(@click="sections.staff = !sections.staff", v-if="sections.staff") .toggle-up(@click="sections.helpfulLinks = !sections.helpfulLinks", v-if="sections.helpfulLinks")
.svg-icon(v-html="icons.upIcon") .svg-icon(v-html="icons.upIcon")
.toggle-down(@click="sections.staff = !sections.staff", v-if="!sections.staff") .toggle-down(@click="sections.helpfulLinks = !sections.helpfulLinks", v-if="!sections.helpfulLinks")
.svg-icon(v-html="icons.downIcon") .svg-icon(v-html="icons.downIcon")
.section.row(v-if="sections.staff") .section.row(v-if="sections.helpfulLinks")
ul ul
li li
a(herf='', v-once) {{ $t('communityGuidelinesLink') }} a(herf='', v-once) {{ $t('communityGuidelinesLink') }}
li li
a(herf='', v-once) {{ $t('lookingForGroup') }} a(herf='', v-once) {{ $t('lookingForGroup') }}
li li
a(herf='', v-once) {{ $t('faq') }} a(herf='', v-once) {{ $t('faq') }}
li li
a(herf='', v-html="$t('glossary')") a(herf='', v-html="$t('glossary')")
li li
a(herf='', v-once) {{ $t('wiki') }} a(herf='', v-once) {{ $t('wiki') }}
li li
a(herf='', v-once) {{ $t('dataDisplayTool') }} a(herf='', v-once) {{ $t('dataDisplayTool') }}
li li
a(herf='', v-once) {{ $t('reportProblem') }} a(herf='', v-once) {{ $t('reportProblem') }}
li li
a(herf='', v-once) {{ $t('requestFeature') }} a(herf='', v-once) {{ $t('requestFeature') }}
li li
a(herf='', v-html="$t('communityForum')") a(herf='', v-html="$t('communityForum')")
li li
a(herf='', v-once) {{ $t('askQuestionGuild') }} a(herf='', v-once) {{ $t('askQuestionGuild') }}
.section-header .section-header
.row .row
.col-10 .col-10
h3(v-once) {{ $t('playerTiers') }} h3(v-once) {{ $t('playerTiers') }}
.col-2 .col-2
.toggle-up(@click="sections.staff = !sections.staff", v-if="sections.staff") .toggle-up(@click="sections.playerTiers = !sections.playerTiers", v-if="sections.playerTiers")
.svg-icon(v-html="icons.upIcon") .svg-icon(v-html="icons.upIcon")
.toggle-down(@click="sections.staff = !sections.staff", v-if="!sections.staff") .toggle-down(@click="sections.playerTiers = !sections.playerTiers", v-if="!sections.playerTiers")
.svg-icon(v-html="icons.downIcon") .svg-icon(v-html="icons.downIcon")
.section.row(v-if="sections.staff") .section.row(v-if="sections.playerTiers")
.col-12 .col-12
p(v-once) {{ $t('playerTiersDesc') }} p(v-once) {{ $t('playerTiersDesc') }}
ul.tier-list ul.tier-list
li.tier1(v-once) {{ $t('tier1') }} li.tier1(v-once) {{ $t('tier1') }}
li.tier2(v-once) {{ $t('tier2') }} li.tier2(v-once) {{ $t('tier2') }}
li.tier3(v-once) {{ $t('tier3') }} li.tier3(v-once) {{ $t('tier3') }}
li.tier4(v-once) {{ $t('tier4') }} li.tier4(v-once) {{ $t('tier4') }}
li.tier5(v-once) {{ $t('tier5') }} li.tier5(v-once) {{ $t('tier5') }}
li.tier6(v-once) {{ $t('tier6') }} li.tier6(v-once) {{ $t('tier6') }}
li.tier7(v-once) {{ $t('tier7') }} li.tier7(v-once) {{ $t('tier7') }}
li.moderator(v-once) {{ $t('tierModerator') }} li.moderator(v-once) {{ $t('tierModerator') }}
li.staff(v-once) {{ $t('tierStaff') }} li.staff(v-once) {{ $t('tierStaff') }}
li.npc(v-once) {{ $t('tierNPC') }} li.npc(v-once) {{ $t('tierNPC') }}
</template> </template>
<style lang='scss' scoped> <style lang='scss' scoped>
@@ -169,7 +169,11 @@
.sidebar { .sidebar {
background-color: $gray-600; background-color: $gray-600;
padding-top: 2em; padding: 0em;
.below-header-sections {
padding: 1em;
}
} }
.toggle-up, .toggle-down { .toggle-up, .toggle-down {
@@ -192,7 +196,7 @@
.grassy-meadow-backdrop { .grassy-meadow-backdrop {
background-image: url('~assets/images/groups/grassy-meadow-backdrop.png'); background-image: url('~assets/images/groups/grassy-meadow-backdrop.png');
width: 472px; width: 100%;
height: 246px; height: 246px;
} }
@@ -314,6 +318,8 @@ export default {
}, },
sections: { sections: {
staff: true, staff: true,
helpfulLinks: true,
playerTiers: true,
}, },
staff: [ staff: [
{ {
@@ -405,16 +411,11 @@ export default {
selectedAutocomplete (newText) { selectedAutocomplete (newText) {
this.newMessage = newText; this.newMessage = newText;
}, },
aggreeToGuideLines () {
// @TODO:
},
pauseDailies () {
// @TODO:
},
acceptCommunityGuidelines () { acceptCommunityGuidelines () {
this.$store.dispatch('user:set', {'flags.communityGuidelinesAccepted': true}); this.$store.dispatch('user:set', {'flags.communityGuidelinesAccepted': true});
}, },
toggleSleep () { toggleSleep () {
this.user.preferences.sleep = !this.user.preferences.sleep;
this.$store.dispatch('user:sleep'); this.$store.dispatch('user:sleep');
}, },
async sendMessage () { async sendMessage () {

View File

@@ -19,8 +19,10 @@
<script> <script>
import { mapState } from 'client/libs/store'; import { mapState } from 'client/libs/store';
import styleHelper from 'client/mixins/styleHelper';
export default { export default {
mixins: [styleHelper],
data () { data () {
return { return {
patrons: [], patrons: [],
@@ -33,21 +35,7 @@ export default {
...mapState({user: 'user.data'}), ...mapState({user: 'user.data'}),
}, },
methods: { methods: {
// @TODO: This is used to style usernames. WE should abstract this to helper mixer // @TODO: Import member modal - clickMember()
userLevelStyle (user, style) {
style = style || '';
let npc = user && user.backer && user.backer.npc ? user.backer.npc : '';
let level = user && user.contributor && user.contributor.level ? user.contributor.level : '';
style += this.userLevelStyleFromLevel(level, npc, style);
return style;
},
userLevelStyleFromLevel (level, npc, style) {
style = style || '';
if (npc) style += ' label-npc';
if (level) style += ` label-contributor-${level}`;
return style;
},
//@TODO: Import member modal - clickMember()
}, },
}; };
</script> </script>

View File

@@ -1,12 +1,13 @@
<template lang="pug"> <template lang="pug">
.d-flex.member-details(:class="{ condensed, expanded }") .d-flex.member-details(:class="{ condensed, expanded }", @click='showMemberModal()')
avatar(:member="member", avatar(:member="member",
@click.native="$emit('click')", @click.native="$emit('click')",
@mouseover.native="$emit('onHover')", @mouseover.native="$emit('onHover')",
@mouseout.native="$emit('onHover')", @mouseout.native="$emit('onHover')",
) )
member-modal(:profile='member')
.member-stats .member-stats
h3.character-name h3.character-name
| {{member.profile.name}} | {{member.profile.name}}
.is-buffed(v-if="isBuffed") .is-buffed(v-if="isBuffed")
.svg-icon(v-html="icons.buff") .svg-icon(v-html="icons.buff")
@@ -29,146 +30,147 @@
</template> </template>
<style lang="scss" scoped> <style lang="scss" scoped>
@import '~client/assets/scss/colors.scss'; @import '~client/assets/scss/colors.scss';
.member-details { .member-details {
white-space: nowrap; white-space: nowrap;
margin-top: 24px; margin-top: 24px;
margin-bottom: 24px; margin-bottom: 24px;
transition: all 0.15s ease-out; transition: all 0.15s ease-out;
}
.member-stats {
padding-left: 16px;
padding-right: 24px;
opacity: 1;
transition: opacity 0.15s ease-out;
}
.member-details.condensed:not(.expanded) .member-stats {
opacity: 0;
position: absolute;
z-index: -1;
}
// Condensed version
.member-details.condensed.expanded {
background: $header-dark-background;
box-shadow: 0 0 0px 9px $header-dark-background;
position: relative;
margin-bottom: 33px;
z-index: 8;
.is-buffed {
background-color: $purple-50;
} }
.member-stats { .member-stats {
background: $header-dark-background; padding-left: 16px;
padding-right: 24px;
opacity: 1;
transition: opacity 0.15s ease-out;
}
.member-details.condensed:not(.expanded) .member-stats {
opacity: 0;
position: absolute; position: absolute;
right: 100%; z-index: -1;
height: calc(100% + 18px); }
margin-top: -9px;
padding-top: 9px; // Condensed version
padding-bottom: 24px; .member-details.condensed.expanded {
padding-right: 16px; background: $header-dark-background;
padding-bottom: 14px; box-shadow: 0 0 0px 9px $header-dark-background;
border-top-left-radius: 4px; position: relative;
border-bottom-left-radius: 4px; margin-bottom: 33px;
z-index: 9; z-index: 8;
.is-buffed {
background-color: $purple-50;
}
.member-stats {
background: $header-dark-background;
position: absolute;
right: 100%;
height: calc(100% + 18px);
margin-top: -9px;
padding-top: 9px;
padding-bottom: 24px;
padding-right: 16px;
padding-bottom: 14px;
border-top-left-radius: 4px;
border-bottom-left-radius: 4px;
z-index: 9;
}
.progress-container > .svg-icon {
width: 19px;
height: 19px;
margin-top: -2px;
}
.progress-container > .progress {
width: 152px;
border-radius: 0px;
height: 10px;
margin-top: 2px;
background: $purple-100;
}
.progress-container > .progress > .progress-bar {
border-radius: 0px;
height: 10px;
}
}
.small-text {
color: $header-color;
}
.character-name {
margin-bottom: 1px;
color: $white;
}
.character-level {
display: block;
font-style: normal;
margin-bottom: 16px;
}
.is-buffed {
width: 20px;
height: 20px;
background: $header-dark-background;
display: inline-block;
margin-left: 16px;
vertical-align: middle;
padding-top: 4px;
.svg-icon {
display: block;
width: 10px;
height: 12px;
margin: 0 auto;
}
}
#header-avatar {
margin-right: 16px;
}
.progress-container {
margin-bottom: 12px;
}
.progress-container > span {
color: $header-color;
margin-left: 16px;
font-style: normal;
} }
.progress-container > .svg-icon { .progress-container > .svg-icon {
width: 19px; width: 24px;
height: 19px; height: 24px;
margin-top: -2px; margin-right: 8px;
margin-top: -4px;
} }
.progress-container > .progress { .progress-container > .progress {
width: 152px; width: 303px;
border-radius: 0px; margin: 0px;
height: 10px; border-radius: 2px;
margin-top: 2px; height: 16px;
background: $purple-100; background-color: $header-dark-background;
} }
.progress-container > .progress > .progress-bar { .progress-container > .progress > .progress-bar {
border-radius: 0px; border-radius: 2px;
height: 10px; height: 16px;
min-width: 0px;
} }
}
.small-text {
color: $header-color;
}
.character-name {
margin-bottom: 1px;
color: $white;
}
.character-level {
display: block;
font-style: normal;
margin-bottom: 16px;
}
.is-buffed {
width: 20px;
height: 20px;
background: $header-dark-background;
display: inline-block;
margin-left: 16px;
vertical-align: middle;
padding-top: 4px;
.svg-icon {
display: block;
width: 10px;
height: 12px;
margin: 0 auto;
}
}
#header-avatar {
margin-right: 16px;
}
.progress-container {
margin-bottom: 12px;
}
.progress-container > span {
color: $header-color;
margin-left: 16px;
font-style: normal;
}
.progress-container > .svg-icon {
width: 24px;
height: 24px;
margin-right: 8px;
margin-top: -4px;
}
.progress-container > .progress {
width: 303px;
margin: 0px;
border-radius: 2px;
height: 16px;
background-color: $header-dark-background;
}
.progress-container > .progress > .progress-bar {
border-radius: 2px;
height: 16px;
min-width: 0px;
}
</style> </style>
<script> <script>
import Avatar from './avatar'; import Avatar from './avatar';
import { mapState } from 'client/libs/store'; import { mapState } from 'client/libs/store';
import memberModal from './members/memberModal';
import { toNextLevel } from '../../common/script/statHelpers'; import { toNextLevel } from '../../common/script/statHelpers';
import statsComputed from '../../common/script/libs/statsComputed'; import statsComputed from '../../common/script/libs/statsComputed';
@@ -182,6 +184,7 @@ import manaIcon from 'assets/svg/mana.svg';
export default { export default {
components: { components: {
Avatar, Avatar,
memberModal,
}, },
props: { props: {
member: { member: {
@@ -231,6 +234,10 @@ export default {
hasClass () { hasClass () {
return this.$store.getters['members:hasClass'](this.member); return this.$store.getters['members:hasClass'](this.member);
}, },
showMemberModal () {
// @TODO: set viewing users in $store?
this.$root.$emit('show::modal', 'member-detail-modal');
},
}, },
}; };
</script> </script>

View File

@@ -3,7 +3,7 @@
.modal-header .modal-header
h4 h4
span {{profile.profile.name}} span {{profile.profile.name}}
span(v-if='contribText && profile.contributor.level') - {{contribText(profile.contributor, profile.backer)}} // @TODO span(v-if='contribText && profile.contributor.level') - {{contribText(profile.contributor, profile.backer)}}
.modal-body .modal-body
.container-fluid .container-fluid
.row .row
@@ -16,15 +16,15 @@
|&nbsp; |&nbsp;
| {{ $t('memberSince') }} | {{ $t('memberSince') }}
|&nbsp; |&nbsp;
| {{profile.auth.timestamps.created | date:user.preferences.dateFormat}} - // @TODO | {{profile.auth.timestamps.created | date:user.preferences.dateFormat}} -
li(v-if='profile.auth.timestamps.loggedin') li(v-if='profile.auth.timestamps.loggedin')
|&nbsp; |&nbsp;
| {{ $t('lastLoggedIn') }} | {{ $t('lastLoggedIn') }}
|&nbsp; |&nbsp;
| {{profile.auth.timestamps.loggedin | date:user.preferences.dateFormat}} - // @TODO | {{profile.auth.timestamps.loggedin | date:user.preferences.dateFormat}} -
h3 {{ $t('stats') }} h3 {{ $t('stats') }}
// @TODO: Figure out why this isn't showing up in front page // @TODO: Figure out why this isn't showing up in front page
.label.label-info {{ {warrior:env.t("warrior"), wizard:env.t("mage"), rogue:env.t("rogue"), healer:env.t("healer")}[profile.stats.class] }} // @TODO .label.label-info {{ {warrior:env.t("warrior"), wizard:env.t("mage"), rogue:env.t("rogue"), healer:env.t("healer")}[profile.stats.class] }}
// include ../profiles/stats_all // include ../profiles/stats_all
.col-md-6 .col-md-6
.row .row

View File

@@ -50,6 +50,59 @@
span.glyphicon.glyphicon-remove-circle span.glyphicon.glyphicon-remove-circle
</template> </template>
<style lang='scss' scoped>
@import '~client/assets/scss/colors.scss';
.svg-icon {
width: 25px;
}
.item-notifications:hover {
cursor: pointer;
}
/* @TODO: Move to shared css */
.dropdown:hover .dropdown-menu {
display: block;
margin-top: 0; // remove the gap so it doesn't close
}
.dropdown + .dropdown {
margin-left: 0px;
}
.dropdown-menu:not(.user-dropdown) {
background: $purple-200;
border-radius: 0px;
border: none;
box-shadow: none;
padding: 0px;
border-bottom-right-radius: 5px;
border-bottom-left-radius: 5px;
.dropdown-item {
font-size: 16px;
box-shadow: none;
color: $white;
border: none;
line-height: 1.5;
&.active {
background: $purple-300;
}
&:hover {
background: $purple-300;
&:last-child {
border-bottom-right-radius: 5px;
border-bottom-left-radius: 5px;
}
}
}
}
</style>
<script> <script>
import isEmpty from 'lodash/isEmpty'; import isEmpty from 'lodash/isEmpty';
import map from 'lodash/map'; import map from 'lodash/map';

View File

@@ -1,51 +0,0 @@
<template lang="pug">
.row
.col-12
h1.page-header Conversation
.card(v-for="message in messages")
.card-block
strong {{message.from}}
span {{message.date}}
p {{message.message}}
form.form.mt-2(@submit.prevent='reply')
.form-group
textarea.form-control(rows="3", v-model='newMessage')
button.btn.btn-primary(type="submit") Add Reply
</template>
<script>
export default {
data () {
// @TODO: Abstract to Store
let messages = [
{
from: 'Paglias',
fromUserId: 1234,
to: 'TheHollidayInn',
message: 'I love the Gang of Four',
date: new Date(),
},
];
return {
messages,
newMessage: '',
};
},
methods: {
reply: function reply () {
// @TODO: This will be default values based on the conversation and current user
let messageToSend = {
from: 'TheHollidayInn',
fromUserId: 3211,
to: 'Paglias',
message: this.newMessage,
date: new Date(),
};
this.messages.push(messageToSend);
this.newMessage = '';
},
},
};
</script>

View File

@@ -1,35 +0,0 @@
<template lang="pug">
.row
.col-12
h1.page-header(v-once) {{ $t('inbox') }}
.card(v-for="conversation in conversations")
.card-block
router-link(:to="{ name: 'conversation', params: { id: conversation.fromUserId } }")
| {{ conversation.from }}
</template>
<script>
export default {
data () {
// @TODO: Abstract to Store
let messages = [
{
from: 'Paglias',
fromUserId: 1234,
to: 'TheHollidayInn',
message: 'I love the Gang of Four',
},
];
let conversations = {};
for (let message of messages) {
if (!conversations[message.fromUserId]) conversations[message.fromUserId] = message;
}
return {
conversations,
};
},
};
</script>

View File

@@ -1,48 +1,51 @@
<template lang="pug"> <template lang="pug">
.standard-page .standard-page.container
h1 Achievements .row(v-for='(category, key) in achievements')
h2.col-12 {{ $t(key+'Achievs') }}
.col-3.text-center(v-for='achievment in category.achievements')
div.achievement-container(:data-popover-html='achievment.title + achievment.text',
popover-placement='achievPopoverPlacement',
popover-append-to-body='achievAppendToBody')
div(popover-trigger='mouseenter',
:data-popover-html='achievment.title + achievment.text',
popover-placement='achievPopoverPlacement',
popover-append-to-body='achievAppendToBody')
.achievement(:class='achievment.icon + "2x"', v-if='achievment.earned')
.counter.badge.badge-info.stack-count(v-if='achievment.optionalCount') {{achievment.optionalCount}}
.achievement(class='achievement-unearned2x', v-if='!achievment.earned')
.row .row
.col-12(v-for='(category, key) in achievements') .col-6
h2 {{ $t(key+'Achievs') }} h2 Challeges Won
.row
.col-1(v-for='achievment in category.achievements')
div.achievement-container(:data-popover-html='achievment.title + achievment.text',
popover-placement='achievPopoverPlacement',
popover-append-to-body='achievAppendToBody')
div(popover-trigger='mouseenter',
:data-popover-html='achievment.title + achievment.text',
popover-placement='achievPopoverPlacement',
popover-append-to-body='achievAppendToBody')
.achievement(:class='achievment.icon + "2x"', v-if='achievment.earned')
.counter.badge.badge-info.stack-count(v-if='achievment.optionalCount') {{achievment.optionalCount}}
.achievement(class='achievement-unearned2x', v-if='!achievment.earned')
.col-12(:class="{ muted: !user.achievements.challenges.length }")
h2(v-once) {{ $t('challengeWinner') }}
div(v-for='chal in user.achievements.challenges') div(v-for='chal in user.achievements.challenges')
span {{chal}} span {{chal}}
.col-6
.col-12(:class="{ muted: !user.achievements.quests }") h2 Quests Completed
h2(v-once) {{ $t('completedQuests') }}
div(v-for='(value, key) in user.achievements.quests') div(v-for='(value, key) in user.achievements.quests')
span {{ content.quests[k].text() }} span {{ content.quests[k].text() }}
span {{ value }} span {{ value }}
</template> </template>
<style lang='scss' scoped> <style lang="scss" scoped>
h2 { h2 {
margin-top: 2em; margin-top: 2em;
} }
.achievement-container { .achievement-container {
margin-bottom: 1em; margin-bottom: 1em;
padding: 2em;
background: #fff;
}
.achievement {
margin: 0 auto;
} }
.counter.badge { .counter.badge {
color: #fff; color: #fff;
position: absolute; position: absolute;
bottom: 0; top: 0;
left: 44px; right: 0;
background-color: #ff944c;
} }
</style> </style>

View File

@@ -25,11 +25,11 @@
.conversations(v-if='filtersConversations.length > 0') .conversations(v-if='filtersConversations.length > 0')
.conversation(v-for='conversation in conversations', @click='selectConversation(conversation.key)', :class="{active: selectedConversation === conversation.key}") .conversation(v-for='conversation in conversations', @click='selectConversation(conversation.key)', :class="{active: selectedConversation === conversation.key}")
div div
span {{conversation.name}} span(:class="userLevelStyle(conversation)") {{conversation.name}}
span.timeago {{conversation.date}} span.timeago {{conversation.date}}
div {{conversation.lastMessageText}} div {{conversation.lastMessageText}}
.col-8.messages .col-8.messages
.message(v-for='message in currentMessages') {{message.text}} chat-message.container-fluid(:chat.sync='activeChat')
// @TODO: Implement new message header here when we fix the above // @TODO: Implement new message header here when we fix the above
@@ -64,6 +64,7 @@
.messages { .messages {
position: relative; position: relative;
padding-left: 0; padding-left: 0;
padding-bottom: 6em;
} }
.to-form input { .to-form input {
@@ -129,17 +130,22 @@
<script> <script>
import moment from 'moment'; import moment from 'moment';
import filter from 'lodash/filter'; import filter from 'lodash/filter';
import sortBy from 'lodash/sortBy';
import { mapState } from 'client/libs/store'; import { mapState } from 'client/libs/store';
import styleHelper from 'client/mixins/styleHelper';
import bModal from 'bootstrap-vue/lib/components/modal'; import bModal from 'bootstrap-vue/lib/components/modal';
import bFormInput from 'bootstrap-vue/lib/components/form-input'; import bFormInput from 'bootstrap-vue/lib/components/form-input';
import messageIcon from 'assets/svg/message.svg'; import messageIcon from 'assets/svg/message.svg';
import chatMessage from '../chat/chatMessages';
export default { export default {
mixins: [styleHelper],
components: { components: {
bModal, bModal,
bFormInput, bFormInput,
chatMessage,
}, },
data () { data () {
return { return {
@@ -150,6 +156,7 @@ export default {
selectedConversation: '', selectedConversation: '',
search: '', search: '',
newMessage: '', newMessage: '',
activeChat: [],
}; };
}, },
computed: { computed: {
@@ -160,7 +167,10 @@ export default {
let message = this.user.inbox.messages[messageId]; let message = this.user.inbox.messages[messageId];
let userId = message.uuid; let userId = message.uuid;
if (!this.selectedConversation) this.selectedConversation = userId; if (!this.selectedConversation) {
this.selectedConversation = userId;
this.selectConversation(userId);
}
if (!conversations[userId]) { if (!conversations[userId]) {
conversations[userId] = { conversations[userId] = {
@@ -197,6 +207,10 @@ export default {
}, },
selectConversation (key) { selectConversation (key) {
this.selectedConversation = key; this.selectedConversation = key;
this.activeChat = this.conversations[this.selectedConversation].messages;
this.activeChat = sortBy(this.activeChat, [(o) => {
return o.timestamp;
}]);
}, },
sendPrivateMessage () { sendPrivateMessage () {
this.$store.dispatch('members:sendPrivateMessage', { this.$store.dispatch('members:sendPrivateMessage', {
@@ -208,6 +222,9 @@ export default {
text: this.newMessage, text: this.newMessage,
timestamp: new Date(), timestamp: new Date(),
}); });
this.activeChat = this.conversations[this.selectedConversation].messages;
this.conversations[this.selectedConversation].lastMessageText = this.newMessage; this.conversations[this.selectedConversation].lastMessageText = this.newMessage;
this.conversations[this.selectedConversation].date = new Date(); this.conversations[this.selectedConversation].date = new Date();

View File

@@ -1,37 +1,44 @@
<template lang="pug"> <template lang="pug">
.standard-page .standard-page
h2 Profile
.row .row
.col-md-12(v-if='!editing') .col-8
button.btn.btn-default(@click='editing = true') {{ $t('edit') }} .header
h2 {{ $t('displayName') }} h1 {{user.profile.name}}
span(v-if='user.profile.name') {{user.profile.name}} h4
p strong User Id:
small.muted {{ $t('displayNameDescription1') }} | {{user._id}}
| &nbsp; .col-4
a(href='/#/options/settings/settings') {{ $t('displayNameDescription2') }} button.btn.btn-secondary(@click='editing = !editing') Edit
| &nbsp; .row(v-if='!editing')
| {{ $t('displayNameDescription3') }} .col-8
span.muted(ng-hide='user.profile.name') -&nbsp; .about
| {{ $t('none') }} h2 About
| &nbsp;- p {{user.profile.blurb}}
.photo
h2 Photo
img.img-rendering-auto(v-if='user.profile.imageUrl', :src='user.profile.imageUrl')
h2 {{ $t('displayPhoto') }} .col-4
img.img-rendering-auto(v-if='user.profile.imageUrl', :src='user.profile.imageUrl') .info
span.muted(ng-hide='user.profile.imageUrl') -&nbsp; h2 info
| {{ $t('none') }} div
| &nbsp;- strong Joined:
| {{user.auth.timestamps.created}}
div
strong Total Log Ins:
span {{ $t('totalCheckins', {count: user.loginIncentives}) }}
div
| {{getProgressDisplay()}}
.progress
.progress-bar(role='progressbar', :aria-valuenow='incentivesProgress', aria-valuemin='0', aria-valuemax='100', :style='{width: incentivesProgress + "%"}')
span.sr-only {{ incentivesProgress }}% Complete
// @TODO: Implement in V2 .social
.row(v-if='editing')
h1 Edit Profile
.col-12
.alert.alert-info.alert-sm(v-html='$t("communityGuidelinesWarning", managerEmail)')
h2 {{ $t('displayBlurb') }}
markdown(v-if='user.profile.blurb', text='user.profile.blurb')
span.muted(ng-hide='user.profile.blurb') -&nbsp;
| {{ $t('none') }}
| &nbsp;-
//{{user.profile.blurb | linky:'_blank'}}
.col-md-12(v-if='editing')
.alert.alert-info.alert-sm
| {{ $t("communityGuidelinesWarning", managerEmail) }}
button.btn.btn-primary(type='submit', @click='save()') {{ $t("save") }}
// TODO use photo-upload instead: https://groups.google.com/forum/?fromgroups=#!topic/derbyjs/xMmADvxBOak // TODO use photo-upload instead: https://groups.google.com/forum/?fromgroups=#!topic/derbyjs/xMmADvxBOak
.form-group .form-group
label {{ $t('displayName') }} label {{ $t('displayName') }}
@@ -40,26 +47,35 @@
label {{ $t('photoUrl') }} label {{ $t('photoUrl') }}
input.form-control(type='url', v-model='editingProfile.imageUrl', :placeholder="$t('imageUrl')") input.form-control(type='url', v-model='editingProfile.imageUrl', :placeholder="$t('imageUrl')")
.form-group .form-group
label {{ $t('displayBlurb') }} label {{ $t('about') }}
textarea.form-control(rows=5, :placeholder="$t('displayBlurbPlaceholder')", v-model='editingProfile.blurb') textarea.form-control(rows=5, :placeholder="$t('displayBlurbPlaceholder')", v-model='editingProfile.blurb')
// include ../../shared/formatting-help // include ../../shared/formatting-help
.row .form-group
.col-md-6 label Facebook
h2 {{ $t('totalCheckinsTitle') }} input.form-control(type='text', placeholder="Paste your link here", v-model='editingProfile.facebook')
span {{ $t('totalCheckins', {count: user.loginIncentives}) }} .form-group
.col-md-6 label Instagram
h2 input.form-control(type='text', placeholder="Paste your link here", v-model='editingProfile.instagram')
| {{getProgressDisplay()}} .form-group
.progress label Twitter
.progress-bar(role='progressbar', :aria-valuenow='incentivesProgress', aria-valuemin='0', aria-valuemax='100', :style='{width: incentivesProgress + "%"}') input.form-control(type='text', placeholder="Paste your link here", v-model='editingProfile.twitter')
span.sr-only {{ incentivesProgress }}% Complete
.col-3.offset-6.text.center
button.btn.btn-primary(@click='save()') {{ $t("save") }}
button.btn.btn-warning(@click='editing = false') {{ $t("cancel") }}
</template> </template>
<style lang="scss" scoped> <style lang="scss" scoped>
@import '~client/assets/scss/colors.scss'; @import '~client/assets/scss/colors.scss';
h2 { .header {
margin-top: 2em; h1 {
color: #4f2a93;
}
h4 {
color: #686274;
}
} }
</style> </style>

View File

@@ -1,6 +1,27 @@
<template lang="pug"> <template lang="pug">
.standard-page .standard-page
h1 Stats h1 Stats
.row
.col-6
h2.text-center Equipment
.well.row
.col-4
.col-6
h2.text-center Costume
.row
.col-6
h2.text-center Pet
.col-6
h2.text-center Mount
.row
hr.col-12
h2.col-12 Attributes
.col-6
.col-6
.row
.col-6
.col-6
.row .row
.col-4 .col-4
div div
@@ -147,7 +168,7 @@
:popover='$t(statInfo.allocatepop)') + :popover='$t(statInfo.allocatepop)') +
</template> </template>
<style lang='scss' scoped> <style lang="scss" scoped>
.btn-xs { .btn-xs {
font-size: 12px; font-size: 12px;

View File

@@ -0,0 +1,17 @@
export default {
methods: {
userLevelStyle (user, style) {
style = style || '';
let npc = user && user.backer && user.backer.npc ? user.backer.npc : '';
let level = user && user.contributor && user.contributor.level ? user.contributor.level : '';
style += this.userLevelStyleFromLevel(level, npc, style);
return style;
},
userLevelStyleFromLevel (level, npc, style) {
style = style || '';
if (npc) style += ' label-npc';
if (level) style += ` label-contributor-${level}`;
return style;
},
},
};

View File

@@ -2,7 +2,7 @@ import Vue from 'vue';
import VueRouter from 'vue-router'; import VueRouter from 'vue-router';
import getStore from 'client/store'; import getStore from 'client/store';
import EmptyView from './components/emptyView'; // import EmptyView from './components/emptyView';
// TODO Dummy elements used as placeholder until real components are implemented // TODO Dummy elements used as placeholder until real components are implemented
import ParentPage from './components/parentPage'; import ParentPage from './components/parentPage';
@@ -66,10 +66,6 @@ const ItemsPage = () => import(/* webpackChunkName: "inventory" */'./components/
const EquipmentPage = () => import(/* webpackChunkName: "inventory" */'./components/inventory/equipment/index'); const EquipmentPage = () => import(/* webpackChunkName: "inventory" */'./components/inventory/equipment/index');
const StablePage = () => import(/* webpackChunkName: "inventory" */'./components/inventory/stable/index'); const StablePage = () => import(/* webpackChunkName: "inventory" */'./components/inventory/stable/index');
// Social
const InboxPage = () => import(/* webpackChunkName: "inbox" */ './components/social/inbox/index');
const InboxConversationPage = () => import(/* webpackChunkName: "inbox" */ './components/social/inbox/conversationPage');
// Guilds // Guilds
const GuildIndex = () => import(/* webpackChunkName: "guilds" */ './components/groups/index'); const GuildIndex = () => import(/* webpackChunkName: "guilds" */ './components/groups/index');
const TavernPage = () => import(/* webpackChunkName: "guilds" */ './components/groups/tavern'); const TavernPage = () => import(/* webpackChunkName: "guilds" */ './components/groups/tavern');
@@ -178,22 +174,6 @@ const router = new VueRouter({
component: ParentPage, component: ParentPage,
children: [ children: [
{ name: 'avatar', path: 'avatar', component: Page }, { name: 'avatar', path: 'avatar', component: Page },
{
path: 'inbox',
component: EmptyView,
children: [
{
name: 'inbox',
path: '',
component: InboxPage,
},
{
name: 'conversation',
path: 'conversation/:id',
component: InboxConversationPage,
},
],
},
{ name: 'backgrounds', path: 'backgrounds', component: BackgroundsPage }, { name: 'backgrounds', path: 'backgrounds', component: BackgroundsPage },
{ name: 'stats', path: 'stats', component: StatsPage }, { name: 'stats', path: 'stats', component: StatsPage },
{ name: 'achievements', path: 'achievements', component: AchievementsPage }, { name: 'achievements', path: 'achievements', component: AchievementsPage },

View File

@@ -16,7 +16,7 @@ export async function joinChallenge (store, payload) {
} }
export async function leaveChallenge (store, payload) { export async function leaveChallenge (store, payload) {
let response = await axios.post(`/api/v3/challenges/${payload.challengeId}/join`, { let response = await axios.post(`/api/v3/challenges/${payload.challengeId}/leave`, {
data: { data: {
keep: payload.keep, keep: payload.keep,
}, },

View File

@@ -15,11 +15,11 @@ export async function getPublicGuilds (store, payload) {
} }
export async function getMyGuilds (store) { export async function getMyGuilds (store) {
let response = await axios.get('/api/v3/groups', { let params = {
params: { type: 'guilds',
type: 'privateGuilds', };
},
}); let response = await axios.get('/api/v3/groups', { params });
let guilds = response.data.data; let guilds = response.data.data;
store.state.myGuilds = guilds; store.state.myGuilds = guilds;
@@ -92,9 +92,7 @@ export async function update (store, payload) {
let groupDetailsToSend = omit(payload.group, ['chat', 'challenges', 'members', 'invites']); let groupDetailsToSend = omit(payload.group, ['chat', 'challenges', 'members', 'invites']);
if (groupDetailsToSend.leader && groupDetailsToSend.leader._id) groupDetailsToSend.leader = groupDetailsToSend.leader._id; if (groupDetailsToSend.leader && groupDetailsToSend.leader._id) groupDetailsToSend.leader = groupDetailsToSend.leader._id;
let response = await axios.put(`/api/v3/groups/${payload.group.id}`, { let response = await axios.put(`/api/v3/groups/${payload.group.id}`, groupDetailsToSend);
data: groupDetailsToSend,
});
let updatedGroup = response.data.data; let updatedGroup = response.data.data;

View File

@@ -36,16 +36,16 @@ export function sellItems (store, params) {
} }
export function pinGear (store, params) { export function pinGear () {
//axios // axios
// .post(`/api/v3/user/pin/${params.key}`); // .post(`/api/v3/user/pin/${params.key}`);
// TODO // TODO
// .then((res) => console.log('equip', res)) // .then((res) => console.log('equip', res))
// .catch((err) => console.error('equip', err)); // .catch((err) => console.error('equip', err));
} }
export function unpinGear (store, params) { export function unpinGear () {
//axios // axios
// .post(`/api/v3/user/unpin/${params.key}`); // .post(`/api/v3/user/unpin/${params.key}`);
// TODO // TODO
// .then((res) => console.log('equip', res)) // .then((res) => console.log('equip', res))

View File

@@ -27,8 +27,9 @@ export function set (store, changes) {
// .catch((err) => console.error('set', err)); // .catch((err) => console.error('set', err));
} }
export function sleep () { export async function sleep () {
// @TODO: Implemented let response = await axios.post('/api/v3/user/sleep');
return response.data.data;
} }
export async function addWebhook (store, payload) { export async function addWebhook (store, payload) {

View File

@@ -213,7 +213,6 @@
"where": "Where*", "where": "Where*",
"challengeMinimum": "Minimum 1 Gem for public Challenges (helps prevent spam, it really does).", "challengeMinimum": "Minimum 1 Gem for public Challenges (helps prevent spam, it really does).",
"group": "Group", "group": "Group",
"sortByType": "Type", "sortByType": "Type",
"sortByPrice": "Price", "sortByPrice": "Price",
"sortByCon": "Con", "sortByCon": "Con",
@@ -228,5 +227,8 @@
"sell": "Sell", "sell": "Sell",
"buyNow": "Buy Now", "buyNow": "Buy Now",
"sortByNumber": "Number", "sortByNumber": "Number",
"featuredItems": "Featured Items!" "featuredItems": "Featured Items!",
"not_participating": "Not Participating",
"owned": "Owned",
"not_owned": "Not Owned"
} }