-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Initialization from save point of mdx-onyva
- Loading branch information
Showing
39 changed files
with
3,654 additions
and
432 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -27,6 +27,7 @@ yarn-error.log* | |
|
||
# local env files | ||
.env*.local | ||
.env | ||
|
||
# vercel | ||
.vercel | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
import type { Metadata } from 'next' | ||
|
||
import { notFound } from 'next/navigation' | ||
import { CustomMDX } from '@/components/mdx' | ||
import { formatDate, getBlogPosts } from '@/utils/mdx-utils' | ||
import { siteConfig } from '@/config/site' | ||
|
||
import { unstable_noStore as noStore } from 'next/cache' | ||
|
||
export async function generateStaticParams() { | ||
let posts = getBlogPosts() | ||
|
||
return posts.map((post) => ({ | ||
slug: post.slug, | ||
})) | ||
} | ||
|
||
export async function generateMetadata({ | ||
params, | ||
}): Promise<Metadata | undefined> { | ||
let post = getBlogPosts().find((post) => post.slug === params.slug) | ||
if (!post) { | ||
return; | ||
} | ||
|
||
let { | ||
title, | ||
publishedAt: publishedTime, | ||
summary: description, | ||
image, | ||
} = post.metadata | ||
let ogImage = image ? image : `${siteConfig.baseUrl}/og?title=${encodeURIComponent(title)}` | ||
|
||
return { | ||
title, | ||
description, | ||
openGraph: { | ||
title, | ||
description, | ||
type: 'article', | ||
publishedTime, | ||
url: `${siteConfig.baseUrl}/blog/${post.slug}`, | ||
images: [ | ||
{ | ||
url: ogImage, | ||
}, | ||
], | ||
}, | ||
twitter: { | ||
card: 'summary_large_image', | ||
title, | ||
description, | ||
images: [ogImage], | ||
}, | ||
} | ||
} | ||
|
||
export default function Blog({ params }) { | ||
let post = getBlogPosts().find((post) => post.slug === params.slug) | ||
|
||
if (!post) { | ||
notFound() | ||
} | ||
|
||
return ( | ||
<section> | ||
<script | ||
type="application/ld+json" | ||
suppressHydrationWarning | ||
dangerouslySetInnerHTML={{ | ||
__html: JSON.stringify({ | ||
'@context': 'https://schema.org', | ||
'@type': 'BlogPosting', | ||
headline: post.metadata.title, | ||
datePublished: post.metadata.publishedAt, | ||
dateModified: post.metadata.publishedAt, | ||
description: post.metadata.summary, | ||
image: post.metadata.image | ||
? `${siteConfig.baseUrl}${post.metadata.image}` | ||
: `/og?title=${encodeURIComponent(post.metadata.title)}`, | ||
url: `${siteConfig.baseUrl}/blog/${post.slug}`, | ||
author: { | ||
'@type': 'Person', | ||
name: 'My Portfolio', | ||
}, | ||
}), | ||
}} | ||
/> | ||
<h1 className="title font-semibold text-2xl tracking-tighter"> | ||
{post.metadata.title} | ||
</h1> | ||
<div className="flex justify-between items-center mt-2 mb-8 text-sm"> | ||
<p className="text-sm text-neutral-600 dark:text-neutral-400"> | ||
{formatDate(post.metadata.publishedAt)} | ||
</p> | ||
</div> | ||
<article className="prose max-w-none"> | ||
<CustomMDX source={post.content} /> | ||
</article> | ||
</section> | ||
) | ||
} | ||
|
||
function formatDateAlternate(date: string) { | ||
noStore(); | ||
let currentDate = new Date().getTime(); | ||
if (!date.includes('T')) { | ||
date = `${date}T00:00:00`; | ||
} | ||
let targetDate = new Date(date).getTime(); | ||
let timeDifference = Math.abs(currentDate - targetDate); | ||
let daysAgo = Math.floor(timeDifference / (1000 * 60 * 60 * 24)); | ||
|
||
let fullDate = new Date(date).toLocaleString('en-us', { | ||
month: 'long', | ||
day: 'numeric', | ||
year: 'numeric', | ||
}); | ||
|
||
if (daysAgo < 1) { | ||
return 'Today'; | ||
} else if (daysAgo < 7) { | ||
return `${fullDate} (${daysAgo}d ago)`; | ||
} else if (daysAgo < 30) { | ||
const weeksAgo = Math.floor(daysAgo / 7) | ||
return `${fullDate} (${weeksAgo}w ago)`; | ||
} else if (daysAgo < 365) { | ||
const monthsAgo = Math.floor(daysAgo / 30) | ||
return `${fullDate} (${monthsAgo}mo ago)`; | ||
} else { | ||
const yearsAgo = Math.floor(daysAgo / 365) | ||
return `${fullDate} (${yearsAgo}y ago)`; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import { BlogPosts } from '@/components/posts' | ||
|
||
export const metadata = { | ||
title: 'Blog', | ||
description: 'Read my blog.', | ||
} | ||
|
||
export default function Page() { | ||
return ( | ||
<section> | ||
<h1 className="font-semibold text-2xl mb-8 tracking-tighter">My Blog</h1> | ||
<BlogPosts /> | ||
</section> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import MainLayout from '@/components/layout/main-layout' | ||
import { Navbar } from '@/components/layout/nav' | ||
import NavBar from '@/components/layout/navbar' | ||
|
||
export default function DefaultLayout({ children }: { children: React.ReactNode }) { | ||
// Create any shared layout or styles here | ||
return ( | ||
<MainLayout> | ||
<NavBar /> | ||
<Navbar /> | ||
{children} | ||
</MainLayout> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
export default function MdxLayout({ children }: { children: React.ReactNode }) { | ||
// Create any shared layout or styles here | ||
return ( | ||
<div className="prose prose-headings:mt-8 prose-headings:font-semibold prose-headings:text-black prose-h1:text-5xl prose-h2:text-4xl prose-h3:text-3xl prose-h4:text-2xl prose-h5:text-xl prose-h6:text-lg "> | ||
{children} | ||
</div> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import Welcome from '@/_markdown/welcome.mdx' | ||
|
||
export default function Page() { | ||
return <Welcome /> | ||
} |
Oops, something went wrong.