diff --git a/packages/nextjs/pages/genre/[category].tsx b/packages/nextjs/pages/genre/[category].tsx new file mode 100644 index 0000000..f2239a7 --- /dev/null +++ b/packages/nextjs/pages/genre/[category].tsx @@ -0,0 +1,66 @@ +import { useEffect, useState } from "react"; +import { customGet } from "../../utils/beat-bridge/customGet"; +import { isAuthenticated } from "../../utils/beat-bridge/isAuthenticated"; +import { GetServerSideProps } from "next"; +import { getSession } from "next-auth/react"; +import DashboardLayout from "~~/components/dashboard/DashboardLayout"; +import Heading from "~~/components/spotify/Heading"; +import Layout from "~~/components/spotify/Layout"; +import PlaylistList from "~~/components/spotify/PlaylistList"; +import { MySession } from "~~/types/session"; +import { PlaylistType } from "~~/types/spotify"; + +interface IProps { + categoryName?: string; + playlists: { + items: PlaylistType[]; + }; +} + +export default function CategoryPlaylists({ categoryName, playlists }: IProps) { + const [capitalizedCategory, setCapitalizedCategory] = useState(""); + + useEffect(() => { + if (categoryName) { + const afterName = categoryName + .split(" ") + .map(i => i[0].toUpperCase() + i.slice(1)) + .join(" "); + setCapitalizedCategory(afterName); + } + }, [categoryName]); + + return ( + + + + + + + ); +} + +export const getServerSideProps: GetServerSideProps = async ctx => { + const session = (await getSession(ctx)) as MySession | null; + + if (!(await isAuthenticated(session))) { + return { + redirect: { + destination: "/login", + permanent: false, + }, + }; + } + + const categoryId = ctx.params?.category; + const category = await customGet(`https://api.spotify.com/v1/browse/categories/${categoryId}`, session); + const playlists = await customGet( + `https://api.spotify.com/v1/browse/categories/${categoryId}/playlists?limit=50`, + session, + ); + + const categoryName = category.name?.toString().split("_").join(" ") || ""; + + console.log(playlists.playlists); + return { props: { categoryName, playlists: playlists.playlists } }; +}; diff --git a/packages/nextjs/pages/playlists/[playlistId].tsx b/packages/nextjs/pages/playlists/[playlistId].tsx new file mode 100644 index 0000000..f6ac2ab --- /dev/null +++ b/packages/nextjs/pages/playlists/[playlistId].tsx @@ -0,0 +1,87 @@ +import Layout from "../../components/spotify/Layout"; +import TracksTable from "../../components/spotify/TracksTable"; +import { PlaylistType } from "../../types/spotify"; +import { customGet } from "../../utils/beat-bridge/customGet"; +import { isAuthenticated } from "../../utils/beat-bridge/isAuthenticated"; +import parse from "html-react-parser"; +import { GetServerSideProps } from "next"; +import { getSession } from "next-auth/react"; +import { RiMusic2Fill } from "react-icons/ri"; +import DashboardLayout from "~~/components/dashboard/DashboardLayout"; +import { MySession } from "~~/types/session"; + +interface IProps { + playlist: PlaylistType; +} + +export default function Playlist({ playlist }: IProps) { + return ( + + +
+ {playlist && ( + <> + {playlist.images && playlist.images?.length > 0 ? ( + {playlist.name} + ) : ( +
+ +
+ )} +
+
{playlist.type}
+

{playlist.name}

+ +

{parse(playlist.description || "")}

+ +
+ {playlist.owner?.display_name} + {playlist?.followers?.total ? ( + playlist?.followers?.total > 0 && ( + + {playlist.followers?.total.toLocaleString()} {playlist.followers?.total > 1 ? "likes" : "like"} + + ) + ) : ( + 0 likes + )} + {playlist?.tracks?.items && playlist?.tracks?.items?.length > 0 && ( + {playlist.tracks.total.toLocaleString()} songs + )}{" "} +
+
+ + )} +
+ +
+ item.track !== null).map(item => item.track) + : [] + } + /> +
+
+
+ ); +} + +export const getServerSideProps: GetServerSideProps = async ctx => { + const session = (await getSession(ctx)) as MySession | null; + + if (!(await isAuthenticated(session))) { + return { + redirect: { + destination: "/login", + permanent: false, + }, + }; + } + + const playlistId = ctx.params?.playlistId; + const playlist = await customGet(`https://api.spotify.com/v1/playlists/${playlistId}`, session); + + return { props: { playlist: playlist } }; +}; diff --git a/packages/nextjs/pages/playlists/index.tsx b/packages/nextjs/pages/playlists/index.tsx new file mode 100644 index 0000000..7cf7d68 --- /dev/null +++ b/packages/nextjs/pages/playlists/index.tsx @@ -0,0 +1,42 @@ +import { GetServerSideProps } from "next"; +import { getSession } from "next-auth/react"; +import DashboardLayout from "~~/components/dashboard/DashboardLayout"; +import Heading from "~~/components/spotify/Heading"; +import Layout from "~~/components/spotify/Layout"; +import PlaylistList from "~~/components/spotify/PlaylistList"; +import { MySession } from "~~/types/session"; +import { PlaylistType } from "~~/types/spotify"; +import { customGet } from "~~/utils/beat-bridge/customGet"; +import { isAuthenticated } from "~~/utils/beat-bridge/isAuthenticated"; + +interface IProps { + userPlaylist: PlaylistType[]; +} + +export default function FollowedArtists({ userPlaylist }: IProps) { + return ( + + + + + + + ); +} + +export const getServerSideProps: GetServerSideProps = async ctx => { + const session = (await getSession(ctx)) as MySession | null; + + if (!(await isAuthenticated(session))) { + return { + redirect: { + destination: "/login", + permanent: false, + }, + }; + } + + const userPlaylist = await customGet(`https://api.spotify.com/v1/me/playlists?limit=50`, session); + + return { props: { userPlaylist: userPlaylist.items } }; +}; diff --git a/packages/nextjs/pages/search/[query]/index.tsx b/packages/nextjs/pages/search/[query]/index.tsx index 3f3913c..16aff49 100644 --- a/packages/nextjs/pages/search/[query]/index.tsx +++ b/packages/nextjs/pages/search/[query]/index.tsx @@ -1,6 +1,5 @@ import { Fragment } from "react"; import Link from "next/link"; -import { useSpotify } from "../../../context/SpotifyContext"; import { GetServerSideProps } from "next"; import { getSession } from "next-auth/react"; import DashboardLayout from "~~/components/dashboard/DashboardLayout"; @@ -9,6 +8,7 @@ import ArtistList from "~~/components/spotify/ArtistList"; import Heading from "~~/components/spotify/Heading"; import Layout from "~~/components/spotify/Layout"; import PlaylistList from "~~/components/spotify/PlaylistList"; +import { useSpotify } from "~~/context/SpotifyContext"; import { MySession } from "~~/types/session"; import { SearchResults, Track } from "~~/types/spotify"; import { customGet } from "~~/utils/beat-bridge/customGet"; diff --git a/packages/nextjs/pages/search/index.tsx b/packages/nextjs/pages/search/index.tsx index a3eb8be..e4358aa 100644 --- a/packages/nextjs/pages/search/index.tsx +++ b/packages/nextjs/pages/search/index.tsx @@ -54,6 +54,7 @@ export const getServerSideProps: GetServerSideProps = async ctx => { }; } - const categories = await customGet("https://api.spotify.com/v1/browse/categories?limit=50&country=IN", session); + // const country = ctx.req.headers.get("cf-ipcountry") ?? ""; + const categories = await customGet("https://api.spotify.com/v1/browse/categories?limit=50&country=NG", session); return { props: { categories } }; }; diff --git a/packages/nextjs/types/spotify.ts b/packages/nextjs/types/spotify.ts index 4d4dae5..a820e0b 100644 --- a/packages/nextjs/types/spotify.ts +++ b/packages/nextjs/types/spotify.ts @@ -40,7 +40,7 @@ export interface PlaylistType { description?: string; id: string; followers?: { - total?: number; + total: number; }; images?: [Image]; name: string;