-
-
Notifications
You must be signed in to change notification settings - Fork 772
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
16 changed files
with
296 additions
and
15 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 |
---|---|---|
|
@@ -21,6 +21,7 @@ words: | |
- clsx | ||
- commitlint | ||
- compat | ||
- frontmatter | ||
- hookform | ||
- ianvs | ||
- ixahmedxi | ||
|
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
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
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
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 |
---|---|---|
@@ -1,5 +1,5 @@ | ||
import type { PropsWithChildren } from 'react'; | ||
|
||
export default function LegalLayout({ children }: PropsWithChildren) { | ||
return <main className="mx-auto max-w-prose py-12">{children}</main>; | ||
return <main className="mx-auto max-w-prose py-8 md:py-12">{children}</main>; | ||
} |
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,22 @@ | ||
import { getLegalDocs } from '@/lib/mdx'; | ||
import { notFound } from 'next/navigation'; | ||
import { CustomMDX, MDXComponents } from '../../_components/custom-mdx'; | ||
|
||
export default async function PrivacyPage() { | ||
const docs = await getLegalDocs(); | ||
const post = docs.find((d) => d.slug === 'privacy'); | ||
|
||
if (!post) { | ||
notFound(); | ||
} | ||
|
||
return ( | ||
<> | ||
<MDXComponents.h1>{post.metadata.title}</MDXComponents.h1> | ||
<p className="my-3 text-sm md:my-4 md:text-base"> | ||
{post.metadata.effectiveDate} | ||
</p> | ||
<CustomMDX source={post.content} /> | ||
</> | ||
); | ||
} |
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,22 @@ | ||
import { getLegalDocs } from '@/lib/mdx'; | ||
import { notFound } from 'next/navigation'; | ||
import { CustomMDX, MDXComponents } from '../../_components/custom-mdx'; | ||
|
||
export default async function TermsPage() { | ||
const docs = await getLegalDocs(); | ||
const post = docs.find((d) => d.slug === 'tos'); | ||
|
||
if (!post) { | ||
notFound(); | ||
} | ||
|
||
return ( | ||
<> | ||
<MDXComponents.h1>{post.metadata.title}</MDXComponents.h1> | ||
<p className="my-3 text-sm md:my-4 md:text-base"> | ||
Effective date: {post.metadata.effectiveDate} | ||
</p> | ||
<CustomMDX source={post.content} /> | ||
</> | ||
); | ||
} |
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,99 @@ | ||
import { cn, slugify } from '@/lib/utils'; | ||
import { buttonVariants } from '@/primitives/button'; | ||
import type { MDXRemoteProps } from 'next-mdx-remote/rsc'; | ||
import { MDXRemote } from 'next-mdx-remote/rsc'; | ||
import type { PropsWithChildren } from 'react'; | ||
import { createElement } from 'react'; | ||
|
||
function createHeading(level: 1 | 2 | 3 | 4 | 5 | 6, className: string) { | ||
const Element = ({ children }: PropsWithChildren) => { | ||
const slug = typeof children === 'string' ? slugify(children) : ''; | ||
|
||
return createElement( | ||
`h${String(level)}`, | ||
{ id: slug }, | ||
createElement( | ||
'a', | ||
{ | ||
href: `#${slug}`, | ||
key: `link-${slug}`, | ||
className: cn('font-medium', className), | ||
}, | ||
children, | ||
), | ||
); | ||
}; | ||
|
||
Element.displayName = `h${String(level)}`; | ||
|
||
return Element; | ||
} | ||
|
||
export const MDXComponents = { | ||
h1: createHeading(1, 'text-2xl md:text-3xl'), | ||
h2: createHeading( | ||
2, | ||
'text-xl md:text-2xl mb-3 md:mb-4 mt-3 md:mt-4 inline-block', | ||
), | ||
ul: ({ children, className, ...props }) => ( | ||
<ul | ||
{...props} | ||
className={cn( | ||
className, | ||
'mb-3 list-disc pl-6 text-sm md:mb-4 md:text-base', | ||
)} | ||
> | ||
{children} | ||
</ul> | ||
), | ||
li: ({ children, className, ...props }) => ( | ||
<li | ||
{...props} | ||
className={cn( | ||
className, | ||
'mb-1.5 text-sm leading-relaxed text-foreground-muted md:mb-2 md:text-base', | ||
)} | ||
> | ||
{children} | ||
</li> | ||
), | ||
strong: ({ children, className, ...props }) => ( | ||
<strong {...props} className={cn(className, 'font-medium text-foreground')}> | ||
{children} | ||
</strong> | ||
), | ||
a: ({ children, className, ...props }) => ( | ||
<a | ||
{...props} | ||
className={cn( | ||
buttonVariants({ variant: 'link' }), | ||
className, | ||
'p-0 pb-0.5 font-bold before:w-full', | ||
)} | ||
target="_blank" | ||
rel="noopener noreferrer" | ||
> | ||
{children} | ||
</a> | ||
), | ||
p: ({ children, className, ...props }) => ( | ||
<p | ||
{...props} | ||
className={cn( | ||
className, | ||
'mb-3 text-sm leading-relaxed text-foreground-muted md:mb-4 md:text-base', | ||
)} | ||
> | ||
{children} | ||
</p> | ||
), | ||
} satisfies MDXRemoteProps['components']; | ||
|
||
export function CustomMDX(props: MDXRemoteProps) { | ||
return ( | ||
<MDXRemote | ||
{...props} | ||
components={{ ...MDXComponents, ...(props.components ?? {}) }} | ||
/> | ||
); | ||
} |
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,28 @@ | ||
import { getBlogPosts } from '@/lib/mdx'; | ||
import { notFound } from 'next/navigation'; | ||
import { CustomMDX, MDXComponents } from '../../_components/custom-mdx'; | ||
|
||
export const dynamic = 'force-static'; | ||
|
||
interface Props { | ||
params: { | ||
slug: string; | ||
}; | ||
} | ||
|
||
export default async function Home({ params }: Props) { | ||
const posts = await getBlogPosts(); | ||
const post = posts.find((p) => p.slug === params.slug); | ||
|
||
if (!post) { | ||
notFound(); | ||
} | ||
|
||
return ( | ||
<main className="mx-auto max-w-prose py-12"> | ||
<MDXComponents.h1>{post.metadata.title}</MDXComponents.h1> | ||
<p>{post.metadata.summary}</p> | ||
<CustomMDX source={post.content} /> | ||
</main> | ||
); | ||
} |
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,7 @@ | ||
export default function BlogPage() { | ||
return ( | ||
<div> | ||
<h1>Blog Page</h1> | ||
</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,11 @@ | ||
--- | ||
title: Hello World | ||
publishedAt: Jun 7th, 2024 | ||
summary: A simple blog post to say hello to the world. | ||
--- | ||
|
||
This is a blog post content. | ||
|
||
```ts | ||
console.log('Hello World'); | ||
``` |
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 |
---|---|---|
@@ -1,4 +1,7 @@ | ||
# Privacy Policy | ||
--- | ||
title: Privacy Policy | ||
effectiveDate: Jun 6th, 2024 | ||
--- | ||
|
||
## 1. Introduction | ||
|
||
|
@@ -36,5 +39,3 @@ We may update this Privacy Policy from time to time. We will notify you of any c | |
## 8. Contact Us | ||
|
||
If you have any questions about this Privacy Policy, please contact us at [[email protected]](mailto:[email protected]). | ||
|
||
Effective Date: Jun 6th, 2024 |
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 |
---|---|---|
@@ -1,4 +1,7 @@ | ||
# Terms of Service | ||
--- | ||
title: Terms of Service | ||
effectiveDate: Jun 6th, 2024 | ||
--- | ||
|
||
## 1. Introduction | ||
|
||
|
@@ -31,5 +34,3 @@ We reserve the right to modify these Terms at any time. We will notify you of an | |
## 8. Contact Us | ||
|
||
If you have any questions about these Terms, please contact us at [[email protected]](mailto:[email protected]). | ||
|
||
Effective Date: Jun 6th, 2024 |
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,74 @@ | ||
import fs from 'node:fs/promises'; | ||
import path from 'path'; | ||
|
||
function parseFrontmatter<T extends Record<string, unknown>>( | ||
fileContent: string, | ||
) { | ||
const frontmatterRegex = /---\n([\s\S]*?)\n---/; | ||
const match = frontmatterRegex.exec(fileContent); | ||
if (!match) { | ||
throw new Error('No frontmatter found'); | ||
} | ||
const frontMatterBlock = match[1]; | ||
const content = fileContent.replace(frontmatterRegex, '').trim(); | ||
const frontMatterLines = frontMatterBlock?.trim().split('\n'); | ||
const metadata: Partial<T> = {}; | ||
|
||
frontMatterLines?.forEach((line) => { | ||
const [key, ...valueArr] = line.split(': '); | ||
let value = valueArr.join(': ').trim(); | ||
value = value.replace(/^['"](.*)['"]$/, '$1'); | ||
if (!key) { | ||
throw new Error('Invalid frontmatter'); | ||
} | ||
(metadata as Record<string, unknown>)[key.trim()] = value; | ||
}); | ||
|
||
return { metadata: metadata as T, content }; | ||
} | ||
|
||
async function getMDXData<T extends Record<string, unknown>>(dir: string) { | ||
const files = await fs.readdir(dir); | ||
const mdxFiles = files.filter( | ||
(file) => path.extname(file) === '.mdx' || path.extname(file) === '.md', | ||
); | ||
|
||
const mapped = await Promise.all( | ||
mdxFiles.map(async (file) => { | ||
const rawContent = await fs.readFile(path.join(dir, file), 'utf-8'); | ||
const { metadata, content } = parseFrontmatter<T>(rawContent); | ||
const slug = path.basename(file, path.extname(file)); | ||
return { | ||
metadata, | ||
slug, | ||
content, | ||
}; | ||
}), | ||
); | ||
|
||
return mapped; | ||
} | ||
|
||
interface BlogMetadata { | ||
[key: string]: unknown; | ||
title: string; | ||
publishedAt: string; | ||
summary: string; | ||
image?: string; | ||
} | ||
|
||
interface LegalMetadata { | ||
[key: string]: unknown; | ||
title: string; | ||
effectiveDate: string; | ||
} | ||
|
||
export function getBlogPosts() { | ||
return getMDXData<BlogMetadata>(path.join(process.cwd(), 'src/content/blog')); | ||
} | ||
|
||
export function getLegalDocs() { | ||
return getMDXData<LegalMetadata>( | ||
path.join(process.cwd(), 'src/content/legal'), | ||
); | ||
} |
Oops, something went wrong.