New client flurry of fixes (#8973)

* Fixed login/reg styles and on submit

* Fixed duedate display in yesterdailiy modal

* Prevented tutorial from showing after logged in has past created

* Hide premium shirts from creating

* Fixed level up notification

* Updated categoires

* Updated justin message

* Fixed notification changes

* Fixed guild nav in join guild modal

* Added buygems modal

* Removed avatar page click

* Fixed group plan nav

* Fixed death issue

* Fixed party header styles
This commit is contained in:
Keith Holliday
2017-08-21 13:28:27 -06:00
committed by GitHub
parent 2760de7951
commit e9141ff5c9
13 changed files with 111 additions and 49 deletions

View File

@@ -46,6 +46,9 @@ export default {
created () { created () {
// Set up Error interceptors // Set up Error interceptors
axios.interceptors.response.use((response) => { axios.interceptors.response.use((response) => {
if (this.user) {
this.$set(this.user, 'notifications', response.data.notifications);
}
return response; return response;
}, (error) => { }, (error) => {
if (error.response.status >= 400) { if (error.response.status >= 400) {

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 18 18">
<path fill="#4267B2" fill-rule="evenodd" d="M17.007 0H.993A.993.993 0 0 0 0 .993v16.014c0 .548.445.993.993.993h8.621v-6.97H7.27V8.312h2.345V6.31c0-2.325 1.42-3.591 3.494-3.591.994 0 1.848.074 2.096.107v2.43h-1.438c-1.128 0-1.346.536-1.346 1.322v1.735h2.69l-.35 2.716h-2.34V18h4.587a.993.993 0 0 0 .993-.993V.993A.993.993 0 0 0 17.007 0"/>
</svg>

After

Width:  |  Height:  |  Size: 434 B

View File

@@ -22,7 +22,7 @@
li.spaced {{ $t('lowHealthTips4') }} li.spaced {{ $t('lowHealthTips4') }}
h4 {{ $t('goodLuck') }} h4 {{ $t('goodLuck') }}
.modal-footer .modal-footer
a.btn.btn-primary(@click='acknowledgeHealthWarning(); close()') {{ $t('ok') }} a.btn.btn-primary(@click='acknowledgeHealthWarning()') {{ $t('ok') }}
</template> </template>
<style scope> <style scope>
@@ -81,7 +81,10 @@ export default {
this.$root.$emit('hide::modal', 'low-health'); this.$root.$emit('hide::modal', 'low-health');
}, },
acknowledgeHealthWarning () { acknowledgeHealthWarning () {
// @TODO: {'flags.warnedLowHealth':true} this.$store.dispatch('user:set', {
'flags.warnedLowHealth': true,
});
this.close();
}, },
}, },
}; };

View File

@@ -10,10 +10,10 @@
.modal-footer .modal-footer
.container-fluid .container-fluid
.row .row
.col-xs-6.text-center .col-6.text-center
button.btn-lg.btn-default(@click='close()') {{ $t('guildReminderDismiss') }} button.btn.btn-secondary(@click='close()') {{ $t('guildReminderDismiss') }}
.col-xs-6.text-center .col-6.text-center(@click='close()')
button.btn-lg.btn-primary(ui-sref='options.social.guilds.public', href='/#/options/groups/guilds/public', ng-click='$close()') {{ $t('guildReminderCTA') }} router-link.btn.btn-primary(:to="{ name: 'guildsDiscovery'}") {{ $t('guildReminderCTA') }}
</template> </template>
<style scope> <style scope>

View File

@@ -2,11 +2,11 @@
#app-header.row #app-header.row
create-party-modal create-party-modal
members-modal(:group='user.party', :hide-badge="true") members-modal(:group='user.party', :hide-badge="true")
member-details(:member="user", @click="$router.push({name: 'avatar'})") member-details(:member="user")
.view-party(v-if="user.party && user.party._id") .view-party(v-if="user.party && user.party._id && partyMembers && partyMembers.length > 1")
// TODO button should open the party members modal // TODO button should open the party members modal
button.btn.btn-primary(@click='openPartyModal()') {{ $t('viewParty') }} button.btn.btn-primary(@click='openPartyModal()') {{ $t('viewParty') }}
.party-members.d-flex(v-if="partyMembers && partyMembers.length > 1") .col-6.party-members.d-flex.flex-row(v-if="partyMembers && partyMembers.length > 1")
member-details( member-details(
v-for="(member, $index) in partyMembers", v-for="(member, $index) in partyMembers",
:key="member._id", :key="member._id",
@@ -49,6 +49,8 @@
} }
.party-members { .party-members {
max-width: 100%;
overflow: scroll;
} }
.view-party { .view-party {

View File

@@ -31,15 +31,12 @@ div
router-link.dropdown-item(:to="{name: 'myGuilds'}") {{ $t('myGuilds') }} router-link.dropdown-item(:to="{name: 'myGuilds'}") {{ $t('myGuilds') }}
router-link.dropdown-item(:to="{name: 'guildsDiscovery'}") {{ $t('guildsDiscovery') }} router-link.dropdown-item(:to="{name: 'guildsDiscovery'}") {{ $t('guildsDiscovery') }}
router-link.nav-item.dropdown( router-link.nav-item.dropdown(
v-if='groupPlans.length === 0',
tag="li", tag="li",
:to="{name: 'groupPlan'}", :to="{name: 'groupPlan'}",
:class="{'active': $route.path.startsWith('/group-plan')}") :class="{'active': $route.path.startsWith('/group-plan')}")
a.nav-link(v-once) {{ $t('group') }} a.nav-link(v-once) {{ $t('group') }}
.nav-item.dropdown(v-if='groupPlans.length > 0', :class="{'active': $route.path.startsWith('/group-plans')}") .dropdown-menu
a.nav-link(v-once) {{ $t('group') }} router-link.dropdown-item(v-for='group in groupPlans', :key='group._id', :to="{name: 'groupPlanDetailTaskInformation', params: {groupId: group._id}}") {{ group.name }}
.dropdown-menu
router-link.dropdown-item(v-for='group in groupPlans', :key='group._id', :to="{name: 'groupPlanDetailTaskInformation', params: {groupId: group._id}}") {{ group.name }}
router-link.nav-item(tag="li", :to="{name: 'myChallenges'}", exact) router-link.nav-item(tag="li", :to="{name: 'myChallenges'}", exact)
a.nav-link(v-once) {{ $t('challenges') }} a.nav-link(v-once) {{ $t('challenges') }}
router-link.nav-item.dropdown(tag="li", to="/help", :class="{'active': $route.path.startsWith('/help')}", :to="{name: 'faq'}") router-link.nav-item.dropdown(tag="li", to="/help", :class="{'active': $route.path.startsWith('/help')}", :to="{name: 'faq'}")
@@ -56,7 +53,7 @@ div
.svg-icon(v-html="icons.hourglasses") .svg-icon(v-html="icons.hourglasses")
span {{ userHourglasses }} span {{ userHourglasses }}
.item-with-icon .item-with-icon
.svg-icon(v-html="icons.gem") .svg-icon.gem(v-html="icons.gem", @click='showBuyGemsModal()')
span {{userGems | roundBigNumber}} span {{userGems | roundBigNumber}}
.item-with-icon .item-with-icon
.svg-icon(v-html="icons.gold") .svg-icon(v-html="icons.gold")
@@ -215,6 +212,10 @@ div
padding-top: 16px; padding-top: 16px;
padding-bottom: 16px; padding-bottom: 16px;
} }
.gem:hover {
cursor: pointer;
}
</style> </style>
<script> <script>
@@ -275,6 +276,9 @@ export default {
async getUserGroupPlans () { async getUserGroupPlans () {
this.groupPlans = await this.$store.dispatch('guilds:getGroupPlans'); this.groupPlans = await this.$store.dispatch('guilds:getGroupPlans');
}, },
showBuyGemsModal () {
this.$root.$emit('show::modal', 'buy-gems');
},
}, },
}; };
</script> </script>

