Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
114 changes: 114 additions & 0 deletions frontend/app/docs/api-reference/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
import { apiSections } from "../data";
import CodeBlock from "../components/CodeBlock";

export default function ApiReferencePage() {
return (
<div className="animate-fade-in">
<h1 className="text-3xl font-bold tracking-tight mb-4">API Reference</h1>
<p className="text-lg text-muted-fg mb-8 max-w-2xl">
Complete reference for all Stellar Suite commands, their parameters, return types,
and usage examples.
</p>

<div className="mb-8 p-4 rounded-lg bg-muted border border-border">
<p className="text-sm font-medium mb-2">On this page</p>
<ul className="flex flex-wrap gap-2">
{apiSections.map((section) => (
<li key={section.slug}>
<a
href={`#${section.slug}`}
className="inline-block px-3 py-1.5 text-xs font-medium rounded-md bg-background border border-border text-muted-fg hover:text-accent hover:border-accent/50 transition-colors"
>
{section.title}
</a>
</li>
))}
</ul>
</div>

{apiSections.map((section) => (
<section key={section.slug} className="mb-16">
<h2 id={section.slug} className="text-2xl font-semibold mb-2">
{section.title}
</h2>
<p className="text-muted-fg mb-6">{section.description}</p>

{section.methods.map((method) => (
<div
key={method.name}
className="mb-8 p-6 rounded-xl border border-border hover:border-accent/30 transition-colors"
>
<div className="flex items-start justify-between gap-4 mb-3">
<h3 className="text-lg font-semibold font-mono text-accent">
{method.name}
</h3>
</div>
<p className="text-sm text-muted-fg mb-4">{method.description}</p>

<div className="mb-4">
<p className="text-xs font-medium text-muted-fg uppercase tracking-wider mb-2">
Signature
</p>
<div className="px-4 py-2 rounded-lg bg-code-bg text-code-text text-sm font-mono overflow-x-auto">
{method.signature}
</div>
</div>

{method.parameters.length > 0 && (
<div className="mb-4">
<p className="text-xs font-medium text-muted-fg uppercase tracking-wider mb-2">
Parameters
</p>
<div className="overflow-x-auto">
<table className="w-full text-sm border-collapse">
<thead>
<tr className="border-b border-border">
<th className="text-left py-2 px-3 font-medium text-xs">Name</th>
<th className="text-left py-2 px-3 font-medium text-xs">Type</th>
<th className="text-left py-2 px-3 font-medium text-xs">Required</th>
<th className="text-left py-2 px-3 font-medium text-xs">Description</th>
</tr>
</thead>
<tbody>
{method.parameters.map((param) => (
<tr key={param.name} className="border-b border-border">
<td className="py-2 px-3 font-mono text-xs text-accent">{param.name}</td>
<td className="py-2 px-3 font-mono text-xs">{param.type}</td>
<td className="py-2 px-3 text-xs">
{param.required ? (
<span className="text-error font-medium">Yes</span>
) : (
<span className="text-muted-fg">No</span>
)}
</td>
<td className="py-2 px-3 text-xs text-muted-fg">{param.description}</td>
</tr>
))}
</tbody>
</table>
</div>
</div>
)}

<div className="mb-4">
<p className="text-xs font-medium text-muted-fg uppercase tracking-wider mb-2">
Returns
</p>
<div className="px-4 py-2 rounded-lg bg-muted text-sm font-mono">
{method.returnType}
</div>
</div>

<div>
<p className="text-xs font-medium text-muted-fg uppercase tracking-wider mb-2">
Example
</p>
<CodeBlock code={method.example} language="typescript" />
</div>
</div>
))}
</section>
))}
</div>
);
}
55 changes: 55 additions & 0 deletions frontend/app/docs/components/CodeBlock.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
"use client";

import { useState } from "react";
import { Copy, Check } from "lucide-react";

interface CodeBlockProps {
code: string;
language?: string;
title?: string;
showLineNumbers?: boolean;
}

export default function CodeBlock({ code, language = "typescript", title, showLineNumbers = false }: CodeBlockProps) {
const [copied, setCopied] = useState(false);

const handleCopy = async () => {
await navigator.clipboard.writeText(code);
setCopied(true);
setTimeout(() => setCopied(false), 2000);
};

const lines = code.split("\n");

return (
<div className="rounded-xl border border-border overflow-hidden my-4">
{title && (
<div className="flex items-center justify-between px-4 py-2 bg-muted border-b border-border">
<span className="text-xs font-medium text-muted-fg">{title}</span>
<span className="text-xs text-muted-fg font-mono">{language}</span>
</div>
)}
<div className="relative group">
<button
onClick={handleCopy}
className="absolute top-3 right-3 p-2 rounded-lg bg-muted/50 text-muted-fg hover:text-foreground hover:bg-muted opacity-0 group-hover:opacity-100 transition-all"
aria-label={copied ? "Copied" : "Copy code"}
>
{copied ? <Check size={16} className="text-green-500" /> : <Copy size={16} />}
</button>
<pre className="overflow-x-auto p-4 bg-code-bg text-code-text text-sm font-mono leading-relaxed">
<code>
{lines.map((line, i) => (
<div key={i} className="flex">
{showLineNumbers && (
<span className="select-none pr-4 text-right min-w-10 text-muted-fg/40">{i + 1}</span>
)}
<span>{line}</span>
</div>
))}
</code>
</pre>
</div>
</div>
);
}
190 changes: 190 additions & 0 deletions frontend/app/docs/components/CodePlayground.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
"use client";

import { useState } from "react";
import { Play, RotateCcw, Copy, Check } from "lucide-react";

