diff --git a/website/client/app.vue b/website/client/app.vue
index 2d0feaaf89..8162035946 100644
--- a/website/client/app.vue
+++ b/website/client/app.vue
@@ -5,15 +5,19 @@
#loading-screen.h-100.w-100.d-flex.justify-content-center.align-items-center(v-if="!isUserLoaded")
p Loading...
template(v-else)
+ notifications
app-menu
.container-fluid
app-header
router-view
+ app-footer
diff --git a/website/client/components/appHeader.vue b/website/client/components/appHeader.vue
index 352ad1086d..a4e9cf185c 100644
--- a/website/client/components/appHeader.vue
+++ b/website/client/components/appHeader.vue
@@ -24,59 +24,59 @@
diff --git a/website/client/components/guilds/createPartyModal.vue b/website/client/components/groups/createPartyModal.vue
similarity index 100%
rename from website/client/components/guilds/createPartyModal.vue
rename to website/client/components/groups/createPartyModal.vue
diff --git a/website/client/components/guilds/discovery.vue b/website/client/components/groups/discovery.vue
similarity index 100%
rename from website/client/components/guilds/discovery.vue
rename to website/client/components/groups/discovery.vue
diff --git a/website/client/components/guilds/groupFormModal.vue b/website/client/components/groups/groupFormModal.vue
similarity index 100%
rename from website/client/components/guilds/groupFormModal.vue
rename to website/client/components/groups/groupFormModal.vue
diff --git a/website/client/components/groups/groupPlan.vue b/website/client/components/groups/groupPlan.vue
new file mode 100644
index 0000000000..856c1bf934
--- /dev/null
+++ b/website/client/components/groups/groupPlan.vue
@@ -0,0 +1,192 @@
+
+.standard-page
+ 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')
+ h2.text-center {{ $t('groupBenefitsTitle') }}
+ .row(style="font-size: 2rem;")
+ .col-md-6.col-md-offset-3.text-center {{ $t('groupBenefitsDescription') }}
+ .row.row-margin
+ .col-md-4
+ h2 {{ $t('teamBasedTasks') }}
+ div
+ // shared tasks
+ h3
+ span.glyphicon.glyphicon-ok-circle(style='margin-right: 1.5rem;')
+ | {{ $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
+ h2 {{ $t('specializedCommunication') }}
+ div
+ // chat privately
+ 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
+ br
+ .row
+ .col-sm-6.col-sm-offset-3
+ a.btn.btn-primary.btn-lg.btn-block(ui-sref="options.social.newGroup") {{ $t('createAGroup') }}
+
+ .row
+ .col-md-6.col-md-offset-3
+ br
+ .text-center {{ $t('groupSubscriptionPrice') }}
+
+
+
diff --git a/website/client/components/guilds/guild.vue b/website/client/components/groups/guild.vue
similarity index 98%
rename from website/client/components/guilds/guild.vue
rename to website/client/components/groups/guild.vue
index d3fa9270ee..54038efbf4 100644
--- a/website/client/components/guilds/guild.vue
+++ b/website/client/components/groups/guild.vue
@@ -1,6 +1,7 @@
.row(v-if="group")
group-form-modal
+ invite-modal
.clearfix.col-8
.row
.col-6.title-details
@@ -40,7 +41,7 @@
.button-container
button.btn.btn-success(class='btn-success', v-if='!isMember') {{ $t('join') }}
.button-container
- button.btn.btn-primary(v-once) {{$t('invite')}}
+ button.btn.btn-primary(v-once, @click='showInviteModal()') {{$t('invite')}}
.button-container
button.btn.btn-primary(v-once, v-if='!isLeader') {{$t('messageGuildLeader')}}
.button-container
@@ -355,6 +356,8 @@ import ownedQuestsModal from './ownedQuestsModal';
import quests from 'common/script/content/quests';
import percent from 'common/script/libs/percent';
import groupFormModal from './groupFormModal';
+import inviteModal from './inviteModal';
+import memberModal from '../members/memberModal';
import chatMessage from '../chat/chatMessages';
import bCollapse from 'bootstrap-vue/lib/components/collapse';
@@ -380,12 +383,14 @@ export default {
props: ['groupId'],
components: {
membersModal,
+ memberModal,
ownedQuestsModal,
bCollapse,
bCard,
bTooltip,
groupFormModal,
chatMessage,
+ inviteModal,
},
directives: {
bToggle,
@@ -507,6 +512,9 @@ export default {
this.$store.state.editingGroup = this.group;
this.$root.$emit('show::modal', 'guild-form');
},
+ showInviteModal () {
+ this.$root.$emit('show::modal', 'invite-modal');
+ },
async fetchGuild () {
let group = await this.$store.dispatch('guilds:getGroup', {groupId: this.groupId});
if (this.isParty) {
diff --git a/website/client/components/guilds/index.vue b/website/client/components/groups/index.vue
similarity index 100%
rename from website/client/components/guilds/index.vue
rename to website/client/components/groups/index.vue
diff --git a/website/client/components/groups/inviteModal.vue b/website/client/components/groups/inviteModal.vue
new file mode 100644
index 0000000000..7b0ac61166
--- /dev/null
+++ b/website/client/components/groups/inviteModal.vue
@@ -0,0 +1,147 @@
+
+b-modal#invite-modal(:title="$t('inviteFriends')", size='lg')
+ .modal-body
+ p.alert.alert-info(v-html="$t('inviteAlertInfo')")
+ .form-horizontal
+ table.table.table-striped
+ thead
+ tr
+ th {{ $t('userId') }}
+ tbody
+ tr(v-for='user in invitees')
+ td
+ input.form-control(type='text', v-model='user.uuid')
+ tr
+ td
+ button.btn.btn-xs.pull-right(@click='addUuid()')
+ i.glyphicon.glyphicon-plus
+ | +
+ tr
+ td
+ .col-6.col-offset-6
+ button.btn.btn-primary.btn-block(@click='inviteNewUsers("uuid")') {{sendInviteText}}
+ hr
+ p.alert.alert-info {{ $t('inviteByEmail') }}
+ .form-horizontal
+ table.table.table-striped
+ thead
+ tr
+ th {{ $t('name') }}
+ th {{ $t('email') }}
+ tbody
+ tr(v-for='email in emails')
+ td
+ input.form-control(type='text', v-model='email.name')
+ td
+ input.form-control(type='email', v-model='email.email')
+ tr
+ td(colspan=2)
+ a.btn.btn-xs.pull-right(@click='addEmail()')
+ i.glyphicon.glyphicon-plus
+ | +
+ tr
+ td.form-group(colspan=2)
+ label.col-sm-1.control-label {{ $t('byColon') }}
+ .col-sm-5
+ input.form-control(type='text', v-model='inviter')
+ .col-sm-6
+ button.btn.btn-primary.btn-block(@click='inviteNewUsers("email")') {{sendInviteText}}
+
+
+
diff --git a/website/client/components/guilds/membersModal.vue b/website/client/components/groups/membersModal.vue
similarity index 100%
rename from website/client/components/guilds/membersModal.vue
rename to website/client/components/groups/membersModal.vue
diff --git a/website/client/components/guilds/myGuilds.vue b/website/client/components/groups/myGuilds.vue
similarity index 100%
rename from website/client/components/guilds/myGuilds.vue
rename to website/client/components/groups/myGuilds.vue
diff --git a/website/client/components/guilds/newPartyModal.jade b/website/client/components/groups/newPartyModal.jade
similarity index 100%
rename from website/client/components/guilds/newPartyModal.jade
rename to website/client/components/groups/newPartyModal.jade
diff --git a/website/client/components/guilds/ownedQuestsModal.vue b/website/client/components/groups/ownedQuestsModal.vue
similarity index 100%
rename from website/client/components/guilds/ownedQuestsModal.vue
rename to website/client/components/groups/ownedQuestsModal.vue
diff --git a/website/client/components/guilds/publicGuildItem.vue b/website/client/components/groups/publicGuildItem.vue
similarity index 100%
rename from website/client/components/guilds/publicGuildItem.vue
rename to website/client/components/groups/publicGuildItem.vue
diff --git a/website/client/components/guilds/sidebar.vue b/website/client/components/groups/sidebar.vue
similarity index 100%
rename from website/client/components/guilds/sidebar.vue
rename to website/client/components/groups/sidebar.vue
diff --git a/website/client/components/guilds/startQuestModal.vue b/website/client/components/groups/startQuestModal.vue
similarity index 100%
rename from website/client/components/guilds/startQuestModal.vue
rename to website/client/components/groups/startQuestModal.vue
diff --git a/website/client/components/guilds/tavern.vue b/website/client/components/groups/tavern.vue
similarity index 97%
rename from website/client/components/guilds/tavern.vue
rename to website/client/components/groups/tavern.vue
index fa441218a6..0bc6797f56 100644
--- a/website/client/components/guilds/tavern.vue
+++ b/website/client/components/groups/tavern.vue
@@ -10,6 +10,7 @@
h3(v-once) {{ $t('welcomeToTavern') }}
textarea(:placeholder="$t('chatPlaceHolder')", v-model='newMessage')
+ 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')
@@ -282,6 +283,7 @@ import { mapState } from 'client/libs/store';
import { TAVERN_ID } from '../../../common/script/constants';
import chatMessage from '../chat/chatMessages';
+import autocomplete from '../chat/autoComplete';
import gemIcon from 'assets/svg/gem.svg';
import questIcon from 'assets/svg/quest.svg';
@@ -294,6 +296,7 @@ import downIcon from 'assets/svg/down.svg';
export default {
components: {
chatMessage,
+ autocomplete,
},
data () {
return {
@@ -399,6 +402,9 @@ export default {
this.group = await this.$store.dispatch('guilds:getGroup', {groupId: TAVERN_ID});
},
methods: {
+ selectedAutocomplete (newText) {
+ this.newMessage = newText;
+ },
aggreeToGuideLines () {
// @TODO:
},
diff --git a/website/client/components/hall/heroes.vue b/website/client/components/hall/heroes.vue
new file mode 100644
index 0000000000..2413f51e6f
--- /dev/null
+++ b/website/client/components/hall/heroes.vue
@@ -0,0 +1,175 @@
+
+.row
+ small.muted(v-html="$t('blurbHallContributors')")
+ .well(v-if='user.contributor.admin')
+ h2 {{ $t('rewardUser') }}
+ form(v-submit='loadHero(_heroID)')
+ .form-group
+ input.form-control(type='text', v-model='_heroID', placeholder {{ $t('UUID') }})
+ .form-group
+ input.btn.btn-default(type='submit')
+ | {{ $t('loadUser') }}
+ form(v-show='hero', v-submit='saveHero(hero)')
+ a(v-click='clickMember(hero._id, true)')
+ h3 {{hero.profile.name}}
+ .form-group
+ input.form-control(type='text', v-model='hero.contributor.text', placeholder {{ $t('contribTitle') }})
+ .form-group
+ label {{ $t('contribLevel') }}
+ input.form-control(type='number', v-model='hero.contributor.level')
+ small {{ $t('contribHallText') }}
+ |
+ a(target='_blank', href='https://trello.com/c/wkFzONhE/277-contributor-gear') {{ $t('moreDetails') }}
+ |,
+ a(target='_blank', href='https://github.com/HabitRPG/habitica/issues/3801') {{ $t('moreDetails2') }}
+ .form-group
+ textarea.form-control(cols=5, placeholder {{ $t('contributions') }}, v-model='hero.contributor.contributions')
+ //include ../../shared/formattiv-help
+ hr
+
+ .form-group
+ label {{ $t('balance') }}
+ input.form-control(type='number', step="any", v-model='hero.balance')
+ small {{ '`user.balance`' + this.$t('notGems') }}
+ accordion
+ accordion-group(heading='Items')
+ h4 Update Item
+ .form-group.well
+ input.form-control(type='text',placeholder='Path (eg, items.pets.BearCub-Base)',v-model='hero.itemPath')
+ small.muted Enter the item path. E.g., items.pets.BearCub-Zombie or items.gear.owned.head_special_0 or items.gear.equipped.head. You can find all the item paths below.
+ br
+ input.form-control(type='text',placeholder='Value (eg, 5)',v-model='hero.itemVal')
+ small.muted Enter the item value. E.g., 5 or false or head_warrior_3. All values are listed in the All Item Paths section below.
+ accordion
+ accordion-group(heading='All Item Paths')
+ pre {{allItemPaths}}
+ accordion-group(heading='Current Items')
+ pre {{toJson(hero.items, true)}}
+ accordion-group(heading='Auth')
+ h4 Auth
+ pre {{toJson(hero.auth)}}
+ .form-group
+ .checkbox
+ label
+ input(type='checkbox', v-model='hero.flags.chatRevoked')
+ | Chat Privileges Revoked
+ .form-group
+ .checkbox
+ label
+ input(type='checkbox', v-model='hero.auth.blocked')
+ | Blocked
+
+ // h4 Backer Status
+ // Add backer stuff like tier, disable adds, etcs
+ .form-group
+ input.form-control.btn.btn-primary(type='submit')
+ | {{ $t('save') }}
+
+ .table-responsive
+ table.table.table-striped
+ thead
+ tr
+ th {{ $t('name') }}
+ th(v-if='user.contributor.admin') {{ $t('UUID') }}
+ th {{ $t('contribLevel') }}
+ th {{ $t('title') }}
+ th {{ $t('contributions') }}
+ tbody
+ tr(v-repeat='hero in heroes')
+ td
+ span(v-if='hero.contributor.admin', :popover="$t('gamemaster')", popover-trigger='mouseenter', popover-placement='right')
+ a.label.label-default(v-class='userLevelStyle(hero)', v-click='clickMember(hero._id, true)')
+ | {{hero.profile.name}}
+ span(v-class='userAdminGlyphiconStyle(hero)')
+ span(v-if='!hero.contributor.admin')
+ a.label.label-default(v-class='userLevelStyle(hero)', v-click='clickMember(hero._id, true)') {{hero.profile.name}}
+ td(v-if='user.contributor.admin', v-click='populateContributorInput(hero._id, $index)').btn-link {{hero._id}}
+ td {{hero.contributor.level}}
+ td {{hero.contributor.text}}
+ td
+ markdown(text='hero.contributor.contributions', target='_blank')
+
+
+
diff --git a/website/client/components/hall/index.vue b/website/client/components/hall/index.vue
new file mode 100644
index 0000000000..f420ebfcfd
--- /dev/null
+++ b/website/client/components/hall/index.vue
@@ -0,0 +1,19 @@
+
+.row
+ secondary-menu.col-12
+ router-link.nav-link(:to="{name: 'contributors'}", exact, :class="{'active': $route.name === 'contributors'}") {{ $t('hallContributors') }}
+ router-link.nav-link(:to="{name: 'patrons'}", :class="{'active': $route.name === 'patrons'}") {{ $t('hallPatrons') }}
+
+ .col-12
+ router-view
+
+
+
diff --git a/website/client/components/hall/patrons.vue b/website/client/components/hall/patrons.vue
new file mode 100644
index 0000000000..610bf9ad91
--- /dev/null
+++ b/website/client/components/hall/patrons.vue
@@ -0,0 +1,53 @@
+
+.row
+ small.muted {{ $t('blurbHallPatrons') }}
+ .table-responsive
+ table.table.table-striped(infinite-scroll="loadMore()")
+ thead
+ tr
+ th {{ $t('name') }}
+ th(v-if='user.contributor.admin') {{ $t('UUID') }}
+ th {{ $t('backerTier') }}
+ tbody
+ tr(v-for='patron in patrons')
+ td
+ a.label.label-default(v-class='userLevelStyle(patron)', @click='clickMember(patron._id, true)')
+ | {{patron.profile.name}}
+ td(v-if='user.contributor.admin') {{patron._id}}
+ td {{patron.backer.tier}}
+
+
+
diff --git a/website/client/components/members/memberModal.vue b/website/client/components/members/memberModal.vue
new file mode 100644
index 0000000000..3aa1780e8d
--- /dev/null
+++ b/website/client/components/members/memberModal.vue
@@ -0,0 +1,143 @@
+
+ b-modal#member-detail-modal(title="Empty", size='lg')
+ .modal-header
+ h4
+ span {{profile.profile.name}}
+ span(v-if='contribText && profile.contributor.level') - {{contribText(profile.contributor, profile.backer)}}
+ .modal-body
+ .container-fluid
+ .row
+ .col-md-6
+ img.img-renderiv-auto(v-if='profile.profile.imageUrl', :src='profile.profile.imageUrl')
+ markdown(v-if='profile.profile.blurb', text='profile.profile.blurb')
+ ul.muted.list-unstyled(v-if='profile.auth.timestamps')
+ li {{profile._id}}
+ li(v-if='profile.auth.timestamps.created')
+ |
+ | {{ $t('memberSince') }}
+ |
+ | {{profile.auth.timestamps.created | date:user.preferences.dateFormat}} -
+ li(v-if='profile.auth.timestamps.loggedin')
+ |
+ | {{ $t('lastLoggedIn') }}
+ |
+ | {{profile.auth.timestamps.loggedin | date:user.preferences.dateFormat}} -
+ h3 {{ $t('stats') }}
+ // @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] }}
+ // include ../profiles/stats_all
+ .col-md-6
+ .row
+ //@TODO: +herobox()
+ .row
+ h3 {{ $t('achievements') }}
+ //include ../profiles/achievements
+ .modal-footer
+ .btn-group.pull-left(v-if='user')
+ button.btn.btn-md.btn-default(v-if='user.inbox.blocks.indexOf(profile._id) !== -1', :tooltip="$t('unblock')", @click="User.blockUser({params:{uuid:profile._id}})", tooltip-placement='right')
+ span.glyphicon.glyphicon-plus
+ button.btn.btn-md.btn-default(v-if='profile._id != user._id && !profile.contributor.admin && !(user.inbox.blocks | contains:profile._id)', tooltip {{ $t('block') }}, @click="User.blockUser({params:{uuid:profile._id}})", tooltip-placement='right')
+ span.glyphicon.glyphicon-ban-circle
+ button.btn.btn-md.btn-default(:tooltip="$t('sendPM')", @click="openModal('private-message',{controller:'MemberModalCtrl'})", tooltip-placement='right')
+ span.glyphicon.glyphicon-envelope
+ button.btn.btn-md.btn-default(:tooltip="$t('sendGift')", @click="openModal('send-gift',{controller:'MemberModalCtrl'})", tooltip-placement='right')
+ span.glyphicon.glyphicon-gift
+ button.btn.btn-default(@click='close()') {{ $t('close') }}
+
+
+
diff --git a/website/client/components/notificationMenu.vue b/website/client/components/notificationMenu.vue
new file mode 100644
index 0000000000..9559c4b3e0
--- /dev/null
+++ b/website/client/components/notificationMenu.vue
@@ -0,0 +1,198 @@
+
+.item-with-icon.item-notifications.dropdown
+ .svg-icon(v-html="icons.notifications")
+ // span.glyphicon(:class='iconClasses()')
+ // span.notification-counter(v-if='getNotificationsCount()') {{getNotificationsCount()}}
+ .dropdown-menu.dropdown-menu-right.user-dropdown
+ a.dropdown-item test
+ h4 {{ $t('notifications') }}
+ div
+ ul.toolbar-notifs-notifs
+ li.toolbar-notifs-no-messages(v-if='hasNoNotifications()') {{ $t('noNotifications') }}
+ li(v-if='user.purchased.plan.mysteryItems.length')
+ a(@click='$state.go("options.inventory.drops"); ')
+ span.glyphicon.glyphicon-gift
+ span {{ $t('newSubscriberItem') }}
+ li(v-for='party in user.invitations.parties')
+ a(ui-sref='options.social.party')
+ span.glyphicon.glyphicon-user
+ span {{ $t('invitedTo', {name: party.name}) }}
+ li(v-if='user.flags.cardReceived')
+ a(@click='$state.go("options.inventory.drops"); ')
+ span.glyphicon.glyphicon-envelope
+ span {{ $t('cardReceived') }}
+ a(@click='clearCards()', :popover="$t('clear')", popover-placement='right', popover-trigger='mouseenter',popover-append-to-body='true')
+ span.glyphicon.glyphicon-remove-circle
+ li(v-for='guild in user.invitations.guilds')
+ a(ui-sref='options.social.guilds.public')
+ span.glyphicon.glyphicon-user
+ span {{ $t('invitedTo', {name: guild.name}) }}
+ li(v-if='user.flags.classSelected && !user.preferences.disableClasses && user.stats.points')
+ a(ui-sref='options.profile.stats')
+ span.glyphicon.glyphicon-plus-sign
+ span {{ $t('haveUnallocated', {points: user.stats.points}) }}
+ li(v-for='(k,v) in user.newMessages', v-if='v.value')
+ a(@click='(k === party._id || k === user.party._id) ? $state.go("options.social.party") : $state.go("options.social.guilds.detail",{gid:k}); ')
+ span.glyphicon.glyphicon-comment
+ span {{v.name}}
+ a(@click='clearMessages(k)', :popover="$t('clear')", popover-placement='right', popover-trigger='mouseenter',popover-append-to-body='true')
+ span.glyphicon.glyphicon-remove-circle
+ li(v-for='notification in user.groupNotifications')
+ a(@click='viewGroupApprovalNotification(notification, $index, true)')
+ span(:class="groupApprovalNotificationIcon(notification)")
+ span
+ | {{notification.data.message}}
+ a(@click='viewGroupApprovalNotification(notification, $index)',
+ :popover="$t('clear')",
+ popover-placement='right',
+ popover-trigger='mouseenter',
+ popover-append-to-body='true')
+ span.glyphicon.glyphicon-remove-circle
+
+
+
diff --git a/website/client/components/notifications.vue b/website/client/components/notifications.vue
new file mode 100644
index 0000000000..3303ffb83d
--- /dev/null
+++ b/website/client/components/notifications.vue
@@ -0,0 +1,401 @@
+
+
+
+
diff --git a/website/client/index.html b/website/client/index.html
index 0a4a7ea6a6..292296c4c2 100644
--- a/website/client/index.html
+++ b/website/client/index.html
@@ -14,6 +14,44 @@
src='https://static-na.payments-amazon.com/OffAmazonPayments/us/sandbox/js/Widgets.js'>
-
+
+