Skip to content

Commit

Permalink
Merge pull request #145 from shunkakinoki/feat/ini-blog-page-v3
Browse files Browse the repository at this point in the history
feat: ini blog page
  • Loading branch information
shunkakinoki authored Aug 23, 2021
2 parents 92c972c + 4b31786 commit de39aa8
Show file tree
Hide file tree
Showing 15 changed files with 376 additions and 139 deletions.
1 change: 1 addition & 0 deletions .env
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
NEXTAUTH_URL=https://shunkakinoki.com
NOTION_BLOG_ID=e4ef762ca07f465e8f5cce906732140b
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
"@heroicons/react": "^1.0.4",
"@next-auth/prisma-adapter": "^0.5.4",
"@next/bundle-analyzer": "^11.1.0",
"@notionhq/client": "^0.3.0",
"@prisma/client": "^2.29.1",
"autoprefixer": "^10.3.2",
"chrome-aws-lambda": "^10.1.0",
Expand Down
23 changes: 0 additions & 23 deletions src/components/Blog/Blog.module.css

This file was deleted.

76 changes: 36 additions & 40 deletions src/components/Blog/Blog.tsx
Original file line number Diff line number Diff line change
@@ -1,48 +1,44 @@
import { MDXRemote } from "next-mdx-remote";
import type { MDXRemoteSerializeResult } from "next-mdx-remote";
import type { Page } from "@notionhq/client/build/src/api-types";
import Link from "next/link";

import type { FC } from "react";

import s from "./Blog.module.css";

export interface Props {
frontMatter: {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
[key: string]: any;
};
source: MDXRemoteSerializeResult;
slug: string;
}

interface BlogLinkProps {
children: string;
href: string;
}