const EXAMPLE_TEMPLATES: Record<string, string> = {
"Deploy Contract": `// Deploy a contract to testnet
const result = await stellarSuite.deployContract({
network: 'testnet',
source: 'dev',
});

console.log('Contract ID:', result.contractId);
console.log('TX Hash:', result.txHash);`,

"Simulate Transaction": `// Simulate a token transfer
const result = await stellarSuite.simulateTransaction({
contractId: 'CABC...XYZ',
function: 'transfer',
args: [
'GABC...sender',
'GXYZ...receiver',
BigInt(1000000)
]
});

console.log('Cost:', result.cost);
console.log('Return:', result.result);`,

"Check RPC Health": `// Check health of all configured endpoints
const statuses = await stellarSuite.checkRpcHealth();

statuses.forEach(status => {
console.log(
status.name + ':',
status.healthy ? 'OK' : 'DOWN',
'(' + status.latencyMs + 'ms)'
);
});`,

"Build Contract": `// Build the current contract with release mode
await stellarSuite.buildContract({
release: true,
target: 'wasm32-unknown-unknown'
});

console.log('Build completed successfully!');`,
};

export default function CodePlayground() {
const [code, setCode] = useState(EXAMPLE_TEMPLATES["Deploy Contract"]);
const [output, setOutput] = useState("");
const [isRunning, setIsRunning] = useState(false);
const [copied, setCopied] = useState(false);
const [activeTemplate, setActiveTemplate] = useState("Deploy Contract");

const handleRun = () => {
setIsRunning(true);
setOutput("");

setTimeout(() => {
const lines: string[] = [];
const codeLines = code.split("\n");
codeLines.forEach((line) => {
const logMatch = line.match(/console\.log\((.+)\)/);
if (logMatch) {
const content = logMatch[1]
.replace(/['"`]/g, "")
.replace(/,\s*/g, " ")
.replace(/result\.\w+/g, "<simulated_value>")
.replace(/status\.\w+/g, "<simulated_value>");
lines.push("> " + content);
}
});

if (lines.length === 0) {
lines.push("> Execution completed successfully.");
}

lines.push("");
lines.push("--- Simulation complete (not a real execution) ---");

setOutput(lines.join("\n"));
setIsRunning(false);
}, 1200);
};

const handleReset = () => {
setCode(EXAMPLE_TEMPLATES[activeTemplate]);
setOutput("");
};

const handleCopy = async () => {
await navigator.clipboard.writeText(code);
setCopied(true);
setTimeout(() => setCopied(false), 2000);
};

const handleTemplateChange = (name: string) => {
setActiveTemplate(name);
setCode(EXAMPLE_TEMPLATES[name]);
setOutput("");
};

return (
<div className="rounded-xl border border-border overflow-hidden">
<div className="flex items-center justify-between px-4 py-3 bg-muted border-b border-border">
<div className="flex items-center gap-2 overflow-x-auto">
{Object.keys(EXAMPLE_TEMPLATES).map((name) => (
<button
key={name}
onClick={() => handleTemplateChange(name)}
className={`px-3 py-1.5 text-xs font-medium rounded-md whitespace-nowrap transition-colors ${
activeTemplate === name
? "bg-accent text-white"
: "text-muted-fg hover:text-foreground hover:bg-background"
}`}
>
{name}
</button>
))}
</div>
</div>

<div className="grid grid-cols-1 lg:grid-cols-2">
<div className="relative border-b lg:border-b-0 lg:border-r border-border">
<div className="flex items-center justify-between px-4 py-2 bg-code-bg border-b border-border">
<span className="text-xs text-code-text/60 font-mono">editor.ts</span>
<div className="flex items-center gap-1">
<button
onClick={handleCopy}
className="p-1.5 rounded-md text-code-text/60 hover:text-code-text transition-colors"
aria-label={copied ? "Copied" : "Copy code"}
>
{copied ? <Check size={14} className="text-green-400" /> : <Copy size={14} />}
</button>
<button
onClick={handleReset}
className="p-1.5 rounded-md text-code-text/60 hover:text-code-text transition-colors"
aria-label="Reset code"
>
<RotateCcw size={14} />
</button>
</div>
</div>
<textarea
value={code}
onChange={(e) => setCode(e.target.value)}
className="w-full h-64 p-4 bg-code-bg text-code-text text-sm font-mono leading-relaxed resize-none outline-none"
spellCheck={false}
aria-label="Code editor"
/>
</div>

<div className="flex flex-col">
<div className="flex items-center justify-between px-4 py-2 bg-code-bg border-b border-border">
<span className="text-xs text-code-text/60 font-mono">output</span>
<button
onClick={handleRun}
disabled={isRunning}
className={`flex items-center gap-1.5 px-3 py-1.5 rounded-md text-xs font-medium transition-colors ${
isRunning
? "bg-accent/50 text-white/70 cursor-not-allowed"
: "bg-accent text-white hover:bg-accent-dark"
}`}
aria-label="Run code"
>
<Play size={12} />
{isRunning ? "Running..." : "Run"}
</button>
</div>
<div className="h-64 p-4 bg-code-bg overflow-auto">
{isRunning ? (
<div className="flex items-center gap-2 text-code-text/60 text-sm font-mono">
<div className="w-2 h-2 bg-accent rounded-full animate-pulse" />
Executing...
</div>
) : output ? (
<pre className="text-sm font-mono text-code-text leading-relaxed whitespace-pre-wrap">{output}</pre>
) : (
<div className="text-sm font-mono text-code-text/40">
Click &quot;Run&quot; to execute the code...
</div>
)}
</div>
</div>
</div>
</div>
);
}
Loading
Loading