mirror of
https://github.com/jordienr/zenblog.git
synced 2026-09-28 01:56:07 -04:00
wip
This commit is contained in:
@@ -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>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
}
|
||||
@@ -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",
|
||||
},
|
||||
|
||||
@@ -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 />
|
||||
|
||||
Generated
+28
-14
@@ -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": {
|
||||
|
||||
Reference in New Issue
Block a user