Client Analytics (#9023)
* start to refactor analytics and some mixins * wip * wip * wip * more analytics * more analytics * more anlytics * fix analytics module * finish analytics * fix env * vue casing
This commit is contained in:
@@ -60,6 +60,7 @@ import bModal from 'bootstrap-vue/lib/components/modal';
|
||||
|
||||
import Avatar from '../avatar';
|
||||
import { mapState } from 'client/libs/store';
|
||||
import * as Analytics from 'client/libs/analytics';
|
||||
import percent from '../../../common/script/libs/percent';
|
||||
import {maxHealth} from '../../../common/script/index';
|
||||
|
||||
@@ -84,6 +85,14 @@ export default {
|
||||
return `${Math.ceil(this.user.stats.hp)} / ${this.maxHealth}`;
|
||||
},
|
||||
},
|
||||
mounted () {
|
||||
Analytics.track({
|
||||
hitType: 'event',
|
||||
eventCategory: 'button',
|
||||
eventAction: 'click',
|
||||
eventLabel: 'Health Warning',
|
||||
});
|
||||
},
|
||||
methods: {
|
||||
close () {
|
||||
this.$root.$emit('hide::modal', 'low-health');
|
||||
|
||||
@@ -219,6 +219,7 @@
|
||||
import axios from 'axios';
|
||||
import moment from 'moment';
|
||||
import { mapState } from 'client/libs/store';
|
||||
import * as Analytics from 'client/libs/analytics';
|
||||
|
||||
import gryphon from 'assets/svg/gryphon.svg';
|
||||
import twitter from 'assets/svg/twitter.svg';
|
||||
@@ -331,6 +332,12 @@ export default {
|
||||
this.$root.$emit('show::modal', 'modify-inventory');
|
||||
},
|
||||
donate () {
|
||||
Analytics.track({
|
||||
hitType: 'event',
|
||||
eventCategory: 'button',
|
||||
eventAction: 'click',
|
||||
eventLabel: 'Gems > Donate',
|
||||
});
|
||||
this.$root.$emit('show::modal', 'buy-gems');
|
||||
},
|
||||
},
|
||||
|
||||
@@ -224,6 +224,7 @@ div
|
||||
|
||||
<script>
|
||||
import { mapState, mapGetters } from 'client/libs/store';
|
||||
import * as Analytics from 'client/libs/analytics';
|
||||
import gemIcon from 'assets/svg/gem.svg';
|
||||
import goldIcon from 'assets/svg/gold.svg';
|
||||
import userIcon from 'assets/svg/user.svg';
|
||||
@@ -289,6 +290,12 @@ export default {
|
||||
this.$root.$emit('show::modal', 'create-party-modal');
|
||||
},
|
||||
showBuyGemsModal () {
|
||||
Analytics.track({
|
||||
hitType: 'event',
|
||||
eventCategory: 'button',
|
||||
eventAction: 'click',
|
||||
eventLabel: 'Gems > Toolbar',
|
||||
});
|
||||
this.$root.$emit('show::modal', 'buy-gems');
|
||||
},
|
||||
},
|
||||
|
||||
@@ -290,6 +290,9 @@ export default {
|
||||
passwordConfirm: this.passwordConfirm,
|
||||
});
|
||||
|
||||
// @TODO do not reload entire page
|
||||
// problem is that app.vue created hook should be called again
|
||||
// after user is logged in / just signed up
|
||||
window.location.href = '/';
|
||||
},
|
||||
async login () {
|
||||
@@ -299,6 +302,9 @@ export default {
|
||||
password: this.password,
|
||||
});
|
||||
|
||||
// @TODO do not reload entire page
|
||||
// problem is that app.vue created hook should be called again
|
||||
// after user is logged in / just signed up
|
||||
window.location.href = '/';
|
||||
},
|
||||
async socialAuth (network) {
|
||||
@@ -314,6 +320,9 @@ export default {
|
||||
auth,
|
||||
});
|
||||
|
||||
// @TODO do not reload entire page
|
||||
// problem is that app.vue created hook should be called again
|
||||
// after user is logged in / just signed up
|
||||
window.location.href = '/';
|
||||
},
|
||||
handleSubmit () {
|
||||
|
||||
@@ -55,6 +55,8 @@
|
||||
.col-12.text-center.submit-button-wrapper
|
||||
.alert.alert-warning(v-if='insufficientGemsForTavernChallenge')
|
||||
You do not have enough gems to create a Tavern challenge
|
||||
// @TODO if buy gems button is added, add analytics tracking to it
|
||||
// see https://github.com/HabitRPG/habitica/blob/develop/website/views/options/social/challenges.jade#L134
|
||||
button.btn.btn-primary(v-once, v-if='creating', @click='createChallenge()') {{$t('createChallengeAddTasks')}}
|
||||
button.btn.btn-primary(v-once, v-if='!creating', @click='updateChallenge()') {{$t('updateChallenge')}}
|
||||
.col-12.text-center
|
||||
|
||||
@@ -17,7 +17,7 @@ b-modal#create-party-modal(title="Empty", size='lg', hide-footer=true)
|
||||
.join-party
|
||||
h3(v-once) {{$t('wantToJoinPartyTitle')}}
|
||||
p(v-once) {{$t('wantToJoinPartyDescription')}}
|
||||
button.btn.btn-primary(v-once, @click='shareUserIdShown = !shareUserIdShown') {{$t('shartUserId')}}
|
||||
button.btn.btn-primary(v-once, @click='shareUserId()') {{$t('shartUserId')}}
|
||||
.share-userid-options(v-if="shareUserIdShown")
|
||||
.option-item(v-once)
|
||||
.svg-icon(v-html="icons.copy")
|
||||
@@ -137,6 +137,7 @@ b-modal#create-party-modal(title="Empty", size='lg', hide-footer=true)
|
||||
|
||||
<script>
|
||||
import { mapState } from 'client/libs/store';
|
||||
import * as Analytics from 'client/libs/analytics';
|
||||
|
||||
import bModal from 'bootstrap-vue/lib/components/modal';
|
||||
|
||||
@@ -166,6 +167,15 @@ export default {
|
||||
...mapState({user: 'user.data'}),
|
||||
},
|
||||
methods: {
|
||||
shareUserId () {
|
||||
Analytics.track({
|
||||
hitType: 'event',
|
||||
eventCategory: 'button',
|
||||
eventAction: 'click',
|
||||
eventLabel: 'Health Warning',
|
||||
});
|
||||
this.shareUserIdShown = !this.shareUserIdShown;
|
||||
},
|
||||
async createParty () {
|
||||
let group = {
|
||||
type: 'party',
|
||||
@@ -174,9 +184,14 @@ export default {
|
||||
let party = await this.$store.dispatch('guilds:create', {group});
|
||||
this.$store.state.party.data = party;
|
||||
this.user.party._id = party._id;
|
||||
|
||||
Analytics.updateUser({
|
||||
partyID: party._id,
|
||||
partySize: 1,
|
||||
});
|
||||
|
||||
this.$root.$emit('hide::modal', 'create-party-modal');
|
||||
this.$router.push('/party');
|
||||
// @TODO: Analytics.updateUser({'partyID': $scope.group ._id, 'partySize': 1});
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -409,6 +409,7 @@ import extend from 'lodash/extend';
|
||||
import groupUtilities from 'client/mixins/groupsUtilities';
|
||||
import styleHelper from 'client/mixins/styleHelper';
|
||||
import { mapState } from 'client/libs/store';
|
||||
import * as Analytics from 'client/libs/analytics';
|
||||
import membersModal from './membersModal';
|
||||
import startQuestModal from './startQuestModal';
|
||||
import quests from 'common/script/content/quests';
|
||||
@@ -636,7 +637,7 @@ export default {
|
||||
},
|
||||
async sendMessage () {
|
||||
let response = await this.$store.dispatch('chat:postChat', {
|
||||
groupId: this.group._id,
|
||||
group: this.group._id,
|
||||
message: this.newMessage,
|
||||
});
|
||||
this.group.chat.unshift(response.message);
|
||||
@@ -699,7 +700,13 @@ export default {
|
||||
this.user.guilds.push(this.group._id);
|
||||
},
|
||||
clickLeave () {
|
||||
// Analytics.track({'hitType':'event','eventCategory':'button','eventAction':'click','eventLabel':'Leave Party'});
|
||||
Analytics.track({
|
||||
hitType: 'event',
|
||||
eventCategory: 'button',
|
||||
eventAction: 'click',
|
||||
eventLabel: 'Leave Party',
|
||||
});
|
||||
|
||||
// @TODO: Get challenges and ask to keep or remove
|
||||
if (!confirm('Are you sure you want to leave?')) return;
|
||||
let keep = true;
|
||||
@@ -714,12 +721,14 @@ export default {
|
||||
keepChallenges,
|
||||
};
|
||||
|
||||
if (this.isParty) data.type = 'party';
|
||||
if (this.isParty) {
|
||||
data.type = 'party';
|
||||
Analytics.updateUser({partySize: null, partyID: null});
|
||||
}
|
||||
|
||||
await this.$store.dispatch('guilds:leave', data);
|
||||
|
||||
// @TODO: Implement
|
||||
// Analytics.updateUser({'partySize':null,'partyID':null});
|
||||
// User.sync().then(function () {
|
||||
// $rootScope.hardRedirect('/#/options/groups/party');
|
||||
// });
|
||||
@@ -743,7 +752,13 @@ export default {
|
||||
await this.$store.dispatch('guilds:join', {groupId: this.group._id});
|
||||
},
|
||||
clickStartQuest () {
|
||||
// Analytics.track({'hitType':'event','eventCategory':'button','eventAction':'click','eventLabel':'Start a Quest'});
|
||||
Analytics.track({
|
||||
hitType: 'event',
|
||||
eventCategory: 'button',
|
||||
eventAction: 'click',
|
||||
eventLabel: 'Start a Quest',
|
||||
});
|
||||
|
||||
let hasQuests = find(this.user.items.quests, (quest) => {
|
||||
return quest > 0;
|
||||
});
|
||||
|
||||
@@ -375,7 +375,14 @@ export default {
|
||||
// @TODO: Add proper notifications
|
||||
alert('Not enough gems');
|
||||
return;
|
||||
// @TODO return $rootScope.openModal('buyGems', {track:"Gems > Create Group"});
|
||||
// @TODO return $rootScope.openModal('buyGems', {track:"Gems > Gems > Create Group"});
|
||||
// @TODO when modal is implemented, enable analytics
|
||||
/* Analytics.track({
|
||||
hitType: 'event',
|
||||
eventCategory: 'button',
|
||||
eventAction: 'click',
|
||||
eventLabel: 'Health Warning',
|
||||
}); */
|
||||
}
|
||||
|
||||
if (!this.workingGroup.name || !this.workingGroup.description) {
|
||||
|
||||
@@ -55,8 +55,12 @@ import filter from 'lodash/filter';
|
||||
import map from 'lodash/map';
|
||||
import bModal from 'bootstrap-vue/lib/components/modal';
|
||||
import notifications from 'client/mixins/notifications';
|
||||
import * as Analytics from 'client/libs/analytics';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
bModal,
|
||||
},
|
||||
mixins: [notifications],
|
||||
props: ['group'],
|
||||
data () {
|
||||
@@ -65,8 +69,13 @@ export default {
|
||||
emails: [],
|
||||
};
|
||||
},
|
||||
components: {
|
||||
bModal,
|
||||
mounted () {
|
||||
Analytics.track({
|
||||
hitType: 'event',
|
||||
eventCategory: 'button',
|
||||
eventAction: 'click',
|
||||
eventLabel: 'Invite Friends',
|
||||
});
|
||||
},
|
||||
computed: {
|
||||
...mapState({user: 'user.data'}),
|
||||
|
||||
@@ -159,6 +159,7 @@
|
||||
|
||||
<script>
|
||||
import { mapState } from 'client/libs/store';
|
||||
import * as Analytics from 'client/libs/analytics';
|
||||
import bModal from 'bootstrap-vue/lib/components/modal';
|
||||
|
||||
import quests from 'common/script/content/quests';
|
||||
@@ -208,10 +209,15 @@ export default {
|
||||
this.selectedQuest = quest;
|
||||
},
|
||||
async questInit () {
|
||||
let key = this.selectedQuest;
|
||||
// Analytics.updateUser({'partyID': party._id, 'partySize': party.memberCount});
|
||||
let response = await this.$store.dispatch('guilds:inviteToQuest', {groupId: this.group._id, key});
|
||||
let quest = response.data.data;
|
||||
Analytics.updateUser({
|
||||
partyID: this.group._id,
|
||||
partySize: this.group.memberCount,
|
||||
});
|
||||
|
||||
const key = this.selectedQuest;
|
||||
const response = await this.$store.dispatch('guilds:inviteToQuest', {groupId: this.group._id, key});
|
||||
const quest = response.data.data;
|
||||
|
||||
this.$store.party.quest = quest;
|
||||
this.$root.$emit('hide::modal', 'start-quest-modal');
|
||||
},
|
||||
|
||||
@@ -137,6 +137,7 @@ import isEmpty from 'lodash/isEmpty';
|
||||
import map from 'lodash/map';
|
||||
|
||||
import { mapState } from 'client/libs/store';
|
||||
import * as Analytics from 'client/libs/analytics';
|
||||
import quests from 'common/script/content/quests';
|
||||
import notificationsIcon from 'assets/svg/notifications.svg';
|
||||
|
||||
@@ -299,7 +300,10 @@ export default {
|
||||
|
||||
if (type === 'party') {
|
||||
// @TODO: pretty sure mutability is wrong. Need to check React docs
|
||||
// @TODO mutation to store data should only happen through actions
|
||||
this.user.invitations.parties.splice(index, 1);
|
||||
|
||||
Analytics.updateUser({partyID: group.id});
|
||||
} else {
|
||||
this.user.invitations.guilds.splice(index, 1);
|
||||
}
|
||||
|
||||
@@ -181,6 +181,7 @@
|
||||
|
||||
<script>
|
||||
import bModal from 'bootstrap-vue/lib/components/modal';
|
||||
import * as Analytics from 'client/libs/analytics';
|
||||
|
||||
import svgClose from 'assets/svg/close.svg';
|
||||
import svgGold from 'assets/svg/gold.svg';
|
||||
@@ -266,6 +267,14 @@
|
||||
this.hideDialog();
|
||||
},
|
||||
purchaseGems () {
|
||||
if (this.item.key === 'rebirth_orb') {
|
||||
Analytics.track({
|
||||
hitType: 'event',
|
||||
eventCategory: 'button',
|
||||
eventAction: 'click',
|
||||
eventLabel: 'Gems > Rebirth',
|
||||
});
|
||||
}
|
||||
this.$root.$emit('show::modal', 'buy-gems');
|
||||
},
|
||||
togglePinned () {
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
.row.row-margin(style="font-size: 2rem;")
|
||||
span {{ $t('enterprisePlansDescription') }}
|
||||
.row.row-margin
|
||||
// TODO
|
||||
a.btn.btn-primary.btn-lg.btn-block(:href="'mailto:vicky@habitica.com?subject=' + $t('enterprisePlansEmailSubject')") {{ $t('enterprisePlansButton') }}
|
||||
|
||||
br
|
||||
@@ -28,3 +29,22 @@
|
||||
.row.row-margin
|
||||
a.btn.btn-primary.btn-lg.btn-block(href="https://docs.google.com/forms/d/e/1FAIpQLSerMKkaCg3UcgpcMvBJtlNgnF9DNY8sxCebpAT-GHeDAQASPQ/viewform?usp=sf_link") {{ $t('familyPlansButton') }}
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as Analytics from 'client/libs/analytics';
|
||||
|
||||
export default {
|
||||
methods: {
|
||||
contactUs () {
|
||||
Analytics.track({
|
||||
hitType: 'event',
|
||||
eventCategory: 'button',
|
||||
eventAction: 'click',
|
||||
eventLabel: 'Contact Us (Plans)',
|
||||
});
|
||||
|
||||
window.location.href = `mailto:vicky@habitica.com?subject=${this.$t('enterprisePlansEmailSubject')}`;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -91,20 +91,29 @@
|
||||
</style>
|
||||
|
||||
<script>
|
||||
import logo from 'assets/svg/logo.svg';
|
||||
import logo from 'assets/svg/logo.svg';
|
||||
import * as Analytics from 'client/libs/analytics';
|
||||
|
||||
export default {
|
||||
data () {
|
||||
return {
|
||||
icons: Object.freeze({
|
||||
logo,
|
||||
}),
|
||||
};
|
||||
export default {
|
||||
data () {
|
||||
return {
|
||||
icons: Object.freeze({
|
||||
logo,
|
||||
}),
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
playButtonClick () {
|
||||
// @TODO duplicate of code in home.vue
|
||||
Analytics.track({
|
||||
hitType: 'event',
|
||||
eventCategory: 'button',
|
||||
eventAction: 'click',
|
||||
eventLabel: 'Play',
|
||||
});
|
||||
|
||||
this.$router.push('/register');
|
||||
},
|
||||
methods: {
|
||||
playButtonClick () {
|
||||
this.$router.push('/register');
|
||||
},
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
+13
-1
@@ -602,6 +602,7 @@
|
||||
<script>
|
||||
import AppFooter from 'client/components/appFooter';
|
||||
import StaticHeader from './header.vue';
|
||||
import * as Analytics from 'client/libs/analytics';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
@@ -614,10 +615,21 @@
|
||||
};
|
||||
},
|
||||
mounted () {
|
||||
// Analytics.track({"hitType":"pageview","eventCategory":"page","eventAction":"landing page","page":"/home"});
|
||||
Analytics.track({
|
||||
hitType: 'pageview',
|
||||
eventCategory: 'page',
|
||||
eventAction: 'landing page',
|
||||
page: '/home',
|
||||
});
|
||||
},
|
||||
methods: {
|
||||
playButtonClick () {
|
||||
Analytics.track({
|
||||
hitType: 'event',
|
||||
eventCategory: 'button',
|
||||
eventAction: 'click',
|
||||
eventLabel: 'Play',
|
||||
});
|
||||
this.$router.push('/register');
|
||||
},
|
||||
},
|
||||
@@ -298,6 +298,7 @@ import moment from 'moment';
|
||||
import axios from 'axios';
|
||||
import scoreTask from 'common/script/ops/scoreTask';
|
||||
import Vue from 'vue';
|
||||
import * as Analytics from 'client/libs/analytics';
|
||||
|
||||
import positiveIcon from 'assets/svg/positive.svg';
|
||||
import negativeIcon from 'assets/svg/negative.svg';
|
||||
@@ -435,6 +436,7 @@ export default {
|
||||
|
||||
if (task.group.approval.required) task.group.approval.requested = true;
|
||||
|
||||
Analytics.updateUser();
|
||||
const response = await axios.post(`/api/v3/tasks/${task._id}/score/${direction}`);
|
||||
const tmp = response.data.data._tmp || {}; // used to notify drops, critical hits and other bonuses
|
||||
const crit = tmp.crit;
|
||||
|
||||
Reference in New Issue
Block a user