Compare commits

..

2 Commits

Author SHA1 Message Date
e0a323ff91 put link to home in "layout" 2026-03-12 23:11:12 +03:00
3f418669f3 add button to delete podcast & link to website 2026-03-12 22:42:22 +03:00
4 changed files with 58 additions and 11 deletions

View File

@@ -47,3 +47,14 @@ export const useCreatePodcastMutation = () => {
}, },
}); });
}; };
export const useDeletePodcastMutation = () => {
return useMutation({
mutationFn: async ({ id }: { id: number }) => {
const resp = await fetch(`/api/podcasts/${id}`, {
method: "DELETE",
});
return await resp.json();
},
});
};

View File

@@ -8,6 +8,7 @@ import { HomePage } from "./pages/home";
import { PodcastPage } from "./pages/podcast"; import { PodcastPage } from "./pages/podcast";
import { PlayerProvider } from "./player/provider"; import { PlayerProvider } from "./player/provider";
import { Player } from "./player/player"; import { Player } from "./player/player";
import { Link } from "react-router";
const queryClient = new QueryClient({ const queryClient = new QueryClient({
defaultOptions: { defaultOptions: {
@@ -23,6 +24,9 @@ createRoot(document.getElementById("root")!).render(
<PlayerProvider> <PlayerProvider>
<div className="max-w-[1440px] w-full mx-auto p-2 relative"> <div className="max-w-[1440px] w-full mx-auto p-2 relative">
<BrowserRouter> <BrowserRouter>
<Link to="/" className="w-fit">
<h1 className="text-3xl font-semibold">podcaster</h1>
</Link>
<Routes> <Routes>
<Route path="/" element={<HomePage />} /> <Route path="/" element={<HomePage />} />
<Route path="/podcasts/:id" element={<PodcastPage />} /> <Route path="/podcasts/:id" element={<PodcastPage />} />

View File

@@ -1,4 +1,3 @@
import { Link } from "react-router";
import { usePodcastsQuery } from "../api/podcasts"; import { usePodcastsQuery } from "../api/podcasts";
import { NewPodcastForm } from "../components/NewPodcastForm"; import { NewPodcastForm } from "../components/NewPodcastForm";
@@ -7,10 +6,6 @@ export const HomePage = () => {
return ( return (
<div> <div>
<Link to="/">
<h1 className="text-3xl font-semibold">podcaster</h1>
</Link>
<NewPodcastForm /> <NewPodcastForm />
<div className="grid grid-cols-1 sm:grid-cols-[repeat(auto-fit,250px)] gap-3 mt-5"> <div className="grid grid-cols-1 sm:grid-cols-[repeat(auto-fit,250px)] gap-3 mt-5">

View File

@@ -1,16 +1,17 @@
import { useParams } from "react-router"; import { useParams } from "react-router";
import { usePodcastQuery } from "../api/podcasts"; import { useDeletePodcastMutation, usePodcastQuery } from "../api/podcasts";
import { import {
usePodcastEpisodesQuery, usePodcastEpisodesQuery,
useUpdateEpisodeMutation, useUpdateEpisodeMutation,
} from "../api/episodes"; } from "../api/episodes";
import { Link } from "react-router";
import { usePlayerContext } from "../player/context"; import { usePlayerContext } from "../player/context";
import { PlayIcon } from "../icons/play"; import { PlayIcon } from "../icons/play";
import { PauseIcon } from "../icons/pause"; import { PauseIcon } from "../icons/pause";
import { useQueryClient } from "@tanstack/react-query"; import { useQueryClient } from "@tanstack/react-query";
import { useNavigate } from "react-router";
export const PodcastPage = () => { export const PodcastPage = () => {
const navigate = useNavigate();
const queryClient = useQueryClient(); const queryClient = useQueryClient();
const { id } = useParams<{ id: string }>(); const { id } = useParams<{ id: string }>();
@@ -20,6 +21,29 @@ export const PodcastPage = () => {
const player = usePlayerContext(); const player = usePlayerContext();
const updateEpisodeMutation = useUpdateEpisodeMutation(); const updateEpisodeMutation = useUpdateEpisodeMutation();
const deletePodcastMutation = useDeletePodcastMutation();
const handleDeletePodcast = () => {
if (
!confirm(
"Are you sure you want to delete this podcast with all episodes?",
)
)
return;
if (typeof id === "undefined") return;
deletePodcastMutation.mutate(
{
id: parseInt(id),
},
{
onSuccess() {
queryClient.invalidateQueries({ queryKey: ["podcasts"] });
navigate("/");
},
},
);
};
const handleMarkCompleted = (episodeId: number) => { const handleMarkCompleted = (episodeId: number) => {
updateEpisodeMutation.mutate( updateEpisodeMutation.mutate(
@@ -55,15 +79,28 @@ export const PodcastPage = () => {
return ( return (
<div> <div>
<Link to="/">
<h1 className="text-3xl font-semibold">podcaster</h1>
</Link>
<div className="mt-3 flex gap-2"> <div className="mt-3 flex gap-2">
<img src={podcast?.image} alt="" className="w-[300px] aspect-square" /> <img src={podcast?.image} alt="" className="w-[300px] aspect-square" />
<div className="flex flex-col gap-1"> <div className="flex flex-col gap-1">
<h2 className="text-2xl font-semibold">{podcast?.name}</h2> <h2 className="text-2xl font-semibold">{podcast?.name}</h2>
<p>{podcast?.description}</p> <p>{podcast?.description}</p>
<div className="mt-auto flex items-center gap-2">
<a
href={podcast?.link}
target="_blank"
rel="noopener noreferrer"
className="block bg-blue-500 text-white py-1 px-4 rounded"
>
Website
</a>
<button
className="bg-red-500 text-white py-1 px-4 rounded w-fit cursor-pointer"
disabled={deletePodcastMutation.isPending}
onClick={handleDeletePodcast}
>
Delete
</button>
</div>
</div> </div>
</div> </div>