raj.how/src/app/(home)/story/page.tsx

144 lines
4.3 KiB
TypeScript
Raw Normal View History

2024-01-09 21:25:30 +05:30
import { NotionAPI } from "notion-client";
import Image from "next/image";
2024-03-11 21:29:40 +05:30
import { getPageImageUrls, getPageProperty, getPageTitle } from "notion-utils";
2024-01-09 21:25:30 +05:30
import "@/components/notion/notion.scss";
import "react-notion-x/src/styles.css";
import "prismjs/themes/prism-tomorrow.css";
2024-01-17 22:19:31 +05:30
import { BackgroundGradentProvider } from "@/components/gradient-provider";
2024-01-09 21:25:30 +05:30
import GrainProvider from "@/components/grain";
import { Footer } from "../Footer";
import { Connect } from "../Connect";
2024-01-10 21:54:17 +05:30
import { Home } from "lucide-react";
2024-01-10 21:57:23 +05:30
import Link from "next/link";
2024-02-18 21:25:43 +05:30
import { NRenderer } from "@/components/notion/renderer";
2024-03-08 17:11:25 +05:30
import { Metadata, ResolvingMetadata } from "next";
2024-03-13 08:34:51 +05:30
import Comments from "@/components/comments";
2024-03-08 17:11:25 +05:30
export const revalidate = 100;
type Props = {
searchParams: { id?: string };
};
export async function generateMetadata(
{ searchParams }: Props,
parent: ResolvingMetadata,
): Promise<Metadata> {
const notion = new NotionAPI();
const recordMap = await notion.getPage(searchParams.id!);
const title = getPageTitle(recordMap);
2024-03-11 21:29:40 +05:30
const page_block = Object.values(recordMap.block)[0].value;
const description = getPageProperty("description", page_block, recordMap);
const author = getPageProperty("author", page_block, recordMap);
const github_username = getPageProperty("github", page_block, recordMap);
2024-03-08 17:11:25 +05:30
const images = getPageImageUrls(recordMap, { mapImageUrl: (url) => url });
2024-03-11 21:29:40 +05:30
const params = new URLSearchParams({
title: title.toString(),
description: description.toString(),
author: author.toString(),
images: images[0],
2024-03-11 21:29:40 +05:30
github_username: github_username.toString(),
});
const image_origin_url =
process.env.NODE_ENV !== "development"
? "https://raj.how"
: "http://localhost:3000";
const og_image_url = new URL("/api/og", image_origin_url);
og_image_url.search = params.toString();
2024-03-08 17:11:25 +05:30
return {
title: title,
2024-03-08 17:38:03 +05:30
description: "Written by raj",
2024-03-08 17:11:25 +05:30
openGraph: {
2024-03-11 21:29:40 +05:30
images: [og_image_url.toString()],
2024-03-08 17:11:25 +05:30
},
2024-03-08 17:38:03 +05:30
twitter: {
2024-03-11 21:29:40 +05:30
images: [og_image_url.toString()],
2024-03-08 17:38:03 +05:30
},
2024-03-08 17:11:25 +05:30
};
}
2024-01-09 21:25:30 +05:30
export default async function Story({
searchParams,
}: {
searchParams: { id?: string };
}) {
if (!searchParams.id) return null;
const notion = new NotionAPI();
const recordMap = await notion.getPage(searchParams.id);
const title = getPageTitle(recordMap);
const images = getPageImageUrls(recordMap, { mapImageUrl: (url) => url });
2024-03-13 08:34:51 +05:30
const repo = process.env.COMMENTS_REPO;
const repoId = process.env.COMMENTS_REPO_ID;
const category = process.env.COMMENTS_CATEGORY;
const categoryId = process.env.COMMENTS_CATEGORY_ID;
console.log(repo, repoId, category, categoryId);
2024-01-09 21:25:30 +05:30
return (
<article suppressHydrationWarning className="relative">
<GrainProvider
grain_options={{
patternWidth: 200,
patternHeight: 200,
grainOpacity: 0.1,
grainDensity: 1,
grainWidth: 1,
grainHeight: 1,
}}
/>
2024-01-09 23:50:28 +05:30
<BackgroundGradentProvider className="-z-10 h-screen w-full opacity-60" />
2024-01-09 23:51:30 +05:30
<Image
width={400}
height={300}
src={images[0]}
alt={title}
2024-02-18 21:25:43 +05:30
priority
2024-01-09 23:51:30 +05:30
className="w-full h-48 object-cover opacity-70 backdrop-saturate-200 backdrop-contrast-200 -z-50"
/>
2024-01-09 21:25:30 +05:30
<div className="container py-12 max-w-2xl">
<h1 className="text-2xl text-center text-pretty font-medium">
{title}
</h1>
2024-01-10 21:57:23 +05:30
<Link className="text-foreground/80 hover:no-underline" href="/">
<div className="border sticky top-12 z-50 mt-2 mx-auto backdrop-blur border-foreground/20 backdrop-saturate-100 backdrop-contrast-125 p-1 px-2 w-fit rounded-full flex gap-1 items-center">
<Home className="animate-in" size={12} />
<span className="text-xs">Home</span>
</div>
</Link>
2024-01-09 21:25:30 +05:30
<NRenderer recordMap={recordMap} />
<section className="connect-section">
<Connect />
</section>
2024-03-13 08:34:51 +05:30
<section className="comments-section">
{repo && repoId && category && categoryId ? (
<Comments
repo={repo as `${string}/${string}`}
repoId={repoId}
category={category}
categoryId={categoryId}
/>
) : null}
</section>
2024-01-09 21:25:30 +05:30
</div>
<Footer className="max-w-2xl" />
</article>
);
}