View File

@@ -3,7 +3,7 @@
#top-background #top-background
.seamless_stars_varied_opacity_repeat .seamless_stars_varied_opacity_repeat
#login-form form#login-form(v-on:submit.prevent='handleSubmit', @keyup.enter="handleSubmit")
.text-center .text-center
div div
.svg-icon.gryphon(v-html="icons.gryphon") .svg-icon.gryphon(v-html="icons.gryphon")
@@ -13,11 +13,11 @@
.col-6 .col-6
.btn.btn-secondary.social-button(@click='socialAuth("facebook")', v-once) .btn.btn-secondary.social-button(@click='socialAuth("facebook")', v-once)
.svg-icon.social-icon(v-html="icons.facebookIcon") .svg-icon.social-icon(v-html="icons.facebookIcon")
span {{this.registering ? $t('signUpWithSocial', {social: 'Facebook'}) : $t('loginWithSocial', {social: 'Facebook'})}} .text {{this.registering ? $t('signUpWithSocial', {social: 'Facebook'}) : $t('loginWithSocial', {social: 'Facebook'})}}
.col-6 .col-6
.btn.btn-secondary.social-button(@click='socialAuth("google")', v-once) .btn.btn-secondary.social-button(@click='socialAuth("google")', v-once)
.svg-icon.social-icon(v-html="icons.googleIcon") .svg-icon.social-icon(v-html="icons.googleIcon")
span {{this.registering ? $t('signUpWithSocial', {social: 'Google'}) : $t('loginWithSocial', {social: 'Google'})}} .text {{this.registering ? $t('signUpWithSocial', {social: 'Google'}) : $t('loginWithSocial', {social: 'Google'})}}
.form-group .form-group
label(for='usernameInput', v-once) {{$t('username')}} label(for='usernameInput', v-once) {{$t('username')}}
input#usernameInput.form-control(type='text', :placeholder='$t("usernamePlaceholder")', v-model='username') input#usernameInput.form-control(type='text', :placeholder='$t("usernamePlaceholder")', v-model='username')
@@ -40,16 +40,33 @@
router-link(:to="{name: 'register'}", v-if='!registering', exact) router-link(:to="{name: 'register'}", v-if='!registering', exact)
a.toggle-link(v-once) Don't have an account? Join Habitica! a.toggle-link(v-once) Don't have an account? Join Habitica!
#bottom-background #bottom-wrap
.seamless_mountains_demo_repeat #bottom-background
.midground_foreground_extended2 .seamless_mountains_demo_repeat
.midground_foreground_extended2
</template> </template>
<style>
html, body, #app {
min-height: 100%;
}
small a {
color: #fff;
}
</style>
<style lang="scss" scoped> <style lang="scss" scoped>
@import '~client/assets/scss/colors.scss'; @import '~client/assets/scss/colors.scss';
.form-wrapper { .form-wrapper {
background-color: $purple-200; background-color: $purple-200;
background: $purple-200; /* For browsers that do not support gradients */
background: -webkit-linear-gradient(to bottom, #4f2a93, #6133b4); /* For Safari 5.1 to 6.0 */
background: -o-linear-gradient(to bottom, #4f2a93, #6133b4); /* For Opera 11.1 to 12.0 */
background: -moz-linear-gradient(to bottom, #4f2a93, #6133b4); /* For Firefox 3.6 to 15 */
background: linear-gradient(to bottom, #4f2a93, #6133b4); /* Standard syntax */
min-height: 100%;
} }
::-webkit-input-placeholder { /* Chrome/Opera/Safari */ ::-webkit-input-placeholder { /* Chrome/Opera/Safari */
@@ -107,14 +124,20 @@
.social-button { .social-button {
width: 100%; width: 100%;
text-align: left; text-align: center;
.text {
display: inline-block;
}
} }
.social-icon { .social-icon {
margin-right: 1em; margin-right: 1em;
width: 13px; width: 18px;
height: 18px;
display: inline-block; display: inline-block;
height: 13px; vertical-align: top;
margin-top: .2em;
} }
} }
@@ -124,17 +147,21 @@
background-repeat: repeat-x; background-repeat: repeat-x;
position: absolute; position: absolute;
height: 500px; height: 500px;
width: 1517px; width: 100%;
} }
} }
#bottom-wrap {
margin-top: 6em;
}
#bottom-background { #bottom-background {
position: relative; position: relative;
.seamless_mountains_demo_repeat { .seamless_mountains_demo_repeat {
background-image: url('~assets/images/auth/seamless_mountains_demo.png'); background-image: url('~assets/images/auth/seamless_mountains_demo.png');
background-repeat: repeat-x; background-repeat: repeat-x;
width: 1517px; width: 100%;
height: 500px; height: 500px;
position: absolute; position: absolute;
z-index: 0; z-index: 0;
@@ -145,7 +172,9 @@
background-image: url('~assets/images/auth/midground_foreground_extended2.png'); background-image: url('~assets/images/auth/midground_foreground_extended2.png');
position: relative; position: relative;
width: 1500px; width: 1500px;
max-width: 100%;
height: 150px; height: 150px;
margin: 0 auto;
} }
} }
@@ -163,7 +192,7 @@ import hello from 'hellojs';
import gryphon from 'assets/svg/gryphon.svg'; import gryphon from 'assets/svg/gryphon.svg';
import habiticaIcon from 'assets/svg/habitica-logo.svg'; import habiticaIcon from 'assets/svg/habitica-logo.svg';
import facebookIcon from 'assets/svg/facebook.svg'; import facebookSquareIcon from 'assets/svg/facebook-square.svg';
import googleIcon from 'assets/svg/google.svg'; import googleIcon from 'assets/svg/google.svg';
export default { export default {
@@ -178,7 +207,7 @@ export default {
data.icons = Object.freeze({ data.icons = Object.freeze({
gryphon, gryphon,
habiticaIcon, habiticaIcon,
facebookIcon, facebookIcon: facebookSquareIcon,
googleIcon, googleIcon,
}); });
@@ -244,6 +273,14 @@ export default {
window.location.href = '/'; window.location.href = '/';
}, },
handleSubmit () {
if (this.registering) {
this.register();
return;
}
this.login();
},
}, },
}; };
</script> </script>

