spotifyplaylistarchive.com/components/stats/FollowerGrowth.vue

111 lines
2.5 KiB
Vue
Raw Normal View History

2022-07-06 14:02:23 +02:00
<script setup lang="ts">
import { $fetch } from 'ohmyfetch';
import ProgressSpinner from 'primevue/progressspinner';
import Dropdown from 'primevue/dropdown';
import Chart from 'primevue/chart';
2022-07-13 19:49:37 +02:00
import { CalendarEntry } from '~~/models/calendar-entry';
2022-07-06 14:02:23 +02:00
const route = useRoute();
const playlistId = route.params.playlistId as string;
const chartPeriodOptions = ['Last week', 'Last month'];
const chartPeriod = useState(`chartPeriod${playlistId}`, () => 'Last week');
2022-07-06 14:02:23 +02:00
const sinceDate = computed(() => {
const baseDate = new Date();
if (chartPeriod.value === 'Last week') {
baseDate.setDate(baseDate.getDate() - 7);
} else {
baseDate.setMonth(baseDate.getMonth() - 1);
}
return baseDate.toISOString();
});
const chartOptions = {
responsive: true,
2022-07-10 22:34:33 +02:00
scales: {
x: {
grid: {
color: 'rgba(255, 255, 255, 0.2)'
}
},
y: {
grid: {
color: 'rgba(255, 255, 255, 0.2)'
}
}
},
2022-07-06 14:02:23 +02:00
plugins: {
legend: {
display: false
}
}
};
const dateFormatter = new Intl.DateTimeFormat('en-US', {
month: 'long',
day: 'numeric'
});
const { pending, error, data, refresh } = await useLazyAsyncData(
2022-07-06 14:02:23 +02:00
`playlist-${playlistId}-follower-growth`,
async () => {
const snapshots = (
2022-07-13 19:49:37 +02:00
await $fetch<CalendarEntry[]>(
2022-07-06 14:02:23 +02:00
`/api/playlists/${playlistId}/snapshots?sinceDate=${sinceDate.value}`
)
).reverse();
const labels = snapshots.map((snapshot) =>
dateFormatter.format(Date.parse(snapshot.dateCaptured))
);
const numFollowersData = snapshots.map(({ numFollowers }) => numFollowers);
return {
labels,
datasets: [
{
type: 'line',
label: 'Followers',
borderColor: '#90cd93',
data: numFollowersData
}
]
};
},
{ server: false }
);
watch(chartPeriod, async () => await refresh());
</script>
<template>
<NuxtLayout name="centered-content">
<ClientOnly>
2022-07-19 22:20:48 +02:00
<p class="my-0 text-lg">
2022-07-06 14:02:23 +02:00
Period:
<Dropdown
v-model="chartPeriod"
:options="chartPeriodOptions"
:disabled="pending"
/>
</p>
2022-07-20 21:41:41 +02:00
<ProgressSpinner v-if="pending" class="mt-3" />
2022-07-06 14:02:23 +02:00
<p v-else-if="error">
Something went wrong while fetching follwer growth data
</p>
2022-07-10 22:34:33 +02:00
<Chart
v-else-if="data"
2022-07-21 11:20:36 +02:00
class="md:w-7 md:mt-3 md:p-0 w-full mt-0 p-4 h-4"
2022-07-10 22:34:33 +02:00
type="line"
:options="chartOptions"
:data="data"
/>
2022-07-06 14:02:23 +02:00
</ClientOnly>
</NuxtLayout>
</template>