mirror of
https://github.com/ershisan99/podcaster.git
synced 2025-12-16 20:59:26 +00:00
chore: refactor to take advantage of routing instead of rendering the same component twice
This commit is contained in:
53
src/components/podcast-episodes-list.tsx
Normal file
53
src/components/podcast-episodes-list.tsx
Normal 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();
|
||||
}
|
||||
@@ -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>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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 />,
|
||||
},
|
||||
],
|
||||
},
|
||||
]);
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ class PodcastsService {
|
||||
const response: GetEpisodesResponse = await this.fetchWithoutCors(
|
||||
url.toString(),
|
||||
);
|
||||
|
||||
let podcast: PodcastExtraDTO = {} as PodcastExtraDTO;
|
||||
const episodes: EpisodeDto[] = [];
|
||||
|
||||
|
||||
Reference in New Issue
Block a user