chore: refactor to take advantage of routing instead of rendering the same component twice

This commit is contained in:
2024-04-20 11:51:05 +02:00
parent 172e9e4c10
commit 2126e6bdbc
6 changed files with 96 additions and 53 deletions

View File

@@ -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 (
<div>
<div>Episodes: {episodesData?.podcast.trackCount}</div>
<div>
<table>
<thead>
<tr>
<th>Title</th>
<th>Release Date</th>
<th>Duration</th>
</tr>
</thead>
<tbody>
{episodesData?.episodes?.map((episode) => {
const formattedDate = formatDate(episode.releaseDate);
const formattedDuration = formatDuration(episode.durationSeconds);
const url = `/podcast/${podcastId}/episode/${episode.id}`;
return (
<tr key={episode.id}>
<td>
<Link to={url}>{episode.title}</Link>
</td>
<td>{formattedDate}</td>
<td>{formattedDuration}</td>
</tr>
);
})}
</tbody>
</table>
</div>
</div>
);
}
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();
}

View File

@@ -5,12 +5,12 @@ type Props = {
imageURL: string;
};
export const PodcastInfoCard = ({
export function PodcastInfoCard({
title,
author,
description,
imageURL,
}: Props) => {
}: Props) {
return (
<div>
<h1>{title}</h1>
@@ -19,4 +19,4 @@ export const PodcastInfoCard = ({
<p>{description}</p>
</div>
);
};
}

View File

@@ -1,3 +1,26 @@
import { useParams } from "react-router-dom";
import { usePodcastEpisodesQuery } from "../services/podcasts/podcast.hooks";
export function Episode() {
return <h1>Episode page</h1>;
const { podcastId, episodeId } = useParams<{
podcastId: string;
episodeId: string;
}>();
const { data: episodesData } = usePodcastEpisodesQuery(podcastId);
const episode = episodesData?.episodes.find(
(episode) => episode.id.toString() === episodeId,
);
return (
<div>
<div>{episode?.description}</div>
<div>
<audio controls src={episode?.audioUrl}>
Audio is not supported by your browser
</audio>
</div>
</div>
);
}

View File

@@ -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 <h1>Podcast not found</h1>;
}
// TODO: break into smaller components
return (
<div>
<PodcastInfoCard
@@ -35,48 +35,7 @@ export function Podcast() {
description={podcast.description}
imageURL={episodesData?.podcast.images.large ?? ""}
/>
<div>Episodes: {episodesData?.podcast.trackCount}</div>
<div>
<table>
<thead>
<tr>
<th>Title</th>
<th>Release Date</th>
<th>Duration</th>
</tr>
</thead>
<tbody>
{episodesData?.episodes?.map((episode) => {
const formattedDate = formatDate(episode.releaseDate);
const formattedDuration = formatDuration(episode.durationSeconds);
const url = `/podcast/${podcastId}/episode/${episode.id}`;
return (
<tr key={episode.id}>
<td>
<Link to={url}>{episode.title}</Link>
</td>
<td>{formattedDate}</td>
<td>{formattedDuration}</td>
</tr>
);
})}
</tbody>
</table>
</div>
<Outlet />
</div>
);
}
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();
}

View File

@@ -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: <Home />,
},
{
path: "/podcast/:podcastId",
path: "/podcast",
element: <Podcast />,
},
{
path: "/podcast/:podcastId/episode/:episodeId",
element: <Episode />,
children: [
{
path: ":podcastId",
element: <PodcastEpisodesList />,
},
{
path: ":podcastId/episode/:episodeId",
element: <Episode />,
},
],
},
]);

View File

@@ -28,6 +28,7 @@ class PodcastsService {
const response: GetEpisodesResponse = await this.fetchWithoutCors(
url.toString(),
);
let podcast: PodcastExtraDTO = {} as PodcastExtraDTO;
const episodes: EpisodeDto[] = [];