This commit is contained in:
Phillip Thelen
2025-08-22 14:04:03 +02:00
parent bd46740d0e
commit 118840d6ce
7 changed files with 186 additions and 134 deletions

View File

@@ -5,12 +5,19 @@
class="row"
>
<div class="form col-12">
<div class="btn-group float-right">
<button
class="btn btn-danger mt-3 float-right"
class="btn btn-danger"
@click="confirmDeleteHero"
>
Begin Member deletion
<span
v-once
class="svg-icon icon-16 mt-1 mb-1"
v-html="icons.deleteIcon"
></span>
</button>
</div>
<basic-details
:user-id="hero._id"
:auth="hero.auth"
@@ -18,7 +25,6 @@
:profile="hero.profile"
/>
<privileges-and-gems
:hero="hero"
:reset-counter="resetCounter"
@@ -202,6 +208,7 @@ import CustomizationsOwned from './customizationsOwned.vue';
import Achievements from './achievements.vue';
import UserHistory from './userHistory.vue';
import Stats from './stats.vue';
import deleteIcon from '@/assets/svg/delete.svg?raw';
import { userStateMixin } from '../../../../mixins/userState';
@@ -240,6 +247,9 @@ export default {
adminHasPrivForParty: true,
deleteHabiticaAccount: true,
deleteAmplitudeData: true,
icons: Object.freeze({
deleteIcon,
}),
};
},
watch: {

View File

@@ -341,16 +341,16 @@ export default {
expand: false,
};
},
computed: {
userIsPartyLeader () {
return this.groupPartyData.leader === this.userId;
},
},
watch: {
resetCounter () {
resetData(this);
},
},
computed: {
userIsPartyLeader () {
return this.groupPartyData.leader === this.userId;
}
},
mounted () {
resetData(this);
},
@@ -363,11 +363,13 @@ export default {
});
},
async makePartyLeader () {
await this.$store.dispatch('guilds:update', { group: {
await this.$store.dispatch('guilds:update', {
group: {
id: this.groupPartyData._id,
leader: this.userId,
} });
}
},
});
},
},
};
</script>

View File

