Album showcase

This commit is contained in:
2024-10-10 23:20:02 -03:00
parent 5d14d03e31
commit 05b9525c4f
3 changed files with 108 additions and 77 deletions

View File

@@ -0,0 +1,30 @@
import { TrackByAlbum } from "./spotify-data";
export default function AlbumShowcase({
album,
position,
tracks,
}: TrackByAlbum) {
const imageSource = album.images[0]
? album.images[0].url
: "https://via.placeholder.com/150";
return (
<div
key={album.id}
className="flex w-full flex-wrap gap-3 rounded-xl bg-white bg-opacity-10 p-5 backdrop-blur-lg backdrop-filter"
>
<img className="h-36 w-36 rounded" src={imageSource} alt={album.name} />
<section className="flex h-36 flex-col">
<h4 className="mb-2 text-lg font-semibold leading-none">
{album.name}
</h4>
<ul className="overflow-scroll">
{tracks.map((track) => (
<li key={track.id}>{track.name}</li>
))}
</ul>
</section>
</div>
);
}

View File

@@ -1,7 +1,21 @@
import SpotifyWebApi from "spotify-web-api-node";
import AlbumShowcase from "./album-showcase";
const TRACKS_LIMIT = 20;
export type TrackByAlbum = {
album: {
id: string;
name: string;
images: { url: string }[];
};
position: number;
tracks: {
id: string;
name: string;
}[];
};
export default async function SpotifyData({
accessToken,
refreshToken,
@@ -33,25 +47,66 @@ export default async function SpotifyData({
...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;
}, {});
const tracksByAlbum = tracksData.body.items.reduce(
(acc: Record<string, TrackByAlbum>, 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: [] } as any)).tracks.push(track);
return acc;
},
{},
);
// type Track = {
// id: string;
// name: string;
// album: {
// id: string;
// name: string;
// images: { url: string }[];
// };
// position: number;
// };
// type Album = {
// album: {
// id: string;
// name: string;
// images: { url: string }[];
// };
// position: number;
// tracks: Track[];
// };
// // type Artist = {
// // id: string;
// // name: string;
// // images: { url: string }[];
// // };
// // type SpotifyDataProps = {
// // accessToken: string;
// // refreshToken: string;
// // };
// // type SpotifyDataResponse = {
// // albums: Album[];
// // artists: Artist[];
// // tracks: Track[];
// // tracksByAlbum: { [key: string]: Album };
// // };
console.log("Albums:", albums);
console.log("Artists:", artists);
console.log("Tracks:", tracks);
@@ -90,29 +145,10 @@ export default async function SpotifyData({
{Object.values(tracksByAlbum)
.sort((a, b) => b.position - a.position)
.map((album) => (
<div key={album.album.id}>
<h4>{album.album.name}</h4>
<div
style={{
display: "flex",
flexWrap: "wrap",
}}
>
<img
style={{ width: "150px", height: "150px" }}
src={album.album.images[0].url}
alt={album.album.name}
/>
<ul>
{album.tracks.map((track) => (
<li key={track.id}>{track.name}</li>
))}
</ul>
</div>
</div>
<AlbumShowcase {...album} />
))}
<h3>Albums images</h3>
{/* <h3>Albums images</h3>
<div
style={{
display: "flex",
@@ -137,7 +173,7 @@ export default async function SpotifyData({
/>
);
})}
</div>
</div> */}
<h3>Artists images</h3>
<div

View File

@@ -1,6 +1,4 @@
import Link from "next/link";
import { LatestPost } from "@/app/_components/post";
import { api, HydrateClient } from "@/trpc/server";
import SpotifyLogin from "./_components/spotify-login";
import SpotifyData from "./_components/spotify-data";
@@ -45,40 +43,8 @@ export default async function Home({
return (
<HydrateClient>
<main className="flex min-h-screen flex-col items-center justify-center bg-gradient-to-b from-[#2e026d] to-[#15162c] text-white">
<div className="container flex flex-col items-center justify-center gap-12 px-4 py-16">
<h1 className="text-5xl font-extrabold tracking-tight sm:text-[5rem]">
Create <span className="text-[hsl(280,100%,70%)]">T3</span> App
</h1>
<div className="grid grid-cols-1 gap-4 sm:grid-cols-2 md:gap-8">
<Link
className="flex max-w-xs flex-col gap-4 rounded-xl bg-white/10 p-4 hover:bg-white/20"
href="https://create.t3.gg/en/usage/first-steps"
target="_blank"
>
<h3 className="text-2xl font-bold">First Steps </h3>
<div className="text-lg">
Just the basics - Everything you need to know to set up your
database and authentication.
</div>
</Link>
<Link
className="flex max-w-xs flex-col gap-4 rounded-xl bg-white/10 p-4 hover:bg-white/20"
href="https://create.t3.gg/en/introduction"
target="_blank"
>
<h3 className="text-2xl font-bold">Documentation </h3>
<div className="text-lg">
Learn more about Create T3 App, the libraries it uses, and how
to deploy it.
</div>
</Link>
</div>
<div className="flex flex-col items-center gap-2">
<p className="text-2xl text-white">
{hello ? hello.greeting : "Loading tRPC query..."}
</p>
</div>
<main className="justify-centerbg-gradient-to-r flex min-h-screen flex-col items-center bg-gradient-to-r from-slate-900 to-slate-700 text-slate-200">
<div className="container flex flex-col items-center justify-center gap-8 px-4 py-16">
{userIsLogged ? (
<SpotifyData
accessToken={access_token as string}
@@ -87,7 +53,6 @@ export default async function Home({
) : (
<SpotifyLogin />
)}
<LatestPost />
</div>
</main>
</HydrateClient>