feat: refactor whole bunch of stuff
This commit is contained in:
@@ -29,7 +29,7 @@ export default function App({ Component }: PageProps) {
|
||||
<Component />
|
||||
</Partial>
|
||||
</body>
|
||||
<script src="/thumbnails.js" type="module" async defer />
|
||||
<script src="/thumbhash.js" type="module" async defer />
|
||||
</html>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ import { Handlers, PageProps } from "$fresh/server.ts";
|
||||
import { AccessDeniedError } from "@lib/errors.ts";
|
||||
import { getLogs, Log } from "@lib/log/index.ts";
|
||||
import { formatDate } from "@lib/string.ts";
|
||||
import { renderMarkdown } from "@lib/documents.ts";
|
||||
import { renderMarkdown } from "@lib/markdown.ts";
|
||||
|
||||
const renderLog = (t: unknown) =>
|
||||
renderMarkdown(`\`\`\`js
|
||||
@@ -42,7 +42,7 @@ function LogLine(
|
||||
<span class="bg-gray-600 py-1 px-2 text-xs rounded-xl text-white">
|
||||
{log.date.getHours().toString().padStart(2, "0")}:{log.date
|
||||
.getMinutes().toString().padStart(2, "0")}:{log.date.getSeconds()
|
||||
.toString().padStart(2, "0")} {formatDate(log.date)}
|
||||
.toString().padStart(2, "0")} {formatDate(log.date)}
|
||||
</span>
|
||||
<span class="bg-gray-600 py-1 px-2 text-xs rounded-xl text-white">
|
||||
{log.scope}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Handlers } from "$fresh/server.ts";
|
||||
import { json } from "@lib/helpers.ts";
|
||||
import { fetchResource } from "@lib/marka.ts";
|
||||
import { fetchResource } from "@lib/marka/index.ts";
|
||||
|
||||
export const handler: Handlers = {
|
||||
async GET(_, ctx) {
|
||||
|
||||
@@ -3,8 +3,6 @@ import { Defuddle } from "defuddle/node";
|
||||
import { AccessDeniedError, BadRequestError } from "@lib/errors.ts";
|
||||
import { createStreamResponse, isValidUrl } from "@lib/helpers.ts";
|
||||
import * as openai from "@lib/openai.ts";
|
||||
|
||||
import { Article } from "@lib/resource/articles.ts";
|
||||
import { getYoutubeVideoDetails } from "@lib/youtube.ts";
|
||||
import {
|
||||
extractYoutubeId,
|
||||
@@ -12,8 +10,9 @@ import {
|
||||
toUrlSafeString,
|
||||
} from "@lib/string.ts";
|
||||
import { createLogger } from "@lib/log/index.ts";
|
||||
import { createResource } from "@lib/marka.ts";
|
||||
import { createResource } from "@lib/marka/index.ts";
|
||||
import { webScrape } from "@lib/webScraper.ts";
|
||||
import { ArticleResource } from "@lib/marka/schema.ts";
|
||||
|
||||
const log = createLogger("api/article");
|
||||
|
||||
@@ -93,7 +92,7 @@ async function processCreateYoutubeVideo(
|
||||
|
||||
const id = newId || youtubeId;
|
||||
|
||||
const newArticle: Article = {
|
||||
const newArticle: ArticleResource["content"] = {
|
||||
_type: "Article",
|
||||
headline: video.snippet.title,
|
||||
articleBody: video.snippet.description,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Handlers } from "$fresh/server.ts";
|
||||
import { json } from "@lib/helpers.ts";
|
||||
import { fetchResource } from "@lib/marka.ts";
|
||||
import { fetchResource } from "@lib/marka/index.ts";
|
||||
|
||||
export const handler: Handlers = {
|
||||
async GET() {
|
||||
|
||||
@@ -63,8 +63,8 @@ function parseParams(reqUrl: URL): ImageParams | string {
|
||||
async function generateETag(content: ArrayBuffer): Promise<string> {
|
||||
const hashBuffer = await crypto.subtle.digest("SHA-256", content);
|
||||
return `"${Array.from(new Uint8Array(hashBuffer))
|
||||
.map((b) => b.toString(16).padStart(2, "0"))
|
||||
.join("")
|
||||
.map((b) => b.toString(16).padStart(2, "0"))
|
||||
.join("")
|
||||
}"`;
|
||||
}
|
||||
|
||||
@@ -80,13 +80,9 @@ async function GET(req: Request, _ctx: FreshContext): Promise<Response> {
|
||||
});
|
||||
}
|
||||
|
||||
const imageUrl = params.image.startsWith("resources")
|
||||
? `https://marka.max-richter.dev/${params.image.replace(/^\//, "")}`
|
||||
: params.image;
|
||||
log.debug("Processing image request:", { params });
|
||||
|
||||
log.debug("Processing image request:", { imageUrl, params });
|
||||
|
||||
const image = await getImageContent(imageUrl, params);
|
||||
const image = await getImageContent(params.image, params);
|
||||
|
||||
// Generate ETag based on image content
|
||||
const eTag = await generateETag(image.content);
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { Handlers } from "$fresh/server.ts";
|
||||
import { Movie } from "@lib/resource/movies.ts";
|
||||
import { json } from "@lib/helpers.ts";
|
||||
import * as tmdb from "@lib/tmdb.ts";
|
||||
import { fileExtension } from "https://deno.land/x/file_extension@v2.1.0/mod.ts";
|
||||
import { isString, safeFileName } from "@lib/string.ts";
|
||||
import { AccessDeniedError } from "@lib/errors.ts";
|
||||
import { createResource, fetchResource } from "@lib/marka.ts";
|
||||
import { createResource, fetchResource } from "@lib/marka/index.ts";
|
||||
import { ReviewResource } from "@lib/marka/schema.ts";
|
||||
|
||||
export const handler: Handlers = {
|
||||
async GET(_, ctx) {
|
||||
@@ -50,7 +50,7 @@ export const handler: Handlers = {
|
||||
);
|
||||
}
|
||||
|
||||
const movie: Movie = {
|
||||
const movie: ReviewResource["content"] = {
|
||||
_type: "Review",
|
||||
image: `resources/${finalPath}`,
|
||||
datePublished: releaseDate,
|
||||
|
||||
@@ -9,7 +9,7 @@ import {
|
||||
NotFoundError,
|
||||
} from "@lib/errors.ts";
|
||||
import { createRecommendationResource } from "@lib/recommendation.ts";
|
||||
import { createResource, fetchResource } from "@lib/marka.ts";
|
||||
import { createResource, fetchResource } from "@lib/marka/index.ts";
|
||||
|
||||
const POST = async (
|
||||
req: Request,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Handlers } from "$fresh/server.ts";
|
||||
import { json } from "@lib/helpers.ts";
|
||||
import { fetchResource } from "@lib/marka.ts";
|
||||
import { fetchResource } from "@lib/marka/index.ts";
|
||||
|
||||
export const handler: Handlers = {
|
||||
async GET() {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Handlers } from "$fresh/server.ts";
|
||||
import { json } from "@lib/helpers.ts";
|
||||
import { fetchResource } from "@lib/marka.ts";
|
||||
import { fetchResource } from "@lib/marka/index.ts";
|
||||
|
||||
export const handler: Handlers = {
|
||||
async GET(_, ctx) {
|
||||
|
||||
@@ -3,15 +3,15 @@ import { AccessDeniedError, BadRequestError } from "@lib/errors.ts";
|
||||
import { createStreamResponse, isValidUrl } from "@lib/helpers.ts";
|
||||
import * as openai from "@lib/openai.ts";
|
||||
import { createLogger } from "@lib/log/index.ts";
|
||||
import { Recipe } from "@lib/resource/recipes.ts";
|
||||
import recipeSchema from "@lib/recipeSchema.ts";
|
||||
import { fileExtension } from "https://deno.land/x/file_extension@v2.1.0/mod.ts";
|
||||
import { safeFileName } from "@lib/string.ts";
|
||||
import { parseJsonLdToRecipeSchema } from "./parseJsonLd.ts";
|
||||
import z from "zod";
|
||||
import { createResource } from "@lib/marka.ts";
|
||||
import { createResource } from "@lib/marka/index.ts";
|
||||
import { webScrape } from "@lib/webScraper.ts";
|
||||
import { Defuddle } from "defuddle/node";
|
||||
import { RecipeResource } from "@lib/marka/schema.ts";
|
||||
|
||||
const log = createLogger("api/article");
|
||||
|
||||
@@ -51,7 +51,7 @@ async function processCreateRecipeFromUrl(
|
||||
recipe = await openai.extractRecipe(result.content);
|
||||
}
|
||||
|
||||
const id = safeFileName(recipe?.title || "");
|
||||
const id = safeFileName(recipe?.name || "");
|
||||
|
||||
if (!recipe) {
|
||||
streamResponse.enqueue("failed to parse recipe");
|
||||
@@ -59,23 +59,13 @@ async function processCreateRecipeFromUrl(
|
||||
return;
|
||||
}
|
||||
|
||||
const newRecipe: Recipe = {
|
||||
const newRecipe: RecipeResource["content"] = {
|
||||
...recipe,
|
||||
_type: "Recipe",
|
||||
name: recipe?.title,
|
||||
description: recipe?.description,
|
||||
recipeIngredient: recipe?.ingredients || [],
|
||||
recipeInstructions: recipe?.instructions || [],
|
||||
keywords: recipe.tags || [],
|
||||
image: recipe?.image,
|
||||
totalTime: recipe?.totalTime
|
||||
? `${recipe?.totalTime?.toString()} minutes`
|
||||
: undefined,
|
||||
url: fetchUrl,
|
||||
author: {
|
||||
_type: "Person",
|
||||
name: recipe?.author,
|
||||
},
|
||||
recipeYield: recipe?.servings,
|
||||
};
|
||||
|
||||
if (newRecipe?.image && newRecipe.image.length > 5) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Handlers } from "$fresh/server.ts";
|
||||
import { json } from "@lib/helpers.ts";
|
||||
import { fetchResource } from "@lib/marka.ts";
|
||||
import { fetchResource } from "@lib/marka/index.ts";
|
||||
|
||||
export const handler: Handlers = {
|
||||
async GET() {
|
||||
|
||||
@@ -1,25 +1,25 @@
|
||||
import { Handlers } from "$fresh/server.ts";
|
||||
import { createStreamResponse } from "@lib/helpers.ts";
|
||||
import { Movie } from "@lib/resource/movies.ts";
|
||||
import * as tmdb from "@lib/tmdb.ts";
|
||||
import {
|
||||
createRecommendationResource,
|
||||
getRecommendation,
|
||||
} from "@lib/recommendation.ts";
|
||||
import { AccessDeniedError } from "@lib/errors.ts";
|
||||
import { fetchResource } from "@lib/marka.ts";
|
||||
import { listResources } from "@lib/marka/index.ts";
|
||||
import { ReviewResource } from "@lib/marka/schema.ts";
|
||||
|
||||
async function processUpdateRecommendations(
|
||||
streamResponse: ReturnType<typeof createStreamResponse>,
|
||||
) {
|
||||
const allMovies = await fetchResource("movies");
|
||||
const allMovies = await listResources<ReviewResource>("movies");
|
||||
|
||||
const movies = allMovies?.content.filter((m) => {
|
||||
const movies = allMovies?.filter((m: ReviewResource) => {
|
||||
if (!m?.content) return false;
|
||||
if (!m.content.reviewRating) return false;
|
||||
if (!m.content.tmdbId) return false;
|
||||
return true;
|
||||
}) as Movie[];
|
||||
}) as ReviewResource[];
|
||||
|
||||
streamResponse.enqueue("Fetched all movies");
|
||||
|
||||
@@ -27,22 +27,23 @@ async function processUpdateRecommendations(
|
||||
const total = movies.length;
|
||||
|
||||
await Promise.all(movies.map(async (movie) => {
|
||||
if (!movie.meta.tmdbId) return;
|
||||
if (!movie.meta.rating) return;
|
||||
const recommendation = getRecommendation(movie.id, movie.type);
|
||||
if (!movie.content.tmdbId) return;
|
||||
if (!movie.content.reviewRating) return;
|
||||
const recommendation = getRecommendation(movie.name, movie.type);
|
||||
if (recommendation) {
|
||||
done++;
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const movieDetails = await tmdb.getMovie(movie.meta.tmdbId);
|
||||
const movieDetails = await tmdb.getMovie(movie.content.tmdbId);
|
||||
await createRecommendationResource(movie, movieDetails.overview);
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
}
|
||||
done++;
|
||||
streamResponse.enqueue(
|
||||
`${Math.floor((done / total) * 100)}% [${done + 1}/${total}] ${movie.id}`,
|
||||
`${Math.floor((done / total) * 100)}% [${done + 1
|
||||
}/${total}] ${movie.name}`,
|
||||
);
|
||||
})).catch((err) => {
|
||||
console.log(err);
|
||||
|
||||
@@ -4,8 +4,8 @@ import * as tmdb from "@lib/tmdb.ts";
|
||||
import { fileExtension } from "https://deno.land/x/file_extension@v2.1.0/mod.ts";
|
||||
import { isString, safeFileName } from "@lib/string.ts";
|
||||
import { AccessDeniedError } from "@lib/errors.ts";
|
||||
import { Series } from "@lib/resource/series.ts";
|
||||
import { createResource, fetchResource } from "@lib/marka.ts";
|
||||
import { createResource, fetchResource } from "@lib/marka/index.ts";
|
||||
import { ReviewResource } from "@lib/marka/schema.ts";
|
||||
|
||||
export const handler: Handlers = {
|
||||
async GET(_, ctx) {
|
||||
@@ -49,7 +49,7 @@ export const handler: Handlers = {
|
||||
);
|
||||
}
|
||||
|
||||
const series: Series = {
|
||||
const series: ReviewResource["content"] = {
|
||||
_type: "Review",
|
||||
image: `resources/${finalPath}`,
|
||||
datePublished: releaseDate,
|
||||
|
||||
@@ -9,7 +9,7 @@ import {
|
||||
BadRequestError,
|
||||
NotFoundError,
|
||||
} from "@lib/errors.ts";
|
||||
import { createResource, fetchResource } from "@lib/marka.ts";
|
||||
import { createResource, fetchResource } from "@lib/marka/index.ts";
|
||||
|
||||
const isString = (input: string | undefined): input is string => {
|
||||
return typeof input === "string";
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Handlers } from "$fresh/server.ts";
|
||||
import { json } from "@lib/helpers.ts";
|
||||
import { fetchResource } from "@lib/marka.ts";
|
||||
import { fetchResource } from "@lib/marka/index.ts";
|
||||
|
||||
export const handler: Handlers = {
|
||||
async GET() {
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
import { Handlers, PageProps } from "$fresh/server.ts";
|
||||
import { MainLayout } from "@components/layouts/main.tsx";
|
||||
import { Article } from "@lib/resource/articles.ts";
|
||||
import { KMenu } from "@islands/KMenu.tsx";
|
||||
import { YoutubePlayer } from "@components/Youtube.tsx";
|
||||
import { HashTags } from "@components/HashTags.tsx";
|
||||
import { isYoutubeLink } from "@lib/string.ts";
|
||||
import { removeImage, renderMarkdown } from "@lib/documents.ts";
|
||||
import { removeImage, renderMarkdown } from "@lib/markdown.ts";
|
||||
import { RedirectSearchHandler } from "@islands/Search.tsx";
|
||||
import PageHero from "@components/PageHero.tsx";
|
||||
import { Star } from "@components/Stars.tsx";
|
||||
import { MetaTags } from "@components/MetaTags.tsx";
|
||||
import { fetchResource } from "@lib/marka.ts";
|
||||
import { fetchResource } from "@lib/marka/index.ts";
|
||||
import { ArticleResource } from "@lib/marka/schema.ts";
|
||||
|
||||
export const handler: Handlers<{ article: Article; session: unknown }> = {
|
||||
export const handler: Handlers<{ article: ArticleResource; session: unknown }> = {
|
||||
async GET(_, ctx) {
|
||||
const article = await fetchResource(`articles/${ctx.params.name}.md`);
|
||||
if (!article) {
|
||||
@@ -30,11 +30,9 @@ export default function Greet(
|
||||
const { author = "", date = "", articleBody = "" } = article?.content || {};
|
||||
|
||||
const content = renderMarkdown(
|
||||
removeImage(articleBody, article.content.image),
|
||||
removeImage(articleBody, article.image?.url),
|
||||
);
|
||||
|
||||
console.log({ article });
|
||||
|
||||
return (
|
||||
<MainLayout
|
||||
url={props.url}
|
||||
@@ -46,8 +44,8 @@ export default function Greet(
|
||||
<MetaTags resource={article} />
|
||||
|
||||
<PageHero
|
||||
image={article.content.image}
|
||||
thumbnail={article.content.thumbnail}
|
||||
image={article.image?.url}
|
||||
thumbhash={article.image?.thumbhash}
|
||||
>
|
||||
<PageHero.Header>
|
||||
<PageHero.BackLink href="/articles" />
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Handlers, PageProps } from "$fresh/server.ts";
|
||||
import { MainLayout } from "@components/layouts/main.tsx";
|
||||
import { Article } from "@lib/resource/articles.ts";
|
||||
import { type ArticleResource } from "@lib/marka/schema.ts";
|
||||
import { KMenu } from "@islands/KMenu.tsx";
|
||||
import { Grid } from "@components/Grid.tsx";
|
||||
import { IconArrowLeft } from "@components/icons.tsx";
|
||||
@@ -9,13 +9,13 @@ import { parseResourceUrl, searchResource } from "@lib/search.ts";
|
||||
import { GenericResource } from "@lib/types.ts";
|
||||
import { ResourceCard } from "@components/Card.tsx";
|
||||
import { Link } from "@islands/Link.tsx";
|
||||
import { fetchResource } from "@lib/marka.ts";
|
||||
import { listResources } from "@lib/marka/index.ts";
|
||||
|
||||
export const handler: Handlers<
|
||||
{ articles: Article[] | null; searchResults?: GenericResource[] }
|
||||
{ articles: ArticleResource[] | null; searchResults?: GenericResource[] }
|
||||
> = {
|
||||
async GET(req, ctx) {
|
||||
const { content: articles } = await fetchResource("articles");
|
||||
const articles = await listResources("articles");
|
||||
const searchParams = parseResourceUrl(req.url);
|
||||
const searchResults = searchParams &&
|
||||
await searchResource({ ...searchParams, types: ["article"] });
|
||||
@@ -25,7 +25,7 @@ export const handler: Handlers<
|
||||
|
||||
export default function Greet(
|
||||
props: PageProps<
|
||||
{ articles: Article[] | null; searchResults: GenericResource[] }
|
||||
{ articles: ArticleResource[] | null; searchResults: GenericResource[] }
|
||||
>,
|
||||
) {
|
||||
const { articles, searchResults } = props.data;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { PageProps, RouteContext } from "$fresh/server.ts";
|
||||
import { MainLayout } from "@components/layouts/main.tsx";
|
||||
import { Movie } from "@lib/resource/movies.ts";
|
||||
import { removeImage, renderMarkdown } from "@lib/documents.ts";
|
||||
import { ReviewResource, ReviewSchema } from "@lib/marka/schema.ts";
|
||||
import { removeImage, renderMarkdown } from "@lib/markdown.ts";
|
||||
import { KMenu } from "@islands/KMenu.tsx";
|
||||
import { RedirectSearchHandler } from "@islands/Search.tsx";
|
||||
import { Recommendations } from "@islands/Recommendations.tsx";
|
||||
@@ -9,20 +9,22 @@ import PageHero from "@components/PageHero.tsx";
|
||||
import { Star } from "@components/Stars.tsx";
|
||||
import { MetaTags } from "@components/MetaTags.tsx";
|
||||
import { parseRating } from "@lib/helpers.ts";
|
||||
import { fetchResource } from "@lib/marka.ts";
|
||||
import { fetchResource } from "@lib/marka/index.ts";
|
||||
|
||||
export default async function Greet(
|
||||
props: PageProps<{ movie: Movie; session: Record<string, string> }>,
|
||||
props: PageProps<{ movie: ReviewResource; session: Record<string, string> }>,
|
||||
ctx: RouteContext,
|
||||
) {
|
||||
const movie = await fetchResource(`movies/${ctx.params.name}.md`);
|
||||
const movie = await fetchResource<ReviewResource>(
|
||||
`movies/${ctx.params.name}.md`,
|
||||
);
|
||||
const session = ctx.state.session;
|
||||
|
||||
if (!movie) {
|
||||
return ctx.renderNotFound();
|
||||
}
|
||||
|
||||
const { author = "", date = "" } = movie.content;
|
||||
const { author = "", datePublished = "" } = movie.content;
|
||||
|
||||
const content = renderMarkdown(
|
||||
removeImage(movie.content.reviewBody || "", movie.content.image),
|
||||
@@ -34,8 +36,8 @@ export default async function Greet(
|
||||
<KMenu type="main" context={movie} />
|
||||
<MetaTags resource={movie} />
|
||||
<PageHero
|
||||
image={movie.content.image}
|
||||
thumbnail={movie.content.thumbnail}
|
||||
image={movie.image?.url}
|
||||
thumbhash={movie.image?.thumbhash}
|
||||
>
|
||||
<PageHero.Header>
|
||||
<PageHero.BackLink href="/movies" />
|
||||
@@ -60,7 +62,7 @@ export default async function Greet(
|
||||
>
|
||||
{movie.content.reviewRating && (
|
||||
<Star
|
||||
rating={parseRating(movie.content.reviewRating?.ratingValue)}
|
||||
rating={parseRating(movie.content?.reviewRating?.ratingValue)}
|
||||
/>
|
||||
)}
|
||||
</PageHero.Subline>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { MainLayout } from "@components/layouts/main.tsx";
|
||||
import { Movie } from "@lib/resource/movies.ts";
|
||||
import { ReviewResource } from "@lib/marka/schema.ts";
|
||||
import { ResourceCard } from "@components/Card.tsx";
|
||||
import { Grid } from "@components/Grid.tsx";
|
||||
import { IconArrowLeft } from "@components/icons.tsx";
|
||||
@@ -7,15 +7,15 @@ import { KMenu } from "@islands/KMenu.tsx";
|
||||
import { RedirectSearchHandler } from "@islands/Search.tsx";
|
||||
import { GenericResource } from "@lib/types.ts";
|
||||
import { PageProps } from "$fresh/server.ts";
|
||||
import { fetchResource } from "@lib/marka.ts";
|
||||
import { listResources } from "@lib/marka/index.ts";
|
||||
import { parseResourceUrl, searchResource } from "@lib/search.ts";
|
||||
|
||||
export default async function Greet(
|
||||
export default async function MovieIndex(
|
||||
props: PageProps<
|
||||
{ movies: Movie[] | null; searchResults: GenericResource[] }
|
||||
{ movies: ReviewResource[] | null; searchResults: GenericResource[] }
|
||||
>,
|
||||
) {
|
||||
const { content: allMovies } = await fetchResource("movies");
|
||||
const allMovies = await listResources("movies");
|
||||
const searchParams = parseResourceUrl(props.url);
|
||||
const searchResults = searchParams &&
|
||||
await searchResource({ ...searchParams, types: ["movie"] });
|
||||
@@ -47,8 +47,8 @@ export default async function Greet(
|
||||
<h3 class="text-2xl text-white font-light">🍿 Movies</h3>
|
||||
</header>
|
||||
<Grid>
|
||||
{movies?.map((doc) => {
|
||||
return <ResourceCard res={doc} />;
|
||||
{movies?.map((doc, i) => {
|
||||
return <ResourceCard key={i} res={doc} />;
|
||||
})}
|
||||
</Grid>
|
||||
</MainLayout>
|
||||
|
||||
@@ -8,10 +8,10 @@ import { RedirectSearchHandler } from "@islands/Search.tsx";
|
||||
import { KMenu } from "@islands/KMenu.tsx";
|
||||
import PageHero from "@components/PageHero.tsx";
|
||||
import { Star } from "@components/Stars.tsx";
|
||||
import { renderMarkdown } from "@lib/documents.ts";
|
||||
import { renderMarkdown } from "@lib/markdown.ts";
|
||||
import { isValidRecipe } from "@lib/recipeSchema.ts";
|
||||
import { MetaTags } from "@components/MetaTags.tsx";
|
||||
import { fetchResource } from "@lib/marka.ts";
|
||||
import { fetchResource } from "@lib/marka/index.ts";
|
||||
|
||||
export const handler: Handlers<{ recipe: Recipe; session: unknown } | null> = {
|
||||
async GET(_, ctx) {
|
||||
@@ -86,8 +86,8 @@ export default function Page(
|
||||
<MetaTags resource={recipe} />
|
||||
|
||||
<PageHero
|
||||
image={recipe.content?.image}
|
||||
thumbnail={recipe.content?.thumbnail}
|
||||
image={recipe.image?.url}
|
||||
thumbhash={recipe.image?.thumbhash}
|
||||
>
|
||||
<PageHero.Header>
|
||||
<PageHero.BackLink href="/recipes" />
|
||||
|
||||
@@ -7,14 +7,14 @@ import { KMenu } from "@islands/KMenu.tsx";
|
||||
import { RedirectSearchHandler } from "@islands/Search.tsx";
|
||||
import { GenericResource } from "@lib/types.ts";
|
||||
import { ResourceCard } from "@components/Card.tsx";
|
||||
import { fetchResource } from "@lib/marka.ts";
|
||||
import { fetchResource, listResources } from "@lib/marka/index.ts";
|
||||
import { parseResourceUrl, searchResource } from "@lib/search.ts";
|
||||
|
||||
export const handler: Handlers<
|
||||
{ recipes: Recipe[] | null; searchResults?: GenericResource[] }
|
||||
> = {
|
||||
async GET(req, ctx) {
|
||||
const { content: recipes } = await fetchResource("recipes");
|
||||
const recipes = await listResources("recipes");
|
||||
const searchParams = parseResourceUrl(req.url);
|
||||
const searchResults = searchParams &&
|
||||
await searchResource({ ...searchParams, types: ["recipe"] });
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
import { Handlers, PageProps } from "$fresh/server.ts";
|
||||
import { MainLayout } from "@components/layouts/main.tsx";
|
||||
import { HashTags } from "@components/HashTags.tsx";
|
||||
import { removeImage, renderMarkdown } from "@lib/documents.ts";
|
||||
import { Series } from "@lib/resource/series.ts";
|
||||
import { removeImage, renderMarkdown } from "@lib/markdown.ts";
|
||||
import { RedirectSearchHandler } from "@islands/Search.tsx";
|
||||
import { KMenu } from "@islands/KMenu.tsx";
|
||||
import PageHero from "@components/PageHero.tsx";
|
||||
import { Star } from "@components/Stars.tsx";
|
||||
import { MetaTags } from "@components/MetaTags.tsx";
|
||||
import { parseRating } from "@lib/helpers.ts";
|
||||
import { fetchResource } from "@lib/marka.ts";
|
||||
import { fetchResource } from "@lib/marka/index.ts";
|
||||
import { ReviewResource } from "@lib/marka/schema.ts";
|
||||
|
||||
export const handler: Handlers<{ serie: Series; session: unknown }> = {
|
||||
export const handler: Handlers<{ serie: ReviewResource; session: unknown }> = {
|
||||
async GET(_, ctx) {
|
||||
const serie = await fetchResource(`series/${ctx.params.name}.md`);
|
||||
|
||||
@@ -44,8 +44,8 @@ export default function Greet(
|
||||
|
||||
<MetaTags resource={serie} />
|
||||
<PageHero
|
||||
image={serie.content?.image}
|
||||
thumbnail={serie.content?.thumbnail}
|
||||
image={serie.image?.url}
|
||||
thumbhash={serie.image?.thumbhash}
|
||||
>
|
||||
<PageHero.Header>
|
||||
<PageHero.BackLink href="/series" />
|
||||
|
||||
@@ -2,19 +2,18 @@ import { Handlers, PageProps } from "$fresh/server.ts";
|
||||
import { MainLayout } from "@components/layouts/main.tsx";
|
||||
import { Grid } from "@components/Grid.tsx";
|
||||
import { IconArrowLeft } from "@components/icons.tsx";
|
||||
import { Series } from "@lib/resource/series.ts";
|
||||
import { RedirectSearchHandler } from "@islands/Search.tsx";
|
||||
import { KMenu } from "@islands/KMenu.tsx";
|
||||
import { ResourceCard } from "@components/Card.tsx";
|
||||
import { GenericResource } from "@lib/types.ts";
|
||||
import { fetchResource } from "@lib/marka.ts";
|
||||
import { listResources } from "@lib/marka/index.ts";
|
||||
import { parseResourceUrl, searchResource } from "@lib/search.ts";
|
||||
import { GenericResource, ReviewResource } from "@lib/marka/schema.ts";
|
||||
|
||||
export const handler: Handlers<
|
||||
{ series: Series[] | null; searchResults?: GenericResource[] }
|
||||
{ series: ReviewResource[] | null; searchResults?: GenericResource[] }
|
||||
> = {
|
||||
async GET(req, ctx) {
|
||||
const { content: series } = await fetchResource("series");
|
||||
const series = await listResources("series");
|
||||
const searchParams = parseResourceUrl(req.url);
|
||||
const searchResults = searchParams &&
|
||||
await searchResource({ ...searchParams, types: ["series"] });
|
||||
@@ -24,7 +23,7 @@ export const handler: Handlers<
|
||||
|
||||
export default function Greet(
|
||||
props: PageProps<
|
||||
{ series: Series[] | null; searchResults: GenericResource[] }
|
||||
{ series: ReviewResource[] | null; searchResults: GenericResource[] }
|
||||
>,
|
||||
) {
|
||||
const { series, searchResults } = props.data;
|
||||
@@ -50,8 +49,8 @@ export default function Greet(
|
||||
<h3 class="text-2xl text-white font-light">🎥 Series</h3>
|
||||
</header>
|
||||
<Grid>
|
||||
{series?.map((doc) => {
|
||||
return <ResourceCard sublink="series" res={doc} />;
|
||||
{series?.map((doc, i) => {
|
||||
return <ResourceCard key={i} sublink="series" res={doc} />;
|
||||
})}
|
||||
</Grid>
|
||||
</MainLayout>
|
||||
|
||||
Reference in New Issue
Block a user