From 0156a17dc71804a374a4c4d413a7652cd2527f1e Mon Sep 17 00:00:00 2001 From: jyswee Date: Thu, 23 Jul 2026 22:15:24 +0000 Subject: [PATCH] Seed: developer-tools template (15 files) --- src/pages/Docs.tsx | 313 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 313 insertions(+) create mode 100644 src/pages/Docs.tsx diff --git a/src/pages/Docs.tsx b/src/pages/Docs.tsx new file mode 100644 index 0000000..65df56c --- /dev/null +++ b/src/pages/Docs.tsx @@ -0,0 +1,313 @@ +import { useState } from "react"; +import { Link } from "react-router-dom"; +import { Button } from "@/components/ui/button"; +import { Badge } from "@/components/ui/badge"; +import { Card, CardContent } from "@/components/ui/card"; +import { ScrollArea } from "@/components/ui/scroll-area"; +import { + BookOpen, Key, Server, AlertTriangle, Gauge, ChevronRight, + Terminal, Copy, CheckCircle2, ArrowRight +} from "lucide-react"; +import { toast } from "sonner"; +import Header from "@/components/Header"; +import Footer from "@/components/Footer"; + +const sidebarSections = [ + { id: "getting-started", label: "Getting Started", icon: BookOpen }, + { id: "authentication", label: "Authentication", icon: Key }, + { id: "endpoints", label: "Endpoints", icon: Server }, + { id: "errors", label: "Error Handling", icon: AlertTriangle }, + { id: "rate-limits", label: "Rate Limits", icon: Gauge }, +]; + +const endpoints = [ + { method: "GET", path: "/v1/projects", desc: "List all projects" }, + { method: "POST", path: "/v1/projects", desc: "Create a new project" }, + { method: "GET", path: "/v1/projects/:id", desc: "Get project by ID" }, + { method: "POST", path: "/v1/deploys", desc: "Create a deployment" }, + { method: "GET", path: "/v1/deploys/:id", desc: "Get deployment status" }, + { method: "DELETE", path: "/v1/projects/:id", desc: "Delete a project" }, +]; + +const errorCodes = [ + { code: "400", name: "Bad Request", desc: "The request body is malformed or missing required fields." }, + { code: "401", name: "Unauthorized", desc: "API key is missing or invalid." }, + { code: "403", name: "Forbidden", desc: "API key does not have the required scope." }, + { code: "404", name: "Not Found", desc: "The requested resource does not exist." }, + { code: "429", name: "Rate Limited", desc: "You have exceeded your rate limit. Retry after the indicated time." }, + { code: "500", name: "Internal Error", desc: "Something went wrong on our end. Contact support." }, +]; + +function CodeBlock({ code, language }: { code: string; language?: string }) { + const [copied, setCopied] = useState(false); + + const handleCopy = () => { + navigator.clipboard.writeText(code); + setCopied(true); + toast.success("Copied to clipboard"); + setTimeout(() => setCopied(false), 2000); + }; + + return ( +
+ {language && ( +
+ {language} + +
+ )} +
+        {code}
+      
+
+ ); +} + +export default function DocsPage() { + const [activeSection, setActiveSection] = useState("getting-started"); + + const scrollTo = (id: string) => { + setActiveSection(id); + document.getElementById(id)?.scrollIntoView({ behavior: "smooth" }); + }; + + return ( +
+
+ +
+
+ {/* Sidebar */} + + + {/* Main Content */} +
+ {/* Mobile nav */} +
+ {sidebarSections.map((s) => ( + + ))} +
+ + {/* Getting Started */} +
+ Getting Started +

Welcome to DevStack Docs

+

+ Get up and running with the DevStack API in minutes. This guide covers installation, authentication, and your first API call. +

+ +

1. Install the SDK

+ + +

2. Initialize the client

+ + +

3. Make your first API call

+ +
+ + {/* Authentication */} +
+ Authentication +

Authentication

+

+ All API requests require a valid API key. Include your key in the Authorization header. +

+ + + + +
+

Keep your API keys secure

+

Never expose your secret API key in client-side code. Use environment variables and server-side requests only.

+
+
+
+
+ + {/* Endpoints */} +
+ API Reference +

Endpoints

+

+ Base URL: https://api.devstack.io +

+
+ {endpoints.map((ep) => ( +
+ + {ep.method} + + {ep.path} + {ep.desc} +
+ ))} +
+ +

Example Request

+ + +

Example Response

+ +
+ + {/* Errors */} +
+ Errors +

Error Handling

+

+ The API uses standard HTTP status codes to indicate success or failure. +

+
+ {errorCodes.map((e) => ( +
+ + {e.code} + +
+

{e.name}

+

{e.desc}

+
+
+ ))} +
+
+ + {/* Rate Limits */} +
+ Rate Limits +

Rate Limits

+

+ Rate limits vary by plan. Exceeding limits returns a 429 response with a Retry-After header. +

+
+ + +

100

+

req/min (Free)

+
+
+ + +

1,000

+

req/min (Pro)

+
+
+ + +

Custom

+

req/min (Enterprise)

+
+
+
+ +
+
+
+
+ +
+ ); +}