diff --git a/src/pages/playlists/[playlistId]/snapshots/[commitSha].astro b/src/pages/playlists/[playlistId]/snapshots/[commitSha].astro new file mode 100644 index 0000000..4317cfe --- /dev/null +++ b/src/pages/playlists/[playlistId]/snapshots/[commitSha].astro @@ -0,0 +1,97 @@ +--- +import { decode } from 'html-entities'; +import formatDuration from 'format-duration'; + +import PlaylistPageTab from '@/layouts/PlaylistPageTab.astro'; +import { getPlaylistLayoutProps } from '@/utils/getPlaylistLayoutProps'; +import { getFormattedDate } from '@/utils/getFormattedDate'; + +import type { PlaylistSnapshot } from '@/models/playlist-snapshot'; + +const layoutProps = await getPlaylistLayoutProps(Astro); + +let snapshot: PlaylistSnapshot | null = null; + +if (layoutProps.playlist) { + try { + const { playlistId, commitSha } = Astro.params; + const githubResponse = await fetch( + `https://raw.githubusercontent.com/mackorone/spotify-playlist-archive/${commitSha}/playlists/pretty/${playlistId}.json` + ); + + if (!githubResponse.ok) { + throw new Error(githubResponse.status.toString()); + } + + snapshot = (await githubResponse.json()) as PlaylistSnapshot; + layoutProps.description = decode(snapshot.description, { level: 'html5' }); + } catch (error) { + const isNotFoundError = (error as Error).message === '404'; + + layoutProps.errorOccurred = true; + layoutProps.title = 'Error'; + layoutProps.description = isNotFoundError + ? "This snapshot doesn't exist." + : 'Failed to load snapshot.'; + + Astro.response.status = isNotFoundError ? 404 : 500; + Astro.response.statusText = layoutProps.description; + } +} +--- + + +

{layoutProps.description}

+
+ + + + + + + + + + + + { + snapshot?.tracks.map((track) => ( + + + + + + + + )) + } + +
TitleArtist(s)AlbumDate addedDuration
+ + {track.name} + + + {track.artists.map((artist) => ( + + {artist.name} + + ))} + + + {track.album.name} + + {getFormattedDate(track.added_at)}{formatDuration(track.duration_ms)}
+
+
diff --git a/src/utils/getFormattedDate.ts b/src/utils/getFormattedDate.ts new file mode 100644 index 0000000..b6c05c2 --- /dev/null +++ b/src/utils/getFormattedDate.ts @@ -0,0 +1,6 @@ +export const getFormattedDate = (date: Date | string) => + new Intl.DateTimeFormat('en-US', { + year: 'numeric', + month: 'long', + day: 'numeric' + }).format(new Date(date));