@@ -136,8 +136,9 @@
</div>
</div>
<formRow
v-model="hero.purchased.plan.customerId"
label="Customer ID"
v-model="hero.purchased.plan.customerId" />
/>
<div
v-if="hero.purchased.plan.planId === 'group_plan_auto'"
class="form-group row"
@@ -188,19 +189,22 @@
</div>
</div>
<formRow
label="Creation date"
v-if="hero.purchased.plan.dateCreated"
v-model="hero.purchased.plan.dateCreated"
:suffix="dateFormat(hero.purchased.plan.dateCreated)" />
label="Creation date"
:suffix="dateFormat(hero.purchased.plan.dateCreated)"
/>
<formRow
label="Current sub start date"
v-if="hero.purchased.plan.dateCurrentTypeCreated"
v-model="hero.purchased.plan.dateCurrentTypeCreated"
:suffix="dateFormat(hero.purchased.plan.dateCurrentTypeCreated)" />
label="Current sub start date"
:suffix="dateFormat(hero.purchased.plan.dateCurrentTypeCreated)"
/>
<formRow
label="Termination date"
v-model="hero.purchased.plan.dateTerminated"
:suffix="dateFormat(hero.purchased.plan.dateTerminated)">
label="Termination date"
:suffix="dateFormat(hero.purchased.plan.dateTerminated)"
>
<template #suffix>
<strong class="input-group-text">
{{ dateFormat(hero.purchased.plan.dateTerminated) }}
@@ -214,23 +218,31 @@
Terminate
</a>
</template>
<template #helpText v-if="isSubscribed() && !isCancelled()">
<template
v-if="isSubscribed() && !isCancelled()"
#helpText
>
<span class="text-success">
The subscription does not have a termination date and is active.
</span>
</template>
</formRow>
<formRow
label="Cumulative months"
v-model="hero.purchased.plan.cumulativeCount"
inputType="number"
helpText="Cumulative subscribed months across subscription periods." />
label="Cumulative months"
input-type="number"
help-text="Cumulative subscribed months across subscription periods."
/>
<formRow
label="Extra months"
v-model="hero.purchased.plan.extraMonths"
inputType="number"
helpText="Additional credit that is applied if a subscription is cancelled.">
<template #suffix v-if="hero.purchased.plan.dateTerminated && hero.purchased.plan.extraMonths > 0">
label="Extra months"
input-type="number"
help-text="Additional credit that is applied if a subscription is cancelled."
>
<template
v-if="hero.purchased.plan.dateTerminated && hero.purchased.plan.extraMonths > 0"
#suffix
>
<a
class="btn btn-warning"
@click="applyExtraMonths"
@@ -240,21 +252,24 @@
</template>
</formRow>
<formRow
label="Received hourglass bonus"
v-model="hero.purchased.plan.hourglassPromoReceived"
:suffix="dateFormat(hero.purchased.plan.hourglassPromoReceived)" />
label="Received hourglass bonus"
:suffix="dateFormat(hero.purchased.plan.hourglassPromoReceived)"
/>
<formRow
label="Mystic Hourglasses"
v-model="hero.purchased.plan.consecutive.trinkets"
inputType="number"
min="0" />
label="Mystic Hourglasses"
input-type="number"
min="0"
/>
<formRow
label="Gem cap increase"
v-model="hero.purchased.plan.consecutive.gemCapExtra"
inputType="number"
label="Gem cap increase"
input-type="number"
min="0"
max="26"
step="2" />
step="2"
/>
<div class="form-group row">
<label class="col-sm-3 col-form-label">
Total Gem cap:
@@ -264,11 +279,12 @@
</strong>
</div>
<formRow
label="Gems bought this month"
v-model="hero.purchased.plan.gemsBought"
inputType="number"
label="Gems bought this month"
input-type="number"
min="0"
:max="hero.purchased.plan.consecutive.gemCapExtra + 24" />
:max="hero.purchased.plan.consecutive.gemCapExtra + 24"
/>
<div class="form-group row">
<label class="col-sm-3 col-form-label">
Mystery Items:
@@ -601,8 +617,8 @@ export default {
return `${PLAY_CONSOLE_ORDERS_BASE_URL}${this.paymentDetails?.transactionId || ''}`;
},
isGroupPlanMember () {
return this.hero.purchased.plan.planId === 'group_plan_auto'
}
return this.hero.purchased.plan.planId === 'group_plan_auto';
},
},
methods: {
dateFormat (date) {

View File

@@ -1,8 +1,10 @@
<template>
<div class="form-group row">
<label class="col-sm-3 col-form-label"><slot name="label">{{ label }}:</slot></label>
<div class="col-sm-9"
:class="editable ? 'editable' : 'col-form-label'">
<div
class="col-sm-9"
:class="editable ? 'editable' : 'col-form-label'"
>
<slot>
<div class="input-group">
<strong v-if="!editable">
@@ -20,12 +22,15 @@
:value="value"
class="form-control"
:type="inputType"
@input="$emit('input', $event.target.value)"
:min="min"
:max="max"
:step="step"
@input="$emit('input', $event.target.value)"
>
<div
v-if="suffix || $slots.suffix"
class="input-group-append"
>
<div class="input-group-append" v-if="suffix || $slots.suffix">
<slot name="suffix">
<strong class="input-group-text">
{{ suffix }}
@@ -34,10 +39,18 @@
</div>
</div>
</slot>
<div class="form-text text-muted" v-if="helpText || $slots.helpText">
<slot name="helpText">{{ helpText }}</slot>
<div
v-if="helpText || $slots.helpText"
class="form-text text-muted"
>
<slot name="helpText">
{{ helpText }}
</slot>
</div>
<div class="form-text text-muted mt-1" v-if="$slots.subtitle">
<div
v-if="$slots.subtitle"
class="form-text text-muted mt-1"
>
<slot name="subtitle"></slot>
</div>
</div>
@@ -60,8 +73,7 @@
</style>
<script>
import { max } from 'lodash';
import { min } from 'lodash';
import { max, min } from 'lodash';
export default {
model: {
@@ -95,20 +107,20 @@ export default {
min: {
type: [Number, String],
default: 0,
validator(value) {
validator (value) {
return !isNaN(value) && min([value, 0]) === 0;
},
},
max: {
type: [Number, String],
validator(value) {
validator (value) {
return !isNaN(value) && max([value, 100]) === 100;
},
},
step: {
type: [Number, String],
default: 1,
validator(value) {
validator (value) {
return !isNaN(value) && min([value, 1]) === 1;
},
},

View File

@@ -1,25 +1,30 @@
<template>
<div v-if="group.purchased.plan">
<form-row
label="Payment Method"
v-model="group.purchased.plan.paymentMethod"
:editable="false" />
label="Payment Method"
:editable="false"
/>
<form-row
label="Plan ID"
v-model="group.purchased.plan.planId"
:editable="false" />
label="Plan ID"
:editable="false"
/>
<form-row
label="Customer ID"
v-model="group.purchased.plan.customerId"
:editable="false" />
label="Customer ID"
:editable="false"
/>
<form-row
label="Creation Date"
v-model="group.purchased.plan.dateCreated"
:editable="false" />
label="Creation Date"
:editable="false"
/>
<form-row
label="Termination Date"
v-model="group.purchased.plan.dateTerminated"
:editable="false" />
label="Termination Date"
:editable="false"
/>
</div>
</template>

View File

@@ -3,32 +3,37 @@
<h2>{{ group.name }}</h2>
<router-link
v-if="isGroupPlan"
:to="{'name': 'groupPlanDetail', 'params': {'groupId': groupId}}">
:to="{'name': 'groupPlanDetail', 'params': {'groupId': groupId}}"
>
Group Plan Page
</router-link>
<supportContainer
:title="$t('groupData')"
:onSave="updateGroup">
:on-save="updateGroup"
>
<groupData
:group="group"
/>
</supportContainer>
<supportContainer
:title="$t('groupPlanSubscription')">
:title="$t('groupPlanSubscription')"
>
<groupPlan
:group="group"
/>
</supportContainer>
<supportContainer
v-if="group.type === 'party'"
:title="$t('questDetails')">
:title="$t('questDetails')"
>
<quest
:group="group"
/>
</supportContainer>
<supportContainer
:title="$t('members')">
:title="$t('members')"
>
<members
:group="group"
/>
@@ -59,14 +64,6 @@ export default {
group: {},
};
},
watch: {
groupId () {
this.loadGroup(this.groupId);
},
},
mounted () {
this.groupId = this.$route.params.groupId;
},
computed: {
isGroupPlan () {
return this.group
@@ -75,6 +72,14 @@ export default {
&& this.group.purchased.plan.planId;
},
},
watch: {
groupId () {
this.loadGroup(this.groupId);
},
},
mounted () {
this.groupId = this.$route.params.groupId;
},
methods: {
clearData () {
this.group = {};
@@ -82,17 +87,16 @@ export default {
async loadGroup (groupId) {
this.$emit('changeGroupId', groupId);
this.group = await this.$store.dispatch('admin:getGroup', { groupId });
},
async updateGroup () {
if (this.group && !this.group.id) {
this.group.id = this.group._id || this.groupId; // Ensure group has an id property
}
await this.$store.dispatch('guilds:update', { group: this.group });
this.group = await this.$store.dispatch('admin:getGroup', { groupId: this.group.id })
this.group = await this.$store.dispatch('admin:getGroup', { groupId: this.group.id });
await this.$store.dispatch('snackbars:add', {
title: '',
text: `Group updated`,
text: 'Group updated',
type: 'info',
});
},

View File

@@ -1,23 +1,26 @@
<template>
<div>
<form-row
label="Quest Identifier"
v-model="group.quest.key"
:editable="false" />
label="Quest Identifier"
:editable="false"
/>
<form-row
label="Quest Leader"
v-model="group.quest.leader"
:editable="false">
label="Quest Leader"
:editable="false"
>
<template slot="subtitle">
<router-link
:to="{'name': 'adminPanelUser', 'params': {'userIdentifier': group.quest.leader}}">
:to="{'name': 'adminPanelUser', 'params': {'userIdentifier': group.quest.leader}}"
>
{{ group.quest.leader }}
</router-link>
</template>
</form-row>
<form-row
label="Is Quest Active"
v-model="group.quest.active"
label="Is Quest Active"
input-type="checkbox"
/>
</div>