From 5d14d03e31c6b0cf05ef9b39c5adcbd3c802112f Mon Sep 17 00:00:00 2001 From: Francisco Pessano Date: Thu, 10 Oct 2024 22:34:58 -0300 Subject: [PATCH] Base structure of top songs/artists --- src/app/_components/spotify-data.tsx | 170 +++++++++++++++++++++++++++ src/app/api/spotify-login/route.ts | 2 +- src/app/page.tsx | 39 +++++- 3 files changed, 206 insertions(+), 5 deletions(-) create mode 100644 src/app/_components/spotify-data.tsx diff --git a/src/app/_components/spotify-data.tsx b/src/app/_components/spotify-data.tsx new file mode 100644 index 0000000..045170c --- /dev/null +++ b/src/app/_components/spotify-data.tsx @@ -0,0 +1,170 @@ +import SpotifyWebApi from "spotify-web-api-node"; + +const TRACKS_LIMIT = 20; + +export default async function SpotifyData({ + accessToken, + refreshToken, +}: { + accessToken: string; + refreshToken: string; +}) { + const spotifyApi = new SpotifyWebApi({ + clientId: process.env.SPOTIFY_CLIENT_ID, + clientSecret: process.env.SPOTIFY_CLIENT_SECRET, + redirectUri: process.env.SPOTIFY_REDIRECT_URI, + }); + spotifyApi.setAccessToken(accessToken); + + const albumsData = await spotifyApi.getMySavedAlbums({ limit: 20 }); + const albums = albumsData.body.items; + + const artistsData = await spotifyApi.getMyTopArtists({ + limit: 20, + time_range: "short_term", + }); + const artists = artistsData.body.items; + + const tracksData = await spotifyApi.getMyTopTracks({ + limit: TRACKS_LIMIT, + time_range: "short_term", + }); + const tracks = tracksData.body.items.map((track, i) => ({ + ...track, + position: i + 1, + })); + const tracksByAlbum = tracksData.body.items.reduce((acc, track) => { + if (!acc[track.album.id]) { + const tracksWithAlbum = tracks.filter( + (t) => t.album.id === track.album.id, + ); + acc[track.album.id] = { + album: track.album, + position: + tracksWithAlbum.reduce( + (acc, _track) => TRACKS_LIMIT / _track.position + acc, + 0, + ) / tracksWithAlbum.length, + tracks: [], + }; + } + acc[track.album.id].tracks.push(track); + return acc; + }, {}); + + console.log("Albums:", albums); + console.log("Artists:", artists); + console.log("Tracks:", tracks); + console.log("Tracks by album:", tracksByAlbum); + + return ( + <> + {/*

Tracks images

+
+ {tracks.map((track) => { + if (!track.album.images[0]) + return ( + {track.name} + ); + return ( + {track.name} + ); + })} +
*/} + +

Tracks by album

+ {Object.values(tracksByAlbum) + .sort((a, b) => b.position - a.position) + .map((album) => ( +
+

{album.album.name}

+
+ {album.album.name} +
    + {album.tracks.map((track) => ( +
  • {track.name}
  • + ))} +
+
+
+ ))} + +

Albums images

+
+ {albums.map((album) => { + if (!album.album.images[0]) + return ( + {album.album.name} + ); + return ( + {album.album.name} + ); + })} +
+ +

Artists images

+
+ {artists.map((artist) => { + if (!artist.images[0]) + return ( + {artist.name} + ); + return ( + {artist.name} + ); + })} +
+ + ); +} diff --git a/src/app/api/spotify-login/route.ts b/src/app/api/spotify-login/route.ts index 09553fa..be3b492 100644 --- a/src/app/api/spotify-login/route.ts +++ b/src/app/api/spotify-login/route.ts @@ -11,7 +11,7 @@ const spotifyApi = new SpotifyWebApi({ const state = process.env.SPOTIFY_STATE as string; export async function GET(req: NextApiRequest, res: NextApiResponse) { - const scopes = ["user-library-read", "user-read-private"]; + const scopes = ["user-library-read", "user-read-private", "user-top-read"]; const authorizeURL = spotifyApi.createAuthorizeURL(scopes, state); console.log(authorizeURL); diff --git a/src/app/page.tsx b/src/app/page.tsx index 4f0284e..d4d69f4 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -3,8 +3,8 @@ import Link from "next/link"; import { LatestPost } from "@/app/_components/post"; import { api, HydrateClient } from "@/trpc/server"; import SpotifyLogin from "./_components/spotify-login"; -import { NextApiRequest } from "next"; -import { NextResponse } from "next/server"; +import SpotifyData from "./_components/spotify-data"; +import SpotifyWebApi from "spotify-web-api-node"; export default async function Home({ searchParams, @@ -15,10 +15,34 @@ export default async function Home({ const access_token = searchParams?.access_token; const refresh_token = searchParams?.refresh_token; - const userLogged = access_token && refresh_token; + let userIsLogged = !!( + access_token && + refresh_token && + typeof access_token === "string" && + typeof refresh_token === "string" + ); + const spotifyApi = new SpotifyWebApi({ + clientId: process.env.SPOTIFY_CLIENT_ID, + clientSecret: process.env.SPOTIFY_CLIENT_SECRET, + redirectUri: process.env.SPOTIFY_REDIRECT_URI, + }); + + if (userIsLogged) + try { + spotifyApi.setAccessToken(access_token as string); + await spotifyApi.getMe(); + } catch (error) { + console.error(error); + userIsLogged = false; + } void api.post.getLatest.prefetch(); + console.log({ + access_token, + refresh_token, + }); + return (
@@ -55,7 +79,14 @@ export default async function Home({ {hello ? hello.greeting : "Loading tRPC query..."}

- + {userIsLogged ? ( + + ) : ( + + )}