export const Blog: FC<Props> = ({ source, slug }) => {
const BlogLink = ({ children, href }: BlogLinkProps) => {
return (
<Link
href={
slug === "blog"
? href.replace(".md", "")
: `${slug}/${href.replace(".md", "")}`
}
>
{children}
</Link>
);
};

const components = {
a: BlogLink,
};
export type Props = {
database: Page[];
locale?: string;
};

export const Blog: FC<Props> = ({ database, locale }) => {
return (
<section className="px-3 text-black dark:text-white">
<div className={s.markdown}>
<MDXRemote {...source} components={components} />
<section className="px-3 w-full text-black dark:text-white">
<div className="flex-col space-y-3 w-full">
{database.map(page => {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
const date = new Date(page.properties.Date.date.start).toLocaleString(
locale,
{
month: "short",
day: "2-digit",
year: "numeric",
},
);
return (
<div key={page.id} className="flex space-x-4">
<Link href={`/${page.id}`}>
<a className="flex flex-grow items-center font-extrabold text-warmGray-800 hover:text-coolGray-600 dark:text-gray-300 dark:hover:text-gray-100 hover:underline line-clamp-1">
<div className="text-xl md:text-2xl">
{/* eslint-disable-next-line @typescript-eslint/ban-ts-comment */}
{/* @ts-ignore */}
{page.properties.Name?.title[0]?.plain_text || ""}
</div>
</a>
</Link>
<div className="flex flex-none justify-center items-center text-sm text-gray-700 dark:text-gray-300">
{date}
</div>
</div>
);
})}
</div>
</section>
);
Expand Down
67 changes: 67 additions & 0 deletions src/components/Notion/Notion.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
.notion {
@apply leading-relaxed;
}

.notion a {
@apply underline;
}

.notion p {
@apply my-3;
}

.notion h1 {
@apply my-8 text-6xl font-semibold tracking-tight;
}

.notion h2 {
@apply my-6 text-4xl font-semibold leading-tight;
}

.notion h3 {
@apply my-5 text-2xl font-semibold leading-snug;
}

.notion h4 {
@apply my-4 text-2xl;
}

.notion h5 {
@apply my-3 text-3xl font-light;
}

.notion h6 {
@apply my-3 text-xl font-thin;
}

.notion ul {
@apply mx-4 my-6 text-lg font-semibold list-disc sm:my-9;
}

.notion li {
@apply my-1;
}

.notion ol {
@apply mx-4 my-6 text-lg font-semibold list-decimal list-inside sm:my-9;
}

.notion table {
@apply table-caption w-full max-w-screen-lg overflow-hidden table-auto;
}

.notion th {
@apply relative font-serif text-2xl font-semibold leading-relaxed text-left border-collapse;
}

.notion td {
@apply px-4 py-2 font-serif leading-relaxed;
}

.notion blockquote {
@apply p-3 mx-16 my-auto font-serif text-xl italic;
}

.notion blockquote > p {
@apply max-w-screen-md mx-0 my-auto text-2xl font-bold;
}
94 changes: 94 additions & 0 deletions src/components/Notion/Notion.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/* eslint-disable @typescript-eslint/no-unsafe-call */

import type { PagesRetrieveResponse } from "@notionhq/client/build/src/api-endpoints";
import type { Block, RichText } from "@notionhq/client/build/src/api-types";
import clsx from "clsx";
import { Fragment } from "react";
import type { FC } from "react";

import s from "./Notion.module.css";

export type Props = {
blocks: Block[];
content: PagesRetrieveResponse;
};

export type TextProps = {
text: RichText[];
};

export const Text: FC<TextProps> = ({ text }) => {
return (
<>
{text.map((value, id) => {
const {
annotations: { bold, code, italic, strikethrough, underline },
plain_text,
href,
} = value;
return (
<span
key={id}
className={clsx(
bold && "font-extrabold",
code && "py-3 px-2 font-mono",
italic && "italic",
strikethrough && "line-through",
underline && "underline",
)}
>
{href ? (
<a
href={href}
target="_blank"
rel="noopener noreferrer"
className="hover:text-coolGray-500 dark:hover:text-coolGray-400"
>
{plain_text}
</a>
) : (
plain_text
)}
</span>
);
})}
</>
);
};

const renderBlock = (block: Block) => {
switch (block.type) {
case "paragraph":
return (
<p>
<Text text={block["paragraph"].text} />
</p>
);
case "heading_1":
return (
<h1>
<Text text={block["heading_1"].text} />
</h1>
);
default:
}
};

export const Notion: FC<Props> = ({ blocks, content }) => {
return (
<section className="px-3 text-black dark:text-white">
<div className="px-3 md:px-0 pb-3">
<h1 className="mb-4 text-3xl md:text-5xl lg:text-6xl font-bold tracking-tight text-warmGray-800 dark:text-white">
{/* eslint-disable-next-line @typescript-eslint/ban-ts-comment */}
{/* @ts-ignore */}
{content.properties.Name?.title[0]?.plain_text}
</h1>
</div>
<div className={s.notion}>
{blocks.map(block => {
return <Fragment key={block.id}>{renderBlock(block)}</Fragment>;
})}
</div>
</section>
);
};
2 changes: 2 additions & 0 deletions src/components/Notion/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { Notion } from "./Notion";
export type { Props } from "./Notion";
10 changes: 8 additions & 2 deletions src/components/Seo/Seo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,15 @@ export interface Props extends NextSeoProps {
export const Seo: FC<Props> = ({ date, title, description, ...rest }) => {
const imageUrl =
date && title
? `https://shunkakinoki.com/api/image?fileType=png&layoutName=Blog&Theme=Dark&Title=${title}&Date=${date}`
? `https://shunkakinoki.com/api/image?fileType=png&layoutName=Blog&Theme=Dark&Title=${title?.replace(
/\s/g,
"%20",
)}&Date=${date?.replace(/\s/g, "%20")}`
: title
? `https://shunkakinoki.com/api/image?fileType=png&layoutName=Website&Theme=Dark&Title=${title}`
? `https://shunkakinoki.com/api/image?fileType=png&layoutName=Website&Theme=Dark&Title=${title?.replace(
/\s/g,
"%20",
)}`
: "https://shunkakinoki.com/api/image?fileType=png&layoutName=Shun&Title=shunkakinoki";

return (
Expand Down
24 changes: 24 additions & 0 deletions src/lib/notion.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/* eslint-disable @typescript-eslint/no-unsafe-call */

import { Client } from "@notionhq/client";

const notion = new Client({
auth: process.env.NOTION_API_KEY,
});

export const getDatabase = async (databaseId: string) => {
const response = await notion.databases.query({
database_id: databaseId,
});
return response.results;
};

export const getPage = async (pageId: string) => {
const response = await notion.pages.retrieve({ page_id: pageId });
return response;
};

export const getBlocks = async (blockId: string) => {
const response = await notion.blocks.children.list({ block_id: blockId });
return response.results;
};
Loading

2 comments on commit de39aa8

@vercel
Copy link

@vercel vercel bot commented on de39aa8 Aug 23, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vercel
Copy link

@vercel vercel bot commented on de39aa8 Aug 23, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.