254 lines
5.8 KiB
Vue
254 lines
5.8 KiB
Vue
<template>
|
|
<div
|
|
v-if="$resources.analytics.data"
|
|
class="grid grid-cols-1 gap-5 sm:grid-cols-2"
|
|
>
|
|
<Card title="Earnings">
|
|
<template #actions>
|
|
<a
|
|
class="text-base text-gray-700 hover:text-gray-800"
|
|
href="/support/tickets"
|
|
target="_blank"
|
|
>
|
|
Contact Support →
|
|
</a>
|
|
</template>
|
|
<ListItem
|
|
title="Total Earnings"
|
|
:subtitle="`Total earnings for ${app.title}`"
|
|
>
|
|
<template #actions>
|
|
<span class="text-base font-semibold text-green-500">{{
|
|
'$' +
|
|
paymentAnalytics.total_payout.usd +
|
|
' + ' +
|
|
'¥' +
|
|
paymentAnalytics.total_payout.cny
|
|
}}</span>
|
|
</template>
|
|
</ListItem>
|
|
<ListItem
|
|
title="Pending Payout"
|
|
subtitle="Payout you are yet to receive from 今果 Jingrow"
|
|
>
|
|
<template #actions>
|
|
<span class="text-base font-semibold">{{
|
|
'$' +
|
|
paymentAnalytics.pending_payout.usd +
|
|
' + ' +
|
|
'¥' +
|
|
paymentAnalytics.pending_payout.cny
|
|
}}</span>
|
|
</template>
|
|
</ListItem>
|
|
<ListItem
|
|
title="Commission"
|
|
subtitle="Payouts start once you have passed $500 threshold"
|
|
>
|
|
<template #actions>
|
|
<span class="text-base font-semibold">{{
|
|
'$' +
|
|
paymentAnalytics.commission.usd +
|
|
' + ' +
|
|
'¥' +
|
|
paymentAnalytics.commission.cny
|
|
}}</span>
|
|
</template>
|
|
</ListItem>
|
|
</Card>
|
|
<Card title="Installs">
|
|
<div class="divide-y" v-if="analytics">
|
|
<ListItem
|
|
v-for="stat in analytics"
|
|
:key="stat.title"
|
|
:title="stat.title"
|
|
:description="stat.value"
|
|
>
|
|
</ListItem>
|
|
</div>
|
|
|
|
<div class="py-10 text-center" v-if="$resources.analytics.loading">
|
|
<Button :loading="true">Loading</Button>
|
|
</div>
|
|
</Card>
|
|
<LineChart
|
|
title="Pageviews"
|
|
type="time"
|
|
:key="pageViewsData"
|
|
:data="pageViewsData"
|
|
unit="views"
|
|
:chartTheme="[$theme.colors.purple[500]]"
|
|
:loading="$resources.plausible_analytics.loading"
|
|
:error="$resources.plausible_analytics.error"
|
|
>
|
|
<template #actions>
|
|
<a
|
|
v-if="app"
|
|
class="text-base text-gray-700 hover:text-gray-800"
|
|
:href="`/marketplace/apps/${app.app}`"
|
|
target="_blank"
|
|
>
|
|
View Marketplace Page →
|
|
</a>
|
|
</template>
|
|
</LineChart>
|
|
<LineChart
|
|
title="Unique Visitors"
|
|
type="time"
|
|
:key="visitorsData"
|
|
:data="visitorsData"
|
|
unit="visitors"
|
|
:chartTheme="[$theme.colors.green[500]]"
|
|
:loading="$resources.plausible_analytics.loading"
|
|
:error="$resources.plausible_analytics.error"
|
|
/>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
import { DateTime } from 'luxon';
|
|
import LineChart from '@/components/charts/LineChart.vue';
|
|
|
|
export default {
|
|
name: 'MarketplaceAppAnalytics',
|
|
props: {
|
|
app: Object
|
|
},
|
|
components: {
|
|
LineChart
|
|
},
|
|
methods: {
|
|
formatDate(data) {
|
|
return data.map(d => d.date);
|
|
},
|
|
getChartOptions(yFormatter) {
|
|
return {
|
|
axisOptions: {
|
|
xIsSeries: true,
|
|
shortenYAxisNumbers: 1
|
|
},
|
|
lineOptions: {
|
|
hideDots: true,
|
|
regionFill: true
|
|
},
|
|
tooltipOptions: {
|
|
formatTooltipX: d => {
|
|
return DateTime.fromISO(d).toLocaleString(DateTime.DATE_MED);
|
|
},
|
|
formatTooltipY: yFormatter
|
|
}
|
|
};
|
|
}
|
|
},
|
|
resources: {
|
|
analytics() {
|
|
return {
|
|
url: 'jcloud.api.marketplace.analytics',
|
|
auto: true,
|
|
params: {
|
|
name: this.app?.app
|
|
}
|
|
};
|
|
},
|
|
plausible_analytics() {
|
|
return {
|
|
url: 'jcloud.api.analytics.plausible_analytics',
|
|
auto: true,
|
|
params: {
|
|
name: this.app?.app
|
|
}
|
|
};
|
|
}
|
|
},
|
|
computed: {
|
|
analytics() {
|
|
if (
|
|
!this.$resources.analytics.loading &&
|
|
this.$resources.analytics.data
|
|
) {
|
|
const analyticsData = this.$resources.analytics.data;
|
|
const {
|
|
total_installs,
|
|
num_installs_active_sites,
|
|
num_installs_active_benches
|
|
} = analyticsData;
|
|
|
|
return [
|
|
{
|
|
title: 'Total Installs',
|
|
value:
|
|
total_installs.toString() +
|
|
' ' +
|
|
(total_installs == 1 ? 'Site' : 'Sites')
|
|
},
|
|
{
|
|
title: 'Active Sites with this App',
|
|
value:
|
|
num_installs_active_sites.toString() +
|
|
' ' +
|
|
(num_installs_active_sites == 1 ? 'Site' : 'Sites')
|
|
},
|
|
{
|
|
title: 'Active Benches with this App',
|
|
value:
|
|
num_installs_active_benches.toString() +
|
|
' ' +
|
|
(num_installs_active_benches == 1 ? 'Bench' : 'Benches')
|
|
}
|
|
];
|
|
}
|
|
},
|
|
pageViewsData() {
|
|
let pageViews = this.$resources.plausible_analytics.data?.pageviews;
|
|
if (!pageViews) return;
|
|
|
|
return {
|
|
datasets: [pageViews.map(d => [+new Date(d.date), d.value])]
|
|
};
|
|
},
|
|
visitorsData() {
|
|
let visitorsData = this.$resources.plausible_analytics.data?.visitors;
|
|
if (!visitorsData) return;
|
|
|
|
return {
|
|
datasets: [visitorsData.map(d => [+new Date(d.date), d.value])]
|
|
};
|
|
},
|
|
paymentAnalytics() {
|
|
if (
|
|
!this.$resources.analytics.loading &&
|
|
this.$resources.analytics.data
|
|
) {
|
|
let data = this.$resources.analytics.data;
|
|
return {
|
|
total_payout: {
|
|
usd: data.total_payout.usd_amount
|
|
? data.total_payout.usd_amount.toFixed(2)
|
|
: 0.0,
|
|
cny: data.total_payout.cny_amount
|
|
? data.total_payout.cny_amount.toFixed(2)
|
|
: 0.0
|
|
},
|
|
pending_payout: {
|
|
usd: data.pending_payout.usd_amount
|
|
? data.pending_payout.usd_amount.toFixed(2)
|
|
: 0.0,
|
|
cny: data.pending_payout.cny_amount
|
|
? data.pending_payout.cny_amount.toFixed(2)
|
|
: 0.0
|
|
},
|
|
commission: {
|
|
usd: data.commission.usd_amount
|
|
? data.commission.usd_amount.toFixed(2)
|
|
: 0.0,
|
|
cny: data.commission.cny_amount
|
|
? data.commission.cny_amount.toFixed(2)
|
|
: 0.0
|
|
}
|
|
};
|
|
}
|
|
}
|
|
}
|
|
};
|
|
</script>
|