This commit is contained in:
Jordi Enric
2024-10-23 01:55:45 +02:00
parent 70f3b09447
commit c5c7f29a39
8 changed files with 180 additions and 29 deletions
+72 -2
View File
@@ -1,11 +1,81 @@
import { CodeBlockComponent } from "@/components/code-block";
export default function GettingStarted() {
return (
<div className="prose mt-8">
<h2 className="text-xl font-medium">Getting started</h2>
<div className="prose prose-headings:font-medium mt-8">
<h1>Getting started</h1>
<p>
Welcome to the Zenblog documentation. To get started, you need to create
a blog in the Zenblog dashboard and grab your API key.
</p>
<h2>1. Install Zenblog</h2>
<CodeBlockComponent
filename="Terminal"
language="bash"
highlightedLines={[2]}
>
{`npm install zenblog`}
</CodeBlockComponent>
<h2>2. Initialize Zenblog</h2>
<p>Initialize Zenblog with your API key.</p>
<CodeBlockComponent
filename="index.ts"
language="typescript"
highlightedLines={[]}
>
{`import { createClient } from "zenblog";
const zenblog = createClient({ apiKey: "your-api-key" });`}
</CodeBlockComponent>
<h2>3. Fetch your posts</h2>
<p>Fetch your posts from the Zenblog API.</p>
<CodeBlockComponent
filename="index.ts"
language="typescript"
highlightedLines={[5]}
>
{`import { createClient } from "zenblog";
const zenblog = createClient({ apiKey: "your-api-key" });
const posts = await zenblog.posts.list();`}
</CodeBlockComponent>
<h2>4. Render your posts</h2>
<p>Render your posts in your app.</p>
<CodeBlockComponent
filename="index.ts"
language="typescript"
highlightedLines={[4]}
>
{`<div>{posts.map((post) => (
<a href={"/blog/{post.slug}"} key={post.id}>{post.title}</a>
))}</div>`}
</CodeBlockComponent>
<h2>5. Fetch a single post with content</h2>
<CodeBlockComponent
filename="index.ts"
language="typescript"
highlightedLines={[5]}
>
{`import { createClient } from "zenblog";
const zenblog = createClient({ apiKey: "your-api-key" });
const post = await zenblog.posts.get({ slug: "my-first-post" });`}
</CodeBlockComponent>
<h2>6. Render your post</h2>
<p>Render your post in your app.</p>
<CodeBlockComponent filename="index.ts" language="typescript">
{`<div>{post.title}</div>
<div>{post.content}</div>
<div>{post.publishedAt}</div>
<div dangerouslySetInnerHTML={{ __html: post.html_content }} />`}
</CodeBlockComponent>
</div>
);
}
+6 -3
View File
@@ -40,8 +40,8 @@ export default function DocsLayout({
</div>
</div>
</nav>
<div className="mx-auto flex h-screen w-full max-w-7xl">
<aside className="h-full min-w-[240px] flex-col overflow-y-auto px-4">
<div className="mx-auto flex w-full max-w-7xl">
<aside className="sticky top-14 h-full min-w-[240px] flex-col overflow-y-auto px-4">
<SidebarTitle>Docs</SidebarTitle>
<SidebarLink href="/docs/getting-started">
Getting Started
@@ -55,10 +55,13 @@ export default function DocsLayout({
))}
</aside>
<main className="h-full max-w-3xl flex-1 space-y-4 overflow-y-auto pb-16">
<main className="h-full max-w-3xl flex-1 space-y-4 pb-16">
{children}
</main>
</div>
<footer className="border-t p-8 text-center text-sm text-slate-400">
<p>Now go ship something cool</p>
</footer>
</div>
);
}
+1 -1
View File
@@ -30,7 +30,7 @@
"@radix-ui/react-label": "^2.0.2",
"@radix-ui/react-popover": "^1.0.5",
"@radix-ui/react-select": "^2.0.0",
"@radix-ui/react-slot": "^1.0.2",
"@radix-ui/react-slot": "^1.1.0",
"@radix-ui/react-switch": "^1.1.0",
"@radix-ui/react-tabs": "^1.0.4",
"@radix-ui/react-toggle": "^1.0.3",
+2
View File
@@ -1,3 +1,5 @@
"use client";
import React, { PropsWithChildren } from "react";
import SyntaxHighlighter from "react-syntax-highlighter";
import { atomOneDark } from "react-syntax-highlighter/dist/esm/styles/hljs";
+70
View File
@@ -0,0 +1,70 @@
"use client";
import React, { useState } from "react";
import { Check, Copy } from "lucide-react";
interface CodeBlockProps {
language: string;
filename?: string;
highlightedLines?: number[];
children: string;
}
export function CodeBlockComponent({
language,
filename,
highlightedLines = [],
children,
}: CodeBlockProps) {
const [isCopied, setIsCopied] = useState(false);
const copyToClipboard = async () => {
await navigator.clipboard.writeText(children);
setIsCopied(true);
setTimeout(() => setIsCopied(false), 2000);
};
const lines = children.split("\n");
return (
<div className="relative rounded-lg border border-slate-700 bg-slate-800">
{filename && (
<div className="flex items-center justify-between border-b border-slate-700 px-4 py-2">
<span className="text-sm font-medium text-slate-100">{filename}</span>
<button
onClick={copyToClipboard}
className="text-slate-300 hover:text-slate-50"
>
{isCopied ? (
<Check className="h-4 w-4 text-green-500" />
) : (
<Copy className="h-4 w-4" />
)}
<span className="sr-only">Copy code</span>
</button>
</div>
)}
<div className="overflow-x-auto">
<pre className="rounded-none bg-transparent p-0 text-white">
<code className={`language-${language} block`}>
{lines.map((line, index) => (
<span
key={index}
className={`block rounded-none border-l-4 border-transparent ${
highlightedLines.includes(index + 1)
? "border-green-500 bg-green-500/10 text-green-300"
: ""
}`}
>
<span className="inline-block w-8 select-none pr-2 text-right text-slate-400">
{language === "bash" ? "$" : index + 1}
</span>
<span className="pl-2">{line}</span>
</span>
))}
</code>
</pre>
</div>
</div>
);
}
+1 -2
View File
@@ -18,8 +18,7 @@ const buttonVariants = cva(
"border-transparent ring-zinc-200 bg-white hover:bg-zinc-100 hover:text-zinc-900 text-zinc-600",
secondary:
"bg-zinc-100 hover:bg-zinc-100/70 text-zinc-700 hover:text-zinc-800",
ghost:
"hover:bg-zinc-100 hover:text-zinc-900 dark:hover:bg-zinc-800 dark:hover:text-zinc-50 text-zinc-600",
ghost: "hover:text-zinc-900 text-zinc-600",
link: "text-zinc-800 underline-offset-4 hover:underline dark:text-zinc-50",
white: "bg-white text-zinc-900 hover:text-zinc-900",
},
-7
View File
@@ -176,19 +176,12 @@ export default function AppLayout({
<div className="flex items-center gap-1 pr-2">
<Link
title="API docs"
target="_blank"
className="rounded-full px-3 py-4 text-sm font-medium text-slate-600 hover:text-orange-600"
href="/docs"
>
Docs
</Link>
<Feedback />
{/* <Link
className="rounded-full px-3 py-4 text-sm font-medium text-slate-600 hover:text-orange-600"
href="/docs/getting-started"
>
Docs
</Link> */}
<Notifications />
<span className="ml-2">
<UserButton />
+28 -14
View File
@@ -587,7 +587,7 @@
"@radix-ui/react-label": "^2.0.2",
"@radix-ui/react-popover": "^1.0.5",
"@radix-ui/react-select": "^2.0.0",
"@radix-ui/react-slot": "^1.0.2",
"@radix-ui/react-slot": "^1.1.0",
"@radix-ui/react-switch": "^1.1.0",
"@radix-ui/react-tabs": "^1.0.4",
"@radix-ui/react-toggle": "^1.0.3",
@@ -1019,6 +1019,24 @@
}
}
},
"apps/web/node_modules/@radix-ui/react-dialog/node_modules/@radix-ui/react-slot": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.0.2.tgz",
"integrity": "sha512-YeTpuq4deV+6DusvVUW4ivBgnkHwECUu0BiN43L5UCDFgdhsRUWAghhTF5MbvNTPzmiFOx90asDSUjWuCNapwg==",
"dependencies": {
"@babel/runtime": "^7.13.10",
"@radix-ui/react-compose-refs": "1.0.1"
},
"peerDependencies": {
"@types/react": "*",
"react": "^16.8 || ^17.0 || ^18.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
}
},
"apps/web/node_modules/@radix-ui/react-dialog/node_modules/@radix-ui/react-use-controllable-state": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.0.1.tgz",
@@ -1055,16 +1073,15 @@
}
},
"apps/web/node_modules/@radix-ui/react-slot": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.0.2.tgz",
"integrity": "sha512-YeTpuq4deV+6DusvVUW4ivBgnkHwECUu0BiN43L5UCDFgdhsRUWAghhTF5MbvNTPzmiFOx90asDSUjWuCNapwg==",
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.1.0.tgz",
"integrity": "sha512-FUCf5XMfmW4dtYl69pdS4DbxKy8nj4M7SafBgPllysxmdachynNflAdp/gCsnYWNDnge6tI9onzMp5ARYc1KNw==",
"dependencies": {
"@babel/runtime": "^7.13.10",
"@radix-ui/react-compose-refs": "1.0.1"
"@radix-ui/react-compose-refs": "1.1.0"
},
"peerDependencies": {
"@types/react": "*",
"react": "^16.8 || ^17.0 || ^18.0"
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
@@ -1073,15 +1090,12 @@
}
},
"apps/web/node_modules/@radix-ui/react-slot/node_modules/@radix-ui/react-compose-refs": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.0.1.tgz",
"integrity": "sha512-fDSBgd44FKHa1FRMU59qBMPFcl2PZE+2nmqunj+BWFyYYjnhIDWL2ItDs3rrbJDQOtzt5nIebLCQc4QRfz6LJw==",
"dependencies": {
"@babel/runtime": "^7.13.10"
},
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.0.tgz",
"integrity": "sha512-b4inOtiaOnYf9KWyO3jAeeCG6FeyfY6ldiEPanbUjWd+xIk5wZeHa8yVwmrJ2vderhu/BQvzCrJI0lHd+wIiqw==",
"peerDependencies": {
"@types/react": "*",
"react": "^16.8 || ^17.0 || ^18.0"
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {