New client footer (#8954)

* Minor footer style fixes

* Added initial gem modal

* Fixed some heroe stuff.

* Preventing system member loading

* Added social delete
This commit is contained in:
Keith Holliday
2017-08-16 10:05:33 -06:00
committed by GitHub
parent 8614f11a31
commit 0bff37b600
10 changed files with 247 additions and 52 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="16" viewBox="0 0 18 16">
<path fill="#F19595" fill-rule="evenodd" d="M17.676 3.065c-.449-1.107-1.35-2.039-2.595-2.615a4.8 4.8 0 0 0-3.366-.26C10.637.502 9.668 1.35 9 2.332 8.332 1.351 7.363.502 6.285.19a4.8 4.8 0 0 0-3.366.26C1.673 1.026.773 1.958.324 3.065c-.449 1.107-.45 2.393.115 3.671C1.649 9.471 8.962 15.89 8.999 16c.04-.11 7.352-6.529 8.562-9.264.566-1.278.564-2.564.115-3.671"/>
</svg>

After

Width:  |  Height:  |  Size: 458 B

View File

@@ -1,5 +1,6 @@
<template lang="pug">
.row
buy-gems-modal
modify-inventory
footer.container-fluid
.row
@@ -59,14 +60,14 @@
a(href='http://habitica.wikia.com/wiki/Guidance_for_Blacksmiths', target='_blank') Guidance for Blacksmiths
li
a(href='http://devs.habitica.com/', target='_blank') The Forge - Developer Blog
.col-6
.col-6.social
h3 Social
.social-circle
a(href='https://twitter.com/habitica', target='_blank')
.social-icon.svg-icon(v-html='icons.twitter')
.social-circle
a(href='https://www.instagram.com/habitica/', target='_blank')
.social-icon.svg-icon(v-html='icons.instagram')
.social-icon.svg-icon.instagram(v-html='icons.instagram')
.social-circle
a(href='https://www.facebook.com/Habitica', target='_blank')
.social-icon.facebook.svg-icon(v-html='icons.facebook')
@@ -74,7 +75,9 @@
.col-10
| Were an open source project that depends on our users for support. The money you donate helps us keep the servers running, maintain a small staff, develop new features, and provide incentives for our volunteers.
.col-2
button.btn.btn-primary Donate
button.btn.btn-donate(@click='donate()')
.svg-icon.heart(v-html='icons.heart')
.text Donate
.row
hr.col-12
.row
@@ -99,10 +102,12 @@
a.btn.btn-default(@click='makeAdmin()') Make Admin
a.btn.btn-default(@click='openModifyInventoryModal()') Modify Inventory
.col-4.text-center
.logo.svg-icon(v-html='icons.gryphon')
.logo
.col-4.text-right
span Privacy Policy
span Terms of Use
span
router-link(to="/static/privacy") Privacy Policy
span.terms-link
router-link(to="/static/terms") Terms of Use
</template>
<style lang="scss" scoped>
@@ -114,6 +119,10 @@
padding-top: 3em;
margin: 0;
color: #878190;
a {
color: #878190;
}
}
h3 {
@@ -129,13 +138,20 @@
margin-bottom: .5em;
}
.social {
h3 {
text-align: right;
}
}
.social-circle {
width: 40px;
height: 40px;
border-radius: 50%;
background-color: #c3c0c7;
display: inline-block;
margin-right: 1em;
margin-left: 1em;
float: right;
.social-icon {
color: #e1e0e3;
@@ -144,15 +160,26 @@
margin-top: 1em;
}
.svg-icon.facebook svg {
height: 20px;
.facebook {
margin-top: .7em;
}
.instagram {
margin-top: .85em;
}
}
.logo.svg-icon {
.logo {
background-image: url('~assets/images/gryphon@3x.png');
width: 24px;
height: 24px;
margin: 0 auto;
color: #c3c0c7;
background-size: cover;
}
.terms-link {
margin-left: 1em;
}
.debug-group {
@@ -162,6 +189,30 @@
border-radius: 2px;
padding: 2em;
}
.btn-donate {
background: #c3c0c7;
box-shadow: none;
border-radius: 4px;
.heart {
width: 18px;
margin-right: .5em;
margin-bottom: .2em;
}
.text, .heart {
display: inline-block;
vertical-align: bottom;
}
}
</style>
<style>
.facebook svg {
width: 10px;
margin: 0 auto;
}
</style>
<script>
@@ -173,14 +224,17 @@ import gryphon from 'assets/svg/gryphon.svg';
import twitter from 'assets/svg/twitter.svg';
import facebook from 'assets/svg/facebook.svg';
import instagram from 'assets/svg/instagram.svg';
import heart from 'assets/svg/heart.svg';
import modifyInventory from './modifyInventory';
import buyGemsModal from './payments/buyGemsModal';
const IS_PRODUCTION = process.env.NODE_ENV === 'production'; // eslint-disable-line no-process-env
export default {
components: {
modifyInventory,
buyGemsModal,
},
data () {
return {
@@ -189,6 +243,7 @@ export default {
twitter,
facebook,
instagram,
heart,
}),
debugMenuShown: false,
IS_PRODUCTION,
@@ -275,6 +330,9 @@ export default {
openModifyInventoryModal () {
this.$root.$emit('show::modal', 'modify-inventory');
},
donate () {
this.$root.$emit('show::modal', 'buy-gems');
},
},
};
</script>

View File

@@ -166,7 +166,8 @@ export default {
this.messages.forEach(message => {
let uuid = message.uuid;
if (!this.cachedProfileData[uuid]) {
if (uuid && !this.cachedProfileData[uuid]) {
if (uuid === 'system') return;
promises.push(axios.get(`/api/v3/members/${uuid}`));
}
});

View File

@@ -3,13 +3,13 @@
small.muted(v-html="$t('blurbHallContributors')")
.well(v-if='user.contributor.admin')
h2 {{ $t('rewardUser') }}
form(v-submit='loadHero(_heroID)')
form(submit='loadHero(heroID)') // @TODO: make click
.form-group
input.form-control(type='text', v-model='_heroID', placeholder {{ $t('UUID') }})
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)')
form(v-if='hero && hero.profile', submit='saveHero(hero)') // @TODO: make click
a(v-click='clickMember(hero._id, true)')
h3 {{hero.profile.name}}
.form-group
@@ -70,19 +70,19 @@
thead
tr
th {{ $t('name') }}
th(v-if='user.contributor.admin') {{ $t('UUID') }}
th(v-if='user.contributor && user.contributor.admin') {{ $t('UUID') }}
th {{ $t('contribLevel') }}
th {{ $t('title') }}
th {{ $t('contributions') }}
tbody
tr(v-repeat='hero in heroes')
tr(v-for='(hero, $index) in heroes')
td
span(v-if='hero.contributor.admin', :popover="$t('gamemaster')", popover-trigger='mouseenter', popover-placement='right')
span(v-if='hero.contributor && 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}}&nbsp;
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}}
span(v-if='!hero.contributor || !hero.contributor.admin')
a.label.label-default(v-if='hero.profile', 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}}
@@ -91,7 +91,7 @@
</template>
<script>
import keys from 'lodash/keys';
// import keys from 'lodash/keys';
import each from 'lodash/each';
import { mapState } from 'client/libs/store';
@@ -105,6 +105,7 @@ export default {
return {
heroes: [],
hero: {},
heroID: '',
currentHeroIndex: -1,
allItemPaths: this.getAllItemPaths(),
quests,
@@ -124,22 +125,22 @@ export default {
},
methods: {
getAllItemPaths () {
let questsFormat = this.getFormattedItemReference('items.quests', keys(this.quests), 'Numeric Quantity');
let mountsFormat = this.getFormattedItemReference('items.mounts', keys(this.mountInfo), 'Boolean');
let foodFormat = this.getFormattedItemReference('items.food', keys(this.food), 'Numeric Quantity');
let eggsFormat = this.getFormattedItemReference('items.eggs', keys(this.eggs), 'Numeric Quantity');
let hatchingPotionsFormat = this.getFormattedItemReference('items.hatchingPotions', keys(this.hatchingPotions), 'Numeric Quantity');
let petsFormat = this.getFormattedItemReference('items.pets', keys(this.petInfo), '-1: Owns Mount, 0: Not Owned, 1-49: Progress to mount');
let specialFormat = this.getFormattedItemReference('items.special', keys(this.special), 'Numeric Quantity');
let gearFormat = this.getFormattedItemReference('items.gear.owned', keys(this.gear.flat), 'Boolean');
let equippedGearFormat = '\nEquipped Gear:\n\titems.gear.{equipped/costume}.{head/headAccessory/eyewear/armor/body/back/shield/weapon}.{gearKey}\n';
let equippedPetFormat = '\nEquipped Pet:\n\titems.currentPet.{petKey}\n';
let equippedMountFormat = '\nEquipped Mount:\n\titems.currentMount.{mountKey}\n';
let data = questsFormat.concat(mountsFormat, foodFormat, eggsFormat, hatchingPotionsFormat, petsFormat, specialFormat, gearFormat, equippedGearFormat, equippedPetFormat, equippedMountFormat);
return data;
// let questsFormat = this.getFormattedItemReference('items.quests', keys(this.quests), 'Numeric Quantity');
// let mountsFormat = this.getFormattedItemReference('items.mounts', keys(this.mountInfo), 'Boolean');
// let foodFormat = this.getFormattedItemReference('items.food', keys(this.food), 'Numeric Quantity');
// let eggsFormat = this.getFormattedItemReference('items.eggs', keys(this.eggs), 'Numeric Quantity');
// let hatchingPotionsFormat = this.getFormattedItemReference('items.hatchingPotions', keys(this.hatchingPotions), 'Numeric Quantity');
// let petsFormat = this.getFormattedItemReference('items.pets', keys(this.petInfo), '-1: Owns Mount, 0: Not Owned, 1-49: Progress to mount');
// let specialFormat = this.getFormattedItemReference('items.special', keys(this.special), 'Numeric Quantity');
// let gearFormat = this.getFormattedItemReference('items.gear.owned', keys(this.gear.flat), 'Boolean');
//
// let equippedGearFormat = ''; // @TODO: '\nEquipped Gear:\n\titems.gear.{equipped/costume}.{head/headAccessory/eyewear/armor/body/back/shield/weapon}.{gearKey}\n';
// let equippedPetFormat = ''; // @TODO: '\nEquipped Pet:\n\titems.currentPet.{petKey}\n';
// let equippedMountFormat = ''; // @TODO: '\nEquipped Mount:\n\titems.currentMount.{mountKey}\n';
//
// let data = questsFormat.concat(mountsFormat, foodFormat, eggsFormat, hatchingPotionsFormat, petsFormat, specialFormat, gearFormat, equippedGearFormat, equippedPetFormat, equippedMountFormat);
//
// return data;
},
getFormattedItemReference (pathPrefix, itemKeys, values) {
let finishedString = '\n'.concat('path: ', pathPrefix, ', ', 'value: {', values, '}\n');
@@ -152,6 +153,7 @@ export default {
},
async loadHero (uuid, heroIndex) {
this.currentHeroIndex = heroIndex;
if (!heroIndex) return;
let hero = await this.$store.dispatch('hall:getHero', { uuid });
this.hero = hero;
},
@@ -161,15 +163,21 @@ export default {
// @TODO: Import
// Notification.text("User updated");
this.hero = {};
this._heroID = -1;
this.heroID = -1;
this.heroes[this.currentHeroIndex] = heroUpdated;
this.currentHeroIndex = -1;
},
populateContributorInput (id, index) {
this._heroID = id;
this.heroID = id;
window.scrollTo(0, 200);
this.loadHero(id, index);
},
clickMember () {
// @TODO: implement
},
userLevelStyle () {
// @TODO: implement
},
},
};
</script>

View File

@@ -0,0 +1,112 @@
<template lang="pug">
b-modal#buy-gems(title="Amazon", :hide-footer="true", size='lg')
.modal-body
.buy-gems
// @TODO: +gemButton(true)
div(ng-if='user.purchased.plan.customerId && (user.purchased.plan.gemsBought >= User.user.purchased.plan.consecutive.gemCapExtra + Shared.planGemLimits.convCap)')
.panel.panel-default
.panel-body
h3 {{ $t('buyGemsGold') }}
p {{ $t('maxBuyGems') }}
div(ng-if='user.purchased.plan.customerId && (user.purchased.plan.gemsBought < User.user.purchased.plan.consecutive.gemCapExtra + Shared.planGemLimits.convCap)')
.panel.panel-default
.panel-body
h3 {{ $t('buyGemsGold') }}
p {{ $t('subGemPop') }}
.container-fluid
.row
.col-md-3
button.customize-option(ng-click='User.purchase({params:{type:"gems",key:"gem"}})')
span.Pet_Currency_Gem.inline-gems
// @TODO: .badge.badge-success.stack-count {{Shared.planGemLimits.convCap + User.user.purchased.plan.consecutive.gemCapExtra - User.user.purchased.plan.gemsBought}}
p
| 20&nbsp;
span.shop_gold
.col-md-8
.popover.right.gem-count-popover
.arrow
.popover-content
p {{ $t('buyGemsAllow1') }}
// @TOOD: | &nbsp;{{Shared.planGemLimits.convCap + User.user.purchased.plan.consecutive.gemCapExtra - User.user.purchased.plan.gemsBought}}&nbsp;
| {{ $t('buyGemsAllow2') }}
p {{ $t('seeSubscriptionDetails') }}
div(ng-if='user.purchased.plan.customerId')
.well
h3 {{ $t('purchaseGemsSeparately') }}
.container-fluid
.row
.col-md-4.col-md-offset-4.alert.alert-info $5&nbsp;
| {{ $t('USD') }}
span#TotalGemPrice.dashed-underline(:popover="$t('donateText1')",
popover-trigger='mouseenter',popover-placement='bottom')
| +20
span(class="Pet_Currency_Gem1x inline-gems")
.container-fluid
.row
.col-md-10.col-md-offset-2
p
small.muted {{ $t('paymentMethods') }}
a.purchase.btn.btn-primary(ng-click='Payments.showStripe({})') {{ $t('card') }}
a.purchase(href='/paypal/checkout?_id=${user._id}&apiToken=${User.settings.auth.apiToken}')
img(src='https://www.paypalobjects.com/webstatic/en_US/i/buttons/pp-acceptance-small.png',alt='Pay now with Paypal')
a.purchase(ng-click="Payments.amazonPayments.init({type: 'single'})")
img(src='https://payments.amazon.com/gp/cba/button', alt='Pay now with Amazon Payments')
div(ng-if='!user.purchased.plan.customerId')
.panel.panel-default
.panel-body
h3 {{ $t('purchaseGems') }}
.small
span.dashed-underline(popover="$t('donateText3')", popover-trigger='mouseenter', popover-placement='bottom')
| {{ $t('donateText2') }}
.container-fluid
.row
.col-md-4.col-md-offset-4.alert.alert-info $5&nbsp;
| {{ $t('USD') }}
span#TotalGemPrice.dashed-underline(popover="$t('donateText1')",
popover-trigger='mouseenter', ement='bottom')
| +20
span(class="Pet_Currency_Gem1x inline-gems")
.container-fluid
.row
.col-md-10.col-md-offset-2
p
small.muted {{ $t('paymentMethods') }}
a.purchase.btn.btn-primary(ng-click='Payments.showStripe({})') {{ $t('card') }}
a.purchase(href='/paypal/checkout?_id=${user._id}&apiToken=${User.settings.auth.apiToken}')
img(src='https://www.paypalobjects.com/webstatic/en_US/i/buttons/pp-acceptance-small.png',
alt='Pay now with Paypal')
a.purchase(ng-click="Payments.amazonPayments.init({type: 'single'})")
img(src='https://payments.amazon.com/gp/cba/button', alt='Pay now with Amazon Payments')
.container-fluid
h3 {{ $t('freeGemsTitle') }}
p {{ $t('subFreeGemsHow') }}
.well
h3
.small {{ $t('buyGemsGoldTitle') }}
h3 {{ $t('becomeSubscriber') }}
div(ng-include="'partials/options.settings.subscription.html'", ng-controller='SettingsCtrl')
div(ng-if='user.purchased.plan.customerId').pull-left
p {{ $t('seeSubscriptionDetails') }}
.text-right
button.btn.btn-default(ng-click='$close()') {{ $t('close') }}
</template>
<script>
import bModal from 'bootstrap-vue/lib/components/modal';
export default {
components: {
bModal,
},
methods: {
close () {
this.$root.$emit('hide::modal', 'buy-gems');
},
},
};
</script>

View File

@@ -1,18 +1,31 @@
<template lang="pug">
b-modal#delete(:title="$t('deleteAccount')", :hide-footer='true' size='md')
strong {{ $t('deleteLocalAccountText') }}
br
.row
.col-6
input.form-control(type='password', v-model='password')
br
.row
#feedback.col-12.form-group
label(for='feedbackTextArea') {{ $t('feedback') }}
textarea#feedbackTextArea.form-control(v-model='feedback')
.modal-footer
button.btn.btn-danger(@click='close()') {{ $t('neverMind') }}
button.btn.btn-primary(@click='deleteAccount()', :disabled='!password') {{ $t('deleteDo') }}
.regular-delete(v-if='user.auth.local.email')
strong {{ $t('deleteLocalAccountText') }}
br
.row
.col-6
input.form-control(type='password', v-model='password')
br
.row
#feedback.col-12.form-group
label(for='feedbackTextArea') {{ $t('feedback') }}
textarea#feedbackTextArea.form-control(v-model='feedback')
.modal-footer
button.btn.btn-danger(@click='close()') {{ $t('neverMind') }}
button.btn.btn-primary(@click='deleteAccount()', :disabled='!password') {{ $t('deleteDo') }}
.modal-header
.social-delete(v-if='!user.auth.local.email')
h4 {{ $t('deleteAccount') }}
.modal-body
p {{ $t('deleteSocialAccountText') }}
br
.row
.col-md-6
input.form-control(type='text', v-model='password')
.modal-footer
button.btn.btn-default(@click='close()') {{ $t('neverMind') }}
button.btn.btn-danger(:disabled='!password', @click='deleteAccount()') {{ $t('deleteDo') }}
</template>
<script>

View File

@@ -10,4 +10,4 @@ export function getMembers (store, forceLoad = false) {
},
forceLoad,
});
}
}