View File

@@ -53,7 +53,7 @@ b-modal#avatar-modal(title="", size='lg', :hide-header='true', :hide-footer='tru
.slim_shirt_pink.option(@click='set({"preferences.shirt":"pink"})', :class='{active: user.preferences.shirt === "pink"}') .slim_shirt_pink.option(@click='set({"preferences.shirt":"pink"})', :class='{active: user.preferences.shirt === "pink"}')
.slim_shirt_white.option(@click='set({"preferences.shirt":"white"})', :class='{active: user.preferences.shirt === "white"}') .slim_shirt_white.option(@click='set({"preferences.shirt":"white"})', :class='{active: user.preferences.shirt === "white"}')
.slim_shirt_yellow.option(@click='set({"preferences.shirt":"yellow"})', :class='{active: user.preferences.shirt === "yellow"}') .slim_shirt_yellow.option(@click='set({"preferences.shirt":"yellow"})', :class='{active: user.preferences.shirt === "yellow"}')
.col-12 .col-12.premium-shirts(v-if='editing')
.broad_shirt_convict.option(@click='set({"preferences.shirt":"convict"})', :class='{active: user.preferences.shirt === "convict"}') .broad_shirt_convict.option(@click='set({"preferences.shirt":"convict"})', :class='{active: user.preferences.shirt === "convict"}')
.section.customize-section(v-if='activeTopPage === "skin"') .section.customize-section(v-if='activeTopPage === "skin"')
@@ -198,7 +198,7 @@ b-modal#avatar-modal(title="", size='lg', :hide-header='true', :hide-footer='tru
label.custom-control.custom-checkbox label.custom-control.custom-checkbox
input.custom-control-input(type="checkbox") input.custom-control-input(type="checkbox")
span.custom-control-indicator span.custom-control-indicator
span.custom-control-description(v-once) {{ $t('health') }} span.custom-control-description(v-once) {{ $t('health_wellness') }}
div div
label.custom-control.custom-checkbox label.custom-control.custom-checkbox
input.custom-control-input(type="checkbox") input.custom-control-input(type="checkbox")
@@ -215,11 +215,6 @@ b-modal#avatar-modal(title="", size='lg', :hide-header='true', :hide-footer='tru
input.custom-control-input(type="checkbox") input.custom-control-input(type="checkbox")
span.custom-control-indicator span.custom-control-indicator
span.custom-control-description(v-once) {{ $t('creativity') }} span.custom-control-description(v-once) {{ $t('creativity') }}
div
label.custom-control.custom-checkbox
input.custom-control-input(type="checkbox")
span.custom-control-indicator
span.custom-control-description(v-once) {{ $t('budgeting') }}
.section.row.justin-message-section(:class='{top: modalPage > 1}') .section.row.justin-message-section(:class='{top: modalPage > 1}')
.col-9 .col-9

