Skip to content

Commit 9c9d07d

Browse files
committed
initial cookbook commit
1 parent 993bb02 commit 9c9d07d

29 files changed

+917
-200
lines changed

app/(docs)/layout.client.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ export function SidebarBanner(): JSX.Element {
9999

100100
return (
101101
<Link key={currentMode.param} href={`/${currentMode.param}`}>
102-
<div className="group flex flex-row items-center gap-2 rounded-lg px-2 mb-3 transition-colors">
102+
<div className="group flex flex-row items-center gap-2 rounded-lg px-2 mb-4 transition-colors">
103103
<ChevronLeft className="text-muted-foreground size-4 shrink-0 rounded-md group-hover:text-primary" />
104104
<div>
105105
<p className="text-muted-foreground group-hover:text-primary">Back</p>

app/(docs)/layout.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { Body, NavChildren, SidebarBanner } from "./layout.client";
77
import { Statuspage } from "statuspage.io";
88

99
const statuspage = new Statuspage("3111l89394q4");
10-
console.log({ status: await statuspage.api.getStatus() });
10+
// console.log({ status: await statuspage.api.getStatus() });
1111

1212
export const layoutOptions: Omit<DocsLayoutProps, "children"> = {
1313
tree: utils.pageTree,

app/api/run/route.ts

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { initSimnet } from "@hirosystems/clarinet-sdk-browser";
2+
import { Cl } from "@stacks/transactions";
3+
import { NextResponse } from "next/server";
4+
5+
export async function POST(request: Request) {
6+
try {
7+
const { code } = await request.json();
8+
9+
const simnet = await initSimnet();
10+
await simnet.initEmtpySession();
11+
simnet.setEpoch("3.0");
12+
13+
const result = simnet.runSnippet(code);
14+
const deserializedResult = Cl.deserialize(result);
15+
const prettyResult = Cl.prettyPrint(deserializedResult, 2);
16+
17+
return NextResponse.json({ result: prettyResult });
18+
} catch (error) {
19+
return NextResponse.json(
20+
{ error: error instanceof Error ? error.message : String(error) },
21+
{ status: 500 }
22+
);
23+
}
24+
}

app/cookbook/[id]/page.tsx

+101
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
import { Code } from "@/components/docskit/code";
2+
import { recipes } from "@/data/recipes";
3+
import { ArrowUpRight, Play, TestTube } from "lucide-react";
4+
import { Button } from "@/components/ui/button";
5+
import { Badge } from "@/components/ui/badge";
6+
import { HoverProvider } from "@/context/hover";
7+
import { HoverLink } from "@/components/docskit/annotations/hover";
8+
import Link from "next/link";
9+
import { Terminal } from "@/components/docskit/terminal";
10+
import { InlineCode } from "@/components/docskit/inline-code";
11+
import { Github } from "@/components/ui/icon";
12+
import { WithNotes } from "@/components/docskit/notes";
13+
import { SnippetResult } from "../components/snippet-result";
14+
15+
interface Param {
16+
id: string;
17+
}
18+
19+
export const dynamicParams = false;
20+
21+
export default async function Page({
22+
params,
23+
}: {
24+
params: Param;
25+
}): Promise<JSX.Element> {
26+
const { id } = params;
27+
const recipe = recipes.find((r) => r.id === id);
28+
29+
if (!recipe) {
30+
return <div>Recipe not found</div>;
31+
}
32+
33+
// Dynamically import MDX content based on recipe id
34+
const Content = await import(`@/content/_recipes/${id}.mdx`).catch(() => {
35+
console.error(`Failed to load MDX content for recipe: ${id}`);
36+
return { default: () => <div>Content not found</div> };
37+
});
38+
39+
const snippetCodeResult = (result: string) => {
40+
<Code
41+
codeblocks={[
42+
{
43+
lang: "bash",
44+
value: result,
45+
meta: `-nw`,
46+
},
47+
]}
48+
/>;
49+
};
50+
51+
return (
52+
<HoverProvider>
53+
<div className="min-h-screen">
54+
<div className="px-4 py-8">
55+
<div className="grid grid-cols-12 gap-12">
56+
<div className="col-span-6">
57+
<div className="space-y-3">
58+
<div className="flex flex-wrap gap-2">
59+
{recipe.tags.map((tag) => (
60+
<Badge key={tag} variant="secondary">
61+
{tag.toUpperCase()}
62+
</Badge>
63+
))}
64+
</div>
65+
<div className="prose max-w-none">
66+
<Content.default
67+
components={{
68+
HoverLink,
69+
Terminal,
70+
Code,
71+
InlineCode,
72+
WithNotes,
73+
}}
74+
/>
75+
</div>
76+
</div>
77+
</div>
78+
79+
{/* Sticky sidebar */}
80+
<div className="col-span-6">
81+
<div className="sticky top-20 space-y-4">
82+
<div className="recipe group relative w-full bg-card overflow-hidden">
83+
<Code
84+
codeblocks={[
85+
{
86+
lang: recipe.type,
87+
value: recipe.files[0].content,
88+
meta: `${recipe.files[0].name} -cnw`, // filename + flags
89+
},
90+
]}
91+
/>
92+
</div>
93+
<SnippetResult code={recipe.files[0].content as string} />
94+
</div>
95+
</div>
96+
</div>
97+
</div>
98+
</div>
99+
</HoverProvider>
100+
);
101+
}
+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { Code } from "@/components/docskit/code";
2+
3+
interface CodeResultProps {
4+
result: string;
5+
}
6+
7+
export function CodeResult({ result }: CodeResultProps) {
8+
return (
9+
<Code
10+
codeblocks={[
11+
{
12+
lang: "bash",
13+
value: result,
14+
meta: `-nw`,
15+
},
16+
]}
17+
/>
18+
);
19+
}

0 commit comments

Comments
 (0)