mirror of
https://github.com/HabitRPG/habitica.git
synced 2025-12-18 07:07:35 +01:00
allow stats to be edited from admin panel
This commit is contained in:
@@ -1,5 +1,8 @@
|
||||
<template>
|
||||
<form @submit.prevent="saveHero({ hero, msg: 'Authentication' })">
|
||||
<form @submit.prevent="saveHero({ hero: {
|
||||
auth: hero.auth,
|
||||
preferences: hero.preferences,
|
||||
}, msg: 'Authentication' })">
|
||||
<div class="card mt-2">
|
||||
<div class="card-header">
|
||||
<h3
|
||||
|
||||
@@ -47,6 +47,11 @@
|
||||
:preferences="hero.preferences"
|
||||
/>
|
||||
|
||||
<stats
|
||||
:hero="hero"
|
||||
:reset-counter="resetCounter"
|
||||
/>
|
||||
|
||||
<items-owned
|
||||
:hero="hero"
|
||||
:reset-counter="resetCounter"
|
||||
@@ -127,6 +132,7 @@ import SubscriptionAndPerks from './subscriptionAndPerks';
|
||||
import CustomizationsOwned from './customizationsOwned.vue';
|
||||
import Achievements from './achievements.vue';
|
||||
import UserHistory from './userHistory.vue';
|
||||
import Stats from './stats.vue';
|
||||
|
||||
import { userStateMixin } from '../../../mixins/userState';
|
||||
|
||||
@@ -142,6 +148,7 @@ export default {
|
||||
ContributorDetails,
|
||||
Transactions,
|
||||
UserHistory,
|
||||
Stats,
|
||||
SubscriptionAndPerks,
|
||||
UserProfile,
|
||||
Achievements,
|
||||
|
||||
266
website/client/src/components/admin-panel/user-support/stats.vue
Normal file
266
website/client/src/components/admin-panel/user-support/stats.vue
Normal file
@@ -0,0 +1,266 @@
|
||||
<template>
|
||||
<form @submit.prevent="submitClicked()">
|
||||
<div class="card mt-2">
|
||||
<div class="card-header">
|
||||
<h3
|
||||
class="mb-0 mt-0"
|
||||
:class="{'open': expand}"
|
||||
@click="expand = !expand"
|
||||
>
|
||||
Stats
|
||||
</h3>
|
||||
</div>
|
||||
<div
|
||||
v-if="expand"
|
||||
class="card-body"
|
||||
>
|
||||
<div class="form-group row">
|
||||
<label class="col-sm-3 col-form-label red-label">Health</label>
|
||||
<div class="col-sm-9">
|
||||
<input
|
||||
v-model="hero.stats.hp"
|
||||
class="form-control"
|
||||
type="number"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label class="col-sm-3 col-form-label yellow-label">Experience</label>
|
||||
<div class="col-sm-9">
|
||||
<input
|
||||
v-model="hero.stats.exp"
|
||||
class="form-control"
|
||||
type="number"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label class="col-sm-3 col-form-label blue-label">Mana</label>
|
||||
<div class="col-sm-9">
|
||||
<input
|
||||
v-model="hero.stats.mp"
|
||||
class="form-control"
|
||||
type="number"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label class="col-sm-3 col-form-label">Level</label>
|
||||
<div class="col-sm-9">
|
||||
<input
|
||||
v-model="hero.stats.lvl"
|
||||
class="form-control"
|
||||
type="number"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label class="col-sm-3 col-form-label">Gold</label>
|
||||
<div class="col-sm-9">
|
||||
<input
|
||||
v-model="hero.stats.gp"
|
||||
class="form-control"
|
||||
type="number"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<h3>Stat Points</h3>
|
||||
<div class="form-group row">
|
||||
<label class="col-sm-3 col-form-label">Unallocated</label>
|
||||
<div class="col-sm-9">
|
||||
<input
|
||||
v-model="hero.stats.points"
|
||||
class="form-control"
|
||||
type="number"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label class="col-sm-3 col-form-label red-label">Strength</label>
|
||||
<div class="col-sm-9">
|
||||
<input
|
||||
v-model="hero.stats.str"
|
||||
class="form-control"
|
||||
type="number"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label class="col-sm-3 col-form-label blue-label">Intelligence</label>
|
||||
<div class="col-sm-9">
|
||||
<input
|
||||
v-model="hero.stats.int"
|
||||
class="form-control"
|
||||
type="number"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label class="col-sm-3 col-form-label purple-label">Perception</label>
|
||||
<div class="col-sm-9">
|
||||
<input
|
||||
v-model="hero.stats.per"
|
||||
class="form-control"
|
||||
type="number"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label class="col-sm-3 col-form-label yellow-label">Constitution</label>
|
||||
<div class="col-sm-9">
|
||||
<input
|
||||
v-model="hero.stats.con"
|
||||
class="form-control"
|
||||
type="number"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row" v-if="statPointsIncorrect">
|
||||
<label class="col-sm-3 col-form-label"></label>
|
||||
<div class="col-sm-9 red-label">Error: Sum of stat points should equal the users level
|
||||
</div>
|
||||
</div>
|
||||
<h3>Buffs</h3>
|
||||
<div class="form-group row">
|
||||
<label class="col-sm-3 col-form-label red-label">Strength</label>
|
||||
<div class="col-sm-9">
|
||||
<input
|
||||
v-model="hero.stats.buffs.str"
|
||||
class="form-control"
|
||||
type="number"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label class="col-sm-3 col-form-label blue-label">Intelligence</label>
|
||||
<div class="col-sm-9">
|
||||
<input
|
||||
v-model="hero.stats.buffs.int"
|
||||
class="form-control"
|
||||
type="number"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label class="col-sm-3 col-form-label purple-label">Perception</label>
|
||||
<div class="col-sm-9">
|
||||
<input
|
||||
v-model="hero.stats.buffs.per"
|
||||
class="form-control"
|
||||
type="number"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label class="col-sm-3 col-form-label yellow-label">Constitution</label>
|
||||
<div class="col-sm-9">
|
||||
<input
|
||||
v-model="hero.stats.buffs.con"
|
||||
class="form-control"
|
||||
type="number"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-if="expand"
|
||||
class="card-footer"
|
||||
>
|
||||
<input
|
||||
type="submit"
|
||||
value="Save"
|
||||
class="btn btn-primary mt-1"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import '~@/assets/scss/colors.scss';
|
||||
|
||||
.about-row {
|
||||
margin-left: 0px;
|
||||
margin-right: 0px;
|
||||
}
|
||||
|
||||
.red-label {
|
||||
color: $red_100;
|
||||
}
|
||||
.blue-label {
|
||||
color: $blue_100;
|
||||
}
|
||||
.purple-label {
|
||||
color: $purple_300;
|
||||
}
|
||||
.yellow-label {
|
||||
color: $yellow_50;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
import markdownDirective from '@/directives/markdown';
|
||||
import saveHero from '../mixins/saveHero';
|
||||
|
||||
import { mapState } from '@/libs/store';
|
||||
import { userStateMixin } from '../../../mixins/userState';
|
||||
|
||||
function resetData (self) {
|
||||
self.expand = false;
|
||||
}
|
||||
|
||||
export default {
|
||||
directives: {
|
||||
markdown: markdownDirective,
|
||||
},
|
||||
mixins: [
|
||||
userStateMixin,
|
||||
saveHero,
|
||||
],
|
||||
computed: {
|
||||
...mapState({ user: 'user.data' }),
|
||||
statPointsIncorrect () {
|
||||
console.log(this.hero.stats.points, this.hero.stats.str,
|
||||
this.hero.stats.int, this.hero.stats.per,
|
||||
this.hero.stats.con, this.hero.stats.lvl);
|
||||
return (parseInt(this.hero.stats.points, 10)
|
||||
+ parseInt(this.hero.stats.str, 10)
|
||||
+ parseInt(this.hero.stats.int, 10)
|
||||
+ parseInt(this.hero.stats.per, 10)
|
||||
+ parseInt(this.hero.stats.con, 10)
|
||||
) !== this.hero.stats.lvl;
|
||||
},
|
||||
},
|
||||
props: {
|
||||
resetCounter: {
|
||||
type: Number,
|
||||
required: true,
|
||||
},
|
||||
hero: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
expand: false,
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
resetCounter () {
|
||||
resetData(this);
|
||||
},
|
||||
},
|
||||
mounted () {
|
||||
resetData(this);
|
||||
},
|
||||
methods: {
|
||||
submitClicked () {
|
||||
if (this.statPointsIncorrect) {
|
||||
return;
|
||||
}
|
||||
this.saveHero({hero: { stats: this.hero.stats }, msg: 'Stats'})
|
||||
},
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -1,5 +1,7 @@
|
||||
<template>
|
||||
<form @submit.prevent="saveHero({ hero, msg: 'Subscription Perks' })">
|
||||
<form @submit.prevent="saveHero({ hero: {
|
||||
purchased: hero.purchased
|
||||
}, msg: 'Subscription Perks' })">
|
||||
<div class="card mt-2">
|
||||
<div class="card-header">
|
||||
<h3
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<form @submit.prevent="saveHero({hero, msg: 'Users Profile'})">
|
||||
<form @submit.prevent="saveHero({hero: { profile: hero.profile }, msg: 'Users Profile'})">
|
||||
<div class="card mt-2">
|
||||
<div class="card-header">
|
||||
<h3
|
||||
|
||||
@@ -146,7 +146,7 @@ api.getHeroes = {
|
||||
// Note, while the following routes are called getHero / updateHero
|
||||
// they can be used by admins to get/update any user
|
||||
|
||||
const heroAdminFields = 'auth balance contributor flags items lastCron party preferences profile purchased secret permissions achievements';
|
||||
const heroAdminFields = 'auth balance contributor flags items lastCron party preferences profile purchased secret permissions achievements stats';
|
||||
const heroAdminFieldsToFetch = heroAdminFields; // these variables will make more sense when...
|
||||
const heroAdminFieldsToShow = heroAdminFields; // ... apiTokenObscured is added
|
||||
|
||||
@@ -319,6 +319,42 @@ api.updateHero = {
|
||||
}
|
||||
}
|
||||
|
||||
if (updateData.stats) {
|
||||
if (updateData.stats.hp) {
|
||||
hero.stats.hp = updateData.stats.hp;
|
||||
}
|
||||
if (updateData.stats.mp) {
|
||||
hero.stats.mp = updateData.stats.mp;
|
||||
}
|
||||
if (updateData.stats.exp) {
|
||||
hero.stats.exp = updateData.stats.exp;
|
||||
}
|
||||
if (updateData.stats.gp) {
|
||||
hero.stats.gp = updateData.stats.gp;
|
||||
}
|
||||
if (updateData.stats.lvl) {
|
||||
hero.stats.lvl = updateData.stats.lvl;
|
||||
}
|
||||
if (updateData.stats.points) {
|
||||
hero.stats.points = updateData.stats.points;
|
||||
}
|
||||
if (updateData.stats.str) {
|
||||
hero.stats.str = updateData.stats.str;
|
||||
}
|
||||
if (updateData.stats.int) {
|
||||
hero.stats.int = updateData.stats.int;
|
||||
}
|
||||
if (updateData.stats.per) {
|
||||
hero.stats.per = updateData.stats.per;
|
||||
}
|
||||
if (updateData.stats.con) {
|
||||
hero.stats.con = updateData.stats.con;
|
||||
}
|
||||
if (updateData.stats.buffs) {
|
||||
hero.stats.buffs = updateData.stats.buffs;
|
||||
}
|
||||
}
|
||||
|
||||
// give them gems if they got an higher level
|
||||
// tier = level in this context
|
||||
let newTier = updateData.contributor && updateData.contributor.level;
|
||||
|
||||
@@ -84,7 +84,7 @@ const commitUserHistoryUpdate = function commitUserHistoryUpdate (update) {
|
||||
).exec();
|
||||
};
|
||||
|
||||
model.beginUserHistoryUpdate = function beginUserHistoryUpdate (userID, client=null) {
|
||||
model.beginUserHistoryUpdate = function beginUserHistoryUpdate (userID, client = null) {
|
||||
return {
|
||||
userId: userID,
|
||||
data: {
|
||||
|
||||
Reference in New Issue
Block a user