View File

@@ -141,15 +141,15 @@ export default {
}, },
watch: { watch: {
baileyShouldShow () { baileyShouldShow () {
this.$root.$emit('show:modal', 'new-stuff'); this.$root.$emit('show::modal', 'new-stuff');
}, },
userHp (after, before) { userHp (after, before) {
if (after <= 0) { if (after <= 0) {
this.playSound('Death'); this.playSound('Death');
this.$root.$emit('show:modal', 'death'); this.$root.$emit('show::modal', 'death');
// @TODO: {keyboard:false, backdrop:'static'} // @TODO: {keyboard:false, backdrop:'static'}
} else if (after <= 30 && !this.user.flags.warnedLowHealth) { } else if (after <= 30 && !this.user.flags.warnedLowHealth) {
this.$root.$emit('show:modal', 'low-health'); this.$root.$emit('show::modal', 'low-health');
// @TODO: {keyboard:false, backdrop:'static', controller:'UserCtrl', track:'Health Warning'} // @TODO: {keyboard:false, backdrop:'static', controller:'UserCtrl', track:'Health Warning'}
} }
if (after === before) return; if (after === before) return;
@@ -199,7 +199,7 @@ export default {
this.playSound('Level_Up'); this.playSound('Level_Up');
if (this.user._tmp && this.user._tmp.drop && this.user._tmp.drop.type === 'Quest') return; if (this.user._tmp && this.user._tmp.drop && this.user._tmp.drop.type === 'Quest') return;
if (this.unlockLevels[`${after}`]) return; if (this.unlockLevels[`${after}`]) return;
if (!this.user.preferences.suppressModals.levelUp) this.$root.$emit('show:modal', 'level-up'); if (!this.user.preferences.suppressModals.levelUp) this.$root.$emit('show::modal', 'level-up');
}, },
userClassSelect (after) { userClassSelect (after) {
if (!after) return; if (!after) return;
@@ -207,7 +207,6 @@ export default {
// @TODO: {controller:'UserCtrl', keyboard:false, backdrop:'static'} // @TODO: {controller:'UserCtrl', keyboard:false, backdrop:'static'}
}, },
userNotifications (after) { userNotifications (after) {
if (!this.user._wrapped) return;
if (this.user.needsCron) return; if (this.user.needsCron) return;
this.handleUserNotifications(after); this.handleUserNotifications(after);
}, },
@@ -230,7 +229,11 @@ export default {
async mounted () { async mounted () {
Promise.all(['user.fetch', 'tasks.fetchUserTasks']) Promise.all(['user.fetch', 'tasks.fetchUserTasks'])
.then(() => { .then(() => {
if (!this.user.flags.welcomed) { let { created, loggedin } = this.user.auth.timestamps;
let createdDate = moment(created);
let loggedinDate = moment(loggedin);
if (!this.user.flags.welcomed && !createdDate.isBefore(loggedinDate)) {
this.$store.state.avatarEditorOptions.editingUser = false; this.$store.state.avatarEditorOptions.editingUser = false;
this.$root.$emit('show::modal', 'avatar-modal'); this.$root.$emit('show::modal', 'avatar-modal');
} }

View File

@@ -309,7 +309,7 @@ export default {
directives: { directives: {
markdown: markdownDirective, markdown: markdownDirective,
}, },
props: ['task', 'isUser', 'group'], // @TODO: maybe we should store the group on state? props: ['task', 'isUser', 'group', 'dueDate'], // @TODO: maybe we should store the group on state?
data () { data () {
return { return {
icons: Object.freeze({ icons: Object.freeze({
@@ -342,11 +342,13 @@ export default {
return false; return false;
}, },
controlClass () { controlClass () {
return this.getTaskClasses(this.task, 'control'); const dueDate = this.dueDate || new Date();
return this.getTaskClasses(this.task, 'control', dueDate);
}, },
contentClass () { contentClass () {
const classes = []; const classes = [];
classes.push(this.getTaskClasses(this.task, 'content')); const dueDate = this.dueDate || new Date();
classes.push(this.getTaskClasses(this.task, 'content'), dueDate);
if (this.task.type === 'reward' || this.task.type === 'habit') { if (this.task.type === 'reward' || this.task.type === 'habit') {
classes.push('no-right-border'); classes.push('no-right-border');
} }

View File

@@ -6,8 +6,10 @@
.tasks-list .tasks-list
task( task(
v-for='task in tasksByType["daily"]', v-for='task in tasksByType["daily"]',
:key='task.id', :task='task', :key='task.id',
:task='task',
:isUser='true', :isUser='true',
:dueDate='dueDate',
) )
.start-day.text-center .start-day.text-center
button.btn.btn-primary(@click='close()') {{ $t('yesterDailiesCallToAction') }} button.btn.btn-primary(@click='close()') {{ $t('yesterDailiesCallToAction') }}
@@ -43,6 +45,7 @@
<script> <script>
import axios from 'axios'; import axios from 'axios';
import moment from 'moment';
import { mapState } from 'client/libs/store'; import { mapState } from 'client/libs/store';
import bModal from 'bootstrap-vue/lib/components/modal'; import bModal from 'bootstrap-vue/lib/components/modal';
import Task from './tasks/task'; import Task from './tasks/task';
@@ -53,6 +56,11 @@ export default {
bModal, bModal,
Task, Task,
}, },
data () {
return {
dueDate: moment().subtract(1, 'days'),
};
},
computed: { computed: {
...mapState({user: 'user.data'}), ...mapState({user: 'user.data'}),
tasksByType () { tasksByType () {

View File

@@ -29,7 +29,8 @@ export function getTaskClasses (store) {
const userPreferences = store.state.user.data.preferences; const userPreferences = store.state.user.data.preferences;
// Purpose is one of 'controls', 'editModal', 'createModal', 'content' // Purpose is one of 'controls', 'editModal', 'createModal', 'content'
return (task, purpose) => { return (task, purpose, dueDate) => {
if (!dueDate) dueDate = new Date();
const type = task.type; const type = task.type;
switch (purpose) { switch (purpose) {
@@ -45,7 +46,7 @@ export function getTaskClasses (store) {
case 'control': case 'control':
switch (type) { switch (type) {
case 'daily': case 'daily':
if (task.completed || !shouldDo(new Date(), task, userPreferences)) return 'task-daily-todo-disabled'; if (task.completed || !shouldDo(dueDate, task, userPreferences)) return 'task-daily-todo-disabled';
return getTaskColorByValue(task.value); return getTaskColorByValue(task.value);
case 'todo': case 'todo':
if (task.completed) return 'task-daily-todo-disabled'; if (task.completed) return 'task-daily-todo-disabled';

View File

@@ -137,7 +137,7 @@
"petLikeToEatText": "Pets will grow no matter what you feed them, but they'll grow faster if you feed them the one food that they like best. Experiment to find out the pattern, or see the answers here: <br/> <a href=\"http://habitica.wikia.com/wiki/Food_Preferences\" target=\"_blank\">http://habitica.wikia.com/wiki/Food_Preferences</a>", "petLikeToEatText": "Pets will grow no matter what you feed them, but they'll grow faster if you feed them the one food that they like best. Experiment to find out the pattern, or see the answers here: <br/> <a href=\"http://habitica.wikia.com/wiki/Food_Preferences\" target=\"_blank\">http://habitica.wikia.com/wiki/Food_Preferences</a>",
"petLikeToEat": "What does my pet like to eat?", "petLikeToEat": "What does my pet like to eat?",
"welcomeTo": "Welcome to", "welcomeTo": "Welcome to",
"justinIntroMessage1": "Hello there! You must be new here. My name is Justin, Ill be your guide in Habitica.", "justinIntroMessage1": "Hello there! You must be new here. My name is Justin, your guide to Habitica.",
"justinIntroMessage2": "To start, youll need to create an avatar.", "justinIntroMessage2": "To start, youll need to create an avatar.",
"justinIntroMessage3": "Great! Now, what are you interested in working on throughout this journey?", "justinIntroMessage3": "Great! Now, what are you interested in working on throughout this journey?",
"prev": "Prev", "prev": "Prev",
@@ -290,5 +290,6 @@
"leader": "Leader", "leader": "Leader",
"partyInformationPlaceHolder": "Write a message to your Party members here!", "partyInformationPlaceHolder": "Write a message to your Party members here!",
"selectPartyMember": "Select a Party Member", "selectPartyMember": "Select a Party Member",
"errorNotInParty": "You are not in a Party" "errorNotInParty": "You are not in a Party",
"health_wellness": "Health & Wellness"
} }