mirror of
https://github.com/maciejpedzich/spotifyplaylistarchive.com.git
synced 2024-11-14 01:03:03 +01:00
111 lines
2.5 KiB
Vue
111 lines
2.5 KiB
Vue
<script setup lang="ts">
|
|
import { $fetch } from 'ohmyfetch';
|
|
|
|
import ProgressSpinner from 'primevue/progressspinner';
|
|
import Dropdown from 'primevue/dropdown';
|
|
import Chart from 'primevue/chart';
|
|
|
|
import { CalendarEntry } from '~~/models/calendar-entry';
|
|
|
|
const route = useRoute();
|
|
const playlistId = route.params.playlistId as string;
|
|
|
|
const chartPeriodOptions = ['Last week', 'Last month'];
|
|
const chartPeriod = useState(`chartPeriod${playlistId}`, () => 'Last week');
|
|
|
|
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,
|
|
scales: {
|
|
x: {
|
|
grid: {
|
|
color: 'rgba(255, 255, 255, 0.2)'
|
|
}
|
|
},
|
|
y: {
|
|
grid: {
|
|
color: 'rgba(255, 255, 255, 0.2)'
|
|
}
|
|
}
|
|
},
|
|
plugins: {
|
|
legend: {
|
|
display: false
|
|
}
|
|
}
|
|
};
|
|
|
|
const dateFormatter = new Intl.DateTimeFormat('en-US', {
|
|
month: 'long',
|
|
day: 'numeric'
|
|
});
|
|
|
|
const { pending, error, data, refresh } = await useLazyAsyncData(
|
|
`playlist-${playlistId}-follower-growth`,
|
|
async () => {
|
|
const snapshots = (
|
|
await $fetch<CalendarEntry[]>(
|
|
`/api/playlists/${playlistId}/snapshots?sinceDate=${sinceDate.value}&allowDuplicates=yes`
|
|
)
|
|
).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>
|
|
<p class="my-0 text-lg">
|
|
Period:
|
|
<Dropdown
|
|
v-model="chartPeriod"
|
|
:options="chartPeriodOptions"
|
|
:disabled="pending"
|
|
/>
|
|
</p>
|
|
<ProgressSpinner v-if="pending" class="mt-3" />
|
|
<p v-else-if="error">
|
|
Something went wrong while fetching follwer growth data
|
|
</p>
|
|
<Chart
|
|
v-else-if="data"
|
|
class="md:w-7 md:mt-3 md:p-0 w-full mt-0 p-4 h-4"
|
|
type="line"
|
|
:options="chartOptions"
|
|
:data="data"
|
|
/>
|
|
</ClientOnly>
|
|
</NuxtLayout>
|
|
</template>
|