add podcast landing page
All checks were successful
ci/woodpecker/push/build Pipeline was successful

This commit is contained in:
Jake Walker 2025-02-06 18:02:48 +00:00
parent ecc4f47321
commit 93bde35cbf
No known key found for this signature in database
5 changed files with 92 additions and 4 deletions

View file

@ -83,6 +83,10 @@ const routes = [
component: () => (
<Protected>{lazy(() => import("./routes/admin/episode"))()}</Protected>
),
},
{
path: "/:podcastId",
component: lazy(() => import("./routes/podcast")),
}
];

View file

@ -89,7 +89,7 @@ export default function AdminPodcast() {
<Show when={podcastQuery.data?.image_filename}>
<div class="column">
<figure class="image is-128x128">
<img src={new URL(params.podcastId + "/" + podcastQuery.data!.image_filename, SERVER_URL).href} />
<img src={new URL(`/files/${params.podcastId}/${podcastQuery.data!.image_filename}`, SERVER_URL).href} />
</figure>
</div>
</Show>

View file

@ -57,7 +57,7 @@ export default function AdminPodcasts() {
<Show when={podcast.image_filename}>
<div class="column">
<figure class="image is-64x64">
<img src={new URL(podcast.id + "/" + podcast.image_filename, SERVER_URL).href} />
<img src={new URL("/files/" + podcast.id + "/" + podcast.image_filename, SERVER_URL).href} />
</figure>
</div>
</Show>

View file

@ -0,0 +1,85 @@
import { useParams } from "@solidjs/router";
import { createQuery } from "@tanstack/solid-query";
import { readPodcastOptions, readEpisodesOptions } from "../client/@tanstack/solid-query.gen";
import { ErrorBoundary, For, Show, Suspense } from "solid-js";
import Error from "../components/error";
import Loading from "../components/loading";
import { DownloadIcon, MusicIcon } from "lucide-solid";
import { SERVER_URL } from "../constants";
export default function Podcast() {
const params = useParams();
const podcastQuery = createQuery(() => ({
...readPodcastOptions({
path: {
podcast_id: params.podcastId,
}
})
}));
const episodeQuery = createQuery(() => ({
...readEpisodesOptions({
path: {
podcast_id: params.podcastId,
}
})
}))
return (
<main>
<ErrorBoundary fallback={(err, reset) => <Error message={err} reset={reset} />}>
<Suspense fallback={<Loading />}>
<section class="hero is-medium is-primary">
<div class="hero-body">
<div class="columns">
<Show when={podcastQuery.data?.image_filename}>
<div class="column">
<figure class="image is-128x128">
<img src={new URL(`/files/${params.podcastId}/${podcastQuery.data!.image_filename}`, SERVER_URL).href} />
</figure>
</div>
</Show>
<div class="column is-full">
<h1 class="title">{podcastQuery.data?.name}</h1>
<p class="subtitle">{podcastQuery.data?.description}</p>
</div>
</div>
</div>
</section>
<section class="section">
<div class="container is-max-desktop">
<For each={episodeQuery.data}>
{(episode) => (
<article class="media">
<figure class="media-left">
<p class="image is-64x64 has-background-primary is-flex is-align-content-center">
<MusicIcon class="p-4 has-text-dark" />
</p>
</figure>
<div class="media-content">
<div class="content">
<p class="title is-5">{episode.name}</p>
<Show when={episode.publish_date}>
<p class="subtitle is-6">{new Date(episode.publish_date!).toLocaleDateString()}</p>
</Show>
<figure class="m-0 mb-4">
<audio controls src={new URL(`/files/${episode.podcast_id}/${episode.id}.m4a`, SERVER_URL).toString()}></audio>
</figure>
<Show when={episode.description_html}>
<p innerHTML={episode.description_html!}></p>
</Show>
</div>
</div>
<div class="media-right">
<a href={new URL(`/files/${episode.podcast_id}/${episode.id}.m4a`, SERVER_URL).toString()}><DownloadIcon /></a>
</div>
</article>
)}
</For>
</div>
</section>
</Suspense>
</ErrorBoundary>
</main>
)
}

View file

@ -23,9 +23,8 @@
"noFallthroughCasesInSwitch": true,
"noUncheckedSideEffectImports": true,
"baseUrl": "./",
"paths": {
"*": ["src/types/*"]
"*": ["./src/types/*"]
}
},
"include": ["src", "src/types"]