fix checkbox alignment in admin panel

This commit is contained in:
Phillip Thelen
2024-07-29 18:18:31 +02:00
parent 26d5a4503c
commit e2f25e34e6
15 changed files with 603 additions and 453 deletions

View File

@@ -175,16 +175,16 @@
}
.btn-warning {
background: $yellow-10;
background: $orange-10;
border: 1px solid transparent;
&:hover:not(:disabled):not(.disabled) {
background: $yellow-100;
background: $orange-100;
border: 1px solid transparent;
}
&:focus {
background: $yellow-10;
background: $orange-10;
border-color: $purple-400;
}
@@ -194,7 +194,7 @@
}
&:not(:disabled):not(.disabled):active, &:not(:disabled):not(.disabled).active {
background: $yellow-10;
background: $orange-10;
border: 1px solid transparent;
}
}

View File

@@ -15,18 +15,27 @@
>
<div class="input-group-append">
<button
class="btn btn-primary"
type="button"
@click="loadUser(userIdentifier)">Load User</button>
class="btn btn-primary"
type="button"
@click="loadUser(userIdentifier)"
>
Load User
</button>
<button
class="btn btn-secondary"
type="button"
@click="searchUsers(userIdentifier)">Search</button>
class="btn btn-secondary"
type="button"
@click="searchUsers(userIdentifier)"
>
Search
</button>
</div>
</div>
</form>
<router-view @changeUserIdentifier="changeUserIdentifier" class="mt-3" />
<router-view
class="mt-3"
@changeUserIdentifier="changeUserIdentifier"
/>
</div>
</div>
</template>
@@ -75,7 +84,7 @@ export default {
},
async searchUsers (userIdentifier) {
if (!userIdentifier || userIdentifier === '') {
loadUser();
this.loadUser();
return;
}
this.$router.push({

View File

@@ -1,32 +1,41 @@
<template>
<div>
<div class="alert alert-warning" role="alert"
<div
v-if="noUsersFound"
class="alert alert-warning"
role="alert"
>
Could not find any matching users.
</div>
<div class="list-group"
v-if="users.length > 0">
<a href="#" class="list-group-item list-group-item-action"
<div
v-if="users.length > 0"
class="list-group"
>
<a
v-for="user in users"
:key="user._id"
href="#"
class="list-group-item list-group-item-action"
@click="loadUser(user._id)"
>
<div class="d-flex w-100 justify-content-between">
<h5 class="mb-1">{{ user.profile.name }}</h5>
<small>{{ user._id }}</small>
</div>
<p class="mb-1"
:class="{'font-weight-bold': matchValueToIdentifier(user.auth.local.username)}">
<p
class="mb-1"
:class="{'font-weight-bold': matchValueToIdentifier(user.auth.local.username)}"
>
@{{ user.auth.local.username }}</p>
<p class="mb-0">
<span
v-for="email in userEmails(user)"
:class="{'font-weigh-bold': matchValueToIdentifier(email)}"
:key="email">
{{ email }}
</span>
</p>
<p class="mb-0">
<span
v-for="email in userEmails(user)"
:key="email"
:class="{'font-weigh-bold': matchValueToIdentifier(email)}"
>
{{ email }}
</span>
</p>
</a>
</div>
</div>

View File

@@ -1,15 +1,18 @@
<template>
<div class="card mt-2">
<div class="card-header">
<h3
class="mb-0 mt-0"
:class="{'open': expand}"
@click="expand = !expand"
<h3
class="mb-0 mt-0"
:class="{'open': expand}"
@click="expand = !expand"
>
Achievements
</h3>
</div>
<div
v-if="expand"
class="card-body"
>
Achievements
</h3>
</div>
<div v-if="expand" class="card-body">
<ul>
<li
v-for="item in achievements"

View File

@@ -1,15 +1,18 @@
<template>
<div class="card mt-2">
<div class="card-header">
<h3
class="mb-0 mt-0"
:class="{'open': expand}"
@click="expand = !expand"
<h3
class="mb-0 mt-0"
:class="{'open': expand}"
@click="expand = !expand"
>
Current Avatar Appearance, Drop Count Today
</h3>
</div>
<div
v-if="expand"
class="card-body"
>
Current Avatar Appearance, Drop Count Today
</h3>
</div>
<div v-if="expand" class="card-body">
<div>Drops Today: {{ items.lastDrop.count }}</div>
<div>Most Recent Drop: {{ items.lastDrop.date | formatDate }}</div>
<div>Use Costume: {{ preferences.costume ? 'on' : 'off' }}</div>

View File

@@ -1,161 +1,129 @@
<template>
<form @submit.prevent="saveHero({hero, msg: 'Contributor details', clearData: true})">
<div class="card mt-2">
<div class="card-header">
<h3
class="mb-0 mt-0"
:class="{'open': expand}"
@click="expand = !expand"
>
Contributor Details
</h3>
</div>
<div v-if="expand" class="card-body">
<form @submit.prevent="saveHero({ hero, msg: 'Contributor details', clearData: true })">
<div class="card mt-2">
<div class="card-header">
<h3
class="mb-0 mt-0"
:class="{ 'open': expand }"
@click="expand = !expand"
>
Contributor Details
</h3>
</div>
<div
v-if="expand"
class="card-body"
>
<div class="mb-4">
<h3 class="mt-0">Permissions</h3>
<div class="checkbox">
<label>
<h3 class="mt-0">
Permissions
</h3>
<div
v-for="permission in permissionList"
:key="permission.key"
class="col-sm-9 offset-sm-3"
>
<div class="custom-control custom-checkbox">
<input
v-model="hero.permissions.fullAccess"
:disabled="!hasPermission(user, 'fullAccess')"
v-model="hero.permissions[permission.key]"
:disabled="!hasPermission(user, permission.key)"
class="custom-control-input"
type="checkbox"
>
Full Admin Access (Allows access to everything. EVERYTHING)
</label>
</div>
<div class="checkbox">
<label>
<input
v-model="hero.permissions.userSupport"
:disabled="!hasPermission(user, 'fullAccess')"
type="checkbox"
>
User Support (Access this form, access purchase history)
</label>
</div>
<div class="checkbox">
<label>
<input
v-model="hero.permissions.news"
:disabled="!hasPermission(user, 'fullAccess')"
type="checkbox"
>
News poster (Bailey CMS)
</label>
</div>
<div class="checkbox">
<label>
<input
v-model="hero.permissions.moderator"
:disabled="!hasPermission(user, 'fullAccess')"
type="checkbox"
>
Community Moderator (ban and mute users, access chat flags, manage social spaces)
</label>
</div>
<div class="checkbox">
<label>
<input
v-model="hero.permissions.challengeAdmin"
:disabled="!hasPermission(user, 'fullAccess')"
type="checkbox"
>
Challenge Admin (can create official habitica challenges and admin all challenges)
</label>
</div>
<div class="checkbox">
<label>
<input
v-model="hero.permissions.coupons"
:disabled="!hasPermission(user, 'fullAccess')"
type="checkbox"
>
Coupon Creator (can manage coupon codes)
</label>
<label class="custom-control-label">
{{ permission.name }}<br>
<small class="text-secondary">{{ permission.description }}</small>
</label>
</div>
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label">Title</label>
<div class="col-sm-9">
<input
v-model="hero.contributor.text"
class="form-control textField"
type="text"
>
<small>
Common titles:
<strong>Ambassador, Artisan, Bard, Blacksmith, Challenger, Comrade, Fletcher,
Linguist, Linguistic Scribe, Scribe, Socialite, Storyteller</strong>.
<br>
Rare titles:
Advisor, Chamberlain, Designer, Mathematician, Shirtster, Spokesperson,
Statistician, Tinker, Transcriber, Troubadour.
</small>
<input
v-model="hero.contributor.text"
class="form-control textField"
type="text"
>
<small>
Common titles:
<strong>Ambassador, Artisan, Bard, Blacksmith, Challenger, Comrade, Fletcher,
Linguist, Linguistic Scribe, Scribe, Socialite, Storyteller</strong>.
<br>
Rare titles:
Advisor, Chamberlain, Designer, Mathematician, Shirtster, Spokesperson,
Statistician, Tinker, Transcriber, Troubadour.
</small>
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label">Tier</label>
<div class="col-sm-9">
<input
v-model="hero.contributor.level"
class="form-control levelField"
type="number"
>
<small>
1-7 for normal contributors, 8 for moderators, 9 for staff.
This determines which items, pets, mounts are available, and name-tag coloring.
Tiers 8 and 9 are automatically given admin status.
</small>
<input
v-model="hero.contributor.level"
class="form-control levelField"
type="number"
>
<small>
1-7 for normal contributors, 8 for moderators, 9 for staff.
This determines which items, pets, mounts are available, and name-tag coloring.
</small>
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label">Contributions</label>
<div class="col-sm-9">
<textarea
v-model="hero.contributor.contributions"
class="form-control"
cols="5"
rows="5"
></textarea>
<div
v-markdown="hero.contributor.contributions"
class="markdownPreview"
></div>
v-model="hero.contributor.contributions"
class="form-control"
cols="5"
rows="5"
>
</textarea>
<div
v-markdown="hero.contributor.contributions"
class="markdownPreview"
></div>
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label">Moderation Notes</label>
<div class="col-sm-9">
<textarea
v-model="hero.secret.text"
class="form-control"
cols="5"
rows="3"
></textarea>
<div
v-markdown="hero.secret.text"
class="markdownPreview"
></div>
<textarea
v-model="hero.secret.text"
class="form-control"
cols="5"
rows="3"
></textarea>
<div
v-markdown="hero.secret.text"
class="markdownPreview"
></div>
</div>
</div>
</div>
<div class="card-footer" v-if="expand">
</div>
<div
v-if="expand"
class="card-footer"
>
<input
type="submit"
value="Save"
class="btn btn-primary mt-1"
></div>
</div>
</form>
>
</div>
</div>
</form>
</template>
<style lang="scss" scoped>
.levelField {
min-width: 10ch;
}
.textField {
min-width: 50ch;
}
.levelField {
min-width: 10ch;
}
.textField {
min-width: 50ch;
}
</style>
<script>
@@ -165,6 +133,39 @@ import saveHero from '../mixins/saveHero';
import { mapState } from '@/libs/store';
import { userStateMixin } from '../../../mixins/userState';
const permissionList = [
{
key: 'fullAccess',
name: 'Full Admin Access',
description: 'Allows access to everything. EVERYTHING',
},
{
key: 'userSupport',
name: 'User Support',
description: 'Access this form, access purchase history',
},
{
key: 'news',
name: 'News Poster',
description: 'Bailey CMS',
},
{
key: 'moderator',
name: 'Community Moderator',
description: 'Ban and mute users, access chat flags, manage social spaces',
},
{
key: 'challengeAdmin',
name: 'Challenge Admin',
description: 'Can create official habitica challenges and admin all challenges',
},
{
key: 'coupons',
name: 'Coupon Creator',
description: 'Can manage coupon codes',
},
];
function resetData (self) {
self.expand = self.hero.contributor.level;
}
@@ -193,6 +194,7 @@ export default {
data () {
return {
expand: false,
permissionList,
};
},
watch: {

View File

@@ -1,175 +1,186 @@
<template>
<form @submit.prevent="saveHero({ hero, msg: 'Authentication' })">
<div class="card mt-2">
<div class="card-header">
<h3
class="mb-0 mt-0"
:class="{'open': expand}"
@click="expand = !expand"
>
Timestamps, Time Zone, Authentication, Email Address
<span
v-if="errorsOrWarningsExist"
>- ERRORS / WARNINGS EXIST</span>
</h3>
</div>
<div v-if="expand" class="card-body">
<p
v-if="errorsOrWarningsExist"
class="errorMessage"
<form @submit.prevent="saveHero({ hero, msg: 'Authentication' })">
<div class="card mt-2">
<div class="card-header">
<h3
class="mb-0 mt-0"
:class="{'open': expand}"
@click="expand = !expand"
>
Timestamps, Time Zone, Authentication, Email Address
<span
v-if="errorsOrWarningsExist"
>- ERRORS / WARNINGS EXIST</span>
</h3>
</div>
<div
v-if="expand"
class="card-body"
>
See error(s) below.
</p>
<p
v-if="errorsOrWarningsExist"
class="errorMessage"
>
See error(s) below.
</p>
<div class="form-group row">
<label class="col-sm-3 col-form-label">Account created:</label>
<strong class="col-sm-9 col-form-label">
{{ hero.auth.timestamps.created | formatDate }}</strong>
</div>
<div class="form-group row" v-if="hero.flags.thirdPartyTools">
User has employed <strong>third party tools</strong>. Last known usage:
<strong class="col-sm-9 col-form-label">
{{ hero.flags.thirdPartyTools | formatDate }}</strong>
</div>
<div v-if="cronError">
"lastCron" value:
<strong>{{ hero.lastCron | formatDate }}</strong>
<br>
<span class="errorMessage">
ERROR: cron probably crashed before finishing
("auth.timestamps.loggedin" and "lastCron" dates are different).
</span>
</div>
<div class="form-group row">
<div class="form-group row">
<label class="col-sm-3 col-form-label">Account created:</label>
<strong class="col-sm-9 col-form-label">
{{ hero.auth.timestamps.created | formatDate }}</strong>
</div>
<div
v-if="hero.flags.thirdPartyTools"
class="form-group row"
>
User has employed <strong>third party tools</strong>. Last known usage:
<strong class="col-sm-9 col-form-label">
{{ hero.flags.thirdPartyTools | formatDate }}</strong>
</div>
<div v-if="cronError">
"lastCron" value:
<strong>{{ hero.lastCron | formatDate }}</strong>
<br>
<span class="errorMessage">
ERROR: cron probably crashed before finishing
("auth.timestamps.loggedin" and "lastCron" dates are different).
</span>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label">Most recent cron:</label>
<div class="col-sm-9 col-form-label">
<strong>
{{ hero.auth.timestamps.loggedin | formatDate }}</strong>
<button
class="btn btn-warning btn-sm ml-4"
@click="resetCron()"
>
Reset Cron to Yesterday
</button>
<div class="col-sm-9 col-form-label">
<strong>
{{ hero.auth.timestamps.loggedin | formatDate }}</strong>
<button
class="btn btn-warning btn-sm ml-4"
@click="resetCron()"
>
Reset Cron to Yesterday
</button>
</div>
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label">Time zone:</label>
<strong class="col-sm-9 col-form-label">
{{ hero.preferences.timezoneOffset | formatTimeZone }}</strong>
</div>
<div class="form-group row">
<div class="form-group row">
<label class="col-sm-3 col-form-label">Time zone:</label>
<strong class="col-sm-9 col-form-label">
{{ hero.preferences.timezoneOffset | formatTimeZone }}</strong>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label">Custom Day Start time (CDS)</label>
<div class="col-sm-9">
<input
v-model="hero.preferences.dayStart"
class="form-control levelField"
type="number"
>
</div>
</div>
<div v-if="timezoneDiffError || timezoneMissingError">
Time zone at previous cron:
<strong>{{ hero.preferences.timezoneOffsetAtLastCron | formatTimeZone }}</strong>
<div class="errorMessage">
<div v-if="timezoneDiffError">
ERROR: the player's current time zone is different than their time zone when
their previous cron ran. This can be because:
<ul>
<li>daylight savings started or stopped <sup>*</sup></li>
<li>the player changed zones due to travel <sup>*</sup></li>
<li>the player has devices set to different zones <sup>**</sup></li>
<li>the player uses a VPN with varying zones <sup>**</sup></li>
<li>something similarly unpleasant is happening. <sup>**</sup></li>
</ul>
<p>
<em>* The problem should fix itself in about a day.</em><br>
<em>** One of these causes is probably happening if the time zones stay
different for more than a day.</em>
</p>
</div>
<div v-if="timezoneMissingError">
ERROR: One of the player's time zones is missing.
This is expected and okay if it's the "Time zone at previous cron"
AND if it's their first day in Habitica.
Otherwise an error has occurred.
<input
v-model="hero.preferences.dayStart"
class="form-control levelField"
type="number"
>
</div>
</div>
</div>
<div v-if="timezoneDiffError || timezoneMissingError">
Time zone at previous cron:
<strong>{{ hero.preferences.timezoneOffsetAtLastCron | formatTimeZone }}</strong>
<div class="form-group row">
<label class="col-sm-3 col-form-label">API Token</label>
<div class="col-sm-9">
<button
@click="changeApiToken()"
value="Change API Token"
class="btn btn-danger">
Change API Token
</button>
<div
v-if="tokenModified"
>
<strong>API Token has been changed. Tell the player something like this:</strong>
<br>
I've given you a new API Token.
You'll need to log out of the website and mobile app then log back in
otherwise they won't work correctly.
If you have trouble logging out, for the website go to
https://habitica.com/static/clear-browser-data and click the red button there,
and for the Android app, clear its data.
For the iOS app, if you can't log out you might need to uninstall it,
reboot your phone, then reinstall it.
<div class="errorMessage">
<div v-if="timezoneDiffError">
ERROR: the player's current time zone is different than their time zone when
their previous cron ran. This can be because:
<ul>
<li>daylight savings started or stopped <sup>*</sup></li>
<li>the player changed zones due to travel <sup>*</sup></li>
<li>the player has devices set to different zones <sup>**</sup></li>
<li>the player uses a VPN with varying zones <sup>**</sup></li>
<li>something similarly unpleasant is happening. <sup>**</sup></li>
</ul>
<p>
<em>* The problem should fix itself in about a day.</em><br>
<em>** One of these causes is probably happening if the time zones stay
different for more than a day.</em>
</p>
</div>
<div v-if="timezoneMissingError">
ERROR: One of the player's time zones is missing.
This is expected and okay if it's the "Time zone at previous cron"
AND if it's their first day in Habitica.
Otherwise an error has occurred.
</div>
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label">API Token</label>
<div class="col-sm-9">
<button
value="Change API Token"
class="btn btn-danger"
@click="changeApiToken()"
>
Change API Token
</button>
<div
v-if="tokenModified"
>
<strong>API Token has been changed. Tell the player something like this:</strong>
<br>
I've given you a new API Token.
You'll need to log out of the website and mobile app then log back in
otherwise they won't work correctly.
If you have trouble logging out, for the website go to
https://habitica.com/static/clear-browser-data and click the red button there,
and for the Android app, clear its data.
For the iOS app, if you can't log out you might need to uninstall it,
reboot your phone, then reinstall it.
</div>
</div>
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label">Local Authentication E-Mail</label>
<div class="col-sm-9">
<input
v-model="hero.auth.local.email"
class="form-control"
type="text"
>
<input
v-model="hero.auth.local.email"
class="form-control"
type="text"
>
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label">Google authentication</label>
<div class="col-sm-9">
<pre v-if="authMethodExists('google')">{{ hero.auth.google }}</pre>
<span v-else><strong>None</strong></span>
<div class="form-group row">
<label class="col-sm-3 col-form-label">Google authentication</label>
<div class="col-sm-9">
<pre v-if="authMethodExists('google')">{{ hero.auth.google }}</pre>
<span v-else><strong>None</strong></span>
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label">Facebook authentication</label>
<div class="col-sm-9">
<pre v-if="authMethodExists('facebook')">{{ hero.auth.facebook }}</pre>
<span v-else><strong>None</strong></span>
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label">Apple ID authentication</label>
<div class="col-sm-9">
<pre v-if="authMethodExists('apple')">{{ hero.auth.apple }}</pre>
<span v-else><strong>None</strong></span>
</div>
</div>
<div class="subsection-start">
Full "auth" object for checking above is correct:
<pre>{{ hero.auth }}</pre>
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label">Facebook authentication</label>
<div class="col-sm-9">
<pre v-if="authMethodExists('facebook')">{{ hero.auth.facebook }}</pre>
<span v-else><strong>None</strong></span>
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label">Apple ID authentication</label>
<div class="col-sm-9">
<pre v-if="authMethodExists('apple')">{{ hero.auth.apple }}</pre>
<span v-else><strong>None</strong></span>
</div>
</div>
<div class="subsection-start">
Full "auth" object for checking above is correct:
<pre>{{ hero.auth }}</pre>
</div>
</div>
<div class="card-footer" v-if="expand">
<div
v-if="expand"
class="card-footer"
>
<input
type="submit"
value="Save"
class="btn btn-primary mt-1"
></div>
</div>
</form>
>
</div>
</div>
</form>
</template>
<script>

View File

@@ -1,15 +1,18 @@
<template>
<div class="card mt-2">
<div class="card-header">
<h3
class="mb-0 mt-0"
:class="{'open': expand}"
@click="expand = !expand"
<h3
class="mb-0 mt-0"
:class="{'open': expand}"
@click="expand = !expand"
>
Customizations
</h3>
</div>
<div
v-if="expand"
class="card-body"
>
Customizations
</h3>
</div>
<div v-if="expand" class="card-body">
<div
v-for="itemType in itemTypes"
:key="itemType"

View File

@@ -1,15 +1,18 @@
<template>
<div class="card mt-2">
<div class="card-header">
<h3
class="mb-0 mt-0"
:class="{'open': expand}"
@click="expand = !expand"
<h3
class="mb-0 mt-0"
:class="{'open': expand}"
@click="expand = !expand"
>
Items
</h3>
</div>
<div
v-if="expand"
class="card-body"
>
Items
</h3>
</div>
<div v-if="expand" class="card-body">
<div>
The sections below display each item's key (bolded if the player has ever owned it),
followed by the item's English name.

View File

@@ -1,18 +1,21 @@
<template>
<div class="card mt-2">
<div class="card-header">
<h3
class="mb-0 mt-0"
:class="{'open': expand}"
@click="expand = !expand"
>
Party, Quest
<span
v-if="errorsOrWarningsExist"
>- ERRORS / WARNINGS EXIST</span>
</h3>
<h3
class="mb-0 mt-0"
:class="{'open': expand}"
@click="expand = !expand"
>
Party, Quest
<span
v-if="errorsOrWarningsExist"
>- ERRORS / WARNINGS EXIST</span>
</h3>
</div>
<div v-if="expand" class="card-body">
<div
v-if="expand"
class="card-body"
>
<div
v-if="errorsOrWarningsExist"
class="errorMessage"

View File

@@ -1,47 +1,62 @@
<template>
<form @submit.prevent="saveHero({hero, msg: 'Privileges or Gems or Moderation Notes'})">
<div class="card mt-2">
<div class="card-header">
<h3
class="mb-0 mt-0"
:class="{'open': expand}"
@click="expand = !expand"
>
Priviliges, Gem Balance
</h3>
</div>
<div v-if="expand" class="card-body">
<p
v-if="errorsOrWarningsExist"
class="errorMessage"
<form @submit.prevent="saveHero({hero, msg: 'Privileges or Gems or Moderation Notes'})">
<div class="card mt-2">
<div class="card-header">
<h3
class="mb-0 mt-0"
:class="{'open': expand}"
@click="expand = !expand"
>
Priviliges, Gem Balance
</h3>
</div>
<div
v-if="expand"
class="card-body"
>
Player has had privileges removed or has moderation notes.
</p>
<div class="form-group row">
<p
v-if="errorsOrWarningsExist"
class="errorMessage"
>
Player has had privileges removed or has moderation notes.
</p>
<div
v-if="hero.flags"
class="form-group row"
>
<div class="col-sm-9 offset-sm-3">
<div class="form-check">
<div class="custom-control custom-checkbox">
<input
v-if="hero.flags"
v-model="hero.flags.chatShadowMuted"
class="form-check-input"
type="checkbox"
>
<label class="form-check-label">
id="chatShadowMuted"
v-model="hero.flags.chatShadowMuted"
class="custom-control-input"
type="checkbox"
>
<label
class="custom-control-label"
for="chatShadowMuted"
>
Shadow Mute
</label>
</div>
</div>
</div>
<div class="form-group row">
<div
v-if="hero.flags"
class="form-group row"
>
<div class="col-sm-9 offset-sm-3">
<div class="form-check">
<div class="custom-control custom-checkbox">
<input
v-if="hero.flags"
v-model="hero.flags.chatRevoked"
class="form-check-input"
type="checkbox"
>
<label class="form-check-label">
id="chatRevoked"
v-model="hero.flags.chatRevoked"
class="custom-control-input"
type="checkbox"
>
<label
class="custom-control-label"
for="chatRevoked"
>
Mute (Revoke Chat Privileges)
</label>
</div>
@@ -49,13 +64,17 @@
</div>
<div class="form-group row">
<div class="col-sm-9 offset-sm-3">
<div class="form-check">
<div class="custom-control custom-checkbox">
<input
v-model="hero.auth.blocked"
class="form-check-input"
type="checkbox"
>
<label class="form-check-label">
id="blocked"
v-model="hero.auth.blocked"
class="custom-control-input"
type="checkbox"
>
<label
class="custom-control-label"
for="blocked"
>
Ban / Block
</label>
</div>
@@ -83,27 +102,31 @@
<div class="form-group row">
<label class="col-sm-3 col-form-label">Moderation Notes</label>
<div class="col-sm-9">
<textarea
v-model="hero.secret.text"
class="form-control"
cols="5"
rows="5"
></textarea>
<div
v-markdown="hero.secret.text"
class="markdownPreview"
></div>
<textarea
v-model="hero.secret.text"
class="form-control"
cols="5"
rows="5"
></textarea>
<div
v-markdown="hero.secret.text"
class="markdownPreview"
></div>
</div>
</div>
</div>
<div class="card-footer" v-if="expand">
</div>
<div
v-if="expand"
class="card-footer"
>
<input
type="submit"
value="Save"
class="btn btn-primary mt-1"
></div>
</div>
</form>
>
</div>
</div>
</form>
</template>
<style lang="scss" scoped>

View File

@@ -2,11 +2,18 @@
<form @submit.prevent="saveHero({ hero, msg: 'Subscription Perks' })">
<div class="card mt-2">
<div class="card-header">
<h3 class="mb-0 mt-0" :class="{ 'open': expand }" @click="expand = !expand">
<h3
class="mb-0 mt-0"
:class="{ 'open': expand }"
@click="expand = !expand"
>
Subscription, Monthly Perks
</h3>
</div>
<div v-if="expand" class="card-body">
<div
v-if="expand"
class="card-body"
>
<div v-if="hero.purchased.plan.paymentMethod">
Payment method:
<strong>{{ hero.purchased.plan.paymentMethod }}</strong>
@@ -19,13 +26,20 @@
Group plan ID:
<strong>{{ hero.purchased.plan.owner }}</strong>
</div>
<div v-if="hero.purchased.plan.dateCreated" class="form-group row">
<div
v-if="hero.purchased.plan.dateCreated"
class="form-group row"
>
<label class="col-sm-3 col-form-label">
Creation date:
</label>
<div class="col-sm-9">
<div class="input-group">
<input v-model="hero.purchased.plan.dateCreated" class="form-control" type="text">
<input
v-model="hero.purchased.plan.dateCreated"
class="form-control"
type="text"
>
<div class="input-group-append">
<strong>
{{ dateFormat(hero.purchased.plan.dateCreated) }}
@@ -34,13 +48,20 @@
</div>
</div>
</div>
<div v-if="hero.purchased.plan.dateCurrentTypeCreated" class="form-group row">
<div
v-if="hero.purchased.plan.dateCurrentTypeCreated"
class="form-group row"
>
<label class="col-sm-3 col-form-label">
Current sub start date:
</label>
<div class="col-sm-9">
<div class="input-group">
<input v-model="hero.purchased.plan.dateCurrentTypeCreated" class="form-control" type="text">
<input
v-model="hero.purchased.plan.dateCurrentTypeCreated"
class="form-control"
type="text"
>
<div class="input-group-append">
<strong>
{{ dateFormat(hero.purchased.plan.dateCurrentTypeCreated) }}
@@ -55,7 +76,11 @@
</label>
<div class="col-sm-9">
<div class="input-group">
<input v-model="hero.purchased.plan.dateTerminated" class="form-control" type="text">
<input
v-model="hero.purchased.plan.dateTerminated"
class="form-control"
type="text"
>
<div class="input-group-append">
<strong class="input-group-text">
{{ dateFormat(hero.purchased.plan.dateTerminated) }}
@@ -69,7 +94,13 @@
Consecutive months:
</label>
<div class="col-sm-9">
<input v-model="hero.purchased.plan.consecutive.count" class="form-control" type="number" min="0" step="1">
<input
v-model="hero.purchased.plan.consecutive.count"
class="form-control"
type="number"
min="0"
step="1"
>
</div>
</div>
<div class="form-group row">
@@ -77,7 +108,13 @@
Perk offset months:
</label>
<div class="col-sm-9">
<input v-model="hero.purchased.plan.consecutive.offset" class="form-control" type="number" min="0" step="1">
<input
v-model="hero.purchased.plan.consecutive.offset"
class="form-control"
type="number"
min="0"
step="1"
>
</div>
</div>
<div class="form-group row">
@@ -85,8 +122,14 @@
Perk month count:
</label>
<div class="col-sm-9">
<input v-model="hero.purchased.plan.perkMonthCount" class="form-control" type="number" min="0" max="2"
step="1">
<input
v-model="hero.purchased.plan.perkMonthCount"
class="form-control"
type="number"
min="0"
max="2"
step="1"
>
</div>
</div>
<div class="form-group row">
@@ -100,8 +143,13 @@
Mystic Hourglasses:
</label>
<div class="col-sm-9">
<input v-model="hero.purchased.plan.consecutive.trinkets" class="form-control" type="number" min="0"
step="1">
<input
v-model="hero.purchased.plan.consecutive.trinkets"
class="form-control"
type="number"
min="0"
step="1"
>
</div>
</div>
<div class="form-group row">
@@ -109,8 +157,14 @@
Gem cap increase:
</label>
<div class="col-sm-9">
<input v-model="hero.purchased.plan.consecutive.gemCapExtra" class="form-control" type="number" min="0"
max="25" step="5">
<input
v-model="hero.purchased.plan.consecutive.gemCapExtra"
class="form-control"
type="number"
min="0"
max="25"
step="5"
>
</div>
</div>
<div class="form-group row">
@@ -126,8 +180,14 @@
Gems bought this month:
</label>
<div class="col-sm-9">
<input v-model="hero.purchased.plan.gemsBought" class="form-control" type="number" min="0"
:max="hero.purchased.plan.consecutive.gemCapExtra + 25" step="1">
<input
v-model="hero.purchased.plan.gemsBought"
class="form-control"
type="number"
min="0"
:max="hero.purchased.plan.consecutive.gemCapExtra + 25"
step="1"
>
</div>
</div>
<div v-if="hero.purchased.plan.extraMonths > 0">
@@ -140,7 +200,10 @@
</label>
<div class="col-sm-9 col-form-label">
<span v-if="hero.purchased.plan.mysteryItems.length > 0">
<span v-for="(item, index) in hero.purchased.plan.mysteryItems" :key="index">
<span
v-for="(item, index) in hero.purchased.plan.mysteryItems"
:key="index"
>
<strong v-if="index < hero.purchased.plan.mysteryItems.length - 1">
{{ item }},
</strong>
@@ -153,8 +216,15 @@
</div>
</div>
</div>
<div class="card-footer" v-if="expand">
<input type="submit" value="Save" class="btn btn-primary mt-1">
<div
v-if="expand"
class="card-footer"
>
<input
type="submit"
value="Save"
class="btn btn-primary mt-1"
>
</div>
</div>
</form>
@@ -185,20 +255,20 @@ export default {
required: true,
},
},
data() {
data () {
return {
expand: false,
};
},
computed: {
nextHourglassDate() {
nextHourglassDate () {
const currentPlanContext = getPlanContext(this.hero, new Date());
return currentPlanContext.nextHourglassDate.format('MMMM YYYY');
},
},
methods: {
dateFormat(date) {
dateFormat (date) {
if (!date) {
return '--';
}

View File

@@ -1,15 +1,18 @@
<template>
<div class="card mt-2">
<div class="card-header">
<h3
class="mb-0 mt-0"
:class="{'open': expand}"
@click="toggleTransactionsOpen"
<h3
class="mb-0 mt-0"
:class="{'open': expand}"
@click="toggleTransactionsOpen"
>
Transactions
</h3>
</div>
<div
v-if="expand"
class="card-body"
>
Transactions
</h3>
</div>
<div v-if="expand" class="card-body">
<purchase-history-table
:gem-transactions="gemTransactions"
:hourglass-transactions="hourglassTransactions"

View File

@@ -1,34 +1,38 @@
<template>
<form @submit.prevent="saveHero({hero, msg: 'Users Profile'})">
<div class="card mt-2">
<div class="card-header">
<h3
class="mb-0 mt-0"
:class="{'open': expand}"
@click="expand = !expand"
>
User Profile
</h3>
</div>
<div v-if="expand" class="card-body">
<form @submit.prevent="saveHero({hero, msg: 'Users Profile'})">
<div class="card mt-2">
<div class="card-header">
<h3
class="mb-0 mt-0"
:class="{'open': expand}"
@click="expand = !expand"
>
User Profile
</h3>
</div>
<div
v-if="expand"
class="card-body"
>
<div class="form-group row">
<label class="col-sm-3 col-form-label">Display name</label>
<div class="col-sm-9">
<input
v-model="hero.profile.name"
class="form-control"
type="text"
>
v-model="hero.profile.name"
class="form-control"
type="text"
>
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label">Photo URL</label>
<div class="col-sm-9">
<input
v-model="hero.profile.imageUrl"
class="form-control"
type="text"
></div>
<input
v-model="hero.profile.imageUrl"
class="form-control"
type="text"
>
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label">About</label>
@@ -44,15 +48,19 @@
></div>
</div>
</div>
</div>
<div class="card-footer" v-if="expand">
</div>
<div
v-if="expand"
class="card-footer"
>
<input
type="submit"
value="Save"
class="btn btn-primary mt-1"
></div>
</div>
</form>
>
</div>
</div>
</form>
</template>
<style lang="scss" scoped>

View File

@@ -16,10 +16,10 @@
class="brand"
aria-label="Habitica"
>
<router-link to="/">
<router-link to="/">
<div
class="logo svg-icon svg color gryphon"
v-html="icons.melior"
class="logo svg-icon svg color gryphon"
v-html="icons.melior"
></div>
<div class="svg-icon"></div>
</router-link>