Skip to content

Commit

Permalink
Fix Blog (#724)
Browse files Browse the repository at this point in the history
  • Loading branch information
rob-gordon authored Aug 29, 2024
1 parent e9bbaac commit a7b89aa
Show file tree
Hide file tree
Showing 7 changed files with 107 additions and 39 deletions.
4 changes: 2 additions & 2 deletions api/_lib/_dates.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { format, parse, parseISO } from "date-fns";

export function niceDate(d: string) {
return format(parse(d, "yyyy-MM-dd", new Date()), "LLLL d, yyyy");
export function niceDate(d: Date) {
return format(d, "LLLL d, yyyy");
}

export function dateString(d: string) {
Expand Down
2 changes: 1 addition & 1 deletion api/blog/post.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export default async function handler(req: VercelRequest, res: VercelResponse) {
if (!("properties" in post)) throw new Error("No properties");
const { properties = {}, id } = post;
const { date, ...props } = getNestedProperties(properties);
const publishDate = niceDate(date);
const publishDate = niceDate(new Date(date));

const htmlContent = await getPostHtmlFromId(id);

Expand Down
66 changes: 47 additions & 19 deletions api/blog/posts.ts
Original file line number Diff line number Diff line change
@@ -1,31 +1,59 @@
import { VercelRequest, VercelResponse } from "@vercel/node";
import { dateAsNumber, dateString, niceDate } from "../_lib/_dates";
import { notion, getNestedProperties } from "../_lib/_notion";
import { niceDate } from "../_lib/_dates";
import { notion } from "../_lib/_notion";
import { z } from "zod";
import { BlogPost, NotionPost } from "shared";

export default async function handler(req: VercelRequest, res: VercelResponse) {
const response = await notion.databases.query({
database_id: "b7a09b10aa83485b94092269239a8b38",
});
const posts = response.results.map((page) => {
if (!("properties" in page)) throw new Error("No properties");
const { properties = {}, id } = page;
const { date, ...props } = getNestedProperties(properties);
if (!("title" in props)) throw new Error("No title");
if (!("status" in props)) throw new Error("No status");
if (!("slug" in props)) throw new Error("No slug");
if (!("description" in props)) throw new Error("No description");

if (!date) throw new Error("No date");

const sanitizedDate = dateString(date);
const publishDate = niceDate(date);
const rawDate = dateAsNumber(date);

return { id, rawDate, date: sanitizedDate, publishDate, ...props };
});

const notionPosts = response.results.filter(
isValidNotionPost
) as unknown as NotionPost[];

const posts = notionPosts.map(notionPostToBlogPost);

// Cache for 1 week, stale-while-revalidate
res.setHeader("Cache-Control", "s-maxage=1, stale-while-revalidate");

res.json(posts);
}

const postSchema: z.ZodType<NotionPost> = z.object({
id: z.string(),
created_time: z.string(),
properties: z.object({
title: z.object({
title: z.array(z.object({ plain_text: z.string() })).min(1),
}),
description: z.object({
rich_text: z.array(z.object({ plain_text: z.string() })).min(1),
}),
status: z.object({
status: z.object({ name: z.string() }),
}),
slug: z.object({
rich_text: z.array(z.object({ plain_text: z.string() })).min(1),
}),
}),
});

function isValidNotionPost(post: unknown): post is NotionPost {
const parsed = postSchema.safeParse(post);
if (parsed.success) return true;
return false;
}

function notionPostToBlogPost(post: NotionPost): BlogPost {
return {
id: post.id,
publishDate: new Date(post.created_time).getTime(),
niceDate: niceDate(new Date(post.created_time)),
description: post.properties.description.rich_text[0].plain_text,
slug: post.properties.slug.rich_text[0].plain_text,
status: post.properties.status.status.name,
title: post.properties.title.title[0].plain_text,
};
}
22 changes: 6 additions & 16 deletions app/src/pages/Blog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,13 @@ import { InfoHeader } from "../components/InfoHeader";
import { Box } from "../slang";
import { Page } from "../ui/Shared";
import { SectionTitle } from "../ui/Typography";
import type { BlogPost } from "shared";
export default function Blog() {
const posts = useQuery("posts", getAndPreparePosts, {
staleTime: Infinity,
suspense: true,
});

return (
<>
<Helmet>
Expand Down Expand Up @@ -41,7 +43,7 @@ export default function Blog() {
);
}

function Post({ post }: { post: PostType }) {
function Post({ post }: { post: BlogPost }) {
return (
<Link
className={`grid gap-4 p-2 md:p-5 rounded transition-all
Expand All @@ -52,7 +54,7 @@ function Post({ post }: { post: PostType }) {
>
<header className="grid gap-2">
<span className="text-xs text-neutral-500 dark:text-neutral-400">
{post.publishDate}
{post.niceDate}
</span>
<SectionTitle>{post.title}</SectionTitle>
</header>
Expand All @@ -65,20 +67,8 @@ function Post({ post }: { post: PostType }) {

async function getAndPreparePosts() {
const response = await axios.get("/api/blog/posts");
const posts = (response.data as PostType[])
.sort((a, b) => b.rawDate - a.rawDate)
// only show posts with status "Done"
const posts = (response.data as BlogPost[])
.sort((a, b) => b.publishDate - a.publishDate)
.filter((post) => post.status === "Done");
return posts;
}

export type PostType = {
id: string;
rawDate: number;
date: string;
publishDate: string;
description: string;
status: string;
slug: string;
title: string;
};
13 changes: 12 additions & 1 deletion app/src/pages/post/Post.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { useParams } from "react-router-dom";

import { Page } from "../../ui/Shared";
import { PageTitle } from "../../ui/Typography";
import { PostType } from "../Blog";

import { Helmet } from "react-helmet";

export default function Post() {
Expand Down Expand Up @@ -78,3 +78,14 @@ async function getPost(
const post = response.data;
return post;
}

export type PostType = {
id: string;
rawDate: number;
date: string;
publishDate: string;
description: string;
status: string;
slug: string;
title: string;
};
38 changes: 38 additions & 0 deletions shared/src/blog.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
export type NotionPost = {
id: string;
created_time: string;
properties: NotionPostProperties;
};

export type NotionPostProperties = {
title: {
title: {
plain_text: string;
}[];
};
description: {
rich_text: {
plain_text: string;
}[];
};
status: {
status: {
name: string;
};
};
slug: {
rich_text: {
plain_text: string;
}[];
};
};

export type BlogPost = {
id: string;
publishDate: number;
niceDate: string;
description: string;
slug: string;
status: string;
title: string;
};
1 change: 1 addition & 0 deletions shared/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export * from "./ImportDataFormType";
export * from "./templates";
export * from "./blog";

0 comments on commit a7b89aa

Please sign in to comment.