refactor change class to design update + clean up old site.vue settings

This commit is contained in:
negue
2023-01-14 21:50:22 +01:00
parent 1f16819bc1
commit 428647fc71
6 changed files with 85 additions and 332 deletions
@@ -1,132 +0,0 @@
<template>
<div>
<div>
<h5>{{ $t('dayStartAdjustment') }}</h5>
<div class="mb-4">
{{ $t('customDayStartInfo1') }}
</div>
<h3 v-once>{{ $t('adjustment') }}</h3>
<div class="form-horizontal">
<div class="form-group">
<div class="">
<select
v-model="newDayStart"
class="form-control"
>
<option
v-for="option in dayStartOptions"
:key="option.value"
:value="option.value"
>
{{ option.name }}
</option>
</select>
</div>
<div>
<button
class="btn btn-primary full-width mt-3"
:disabled="newDayStart === user.preferences.dayStart"
@click="openDayStartModal()"
>
{{ $t('save') }}
</button>
</div>
</div>
</div>
</div>
<div class="form-horizontal">
<div class="form-group">
<small>
<p v-html="$t('timezoneUTC', {utc: timezoneOffsetToUtc})"></p>
<p v-html="$t('timezoneInfo')"></p>
</small>
</div>
</div>
</div>
</template>
<script>
import axios from 'axios';
import moment from 'moment';
import getUtcOffset from '../../../../common/script/fns/getUtcOffset';
import { mapState } from '@/libs/store';
export default {
name: 'dayStartAdjustment',
data () {
const dayStartOptions = [];
for (let number = 0; number <= 12; number += 1) {
const meridian = number < 12 ? 'AM' : 'PM';
const hour = number % 12;
const timeWithMeridian = `(${hour || 12}:00 ${meridian})`;
const option = {
value: number,
name: `+${number} hours ${timeWithMeridian}`,
};
if (number === 0) {
option.name = `Default ${timeWithMeridian}`;
}
dayStartOptions.push(option);
}
return {
newDayStart: 0,
dayStartOptions,
};
},
mounted () {
this.newDayStart = this.user.preferences.dayStart;
},
computed: {
...mapState({
user: 'user.data',
}),
timezoneOffsetToUtc () {
const offsetString = moment().utcOffset(getUtcOffset(this.user)).format('Z');
return `UTC${offsetString}`;
},
dayStart () {
return this.user.preferences.dayStart;
},
},
methods: {
async saveDayStart () {
this.user.preferences.dayStart = this.newDayStart;
await axios.post('/api/v4/user/custom-day-start', {
dayStart: this.newDayStart,
});
// @TODO
// Notification.text(response.data.data.message);
},
openDayStartModal () {
const nextCron = this.calculateNextCron();
// @TODO: Add generic modal
if (!window.confirm(this.$t('sureChangeCustomDayStartTime', { time: nextCron }))) return; // eslint-disable-line no-alert
this.saveDayStart();
// $rootScope.openModal('change-day-start', { scope: $scope });
},
calculateNextCron () {
let nextCron = moment()
.hours(this.newDayStart)
.minutes(0)
.seconds(0)
.milliseconds(0);
const currentHour = moment().format('H');
if (currentHour >= this.newDayStart) {
nextCron = nextCron.add(1, 'day');
}
return nextCron.format(`${this.user.preferences.dateFormat.toUpperCase()} @ h:mm a`);
},
},
};
</script>
<style scoped>
.full-width {
width: 100%;
}
</style>
@@ -7,94 +7,6 @@
{{ $t('settings') }}
</h1>
<div class="col-sm-6">
<div class="form-horizontal">
<h5>{{ $t('language') }}</h5>
<select
class="form-control"
:value="user.preferences.language"
@change="changeLanguage($event)"
>
<option
v-for="lang in availableLanguages"
:key="lang.code"
:value="lang.code"
>
{{ lang.name }}
</option>
</select>
<small>
{{ $t('americanEnglishGovern') }}
<br>
<strong v-html="$t('helpWithTranslation')"></strong>
</small>
</div>
<hr>
<div class="form-horizontal">
<h5>{{ $t('dateFormat') }}</h5>
<select
v-model="user.preferences.dateFormat"
class="form-control"
@change="set('dateFormat')"
>
<option
v-for="dateFormat in availableFormats"
:key="dateFormat"
:value="dateFormat"
>
{{ dateFormat }}
</option>
</select>
</div>
<hr>
<div class="form-horizontal">
<div class="form-group">
<h5>{{ $t('audioTheme') }}</h5>
<select
v-model="user.preferences.sound"
class="form-control"
@change="changeAudioTheme"
>
<option
v-for="sound in availableAudioThemes"
:key="sound"
:value="sound"
>
{{ $t(`audioTheme_${sound}`) }}
</option>
</select>
</div>
<button
v-once
class="btn btn-primary btn-xs"
@click="playAudio"
>
{{ $t('demo') }}
</button>
</div>
<hr>
<div
v-if="hasClass"
class="form-horizontal"
>
<h5>{{ $t('characterBuild') }}</h5>
<h6 v-once>
{{ $t('class') + ': ' }}
<!-- @TODO: what is classText-->
<!-- span(v-if='classText') {{ classText }}&nbsp;-->
<button
v-once
class="btn btn-danger btn-xs"
@click="changeClassForUser(true)"
>
{{ $t('changeClass') }}
</button>
<small class="cost">
&nbsp; 3 {{ $t('gems') }}
<!-- @TODO add icon span.Pet_Currency_Gem1x.inline-gems-->
</small>
</h6>
<hr>
</div>
<div>
<div class="checkbox">
<label>
@@ -157,18 +69,6 @@
>
{{ $t('fixVal') }}
</button>
<button
v-if="user.preferences.disableClasses == true"
class="btn btn-primary mb-2"
popover-trigger="mouseenter"
popover-placement="right"
:popover="$t('enableClassPop')"
@click="changeClassForUser(false)"
>
{{ $t('enableClass') }}
</button>
<hr>
<day-start-adjustment />
</div>
</div>
<div class="col-sm-6">
@@ -359,22 +259,16 @@ import { mapState } from '@/libs/store';
import restoreModal from './restoreModal';
import resetModal from './resetModal';
import deleteModal from './deleteModal';
import dayStartAdjustment from './dayStartAdjustment';
import { SUPPORTED_SOCIAL_NETWORKS } from '@/../../common/script/constants';
import changeClass from '@/../../common/script/ops/changeClass';
import notificationsMixin from '../../mixins/notifications';
import sounds from '../../libs/sounds';
import { buildAppleAuthUrl } from '../../libs/auth';
// @TODO: this needs our window.env fix
// import { availableLanguages } from '../../../server/libs/i18n';
export default {
components: {
restoreModal,
resetModal,
deleteModal,
dayStartAdjustment,
},
mixins: [notificationsMixin],
data () {
@@ -469,12 +363,6 @@ export default {
return false;
});
},
async changeLanguage (e) {
const newLang = e.target.value;
this.user.preferences.language = newLang;
await this.set('language');
setTimeout(() => window.location.reload(true));
},
async changeUser (attribute, updates) {
await axios.put(`/api/v4/user/auth/update-${attribute}`, updates);
if (attribute === 'password') {
@@ -512,15 +400,6 @@ export default {
window.location.href = '/';
}
},
async changeClassForUser (confirmationNeeded) {
if (confirmationNeeded && !window.confirm(this.$t('changeClassConfirmCost'))) return; // eslint-disable-line no-alert
try {
changeClass(this.user);
await axios.post('/api/v4/user/change-class');
} catch (e) {
window.alert(e.message); // eslint-disable-line no-alert
}
},
async addLocalAuth () {
if (this.localAuth.email === '') {
this.localAuth.email = this.user.auth.local.email;
@@ -1,5 +1,8 @@
<template>
<div class="gem-price-div">
<div
class="gem-price-div"
:class="{'background': withBackground}"
>
<div
:class="'mr-2 svg-icon gem icon-' +iconSize"
v-html="icons.gem"
@@ -13,7 +16,7 @@ import gemIcon from '@/assets/svg/gem.svg';
export default {
name: 'GemPrice',
props: ['gemPrice', 'iconSize'],
props: ['gemPrice', 'iconSize', 'withBackground'],
data () {
return {
icons: Object.freeze({
@@ -39,4 +42,12 @@ export default {
display: inline-flex;
align-items: center;
}
.background {
align-self: center;
border-radius: 20px;
padding: 6px 20px;
background-color: rgba($green-100, 0.15);
}
</style>
@@ -7,7 +7,11 @@
{{ $t('yourBalance') }}:
</span>
<balance-info class="balance-info" />
<balance-info
class="balance-info"
:currency-needed="currencyNeeded"
:amount-needed="amountNeeded"
/>
</div>
</template>
@@ -17,6 +21,14 @@ import BalanceInfo from '@/components/shops/balanceInfo.vue';
export default {
name: 'YourBalance',
components: { BalanceInfo },
props: {
currencyNeeded: {
type: String,
},
amountNeeded: {
type: Number,
},
},
};
</script>
@@ -9,14 +9,24 @@
<td class="settings-value">
<div
class="class-value"
:class="{[selectedClass]: true}"
:class="{[selectedClass]: !classDisabled, disabled: classDisabled}"
>
<span
v-if="!classDisabled"
class="svg-icon icon-16 mr-2"
v-html="classIcons[selectedClass]"
></span>
<span class="label">
<span
v-if="classDisabled"
class="label"
>
{{ $t('noClassSelected') }}
</span>
<span
v-else
class="label"
>
{{ $t(selectedClass) }}
</span>
</div>
@@ -26,7 +36,7 @@
class="edit-link"
@click.prevent="openModal()"
>
{{ $t('edit') }}
{{ $t(classDisabled ? 'chooseClassSetting' : 'edit') }}
</a>
</td>
</tr>
@@ -48,50 +58,25 @@
<span>{{ $t("changeClassDisclaimer") }}</span>
</div>
<div class="content-centered">
<div class="class-selection">
<div
v-for="classType in classList"
:key="classType"
class="class-card"
:class="{[classType]: true, selected: classType === selectedClass}"
@click="markSelectedClass(classType)"
>
<span
class="svg-icon icon-48 mb-1"
v-html="classIcons[classType]"
></span>
<span class="label">
{{ $t(classType) }}
</span>
<div
v-if="classType === selectedClass"
class="selected-badge"
>
<span
class="svg-icon"
v-html="icons.check"
></span>
</div>
</div>
</div>
<gem-price
gem-price="3"
icon-size="24"
class="gem-price-spacing"
:with-background="true"
/>
<save-cancel-buttons
primary-button-label="changeClassSetting"
class="mb-2"
:disable-save="previousValue === selectedClass"
:disable-save="amountNeeded > userGems"
@saveClicked="changeClassAndClose()"
@cancelClicked="requestCloseModal()"
/>
<your-balance />
<your-balance
:amount-needed="amountNeeded"
currency-needed="gems"
/>
</div>
</td>
</tr>
@@ -127,6 +112,7 @@ input {
}
.gem-price-spacing {
margin-top: 1.5rem;
margin-bottom: 1.125rem;
justify-content: center;
}
@@ -140,34 +126,6 @@ input {
margin-top: 1.5rem;
}
.class-card {
position: relative;
height: 96px;
width: 96px;
min-width: 96px;
border-radius: 4px;
box-shadow: 0 1px 3px 0 rgba($black, 0.12), 0 1px 2px 0 rgba($black, 0.24);
background-color: $white;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
cursor: pointer;
&:hover {
box-shadow: 0 3px 6px 0 rgba($black, 0.16), 0 3px 6px 0 rgba($black, 0.24);
border: solid 1px $purple-400;
}
&.selected {
border: solid 1px $green-100;
}
}
.healer {
color: $healer-color;
}
@@ -184,9 +142,12 @@ input {
color: $wizard-color;
}
.disabled {
color: $maroon-50;
}
.label {
font-size: 14px;
font-weight: bold;
line-height: 1.71;
text-align: center;
}
@@ -210,16 +171,19 @@ input {
display: flex;
align-items: center;
.label {
font-weight: bold;
line-height: 1.71;
&:not(.disabled) {
.label {
font-weight: bold;
line-height: 1.71;
}
}
}
</style>
<script>
import { mapState } from '@/libs/store';
import axios from 'axios';
import { mapGetters, mapState } from '@/libs/store';
import SaveCancelButtons from '../components/saveCancelButtons.vue';
import { InlineSettingMixin } from '../components/inlineSettingMixin';
@@ -231,6 +195,7 @@ import rogueIcon from '@/assets/svg/rogue.svg';
import healerIcon from '@/assets/svg/healer.svg';
import wizardIcon from '@/assets/svg/wizard.svg';
import checkIcon from '@/assets/svg/check.svg';
import changeClass from '@/../../common/script/ops/changeClass';
export default {
components: {
@@ -241,7 +206,7 @@ export default {
mixins: [InlineSettingMixin, GenericUserPreferencesMixin],
data () {
return {
previousValue: '',
amountNeeded: 3 / 4,
selectedClass: '',
classIcons: Object.freeze({
warrior: warriorIcon,
@@ -255,6 +220,9 @@ export default {
};
},
computed: {
...mapGetters({
userGems: 'user:gems',
}),
...mapState({
user: 'user.data',
availableLanguages: 'i18n.availableLanguages',
@@ -263,22 +231,35 @@ export default {
classList () {
return this.content.classes;
},
classDisabled () {
return this.user.preferences.disableClasses;
},
},
mounted () {
this.previousValue = this.user.stats.class;
this.selectedClass = this.user.stats.class;
this.resetControls();
},
methods: {
markSelectedClass (newValue) {
this.selectedClass = newValue;
this.modalValuesChanged(this.previousValue !== newValue);
},
async changeClassAndClose () {
if (this.user.flags.classSelected && !window.confirm(this.$t('changeClassConfirmCost'))) {
if (!this.classDisabled && !window.confirm(this.$t('changeClassConfirmCost'))) {
return;
}
this.$store.dispatch('user:changeClass', { query: { class: this.selectedClass } });
this.$root.$once('bv::hide::modal', () => {
// update the label in the settings list
this.selectedClass = this.user.stats.class;
});
try {
await Promise.all([
// resets the class settings and triggers indirectly the modal of
// src/components/achievemnts/chooseClass - I don't know if we should keep this weird way
changeClass(this.user),
axios.post('/api/v4/user/change-class'),
]);
} catch (e) {
window.alert(e.message); // eslint-disable-line no-alert
}
this.closeModal();
},
@@ -287,7 +268,7 @@ export default {
* do not remove
*/
resetControls () {
this.selectedClass = this.previousValue;
this.selectedClass = this.user.stats.class;
},
},
};
+2
View File
@@ -219,7 +219,9 @@
"amount": "Amount",
"action": "Action",
"note": "Note",
"noClassSelected": "No Class Selected",
"changeClassSetting": "Change Class",
"chooseClassSetting": "Choose Class",
"changeClassDisclaimer": "Changing your class will refund all of your existing Stat Points. Once you have selected your new class, adjust your Stat Points from the Stats section of your profile.",
"remainingBalance": "Remaining Balance",
"transactions": "Transactions",