From 2126e6bdbccd380be68fb8d48b04458c971912fe Mon Sep 17 00:00:00 2001 From: Andres Date: Sat, 20 Apr 2024 11:51:05 +0200 Subject: [PATCH] chore: refactor to take advantage of routing instead of rendering the same component twice --- src/components/podcast-episodes-list.tsx | 53 +++++++++++++++++++++++ src/components/podcast-info-card.tsx | 6 +-- src/pages/episode.tsx | 25 ++++++++++- src/pages/podcast.tsx | 47 ++------------------ src/router.tsx | 17 +++++--- src/services/podcasts/podcasts.service.ts | 1 + 6 files changed, 96 insertions(+), 53 deletions(-) create mode 100644 src/components/podcast-episodes-list.tsx diff --git a/src/components/podcast-episodes-list.tsx b/src/components/podcast-episodes-list.tsx new file mode 100644 index 0000000..18a33e0 --- /dev/null +++ b/src/components/podcast-episodes-list.tsx @@ -0,0 +1,53 @@ +import { Link, useParams } from "react-router-dom"; +import { usePodcastEpisodesQuery } from "../services/podcasts/podcast.hooks"; + +export function PodcastEpisodesList() { + const { podcastId } = useParams<{ podcastId: string }>(); + const { data: episodesData } = usePodcastEpisodesQuery(podcastId); + return ( +
+
Episodes: {episodesData?.podcast.trackCount}
+
+ + + + + + + + + + {episodesData?.episodes?.map((episode) => { + const formattedDate = formatDate(episode.releaseDate); + const formattedDuration = formatDuration(episode.durationSeconds); + const url = `/podcast/${podcastId}/episode/${episode.id}`; + + return ( + + + + + + ); + })} + +
TitleRelease DateDuration
+ {episode.title} + {formattedDate}{formattedDuration}
+
+
+ ); +} + +function formatDuration(duration?: number) { + if (!duration) { + return "N/A"; + } + const minutes = Math.floor(duration / 60); + const seconds = Math.floor(duration % 60); + return `${minutes.toString().padStart(2, "0")}:${seconds.toString().padStart(2, "0")}`; +} + +function formatDate(date: string) { + return new Date(date).toLocaleDateString(); +} diff --git a/src/components/podcast-info-card.tsx b/src/components/podcast-info-card.tsx index 8fb2df9..22da262 100644 --- a/src/components/podcast-info-card.tsx +++ b/src/components/podcast-info-card.tsx @@ -5,12 +5,12 @@ type Props = { imageURL: string; }; -export const PodcastInfoCard = ({ +export function PodcastInfoCard({ title, author, description, imageURL, -}: Props) => { +}: Props) { return (

{title}

@@ -19,4 +19,4 @@ export const PodcastInfoCard = ({

{description}

); -}; +} diff --git a/src/pages/episode.tsx b/src/pages/episode.tsx index f97c851..d6ef56a 100644 --- a/src/pages/episode.tsx +++ b/src/pages/episode.tsx @@ -1,3 +1,26 @@ +import { useParams } from "react-router-dom"; +import { usePodcastEpisodesQuery } from "../services/podcasts/podcast.hooks"; + export function Episode() { - return

Episode page

; + const { podcastId, episodeId } = useParams<{ + podcastId: string; + episodeId: string; + }>(); + + const { data: episodesData } = usePodcastEpisodesQuery(podcastId); + + const episode = episodesData?.episodes.find( + (episode) => episode.id.toString() === episodeId, + ); + + return ( +
+
{episode?.description}
+
+ +
+
+ ); } diff --git a/src/pages/podcast.tsx b/src/pages/podcast.tsx index ce63194..d3ea7b2 100644 --- a/src/pages/podcast.tsx +++ b/src/pages/podcast.tsx @@ -1,4 +1,4 @@ -import { Link, useParams } from "react-router-dom"; +import { Outlet, useParams } from "react-router-dom"; import { usePodcastEpisodesQuery, useTopPodcastsQuery, @@ -26,7 +26,7 @@ export function Podcast() { if (!podcast) { return

Podcast not found

; } - // TODO: break into smaller components + return (
-
Episodes: {episodesData?.podcast.trackCount}
-
- - - - - - - - - - {episodesData?.episodes?.map((episode) => { - const formattedDate = formatDate(episode.releaseDate); - const formattedDuration = formatDuration(episode.durationSeconds); - const url = `/podcast/${podcastId}/episode/${episode.id}`; - - return ( - - - - - - ); - })} - -
TitleRelease DateDuration
- {episode.title} - {formattedDate}{formattedDuration}
-
+
); } - -function formatDuration(duration?: number) { - if (!duration) { - return "N/A"; - } - const minutes = Math.floor(duration / 60); - const seconds = Math.floor(duration % 60); - return `${minutes.toString().padStart(2, "0")}:${seconds.toString().padStart(2, "0")}`; -} - -function formatDate(date: string) { - return new Date(date).toLocaleDateString(); -} diff --git a/src/router.tsx b/src/router.tsx index b4960e7..073f5b4 100644 --- a/src/router.tsx +++ b/src/router.tsx @@ -2,6 +2,7 @@ import { createBrowserRouter, RouterProvider } from "react-router-dom"; import { Home } from "./pages/home"; import { Podcast } from "./pages/podcast"; import { Episode } from "./pages/episode"; +import { PodcastEpisodesList } from "./components/podcast-episodes-list"; const router = createBrowserRouter([ { @@ -9,12 +10,18 @@ const router = createBrowserRouter([ element: , }, { - path: "/podcast/:podcastId", + path: "/podcast", element: , - }, - { - path: "/podcast/:podcastId/episode/:episodeId", - element: , + children: [ + { + path: ":podcastId", + element: , + }, + { + path: ":podcastId/episode/:episodeId", + element: , + }, + ], }, ]); diff --git a/src/services/podcasts/podcasts.service.ts b/src/services/podcasts/podcasts.service.ts index 5eb9a3b..3c0814d 100644 --- a/src/services/podcasts/podcasts.service.ts +++ b/src/services/podcasts/podcasts.service.ts @@ -28,6 +28,7 @@ class PodcastsService { const response: GetEpisodesResponse = await this.fetchWithoutCors( url.toString(), ); + let podcast: PodcastExtraDTO = {} as PodcastExtraDTO; const episodes: EpisodeDto[] = [];