diff --git a/apps/landing/src/app/docs/layout.tsx b/apps/landing/src/app/docs/layout.tsx new file mode 100644 index 0000000..7c810cb --- /dev/null +++ b/apps/landing/src/app/docs/layout.tsx @@ -0,0 +1,32 @@ +import { ReactNode } from 'react'; + +/** + * Root Documentation Layout + * + * Simple wrapper for all documentation pages. + * Each variant handles its own layout/navigation. + * + * Features: + * - Consistent background gradient matching landing page + * - No navigation/sidebars at this level + * - Children render their own layouts + */ + +interface DocsRootLayoutProps { + children: ReactNode; +} + +export default function DocsRootLayout({ children }: DocsRootLayoutProps) { + return ( +
+ {/* Animated gradient background (matching landing page) */} +
+
+
+
+ + {/* Content */} +
{children}
+
+ ); +} diff --git a/apps/landing/src/app/docs/page.tsx b/apps/landing/src/app/docs/page.tsx new file mode 100644 index 0000000..34fdbce --- /dev/null +++ b/apps/landing/src/app/docs/page.tsx @@ -0,0 +1,269 @@ +'use client'; + +/** + * Documentation Variants Comparison Page + * + * Landing page that introduces users to the three documentation design variants. + * Helps users choose the variant that best suits their preferences. + * + * Three Variants: + * - Variant A: Clean & Minimal (Vercel-inspired) + * - Variant B: Dense & Information-Rich (Next.js docs-inspired) + * - Variant C: Modern & Visual (Shopify-inspired) + * + * Design: + * - Hero section explaining the concept + * - Three large gradient-bordered cards + * - Visual preview descriptions + * - Clear CTAs to each variant + */ + +export default function DocsIndexPage() { + return ( +
+ {/* Header with back to home */} +
+
+ + + + + Back to Home + +
Choose Your Documentation Style
+
+
+ +
+ {/* Hero Section */} +
+
+ πŸ“š + DOCUMENTATION +
+

+ Choose Your Documentation Style +

+

+ We've created three distinct documentation designs. Pick the style that works best for + youβ€”same content, different presentation. +

+
+ + {/* Variant Cards */} +
+ {/* Variant A: Clean & Minimal */} + +
✨
+

+ Variant A +

+

Clean & Minimal

+

+ Vercel-inspired spacious layout with generous whitespace, focused reading experience, + and subtle visual hierarchy. +

+ +
+
+ + + + Wide margins, comfortable reading +
+
+ + + + Subtle borders and minimal design +
+
+ + + + Focus on content clarity +
+
+ +
+ Explore Variant A + + + +
+
+ + {/* Variant B: Dense & Information-Rich */} + +
πŸ“Š
+

+ Variant B +

+

Dense & Information-Rich

+

+ Next.js docs-inspired compact layout with section numbers, nested navigation, and + maximum information density per screen. +

+ +
+
+ + + + Compact spacing, more content visible +
+
+ + + + Section numbers (1., 2.1, etc.) +
+
+ + + + Hierarchical nested tree navigation +
+
+ +
+ Explore Variant B + + + +
+
+ + {/* Variant C: Modern & Visual */} + +
🎨
+

+ Variant C +

+

Modern & Visual

+

+ Shopify-inspired colorful card-based design with large emoji icons, gradient borders, + and playful engaging visual style. +

+ +
+
+ + + + Colorful gradient borders everywhere +
+
+ + + + Large emoji icons and visual elements +
+
+ + + + Fun, engaging, playful design +
+
+ +
+ Explore Variant C + + + +
+
+
+ + {/* Feature Comparison */} +
+

+ All Variants Include +

+
+
+
πŸ“š
+

Same Content

+

+ Identical API documentation, just styled differently +

+
+
+
⚑
+

Interactive Widgets

+

+ Live API testing with your own keys +

+
+
+
πŸ”
+

Navigation & Search

+

+ Sidebar, TOC, and breadcrumb navigation +

+
+
+
+ + {/* Footer CTA */} +
+

+ Not sure which to choose? Try all three and see which feels right! +

+

+ Each variant links to the same API contentβ€”pick your preferred reading experience. +

+
+
+
+ ); +} diff --git a/apps/landing/src/app/docs/variant-a/api/text-to-image/page.tsx b/apps/landing/src/app/docs/variant-a/api/text-to-image/page.tsx new file mode 100644 index 0000000..61e796c --- /dev/null +++ b/apps/landing/src/app/docs/variant-a/api/text-to-image/page.tsx @@ -0,0 +1,299 @@ +'use client'; + +/** + * API Reference: Text to Image - Variant A: Clean & Minimal + * + * This page demonstrates the interactive API reference design with live code execution. + * Features placeholder content and a fully functional API widget. + */ + +import { DocsLayoutA } from '@/components/docs/variant-a/DocsLayoutA'; +import { DocsSidebarA } from '@/components/docs/variant-a/DocsSidebarA'; +import { DocsTOCA } from '@/components/docs/variant-a/DocsTOCA'; +import { Breadcrumb } from '@/components/docs/shared/Breadcrumb'; +import { InteractiveAPIWidgetA } from '@/components/docs/variant-a/InteractiveAPIWidgetA'; + +const tocItems = [ + { id: 'overview', text: 'Overview', level: 2 }, + { id: 'endpoint', text: 'Endpoint', level: 2 }, + { id: 'request', text: 'Request', level: 2 }, + { id: 'headers', text: 'Headers', level: 3 }, + { id: 'body', text: 'Body Parameters', level: 3 }, + { id: 'response', text: 'Response', level: 2 }, + { id: 'examples', text: 'Examples', level: 2 }, + { id: 'errors', text: 'Error Codes', level: 2 }, +]; + +export default function TextToImageAPIPageA() { + return ( + } + toc={} + > + + + {/* Hero Section */} +
+
+ POST +
+

Text to Image

+

+ Generate high-quality images from text prompts using AI-powered models. +

+
+ + {/* Overview */} +
+

Overview

+

+ The Text to Image endpoint generates images from text descriptions. It supports various + aspect ratios, automatic prompt enhancement, and optional reference images for style + matching. +

+
+

+ Tip: Enable autoEnhance for better results. The AI will optimize your + prompt for higher quality outputs while preserving your intent. +

+
+
+ + {/* Endpoint */} +
+

Endpoint

+
+ POST + https://api.banatie.com/api/text-to-image +
+
+ + {/* Request */} +
+

Request

+ +
+

Headers

+
+ + + + + + + + + + + + + + + + + + + + +
HeaderValueRequired
X-API-KeyYour project API key + Yes +
Content-Typeapplication/json + Yes +
+
+
+ +
+

Body Parameters

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParameterTypeDescriptionRequired
promptstringText description of the image to generate + Yes +
filenamestringName for the generated image file + Yes +
aspectRatiostring + Image aspect ratio. Options: 1:1, 3:4, 4:3, 9:16, 16:9, 21:9 + + No +
autoEnhancebooleanEnable automatic prompt enhancement (default: true) + No +
enhancementOptionsobjectTemplate and enhancement settings + No +
+
+
+
+ + {/* Interactive API Widget */} + + + {/* Response */} +
+

Response

+

+ Returns a JSON object with the generated image URL and metadata. +

+ +
+
+            {`{
+  "success": true,
+  "data": {
+    "url": "https://cdn.banatie.com/org/project/generated/2025-01/city.png",
+    "filepath": "org/project/generated/2025-01/city.png",
+    "width": 1920,
+    "height": 1080,
+    "promptEnhancement": {
+      "originalPrompt": "a futuristic city at sunset",
+      "enhancedPrompt": "A breathtaking futuristic cityscape...",
+      "template": "photorealistic"
+    },
+    "generatedAt": "2025-01-15T10:30:00Z"
+  }
+}`}
+          
+
+
+ + {/* Examples */} +
+

Examples

+ +
+
+

Basic Image Generation

+

Generate a simple image with default settings

+
+
+                {`{
+  "prompt": "a serene mountain landscape",
+  "filename": "mountain"
+}`}
+              
+
+
+ +
+

Custom Aspect Ratio

+

Generate a widescreen image

+
+
+                {`{
+  "prompt": "cinematic space battle scene",
+  "filename": "space_battle",
+  "aspectRatio": "21:9"
+}`}
+              
+
+
+
+
+ + {/* Error Codes */} +
+

Error Codes

+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
CodeDescription
400Invalid request parameters
401Missing or invalid API key
429Rate limit exceeded
500Internal server error
+
+
+
+ ); +} diff --git a/apps/landing/src/app/docs/variant-a/guides/authentication/page.tsx b/apps/landing/src/app/docs/variant-a/guides/authentication/page.tsx new file mode 100644 index 0000000..535e8bb --- /dev/null +++ b/apps/landing/src/app/docs/variant-a/guides/authentication/page.tsx @@ -0,0 +1,300 @@ +'use client'; + +/** + * Guide: Authentication - Variant A: Clean & Minimal + * + * This page demonstrates a guide/tutorial style page with step-by-step instructions. + * Features placeholder content focused on authentication concepts. + */ + +import { DocsLayoutA } from '@/components/docs/variant-a/DocsLayoutA'; +import { DocsSidebarA } from '@/components/docs/variant-a/DocsSidebarA'; +import { DocsTOCA } from '@/components/docs/variant-a/DocsTOCA'; +import { Breadcrumb } from '@/components/docs/shared/Breadcrumb'; +import { CodeBlock } from '@/components/docs/shared/CodeBlock'; + +const tocItems = [ + { id: 'overview', text: 'Overview', level: 2 }, + { id: 'api-keys', text: 'API Keys', level: 2 }, + { id: 'key-types', text: 'Key Types', level: 3 }, + { id: 'creating-keys', text: 'Creating Keys', level: 3 }, + { id: 'using-keys', text: 'Using API Keys', level: 2 }, + { id: 'security', text: 'Security Best Practices', level: 2 }, + { id: 'rate-limits', text: 'Rate Limits', level: 2 }, +]; + +export default function AuthenticationGuidePageA() { + return ( + } + toc={} + > + + + {/* Hero Section */} +
+
+ GUIDE +
+

Authentication

+

+ Learn how to authenticate your requests and manage API keys securely. +

+
+ + {/* Overview */} +
+

Overview

+

+ Banatie uses API keys to authenticate requests. Each request must include a valid API key + in the X-API-Key header. API keys are tied to your organization and project, providing + secure, isolated access to resources. +

+
+

+ Security First: Never expose your API keys in client-side code, public + repositories, or logs. Treat them like passwords. +

+
+
+ + {/* API Keys */} +
+

API Keys

+ +
+

Key Types

+

+ Banatie provides two types of API keys, each with different permissions and use cases: +

+ +
+
+
+
+ πŸ”‘ +
+
+

Master Keys

+

+ Full administrative access to your organization. Can create and revoke other + keys, access all projects, and manage settings. +

+
    +
  • β€’ Never expire
  • +
  • β€’ Full API access
  • +
  • β€’ One per organization (initially)
  • +
  • β€’ Should be kept extremely secure
  • +
+
+
+
+ +
+
+
+ 🎫 +
+
+

Project Keys

+

+ Scoped to a specific project. Used for image generation and resource access + within that project only. +

+
    +
  • β€’ Expire after 90 days
  • +
  • β€’ Project-specific access
  • +
  • β€’ Rate limited
  • +
  • β€’ Safe for production use
  • +
+
+
+
+
+
+ +
+

Creating Keys

+ +
+

Bootstrap Your First Key

+

+ When setting up Banatie for the first time, create your initial master key using the + bootstrap endpoint: +

+ +
+

+ Important: This endpoint can only be used once. Save the returned + key immediately - it will never be shown again. +

+
+
+ +
+

Create Project Keys

+

+ Use your master key to create project-specific keys: +

+ +
+
+
+ + {/* Using Keys */} +
+

Using API Keys

+

+ Include your API key in every request using the X-API-Key header: +

+ + +
+ + {/* Security */} +
+

Security Best Practices

+ +
+
+
πŸ”’
+
+

Never Commit Keys

+

+ Use environment variables or secret management tools. Never commit keys to version + control. +

+
+
+ +
+
πŸ”„
+
+

Rotate Keys Regularly

+

+ Project keys expire after 90 days. Plan for rotation and implement graceful + handling. +

+
+
+ +
+
🚫
+
+

Server-Side Only

+

+ Never use API keys in client-side code. Always make requests from your backend. +

+
+
+ +
+
πŸ‘οΈ
+
+

Monitor Usage

+

+ Track API key usage patterns. Unusual activity may indicate a compromised key. +

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

Rate Limits

+

+ To ensure fair usage and system stability, all API keys are subject to rate limits: +

+ +
+ + + + + + + + + + + + + + + + + + + + +
Key TypeLimitWindow
Master Key500 requestsper hour
Project Key100 requestsper hour
+
+ +
+

+ Need Higher Limits? Contact our sales team to discuss enterprise plans + with custom rate limits. +

+
+
+
+ ); +} diff --git a/apps/landing/src/app/docs/variant-a/page.tsx b/apps/landing/src/app/docs/variant-a/page.tsx new file mode 100644 index 0000000..972c2e6 --- /dev/null +++ b/apps/landing/src/app/docs/variant-a/page.tsx @@ -0,0 +1,208 @@ +'use client'; + +/** + * Getting Started Page - Variant A: Clean & Minimal + * + * This is the main landing page for the documentation. + * Features placeholder content to demonstrate the layout and design. + */ + +import { DocsLayoutA } from '@/components/docs/variant-a/DocsLayoutA'; +import { DocsSidebarA } from '@/components/docs/variant-a/DocsSidebarA'; +import { DocsTOCA } from '@/components/docs/variant-a/DocsTOCA'; +import { Breadcrumb } from '@/components/docs/shared/Breadcrumb'; +import { CodeBlock } from '@/components/docs/shared/CodeBlock'; + +const tocItems = [ + { id: 'introduction', text: 'Introduction', level: 2 }, + { id: 'quick-start', text: 'Quick Start', level: 2 }, + { id: 'installation', text: 'Installation', level: 3 }, + { id: 'authentication', text: 'Authentication', level: 3 }, + { id: 'first-request', text: 'Your First Request', level: 2 }, + { id: 'next-steps', text: 'Next Steps', level: 2 }, +]; + +export default function GettingStartedPageA() { + return ( + } + toc={} + > + + + {/* Hero Section */} +
+

Getting Started

+

+ Welcome to the Banatie API documentation. Learn how to integrate AI-powered image + generation into your applications in minutes. +

+
+ + {/* Introduction */} +
+

Introduction

+

+ Banatie is a developer-first API for AI-powered image generation. Built on Google Gemini + 2.5 Flash and Imagen 4.0, it transforms text prompts and reference images into + production-ready visuals. +

+

+ Whether you're building a content creation platform, e-commerce site, or creative tool, + Banatie provides the infrastructure you need to generate high-quality images at scale. +

+
+ + {/* Quick Start */} +
+

Quick Start

+ +
+

Installation

+

+ Banatie is a REST API, so you don't need to install any libraries. However, we provide + SDKs for popular languages to make integration easier. +

+ + +
+ +
+

Authentication

+

+ All API requests require an API key. You can create an API key from your dashboard or + using the bootstrap endpoint for initial setup. +

+ +
+

+ Note: Keep your API keys secure. Never commit them to public + repositories or expose them in client-side code. +

+
+ + +
+
+ + {/* First Request */} +
+

Your First Request

+

+ Let's generate your first image! This example uses curl, but you can use any HTTP client + or our SDKs. +

+ + + +
+

Response:

+
+            {`{
+  "success": true,
+  "data": {
+    "url": "https://cdn.banatie.com/org/project/generated/2025-01/mountain_sunset.png",
+    "filepath": "org/project/generated/2025-01/mountain_sunset.png",
+    "width": 1920,
+    "height": 1080,
+    "promptEnhancement": {
+      "enhancedPrompt": "A breathtaking mountain landscape..."
+    }
+  }
+}`}
+          
+
+
+ + {/* Next Steps */} +
+

Next Steps

+ +
+ +
πŸ“š
+

+ API Reference +

+

+ Explore all available endpoints, parameters, and response formats. +

+
+ + +
πŸ”
+

+ Authentication Guide +

+

+ Learn about API keys, rate limits, and security best practices. +

+
+ + +
πŸ’‘
+

+ Examples +

+

+ Browse code examples and use cases for common scenarios. +

+
+ + +
⚠️
+

+ Error Handling +

+

+ Understand error codes and how to handle failures gracefully. +

+
+
+
+
+ ); +} diff --git a/apps/landing/src/app/docs/variant-b/api/text-to-image/page.tsx b/apps/landing/src/app/docs/variant-b/api/text-to-image/page.tsx new file mode 100644 index 0000000..3c830bd --- /dev/null +++ b/apps/landing/src/app/docs/variant-b/api/text-to-image/page.tsx @@ -0,0 +1,304 @@ +'use client'; + +/** + * API Reference: Text to Image - Variant B: Dense & Information-Rich + * + * Design Philosophy: Compact, information-dense layout with section numbers + * + * Key Differences from Variant A: + * - Section numbers in all headings (1., 1.1, 1.2, etc.) + * - More compact spacing (mb-6 vs mb-12, p-3 vs p-4) + * - Smaller text sizes throughout + * - Denser tables and narrower content + */ + +import { DocsLayoutB } from '@/components/docs/variant-b/DocsLayoutB'; +import { DocsSidebarB } from '@/components/docs/variant-b/DocsSidebarB'; +import { DocsTOCB } from '@/components/docs/variant-b/DocsTOCB'; +import { Breadcrumb } from '@/components/docs/shared/Breadcrumb'; +import { InteractiveAPIWidgetB } from '@/components/docs/variant-b/InteractiveAPIWidgetB'; + +const tocItems = [ + { id: 'overview', text: '1. Overview', level: 2 }, + { id: 'endpoint', text: '2. Endpoint', level: 2 }, + { id: 'request', text: '3. Request', level: 2 }, + { id: 'headers', text: '3.1 Headers', level: 3 }, + { id: 'body', text: '3.2 Body Parameters', level: 3 }, + { id: 'response', text: '4. Response', level: 2 }, + { id: 'examples', text: '5. Examples', level: 2 }, + { id: 'errors', text: '6. Error Codes', level: 2 }, +]; + +export default function TextToImageAPIPageB() { + return ( + } + toc={} + > + + + {/* Hero Section - More compact */} +
+
+ POST +
+

Text to Image

+

+ Generate high-quality images from text prompts using AI-powered models. +

+
+ + {/* Overview */} +
+

1. Overview

+

+ The Text to Image endpoint generates images from text descriptions. It supports various + aspect ratios, automatic prompt enhancement, and optional reference images for style + matching. +

+
+

+ Tip: Enable autoEnhance for better results. The AI will optimize your + prompt for higher quality outputs while preserving your intent. +

+
+
+ + {/* Endpoint */} +
+

2. Endpoint

+
+ POST + https://api.banatie.com/api/text-to-image +
+
+ + {/* Request */} +
+

3. Request

+ +
+

3.1 Headers

+
+ + + + + + + + + + + + + + + + + + + + +
HeaderValueRequired
X-API-KeyYour project API key + Yes +
Content-Typeapplication/json + Yes +
+
+
+ +
+

3.2 Body Parameters

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParameterTypeDescriptionRequired
promptstringText description of the image to generate + Yes +
filenamestringName for the generated image file + Yes +
aspectRatiostring + Image aspect ratio. Options: 1:1, 3:4, 4:3, 9:16, 16:9, 21:9 + + No +
autoEnhancebooleanEnable automatic prompt enhancement (default: true) + No +
enhancementOptionsobjectTemplate and enhancement settings + No +
+
+
+
+ + {/* Interactive API Widget */} + + + {/* Response */} +
+

4. Response

+

+ Returns a JSON object with the generated image URL and metadata. +

+ +
+
+            {`{
+  "success": true,
+  "data": {
+    "url": "https://cdn.banatie.com/org/project/generated/2025-01/city.png",
+    "filepath": "org/project/generated/2025-01/city.png",
+    "width": 1920,
+    "height": 1080,
+    "promptEnhancement": {
+      "originalPrompt": "a futuristic city at sunset",
+      "enhancedPrompt": "A breathtaking futuristic cityscape...",
+      "template": "photorealistic"
+    },
+    "generatedAt": "2025-01-15T10:30:00Z"
+  }
+}`}
+          
+
+
+ + {/* Examples */} +
+

5. Examples

+ +
+
+

5.1 Basic Image Generation

+

Generate a simple image with default settings

+
+
+                {`{
+  "prompt": "a serene mountain landscape",
+  "filename": "mountain"
+}`}
+              
+
+
+ +
+

5.2 Custom Aspect Ratio

+

Generate a widescreen image

+
+
+                {`{
+  "prompt": "cinematic space battle scene",
+  "filename": "space_battle",
+  "aspectRatio": "21:9"
+}`}
+              
+
+
+
+
+ + {/* Error Codes */} +
+

6. Error Codes

+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
CodeDescription
400Invalid request parameters
401Missing or invalid API key
429Rate limit exceeded
500Internal server error
+
+
+
+ ); +} diff --git a/apps/landing/src/app/docs/variant-b/guides/authentication/page.tsx b/apps/landing/src/app/docs/variant-b/guides/authentication/page.tsx new file mode 100644 index 0000000..a4b8ffb --- /dev/null +++ b/apps/landing/src/app/docs/variant-b/guides/authentication/page.tsx @@ -0,0 +1,305 @@ +'use client'; + +/** + * Guide: Authentication - Variant B: Dense & Information-Rich + * + * Design Philosophy: Compact, information-dense layout with section numbers + * + * Key Differences from Variant A: + * - Section numbers in all headings (1., 2., 2.1, etc.) + * - More compact spacing (mb-6 vs mb-12, p-3 vs p-4) + * - Smaller text sizes throughout (text-xs, text-sm) + * - Denser layout with narrower content area + */ + +import { DocsLayoutB } from '@/components/docs/variant-b/DocsLayoutB'; +import { DocsSidebarB } from '@/components/docs/variant-b/DocsSidebarB'; +import { DocsTOCB } from '@/components/docs/variant-b/DocsTOCB'; +import { Breadcrumb } from '@/components/docs/shared/Breadcrumb'; +import { CodeBlock } from '@/components/docs/shared/CodeBlock'; + +const tocItems = [ + { id: 'overview', text: '1. Overview', level: 2 }, + { id: 'api-keys', text: '2. API Keys', level: 2 }, + { id: 'key-types', text: '2.1 Key Types', level: 3 }, + { id: 'creating-keys', text: '2.2 Creating Keys', level: 3 }, + { id: 'using-keys', text: '3. Using API Keys', level: 2 }, + { id: 'security', text: '4. Security Best Practices', level: 2 }, + { id: 'rate-limits', text: '5. Rate Limits', level: 2 }, +]; + +export default function AuthenticationGuidePageB() { + return ( + } + toc={} + > + + + {/* Hero Section - More compact */} +
+
+ GUIDE +
+

Authentication

+

+ Learn how to authenticate your requests and manage API keys securely. +

+
+ + {/* Overview */} +
+

1. Overview

+

+ Banatie uses API keys to authenticate requests. Each request must include a valid API key + in the X-API-Key header. API keys are tied to your organization and project, providing + secure, isolated access to resources. +

+
+

+ Security First: Never expose your API keys in client-side code, public + repositories, or logs. Treat them like passwords. +

+
+
+ + {/* API Keys */} +
+

2. API Keys

+ +
+

2.1 Key Types

+

+ Banatie provides two types of API keys, each with different permissions and use cases: +

+ +
+
+
+
+ πŸ”‘ +
+
+

Master Keys

+

+ Full administrative access to your organization. Can create and revoke other + keys, access all projects, and manage settings. +

+
    +
  • β€’ Never expire
  • +
  • β€’ Full API access
  • +
  • β€’ One per organization (initially)
  • +
  • β€’ Should be kept extremely secure
  • +
+
+
+
+ +
+
+
+ 🎫 +
+
+

Project Keys

+

+ Scoped to a specific project. Used for image generation and resource access + within that project only. +

+
    +
  • β€’ Expire after 90 days
  • +
  • β€’ Project-specific access
  • +
  • β€’ Rate limited
  • +
  • β€’ Safe for production use
  • +
+
+
+
+
+
+ +
+

2.2 Creating Keys

+ +
+

2.2.1 Bootstrap Your First Key

+

+ When setting up Banatie for the first time, create your initial master key using the + bootstrap endpoint: +

+ +
+

+ Important: This endpoint can only be used once. Save the returned + key immediately - it will never be shown again. +

+
+
+ +
+

2.2.2 Create Project Keys

+

+ Use your master key to create project-specific keys: +

+ +
+
+
+ + {/* Using Keys */} +
+

3. Using API Keys

+

+ Include your API key in every request using the X-API-Key header: +

+ + +
+ + {/* Security */} +
+

4. Security Best Practices

+ +
+
+
πŸ”’
+
+

Never Commit Keys

+

+ Use environment variables or secret management tools. Never commit keys to version + control. +

+
+
+ +
+
πŸ”„
+
+

Rotate Keys Regularly

+

+ Project keys expire after 90 days. Plan for rotation and implement graceful + handling. +

+
+
+ +
+
🚫
+
+

Server-Side Only

+

+ Never use API keys in client-side code. Always make requests from your backend. +

+
+
+ +
+
πŸ‘οΈ
+
+

Monitor Usage

+

+ Track API key usage patterns. Unusual activity may indicate a compromised key. +

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

5. Rate Limits

+

+ To ensure fair usage and system stability, all API keys are subject to rate limits: +

+ +
+ + + + + + + + + + + + + + + + + + + + +
Key TypeLimitWindow
Master Key500 requestsper hour
Project Key100 requestsper hour
+
+ +
+

+ Need Higher Limits? Contact our sales team to discuss enterprise plans + with custom rate limits. +

+
+
+
+ ); +} diff --git a/apps/landing/src/app/docs/variant-b/page.tsx b/apps/landing/src/app/docs/variant-b/page.tsx new file mode 100644 index 0000000..c8320e6 --- /dev/null +++ b/apps/landing/src/app/docs/variant-b/page.tsx @@ -0,0 +1,211 @@ +'use client'; + +/** + * Getting Started Page - Variant B: Dense & Information-Rich + * + * Same content as Variant A but with Variant B styling: + * - Compact spacing (py-10 vs py-12, p-4 vs p-6) + * - Narrower max-width (max-w-4xl) + * - Section numbers in headings where appropriate + * - Denser tables and lists + */ + +import { DocsLayoutB } from '@/components/docs/variant-b/DocsLayoutB'; +import { DocsSidebarB } from '@/components/docs/variant-b/DocsSidebarB'; +import { DocsTOCB } from '@/components/docs/variant-b/DocsTOCB'; +import { Breadcrumb } from '@/components/docs/shared/Breadcrumb'; +import { CodeBlock } from '@/components/docs/shared/CodeBlock'; + +const tocItems = [ + { id: 'introduction', text: '1. Introduction', level: 2 }, + { id: 'quick-start', text: '2. Quick Start', level: 2 }, + { id: 'installation', text: '2.1 Installation', level: 3 }, + { id: 'authentication', text: '2.2 Authentication', level: 3 }, + { id: 'first-request', text: '3. Your First Request', level: 2 }, + { id: 'next-steps', text: '4. Next Steps', level: 2 }, +]; + +export default function GettingStartedPageB() { + return ( + } + toc={} + > + + + {/* Hero Section - More compact */} +
+

Getting Started

+

+ Welcome to the Banatie API documentation. Learn how to integrate AI-powered image + generation into your applications in minutes. +

+
+ + {/* Introduction */} +
+

1. Introduction

+

+ Banatie is a developer-first API for AI-powered image generation. Built on Google Gemini + 2.5 Flash and Imagen 4.0, it transforms text prompts and reference images into + production-ready visuals. +

+

+ Whether you're building a content creation platform, e-commerce site, or creative tool, + Banatie provides the infrastructure you need to generate high-quality images at scale. +

+
+ + {/* Quick Start */} +
+

2. Quick Start

+ +
+

2.1 Installation

+

+ Banatie is a REST API, so you don't need to install any libraries. However, we provide + SDKs for popular languages to make integration easier. +

+ + +
+ +
+

2.2 Authentication

+

+ All API requests require an API key. You can create an API key from your dashboard or + using the bootstrap endpoint for initial setup. +

+ +
+

+ Note: Keep your API keys secure. Never commit them to public + repositories or expose them in client-side code. +

+
+ + +
+
+ + {/* First Request */} +
+

3. Your First Request

+

+ Let's generate your first image! This example uses curl, but you can use any HTTP client + or our SDKs. +

+ + + +
+

Response:

+
+            {`{
+  "success": true,
+  "data": {
+    "url": "https://cdn.banatie.com/org/project/generated/2025-01/mountain_sunset.png",
+    "filepath": "org/project/generated/2025-01/mountain_sunset.png",
+    "width": 1920,
+    "height": 1080,
+    "promptEnhancement": {
+      "enhancedPrompt": "A breathtaking mountain landscape..."
+    }
+  }
+}`}
+          
+
+
+ + {/* Next Steps */} +
+

4. Next Steps

+ +
+ +
πŸ“š
+

+ API Reference +

+

+ Explore all available endpoints, parameters, and response formats. +

+
+ + +
πŸ”
+

+ Authentication Guide +

+

+ Learn about API keys, rate limits, and security best practices. +

+
+ + +
πŸ’‘
+

+ Examples +

+

+ Browse code examples and use cases for common scenarios. +

+
+ + +
⚠️
+

+ Error Handling +

+

+ Understand error codes and how to handle failures gracefully. +

+
+
+
+
+ ); +} diff --git a/apps/landing/src/app/docs/variant-c/api/text-to-image/page.tsx b/apps/landing/src/app/docs/variant-c/api/text-to-image/page.tsx new file mode 100644 index 0000000..83665b8 --- /dev/null +++ b/apps/landing/src/app/docs/variant-c/api/text-to-image/page.tsx @@ -0,0 +1,369 @@ +'use client'; + +/** + * API Reference: Text to Image - Variant C: Modern & Visual (Shopify-inspired) + * + * Design Philosophy: Colorful, card-based, engaging visual design + * + * Key Characteristics: + * - NO section numbers (more visual/playful) + * - Large emoji icons (text-3xl) + * - Gradient borders everywhere + * - Colorful method badge (large, gradient) + * - Visual cards for parameter tables + * - Generous spacing (mb-12, p-6) + */ + +import { DocsLayoutC } from '@/components/docs/variant-c/DocsLayoutC'; +import { DocsSidebarC } from '@/components/docs/variant-c/DocsSidebarC'; +import { DocsTOCC } from '@/components/docs/variant-c/DocsTOCC'; +import { Breadcrumb } from '@/components/docs/shared/Breadcrumb'; +import { InteractiveAPIWidgetC } from '@/components/docs/variant-c/InteractiveAPIWidgetC'; + +const tocItems = [ + { id: 'overview', text: 'Overview', level: 2 }, + { id: 'endpoint', text: 'Endpoint', level: 2 }, + { id: 'request', text: 'Request', level: 2 }, + { id: 'headers', text: 'Headers', level: 3 }, + { id: 'body', text: 'Body Parameters', level: 3 }, + { id: 'response', text: 'Response', level: 2 }, + { id: 'examples', text: 'Examples', level: 2 }, + { id: 'errors', text: 'Error Codes', level: 2 }, +]; + +export default function TextToImageAPIPageC() { + return ( + } + toc={} + > + + + {/* Hero Section - Large and Colorful */} +
+
+ POST +
+

+ Text to Image +

+

+ Generate high-quality images from text prompts using AI-powered models. +

+
+ + {/* Overview */} +
+
+ πŸ“– +

Overview

+
+
+

+ The Text to Image endpoint generates images from text descriptions. It supports various + aspect ratios, automatic prompt enhancement, and optional reference images for style + matching. +

+
+
+ πŸ’‘ +
+

Pro Tip

+

+ Enable autoEnhance for better results. The AI will optimize your prompt for higher + quality outputs while preserving your intent. +

+
+
+
+
+
+ + {/* Endpoint */} +
+
+ πŸ”— +

Endpoint

+
+
+
+ + POST + + https://api.banatie.com/api/text-to-image +
+
+
+ + {/* Request */} +
+
+ πŸ“€ +

Request

+
+ +
+
+ 🏷️ +

Headers

+
+
+ + + + + + + + + + + + + + + + + + + + +
HeaderValueRequired
X-API-KeyYour project API key + + Required + +
Content-Typeapplication/json + + Required + +
+
+
+ +
+
+ βš™οΈ +

Body Parameters

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParameterTypeDescriptionRequired
promptstringText description of the image to generate + + Required + +
filenamestringName for the generated image file + + Required + +
aspectRatiostring + Image aspect ratio. Options: 1:1, 3:4, 4:3, 9:16, 16:9, 21:9 + + + Optional + +
autoEnhancebooleanEnable automatic prompt enhancement (default: true) + + Optional + +
enhancementOptionsobjectTemplate and enhancement settings + + Optional + +
+
+
+
+ + {/* Interactive API Widget */} + + + {/* Response */} +
+
+ πŸ“¦ +

Response

+
+

+ Returns a JSON object with the generated image URL and metadata. +

+ +
+
+ + βœ“ 200 Success + +
+
+            {`{
+  "success": true,
+  "data": {
+    "url": "https://cdn.banatie.com/org/project/generated/2025-01/city.png",
+    "filepath": "org/project/generated/2025-01/city.png",
+    "width": 1920,
+    "height": 1080,
+    "promptEnhancement": {
+      "originalPrompt": "a futuristic city at sunset",
+      "enhancedPrompt": "A breathtaking futuristic cityscape...",
+      "template": "photorealistic"
+    },
+    "generatedAt": "2025-01-15T10:30:00Z"
+  }
+}`}
+          
+
+
+ + {/* Examples */} +
+
+ πŸ’‘ +

Examples

+
+ +
+
+
+ 🎨 +

Basic Image Generation

+
+

Generate a simple image with default settings

+
+
+                {`{
+  "prompt": "a serene mountain landscape",
+  "filename": "mountain"
+}`}
+              
+
+
+ +
+
+ 🎬 +

Custom Aspect Ratio

+
+

Generate a widescreen image

+
+
+                {`{
+  "prompt": "cinematic space battle scene",
+  "filename": "space_battle",
+  "aspectRatio": "21:9"
+}`}
+              
+
+
+
+
+ + {/* Error Codes */} +
+
+ ⚠️ +

Error Codes

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
CodeDescription
400Invalid request parameters
401Missing or invalid API key
429Rate limit exceeded
500Internal server error
+
+
+
+ ); +} diff --git a/apps/landing/src/app/docs/variant-c/guides/authentication/page.tsx b/apps/landing/src/app/docs/variant-c/guides/authentication/page.tsx new file mode 100644 index 0000000..1e9b3ef --- /dev/null +++ b/apps/landing/src/app/docs/variant-c/guides/authentication/page.tsx @@ -0,0 +1,370 @@ +'use client'; + +/** + * Guide: Authentication - Variant C: Modern & Visual (Shopify-inspired) + * + * Design Philosophy: Colorful, card-based, playful visual design + * + * Key Characteristics: + * - NO section numbers (more visual/playful) + * - Security best practices as large visual cards + * - Emoji icons prominent (text-3xl) + * - Gradient borders everywhere + * - Generous spacing and padding + */ + +import { DocsLayoutC } from '@/components/docs/variant-c/DocsLayoutC'; +import { DocsSidebarC } from '@/components/docs/variant-c/DocsSidebarC'; +import { DocsTOCC } from '@/components/docs/variant-c/DocsTOCC'; +import { Breadcrumb } from '@/components/docs/shared/Breadcrumb'; +import { CodeBlock } from '@/components/docs/shared/CodeBlock'; + +const tocItems = [ + { id: 'overview', text: 'Overview', level: 2 }, + { id: 'api-keys', text: 'API Keys', level: 2 }, + { id: 'key-types', text: 'Key Types', level: 3 }, + { id: 'creating-keys', text: 'Creating Keys', level: 3 }, + { id: 'using-keys', text: 'Using API Keys', level: 2 }, + { id: 'security', text: 'Security Best Practices', level: 2 }, + { id: 'rate-limits', text: 'Rate Limits', level: 2 }, +]; + +export default function AuthenticationGuidePageC() { + return ( + } + toc={} + > + + + {/* Hero Section - Large and Colorful */} +
+
+ πŸ“š + GUIDE +
+

+ Authentication +

+

+ Learn how to authenticate your requests and manage API keys securely. +

+
+ + {/* Overview */} +
+
+ πŸ” +

Overview

+
+
+

+ Banatie uses API keys to authenticate requests. Each request must include a valid API key + in the X-API-Key header. API keys are tied to your organization and project, providing + secure, isolated access to resources. +

+
+
+ πŸ›‘οΈ +
+

Security First

+

+ Never expose your API keys in client-side code, public repositories, or logs. Treat + them like passwords. +

+
+
+
+
+
+ + {/* API Keys */} +
+
+ πŸ”‘ +

API Keys

+
+ +
+
+ 🏷️ +

Key Types

+
+

+ Banatie provides two types of API keys, each with different permissions and use cases: +

+ +
+
+
+
+ πŸ”‘ +
+
+

Master Keys

+

+ Full administrative access to your organization. Can create and revoke other + keys, access all projects, and manage settings. +

+
    +
  • + βœ“ Never expire +
  • +
  • + βœ“ Full API access +
  • +
  • + βœ“ One per organization (initially) +
  • +
  • + βœ“ Should be kept extremely secure +
  • +
+
+
+
+ +
+
+
+ 🎫 +
+
+

Project Keys

+

+ Scoped to a specific project. Used for image generation and resource access + within that project only. +

+
    +
  • + βœ“ Expire after 90 days +
  • +
  • + βœ“ Project-specific access +
  • +
  • + βœ“ Rate limited +
  • +
  • + βœ“ Safe for production use +
  • +
+
+
+
+
+
+ +
+
+ ⚑ +

Creating Keys

+
+ +
+
+ πŸš€ +

Bootstrap Your First Key

+
+

+ When setting up Banatie for the first time, create your initial master key using the + bootstrap endpoint: +

+ +
+
+ ⚠️ +
+

Important

+

+ This endpoint can only be used once. Save the returned key immediately - it will + never be shown again. +

+
+
+
+
+ +
+
+ 🎨 +

Create Project Keys

+
+

+ Use your master key to create project-specific keys: +

+ +
+
+
+ + {/* Using Keys */} +
+
+ πŸ’» +

Using API Keys

+
+

+ Include your API key in every request using the X-API-Key header: +

+ + +
+ + {/* Security */} +
+
+ πŸ›‘οΈ +

Security Best Practices

+
+ +
+
+
πŸ”’
+

Never Commit Keys

+

+ Use environment variables or secret management tools. Never commit keys to version + control. +

+
+ +
+
πŸ”„
+

Rotate Keys Regularly

+

+ Project keys expire after 90 days. Plan for rotation and implement graceful handling. +

+
+ +
+
🚫
+

Server-Side Only

+

+ Never use API keys in client-side code. Always make requests from your backend. +

+
+ +
+
πŸ‘οΈ
+

Monitor Usage

+

+ Track API key usage patterns. Unusual activity may indicate a compromised key. +

+
+
+
+ + {/* Rate Limits */} +
+
+ ⏱️ +

Rate Limits

+
+

+ To ensure fair usage and system stability, all API keys are subject to rate limits: +

+ +
+ + + + + + + + + + + + + + + + + + + + +
Key TypeLimitWindow
Master Key + + 500 requests + + per hour
Project Key + + 100 requests + + per hour
+
+ +
+
+ πŸ’¬ +
+

Need Higher Limits?

+

+ Contact our sales team to discuss enterprise plans with custom rate limits. +

+
+
+
+
+
+ ); +} diff --git a/apps/landing/src/app/docs/variant-c/page.tsx b/apps/landing/src/app/docs/variant-c/page.tsx new file mode 100644 index 0000000..b80157e --- /dev/null +++ b/apps/landing/src/app/docs/variant-c/page.tsx @@ -0,0 +1,268 @@ +'use client'; + +/** + * Getting Started Page - Variant C: Modern & Visual (Shopify-inspired) + * + * Design Philosophy: Colorful, card-based, playful visual design + * + * Key Characteristics: + * - NO section numbers (more visual/playful) + * - Large emoji icons throughout (text-3xl) + * - Gradient borders on all callout boxes + * - More colorful design (purple/cyan/amber accents) + * - Generous spacing (mb-12, p-6) + * - Larger padding and gaps throughout + * - Card-based sections with shadows + * - Floating visual effects + */ + +import { DocsLayoutC } from '@/components/docs/variant-c/DocsLayoutC'; +import { DocsSidebarC } from '@/components/docs/variant-c/DocsSidebarC'; +import { DocsTOCC } from '@/components/docs/variant-c/DocsTOCC'; +import { Breadcrumb } from '@/components/docs/shared/Breadcrumb'; +import { CodeBlock } from '@/components/docs/shared/CodeBlock'; + +const tocItems = [ + { id: 'introduction', text: 'Introduction', level: 2 }, + { id: 'quick-start', text: 'Quick Start', level: 2 }, + { id: 'installation', text: 'Installation', level: 3 }, + { id: 'authentication', text: 'Authentication', level: 3 }, + { id: 'first-request', text: 'Your First Request', level: 2 }, + { id: 'next-steps', text: 'Next Steps', level: 2 }, +]; + +export default function GettingStartedPageC() { + return ( + } + toc={} + > + + + {/* Hero Section - Large and Colorful */} +
+
+ πŸš€ + START HERE +
+

+ Getting Started +

+

+ Welcome to the Banatie API documentation. Learn how to integrate AI-powered image + generation into your applications in minutes. +

+
+ + {/* Introduction */} +
+
+ πŸ‘‹ +

Introduction

+
+
+

+ Banatie is a developer-first API for AI-powered image generation. Built on Google Gemini + 2.5 Flash and Imagen 4.0, it transforms text prompts and reference images into + production-ready visuals. +

+

+ Whether you're building a content creation platform, e-commerce site, or creative tool, + Banatie provides the infrastructure you need to generate high-quality images at scale. +

+
+
+ + {/* Quick Start */} +
+
+ ⚑ +

Quick Start

+
+ +
+
+ πŸ“¦ +

Installation

+
+

+ Banatie is a REST API, so you don't need to install any libraries. However, we provide + SDKs for popular languages to make integration easier. +

+ + +
+ +
+
+ πŸ”‘ +

Authentication

+
+

+ All API requests require an API key. You can create an API key from your dashboard or + using the bootstrap endpoint for initial setup. +

+ +
+
+ πŸ’‘ +
+

Security Tip

+

+ Keep your API keys secure. Never commit them to public repositories or expose them + in client-side code. +

+
+
+
+ + +
+
+ + {/* First Request */} +
+
+ 🎨 +

Your First Request

+
+

+ Let's generate your first image! This example uses curl, but you can use any HTTP client + or our SDKs. +

+ + + +
+
+ ✨ +

Expected Response:

+
+
+            {`{
+  "success": true,
+  "data": {
+    "url": "https://cdn.banatie.com/org/project/generated/2025-01/mountain_sunset.png",
+    "filepath": "org/project/generated/2025-01/mountain_sunset.png",
+    "width": 1920,
+    "height": 1080,
+    "promptEnhancement": {
+      "enhancedPrompt": "A breathtaking mountain landscape..."
+    }
+  }
+}`}
+          
+
+
+ + {/* Next Steps */} +
+
+ 🎯 +

Next Steps

+
+ +
+ +
πŸ“š
+

+ API Reference +

+

+ Explore all available endpoints, parameters, and response formats. +

+
+ + +
πŸ”
+

+ Authentication Guide +

+

+ Learn about API keys, rate limits, and security best practices. +

+
+ + +
πŸ’‘
+

+ Examples +

+

+ Browse code examples and use cases for common scenarios. +

+
+ + +
⚠️
+

+ Error Handling +

+

+ Understand error codes and how to handle failures gracefully. +

+
+
+
+ + {/* Fun CTA Card */} +
+
πŸŽ‰
+

Ready to Build Something Amazing?

+

+ Start creating stunning AI-generated images for your applications today! +

+ + ⚑ + Explore the API + +
+
+ ); +} diff --git a/apps/landing/src/components/docs/shared/Breadcrumb.tsx b/apps/landing/src/components/docs/shared/Breadcrumb.tsx new file mode 100644 index 0000000..3656001 --- /dev/null +++ b/apps/landing/src/components/docs/shared/Breadcrumb.tsx @@ -0,0 +1,73 @@ +'use client'; + +/** + * Breadcrumb Navigation Component + * + * Displays hierarchical navigation path for documentation pages. + * Follows WCAG 2.1 AA accessibility guidelines with proper ARIA labels. + * + * Design: + * - Consistent with Banatie dark theme + * - Gray text with white hover for inactive items + * - White text for current page + * - Chevron separators between items + */ + +interface BreadcrumbItem { + label: string; + href?: string; +} + +interface BreadcrumbProps { + items: BreadcrumbItem[]; +} + +export const Breadcrumb = ({ items }: BreadcrumbProps) => { + return ( + + ); +}; diff --git a/apps/landing/src/components/docs/shared/CodeBlock.tsx b/apps/landing/src/components/docs/shared/CodeBlock.tsx new file mode 100644 index 0000000..c345843 --- /dev/null +++ b/apps/landing/src/components/docs/shared/CodeBlock.tsx @@ -0,0 +1,69 @@ +'use client'; + +/** + * CodeBlock Component + * + * Wrapper for displaying syntax-highlighted code blocks in documentation. + * Uses the existing Banatie design pattern from the landing page. + * + * Design Features: + * - MacOS-style window with traffic light dots + * - Dark slate background with backdrop blur + * - Copy button in top-right + * - Scrollable code area + * - Optional language label + */ + +import { useState } from 'react'; + +interface CodeBlockProps { + code: string; + language?: string; + filename?: string; + showLineNumbers?: boolean; +} + +export const CodeBlock = ({ + code, + language = 'bash', + filename, + showLineNumbers = false, +}: CodeBlockProps) => { + const [copied, setCopied] = useState(false); + + const handleCopy = () => { + navigator.clipboard.writeText(code); + setCopied(true); + setTimeout(() => setCopied(false), 2000); + }; + + return ( +
+ {/* Header with traffic lights and copy button */} +
+
+
+
+
+
+
+ {(filename || language) && ( + {filename || language} + )} +
+ +
+ + {/* Code content */} +
+        {code}
+      
+
+ ); +}; diff --git a/apps/landing/src/components/docs/variant-a/DocsLayoutA.tsx b/apps/landing/src/components/docs/variant-a/DocsLayoutA.tsx new file mode 100644 index 0000000..66f33e5 --- /dev/null +++ b/apps/landing/src/components/docs/variant-a/DocsLayoutA.tsx @@ -0,0 +1,62 @@ +'use client'; + +/** + * Documentation Layout - Variant A: Clean & Minimal + * + * Design Philosophy: Vercel-inspired spacious, focused reading experience + * + * Layout Structure: + * - Left Sidebar: Thin (256px) with minimal design + * - Content Area: Wide margins (max-w-3xl) for comfortable reading + * - Right TOC: Subtle and unobtrusive (224px) + * + * Responsive Behavior: + * - Mobile (<768px): Single column, sidebars become overlays + * - Tablet (768px-1024px): Content + TOC only + * - Desktop (>1024px): Full three-column layout + * + * Design Characteristics: + * - Generous whitespace + * - Subtle borders and shadows + * - Focus on content clarity + * - Minimal visual noise + */ + +import { ReactNode } from 'react'; + +interface DocsLayoutAProps { + sidebar: ReactNode; + children: ReactNode; + toc: ReactNode; +} + +export const DocsLayoutA = ({ sidebar, children, toc }: DocsLayoutAProps) => { + return ( +
+ {/* Animated gradient background (matching landing page) */} +
+
+
+
+ +
+ {/* Left Sidebar - Thin, minimal design */} + + + {/* Main Content Area - Wide margins for comfortable reading */} +
+
+ {children} +
+
+ + {/* Right TOC - Subtle and unobtrusive */} + +
+
+ ); +}; diff --git a/apps/landing/src/components/docs/variant-a/DocsSidebarA.tsx b/apps/landing/src/components/docs/variant-a/DocsSidebarA.tsx new file mode 100644 index 0000000..34bb8d4 --- /dev/null +++ b/apps/landing/src/components/docs/variant-a/DocsSidebarA.tsx @@ -0,0 +1,178 @@ +'use client'; + +/** + * Documentation Sidebar - Variant A: Clean & Minimal + * + * Design Philosophy: Vercel-inspired minimal navigation + * + * Features: + * - Thin sidebar with subtle hover states + * - Collapsible section groups + * - Active state: Purple left border + text + * - Minimal icons (chevron for expandable items) + * - Clean, uncluttered appearance + * + * Navigation Structure: + * - Getting Started + * - API Reference (collapsible) + * - Text to Image + * - Upload + * - Images + * - Guides (collapsible) + * - Authentication + * - Error Handling + * - Rate Limits + * - Examples + */ + +import { useState } from 'react'; + +interface NavItem { + label: string; + href: string; + icon?: string; + children?: NavItem[]; +} + +interface DocsSidebarAProps { + currentPath: string; +} + +const navigationItems: NavItem[] = [ + { + label: 'Getting Started', + href: '/docs/variant-a', + icon: 'πŸš€', + }, + { + label: 'API Reference', + href: '/docs/variant-a/api', + icon: 'πŸ“š', + children: [ + { label: 'Text to Image', href: '/docs/variant-a/api/text-to-image' }, + { label: 'Upload', href: '/docs/variant-a/api/upload' }, + { label: 'Images', href: '/docs/variant-a/api/images' }, + ], + }, + { + label: 'Guides', + href: '/docs/variant-a/guides', + icon: 'πŸ“–', + children: [ + { label: 'Authentication', href: '/docs/variant-a/guides/authentication' }, + { label: 'Error Handling', href: '/docs/variant-a/guides/error-handling' }, + { label: 'Rate Limits', href: '/docs/variant-a/guides/rate-limits' }, + ], + }, + { + label: 'Examples', + href: '/docs/variant-a/examples', + icon: 'πŸ’‘', + }, +]; + +export const DocsSidebarA = ({ currentPath }: DocsSidebarAProps) => { + const [expandedSections, setExpandedSections] = useState(['API Reference', 'Guides']); + + const toggleSection = (label: string) => { + setExpandedSections((prev) => + prev.includes(label) ? prev.filter((item) => item !== label) : [...prev, label] + ); + }; + + const isActive = (href: string) => currentPath === href; + const isExpanded = (label: string) => expandedSections.includes(label); + + return ( + + ); +}; diff --git a/apps/landing/src/components/docs/variant-a/DocsTOCA.tsx b/apps/landing/src/components/docs/variant-a/DocsTOCA.tsx new file mode 100644 index 0000000..330edf9 --- /dev/null +++ b/apps/landing/src/components/docs/variant-a/DocsTOCA.tsx @@ -0,0 +1,102 @@ +'use client'; + +/** + * Table of Contents - Variant A: Clean & Minimal + * + * Design Philosophy: Subtle, unobtrusive TOC + * + * Features: + * - Small indicator dots for section levels + * - Smooth scroll to section + * - Active section highlighting (purple text) + * - Sticky positioning + * - Minimal visual weight + * + * Behavior: + * - Extracts H2 and H3 headings from content + * - Tracks scroll position to highlight active section + * - Click to smooth scroll to section + */ + +import { useEffect, useState } from 'react'; + +interface TocItem { + id: string; + text: string; + level: number; +} + +interface DocsTOCAProps { + items: TocItem[]; +} + +export const DocsTOCA = ({ items }: DocsTOCAProps) => { + const [activeId, setActiveId] = useState(''); + + useEffect(() => { + const observer = new IntersectionObserver( + (entries) => { + entries.forEach((entry) => { + if (entry.isIntersecting) { + setActiveId(entry.target.id); + } + }); + }, + { rootMargin: '-20% 0px -35% 0px' } + ); + + items.forEach((item) => { + const element = document.getElementById(item.id); + if (element) observer.observe(element); + }); + + return () => observer.disconnect(); + }, [items]); + + const scrollToSection = (id: string) => { + const element = document.getElementById(id); + if (element) { + element.scrollIntoView({ behavior: 'smooth', block: 'start' }); + } + }; + + if (items.length === 0) { + return null; + } + + return ( + + ); +}; diff --git a/apps/landing/src/components/docs/variant-a/InteractiveAPIWidgetA.tsx b/apps/landing/src/components/docs/variant-a/InteractiveAPIWidgetA.tsx new file mode 100644 index 0000000..a1d443a --- /dev/null +++ b/apps/landing/src/components/docs/variant-a/InteractiveAPIWidgetA.tsx @@ -0,0 +1,293 @@ +'use client'; + +/** + * Interactive API Widget - Variant A: Clean & Minimal + * + * Design Philosophy: Inline playground with tabbed interface + * + * Features: + * - Multi-language code tabs (curl, JavaScript, Python, Go) + * - API key input field (persists via localStorage) + * - "Try It" button to execute live requests + * - Response viewer with syntax highlighting + * - Request/Response tabs + * - Error state handling + * - Clean, focused design + * + * Layout: + * - Top: Language tabs + Copy button + * - Middle: Code preview OR Request params + * - Bottom: Try It button + * - Response: Expandable section below + */ + +import { useState, useEffect } from 'react'; + +interface InteractiveAPIWidgetAProps { + endpoint: string; + method: 'GET' | 'POST' | 'PUT' | 'DELETE'; + description: string; + parameters?: Array<{ + name: string; + type: string; + required: boolean; + description: string; + defaultValue?: string; + }>; +} + +type Language = 'curl' | 'javascript' | 'python' | 'go'; +type ViewMode = 'code' | 'response'; + +const API_BASE_URL = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:3000'; +const API_KEY_STORAGE = 'banatie_docs_api_key'; + +export const InteractiveAPIWidgetA = ({ + endpoint, + method, + description, + parameters = [], +}: InteractiveAPIWidgetAProps) => { + const [language, setLanguage] = useState('curl'); + const [apiKey, setApiKey] = useState(''); + const [isExecuting, setIsExecuting] = useState(false); + const [viewMode, setViewMode] = useState('code'); + const [response, setResponse] = useState(null); + const [error, setError] = useState(null); + + // Parameter values + const [paramValues, setParamValues] = useState>({}); + + // Load API key from localStorage + useEffect(() => { + const stored = localStorage.getItem(API_KEY_STORAGE); + if (stored) setApiKey(stored); + + // Initialize parameter default values + const defaults: Record = {}; + parameters.forEach((param) => { + if (param.defaultValue) { + defaults[param.name] = param.defaultValue; + } + }); + setParamValues(defaults); + }, [parameters]); + + // Save API key to localStorage + const handleApiKeyChange = (value: string) => { + setApiKey(value); + if (value) { + localStorage.setItem(API_KEY_STORAGE, value); + } else { + localStorage.removeItem(API_KEY_STORAGE); + } + }; + + // Generate code examples + const generateCode = (): string => { + const url = `${API_BASE_URL}${endpoint}`; + + switch (language) { + case 'curl': + return `curl -X ${method} "${url}" \\ + -H "X-API-Key: ${apiKey || 'YOUR_API_KEY'}" \\ + -H "Content-Type: application/json" \\ + -d '{ + "prompt": "a futuristic city at sunset", + "filename": "city", + "aspectRatio": "16:9" + }'`; + + case 'javascript': + return `const response = await fetch('${url}', { + method: '${method}', + headers: { + 'X-API-Key': '${apiKey || 'YOUR_API_KEY'}', + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ + prompt: 'a futuristic city at sunset', + filename: 'city', + aspectRatio: '16:9' + }) +}); + +const data = await response.json(); +console.log(data);`; + + case 'python': + return `import requests + +url = '${url}' +headers = { + 'X-API-Key': '${apiKey || 'YOUR_API_KEY'}', + 'Content-Type': 'application/json' +} +data = { + 'prompt': 'a futuristic city at sunset', + 'filename': 'city', + 'aspectRatio': '16:9' +} + +response = requests.${method.toLowerCase()}(url, headers=headers, json=data) +print(response.json())`; + + case 'go': + return `package main + +import ( + "bytes" + "encoding/json" + "fmt" + "net/http" +) + +func main() { + url := "${url}" + data := map[string]interface{}{ + "prompt": "a futuristic city at sunset", + "filename": "city", + "aspectRatio": "16:9", + } + + jsonData, _ := json.Marshal(data) + req, _ := http.NewRequest("${method}", url, bytes.NewBuffer(jsonData)) + req.Header.Set("X-API-Key", "${apiKey || 'YOUR_API_KEY'}") + req.Header.Set("Content-Type", "application/json") + + client := &http.Client{} + resp, _ := client.Do(req) + defer resp.Body.Close() +}`; + + default: + return ''; + } + }; + + // Execute API request + const executeRequest = async () => { + if (!apiKey) { + setError('Please enter your API key'); + return; + } + + setIsExecuting(true); + setError(null); + setViewMode('response'); + + try { + const body: Record = {}; + parameters.forEach((param) => { + if (paramValues[param.name]) { + body[param.name] = paramValues[param.name]; + } + }); + + const res = await fetch(`${API_BASE_URL}${endpoint}`, { + method, + headers: { + 'X-API-Key': apiKey, + 'Content-Type': 'application/json', + }, + body: method !== 'GET' ? JSON.stringify(body) : undefined, + }); + + const data = await res.json(); + setResponse(data); + } catch (err) { + setError(err instanceof Error ? err.message : 'Failed to execute request'); + } finally { + setIsExecuting(false); + } + }; + + // Copy code to clipboard + const copyCode = () => { + navigator.clipboard.writeText(generateCode()); + }; + + return ( +
+ {/* Header with API Key Input */} +
+
+
+

Try it out

+

{description}

+
+
+ handleApiKeyChange(e.target.value)} + placeholder="Enter your API key" + className="w-full px-3 py-2 text-xs bg-slate-800 border border-slate-700 rounded-lg text-white placeholder-gray-500 focus:outline-none focus:ring-2 focus:ring-purple-500 focus:border-transparent" + /> +
+
+
+ + {/* Language Tabs */} +
+
+ {(['curl', 'javascript', 'python', 'go'] as Language[]).map((lang) => ( + + ))} +
+ +
+ + {/* Code Display */} +
+
+          {generateCode()}
+        
+
+ + {/* Try It Button */} +
+ +
+ + {/* Response Section */} + {(response || error) && ( +
+
+

Response

+ {error ? ( +
+ {error} +
+ ) : ( +
+                {JSON.stringify(response, null, 2)}
+              
+ )} +
+
+ )} +
+ ); +}; diff --git a/apps/landing/src/components/docs/variant-b/DocsLayoutB.tsx b/apps/landing/src/components/docs/variant-b/DocsLayoutB.tsx new file mode 100644 index 0000000..c019a9e --- /dev/null +++ b/apps/landing/src/components/docs/variant-b/DocsLayoutB.tsx @@ -0,0 +1,62 @@ +'use client'; + +/** + * Documentation Layout - Variant B: Dense & Information-Rich + * + * Design Philosophy: Next.js-inspired dense, hierarchical layout + * + * Layout Structure: + * - Left Sidebar: Wider (280px) with nested tree structure + * - Content Area: Narrower margins to show more content + * - Right TOC: Prominent with progress indicator (240px) + * + * Responsive Behavior: + * - Mobile (<768px): Bottom sheet navigation + * - Tablet (768px-1024px): Collapsible sidebar + TOC + * - Desktop (>1024px): Full three-column layout + * + * Design Characteristics: + * - Compact spacing + * - More content per screen + * - Nested navigation tree + * - Section numbers throughout + */ + +import { ReactNode } from 'react'; + +interface DocsLayoutBProps { + sidebar: ReactNode; + children: ReactNode; + toc: ReactNode; +} + +export const DocsLayoutB = ({ sidebar, children, toc }: DocsLayoutBProps) => { + return ( +
+ {/* Animated gradient background (matching landing page) */} +
+
+
+
+ +
+ {/* Left Sidebar - Wider with nested structure */} + + + {/* Main Content Area - Narrower margins for more content */} +
+
+ {children} +
+
+ + {/* Right TOC - Prominent with progress */} + +
+
+ ); +}; diff --git a/apps/landing/src/components/docs/variant-b/DocsSidebarB.tsx b/apps/landing/src/components/docs/variant-b/DocsSidebarB.tsx new file mode 100644 index 0000000..8f55dcf --- /dev/null +++ b/apps/landing/src/components/docs/variant-b/DocsSidebarB.tsx @@ -0,0 +1,205 @@ +'use client'; + +/** + * Documentation Sidebar - Variant B: Dense & Information-Rich + * + * Design Philosophy: Next.js-inspired nested tree structure + * + * Features: + * - Wider sidebar with deep nesting + * - Section numbers for all items + * - Compact spacing (more items visible) + * - Indent levels for hierarchy + * - Active state: Purple background + bold + * - Expand/collapse all button + * + * Navigation Structure with numbers: + * 1. Getting Started + * 2. API Reference + * 2.1 Text to Image + * 2.2 Upload + * 2.3 Images + * 3. Guides + * 3.1 Authentication + * 3.2 Error Handling + * 3.3 Rate Limits + * 4. Examples + */ + +import { useState } from 'react'; + +interface NavItem { + label: string; + href: string; + number?: string; + children?: NavItem[]; +} + +interface DocsSidebarBProps { + currentPath: string; +} + +const navigationItems: NavItem[] = [ + { + label: 'Getting Started', + href: '/docs/variant-b', + number: '1', + }, + { + label: 'API Reference', + href: '/docs/variant-b/api', + number: '2', + children: [ + { label: 'Text to Image', href: '/docs/variant-b/api/text-to-image', number: '2.1' }, + { label: 'Upload', href: '/docs/variant-b/api/upload', number: '2.2' }, + { label: 'Images', href: '/docs/variant-b/api/images', number: '2.3' }, + ], + }, + { + label: 'Guides', + href: '/docs/variant-b/guides', + number: '3', + children: [ + { label: 'Authentication', href: '/docs/variant-b/guides/authentication', number: '3.1' }, + { label: 'Error Handling', href: '/docs/variant-b/guides/error-handling', number: '3.2' }, + { label: 'Rate Limits', href: '/docs/variant-b/guides/rate-limits', number: '3.3' }, + ], + }, + { + label: 'Examples', + href: '/docs/variant-b/examples', + number: '4', + }, +]; + +export const DocsSidebarB = ({ currentPath }: DocsSidebarBProps) => { + const [expandedSections, setExpandedSections] = useState(['API Reference', 'Guides']); + + const toggleSection = (label: string) => { + setExpandedSections((prev) => + prev.includes(label) ? prev.filter((item) => item !== label) : [...prev, label] + ); + }; + + const isActive = (href: string) => currentPath === href; + const isExpanded = (label: string) => expandedSections.includes(label); + + return ( + + ); +}; diff --git a/apps/landing/src/components/docs/variant-b/DocsTOCB.tsx b/apps/landing/src/components/docs/variant-b/DocsTOCB.tsx new file mode 100644 index 0000000..4d6c274 --- /dev/null +++ b/apps/landing/src/components/docs/variant-b/DocsTOCB.tsx @@ -0,0 +1,141 @@ +'use client'; + +/** + * Table of Contents - Variant B: Dense & Information-Rich + * + * Design Philosophy: Prominent TOC with progress indicator + * + * Features: + * - Section numbers matching content + * - Progress bar showing read percentage + * - Larger, more prominent design + * - Active section with purple highlight + * - Sticky positioning with scroll progress + * + * Behavior: + * - Extracts H2 and H3 headings with numbers + * - Shows reading progress percentage + * - Click to smooth scroll to section + * - Visual progress bar + */ + +import { useEffect, useState } from 'react'; + +interface TocItem { + id: string; + text: string; + level: number; +} + +interface DocsTOCBProps { + items: TocItem[]; +} + +export const DocsTOCB = ({ items }: DocsTOCBProps) => { + const [activeId, setActiveId] = useState(''); + const [scrollProgress, setScrollProgress] = useState(0); + + useEffect(() => { + const observer = new IntersectionObserver( + (entries) => { + entries.forEach((entry) => { + if (entry.isIntersecting) { + setActiveId(entry.target.id); + } + }); + }, + { rootMargin: '-20% 0px -35% 0px' } + ); + + items.forEach((item) => { + const element = document.getElementById(item.id); + if (element) observer.observe(element); + }); + + // Track scroll progress + const handleScroll = () => { + const windowHeight = window.innerHeight; + const documentHeight = document.documentElement.scrollHeight; + const scrollTop = window.scrollY; + const progress = (scrollTop / (documentHeight - windowHeight)) * 100; + setScrollProgress(Math.min(progress, 100)); + }; + + window.addEventListener('scroll', handleScroll); + + return () => { + observer.disconnect(); + window.removeEventListener('scroll', handleScroll); + }; + }, [items]); + + const scrollToSection = (id: string) => { + const element = document.getElementById(id); + if (element) { + element.scrollIntoView({ behavior: 'smooth', block: 'start' }); + } + }; + + if (items.length === 0) { + return null; + } + + return ( + + ); +}; diff --git a/apps/landing/src/components/docs/variant-b/InteractiveAPIWidgetB.tsx b/apps/landing/src/components/docs/variant-b/InteractiveAPIWidgetB.tsx new file mode 100644 index 0000000..21c543d --- /dev/null +++ b/apps/landing/src/components/docs/variant-b/InteractiveAPIWidgetB.tsx @@ -0,0 +1,291 @@ +'use client'; + +/** + * Interactive API Widget - Variant B: Dense & Information-Rich + * + * Design Philosophy: Side-by-side code editor with persistent API key bar + * + * Features: + * - Persistent API key bar at the top of page (sticky) + * - Side-by-side code and response layout + * - Multi-language tabs (curl, JavaScript, Python, Go) + * - Live request execution + * - Compact, information-dense design + * - Parameter form on the left + * - Response on the right + * + * Layout: + * - Top: Sticky API key bar (global for page) + * - Left: Code + Parameters + * - Right: Response viewer + * - Bottom: Try It button + */ + +import { useState, useEffect } from 'react'; + +interface InteractiveAPIWidgetBProps { + endpoint: string; + method: 'GET' | 'POST' | 'PUT' | 'DELETE'; + description: string; + parameters?: Array<{ + name: string; + type: string; + required: boolean; + description: string; + defaultValue?: string; + }>; +} + +type Language = 'curl' | 'javascript' | 'python' | 'go'; + +const API_BASE_URL = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:3000'; +const API_KEY_STORAGE = 'banatie_docs_api_key'; + +export const InteractiveAPIWidgetB = ({ + endpoint, + method, + description, + parameters = [], +}: InteractiveAPIWidgetBProps) => { + const [language, setLanguage] = useState('curl'); + const [apiKey, setApiKey] = useState(''); + const [isExecuting, setIsExecuting] = useState(false); + const [response, setResponse] = useState(null); + const [error, setError] = useState(null); + const [paramValues, setParamValues] = useState>({}); + + // Load API key from localStorage + useEffect(() => { + const stored = localStorage.getItem(API_KEY_STORAGE); + if (stored) setApiKey(stored); + + // Initialize parameter default values + const defaults: Record = {}; + parameters.forEach((param) => { + if (param.defaultValue) { + defaults[param.name] = param.defaultValue; + } + }); + setParamValues(defaults); + }, [parameters]); + + // Save API key to localStorage + const handleApiKeyChange = (value: string) => { + setApiKey(value); + if (value) { + localStorage.setItem(API_KEY_STORAGE, value); + } else { + localStorage.removeItem(API_KEY_STORAGE); + } + }; + + // Generate code examples + const generateCode = (): string => { + const url = `${API_BASE_URL}${endpoint}`; + + switch (language) { + case 'curl': + return `curl -X ${method} "${url}" \\ + -H "X-API-Key: ${apiKey || 'YOUR_API_KEY'}" \\ + -H "Content-Type: application/json" \\ + -d '{ + "prompt": "a futuristic city at sunset", + "filename": "city", + "aspectRatio": "16:9" + }'`; + + case 'javascript': + return `const response = await fetch('${url}', { + method: '${method}', + headers: { + 'X-API-Key': '${apiKey || 'YOUR_API_KEY'}', + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ + prompt: 'a futuristic city at sunset', + filename: 'city', + aspectRatio: '16:9' + }) +}); + +const data = await response.json();`; + + case 'python': + return `import requests + +url = '${url}' +headers = { + 'X-API-Key': '${apiKey || 'YOUR_API_KEY'}', + 'Content-Type': 'application/json' +} +data = { + 'prompt': 'a futuristic city at sunset', + 'filename': 'city', + 'aspectRatio': '16:9' +} + +response = requests.${method.toLowerCase()}(url, headers=headers, json=data)`; + + case 'go': + return `package main + +import ( + "bytes" + "encoding/json" + "net/http" +) + +func main() { + url := "${url}" + data := map[string]interface{}{ + "prompt": "a futuristic city at sunset", + "filename": "city", + "aspectRatio": "16:9", + } + + jsonData, _ := json.Marshal(data) + req, _ := http.NewRequest("${method}", url, bytes.NewBuffer(jsonData)) + req.Header.Set("X-API-Key", "${apiKey || 'YOUR_API_KEY'}") + req.Header.Set("Content-Type", "application/json") + + client := &http.Client{} + resp, _ := client.Do(req) +}`; + + default: + return ''; + } + }; + + // Execute API request + const executeRequest = async () => { + if (!apiKey) { + setError('Please enter your API key in the bar above'); + return; + } + + setIsExecuting(true); + setError(null); + + try { + const body: Record = {}; + parameters.forEach((param) => { + if (paramValues[param.name]) { + body[param.name] = paramValues[param.name]; + } + }); + + const res = await fetch(`${API_BASE_URL}${endpoint}`, { + method, + headers: { + 'X-API-Key': apiKey, + 'Content-Type': 'application/json', + }, + body: method !== 'GET' ? JSON.stringify(body) : undefined, + }); + + const data = await res.json(); + setResponse(data); + } catch (err) { + setError(err instanceof Error ? err.message : 'Failed to execute request'); + } finally { + setIsExecuting(false); + } + }; + + // Copy code to clipboard + const copyCode = () => { + navigator.clipboard.writeText(generateCode()); + }; + + return ( +
+ {/* API Key Bar - Persistent at top */} +
+
+ + handleApiKeyChange(e.target.value)} + placeholder="Enter your API key (persists across examples)" + className="flex-1 px-3 py-1.5 text-xs bg-slate-800 border border-slate-700 rounded text-white placeholder-gray-600 focus:outline-none focus:ring-1 focus:ring-purple-500 focus:border-transparent" + /> + + {apiKey ? 'βœ“ Set' : 'Not set'} + +
+
+ + {/* Main Widget - Two Column Layout */} +
+ {/* Left Column: Code */} +
+ {/* Language Tabs */} +
+
+ {(['curl', 'javascript', 'python', 'go'] as Language[]).map((lang) => ( + + ))} +
+ +
+ + {/* Code Display */} +
+
+              {generateCode()}
+            
+
+
+ + {/* Right Column: Response */} +
+
+

Response

+
+ +
+ {error ? ( +
+ {error} +
+ ) : response ? ( +
+                {JSON.stringify(response, null, 2)}
+              
+ ) : ( +

+ Click "Execute Request" to see the response +

+ )} +
+
+
+ + {/* Try It Button - Full Width */} + + +

{description}

+
+ ); +}; diff --git a/apps/landing/src/components/docs/variant-c/DocsLayoutC.tsx b/apps/landing/src/components/docs/variant-c/DocsLayoutC.tsx new file mode 100644 index 0000000..435ee90 --- /dev/null +++ b/apps/landing/src/components/docs/variant-c/DocsLayoutC.tsx @@ -0,0 +1,74 @@ +'use client'; + +/** + * Documentation Layout - Variant C: Modern & Visual (Shopify-inspired) + * + * Design Philosophy: Colorful, card-based, engaging visual layout + * + * Layout Structure: + * - Left Sidebar: Wide (320px) with large card-style navigation + * - Content Area: Generous padding (p-12) with wide max-width (max-w-5xl) + * - Right TOC: Floating card with gradient borders (280px) + * + * Design Characteristics: + * - Colorful gradient borders everywhere (purple/cyan) + * - Card-based design with shadows + * - Large, generous spacing (p-6, gap-6, mb-12) + * - Playful and engaging visual style + * - NO section numbers (more visual/intuitive) + * - Large emoji icons throughout + * - Floating shadow effects + * + * Responsive Behavior: + * - Mobile (<768px): Single column, cards stack + * - Tablet (768px-1024px): Content + floating TOC + * - Desktop (>1024px): Full three-column card layout + * + * Color Palette: + * - Purple gradients: from-purple-500/30 to-purple-600/20 + * - Cyan gradients: from-cyan-500/30 to-cyan-600/20 + * - Amber accents: amber-500, amber-600 + * - Background: slate-950, slate-900 + * - Borders: purple-500/40, cyan-500/40, slate-700 + * - Shadows: shadow-lg shadow-purple-500/20 + */ + +import { ReactNode } from 'react'; + +interface DocsLayoutCProps { + sidebar: ReactNode; + children: ReactNode; + toc: ReactNode; +} + +export const DocsLayoutC = ({ sidebar, children, toc }: DocsLayoutCProps) => { + return ( +
+ {/* Animated gradient background - More colorful */} +
+
+
+
+
+ +
+ {/* Left Sidebar - Wide with card-style navigation */} + + + {/* Main Content Area - Wide with generous padding */} +
+
+ {children} +
+
+ + {/* Right TOC - Floating card with gradient border */} + +
+
+ ); +}; diff --git a/apps/landing/src/components/docs/variant-c/DocsSidebarC.tsx b/apps/landing/src/components/docs/variant-c/DocsSidebarC.tsx new file mode 100644 index 0000000..7b96844 --- /dev/null +++ b/apps/landing/src/components/docs/variant-c/DocsSidebarC.tsx @@ -0,0 +1,238 @@ +'use client'; + +/** + * Documentation Sidebar - Variant C: Modern & Visual (Shopify-inspired) + * + * Design Philosophy: Card-based navigation with large colorful visual elements + * + * Features: + * - Navigation items as large gradient-bordered cards + * - Large emoji icons (text-2xl) for visual hierarchy + * - Alternating purple/cyan gradient accents + * - Generous spacing (gap-4, p-4 per item) + * - Touch-friendly minimum heights (min-h-12) + * - NO section numbers (more playful/intuitive) + * - Hover effects with shadow and scale + * - Active state with prominent gradient background + * + * Navigation Structure (NO numbers): + * - πŸš€ Getting Started + * - πŸ“š API Reference + * - 🎨 Text to Image + * - πŸ“€ Upload + * - πŸ–ΌοΈ Images + * - πŸ” Guides + * - πŸ”‘ Authentication + * - ⚠️ Error Handling + * - ⏱️ Rate Limits + * - πŸ’‘ Examples + * + * Color Palette: + * - Purple: from-purple-500/30 to-purple-600/20 + * - Cyan: from-cyan-500/30 to-cyan-600/20 + * - Active: bg-gradient-to-br from-purple-500/30 to-cyan-500/30 + * - Hover: shadow-lg shadow-purple-500/20, scale-102 + */ + +import { useState } from 'react'; + +interface NavItem { + label: string; + href: string; + icon: string; + color: 'purple' | 'cyan' | 'amber'; + children?: NavItem[]; +} + +interface DocsSidebarCProps { + currentPath: string; +} + +const navigationItems: NavItem[] = [ + { + label: 'Getting Started', + href: '/docs/variant-c', + icon: 'πŸš€', + color: 'purple', + }, + { + label: 'API Reference', + href: '/docs/variant-c/api', + icon: 'πŸ“š', + color: 'cyan', + children: [ + { label: 'Text to Image', href: '/docs/variant-c/api/text-to-image', icon: '🎨', color: 'purple' }, + { label: 'Upload', href: '/docs/variant-c/api/upload', icon: 'πŸ“€', color: 'cyan' }, + { label: 'Images', href: '/docs/variant-c/api/images', icon: 'πŸ–ΌοΈ', color: 'purple' }, + ], + }, + { + label: 'Guides', + href: '/docs/variant-c/guides', + icon: 'πŸ”', + color: 'purple', + children: [ + { label: 'Authentication', href: '/docs/variant-c/guides/authentication', icon: 'πŸ”‘', color: 'cyan' }, + { label: 'Error Handling', href: '/docs/variant-c/guides/error-handling', icon: '⚠️', color: 'purple' }, + { label: 'Rate Limits', href: '/docs/variant-c/guides/rate-limits', icon: '⏱️', color: 'cyan' }, + ], + }, + { + label: 'Examples', + href: '/docs/variant-c/examples', + icon: 'πŸ’‘', + color: 'amber', + }, +]; + +const getGradientClasses = (color: 'purple' | 'cyan' | 'amber', active: boolean) => { + if (active) { + return 'bg-gradient-to-br from-purple-500/30 to-cyan-500/30 border-purple-500/60 shadow-lg shadow-purple-500/30'; + } + + const baseClasses = 'border-2 hover:shadow-lg transition-all duration-300 hover:scale-[1.02]'; + + switch (color) { + case 'purple': + return `${baseClasses} border-purple-500/30 hover:border-purple-500/50 hover:shadow-purple-500/20 hover:bg-purple-500/10`; + case 'cyan': + return `${baseClasses} border-cyan-500/30 hover:border-cyan-500/50 hover:shadow-cyan-500/20 hover:bg-cyan-500/10`; + case 'amber': + return `${baseClasses} border-amber-500/30 hover:border-amber-500/50 hover:shadow-amber-500/20 hover:bg-amber-500/10`; + default: + return baseClasses; + } +}; + +export const DocsSidebarC = ({ currentPath }: DocsSidebarCProps) => { + const [expandedSections, setExpandedSections] = useState(['API Reference', 'Guides']); + + const toggleSection = (label: string) => { + setExpandedSections((prev) => + prev.includes(label) ? prev.filter((item) => item !== label) : [...prev, label] + ); + }; + + const isActive = (href: string) => currentPath === href; + const isExpanded = (label: string) => expandedSections.includes(label); + + return ( + + ); +}; diff --git a/apps/landing/src/components/docs/variant-c/DocsTOCC.tsx b/apps/landing/src/components/docs/variant-c/DocsTOCC.tsx new file mode 100644 index 0000000..d23f756 --- /dev/null +++ b/apps/landing/src/components/docs/variant-c/DocsTOCC.tsx @@ -0,0 +1,212 @@ +'use client'; + +/** + * Table of Contents - Variant C: Modern & Visual (Shopify-inspired) + * + * Design Philosophy: Floating card with colorful visual indicators + * + * Features: + * - Wrapped in large gradient-bordered card + * - Colorful dot indicators (alternating purple/cyan/amber) + * - Large text sizes (text-base for items) + * - Generous spacing (p-6, gap-4) + * - Floating shadow effect with colored glow + * - NO section numbers (more visual/playful) + * - Active state with gradient background + * - Smooth hover animations with scale + * - Fun, engaging design with emoji header + * + * Visual Elements: + * - Large colored dots instead of numbers + * - Gradient progress bar with rainbow colors + * - Active item with gradient highlight + * - Hover effects with shadow and scale + * + * Behavior: + * - Extracts H2 and H3 headings (no numbers) + * - Shows reading progress with colorful bar + * - Click to smooth scroll to section + * - Visual feedback with animations + */ + +import { useEffect, useState } from 'react'; + +interface TocItem { + id: string; + text: string; + level: number; +} + +interface DocsTOCCProps { + items: TocItem[]; +} + +const getColorForIndex = (index: number): string => { + const colors = ['purple', 'cyan', 'amber']; + return colors[index % colors.length]; +}; + +const getDotClasses = (color: string, isActive: boolean): string => { + const baseClasses = 'w-2.5 h-2.5 rounded-full flex-shrink-0 transition-all duration-300'; + + if (isActive) { + return `${baseClasses} shadow-lg ${ + color === 'purple' + ? 'bg-purple-500 shadow-purple-500/50' + : color === 'cyan' + ? 'bg-cyan-500 shadow-cyan-500/50' + : 'bg-amber-500 shadow-amber-500/50' + }`; + } + + return `${baseClasses} ${ + color === 'purple' + ? 'bg-purple-500/40' + : color === 'cyan' + ? 'bg-cyan-500/40' + : 'bg-amber-500/40' + }`; +}; + +export const DocsTOCC = ({ items }: DocsTOCCProps) => { + const [activeId, setActiveId] = useState(''); + const [scrollProgress, setScrollProgress] = useState(0); + + useEffect(() => { + const observer = new IntersectionObserver( + (entries) => { + entries.forEach((entry) => { + if (entry.isIntersecting) { + setActiveId(entry.target.id); + } + }); + }, + { rootMargin: '-20% 0px -35% 0px' } + ); + + items.forEach((item) => { + const element = document.getElementById(item.id); + if (element) observer.observe(element); + }); + + const handleScroll = () => { + const windowHeight = window.innerHeight; + const documentHeight = document.documentElement.scrollHeight; + const scrollTop = window.scrollY; + const progress = (scrollTop / (documentHeight - windowHeight)) * 100; + setScrollProgress(Math.min(progress, 100)); + }; + + window.addEventListener('scroll', handleScroll); + + return () => { + observer.disconnect(); + window.removeEventListener('scroll', handleScroll); + }; + }, [items]); + + const scrollToSection = (id: string) => { + const element = document.getElementById(id); + if (element) { + element.scrollIntoView({ behavior: 'smooth', block: 'start' }); + } + }; + + if (items.length === 0) { + return null; + } + + return ( + + ); +}; diff --git a/apps/landing/src/components/docs/variant-c/InteractiveAPIWidgetC.tsx b/apps/landing/src/components/docs/variant-c/InteractiveAPIWidgetC.tsx new file mode 100644 index 0000000..c2c6ad9 --- /dev/null +++ b/apps/landing/src/components/docs/variant-c/InteractiveAPIWidgetC.tsx @@ -0,0 +1,393 @@ +'use client'; + +/** + * Interactive API Widget - Variant C: Modern & Visual (Shopify-inspired) + * + * Design Philosophy: Floating, expandable card with colorful visual feedback + * + * Features: + * - Full-screen expandable mode toggle button + * - Large gradient-bordered card with shadow glow + * - Prominent "Test Now ⚑" button (larger, more visual) + * - Response in colorful gradient-bordered card + * - Success/error states with vibrant colored badges + * - More visual feedback and animations + * - Large emoji icons throughout + * - Colorful code syntax highlighting hints + * - Floating shadow effects + * + * Layout: + * - Top: Large colorful API key input card + * - Main: Expandable code editor with rainbow gradient border + * - Language tabs as colorful pills + * - Large prominent "Test Now" button with gradient + * - Response card with colored status indicators + * + * Visual Elements: + * - Purple/cyan/amber gradients everywhere + * - Large shadows with colored glows + * - Scale and hover animations + * - Success: Green gradient with glow + * - Error: Red gradient with glow + */ + +import { useState, useEffect } from 'react'; + +interface InteractiveAPIWidgetCProps { + endpoint: string; + method: 'GET' | 'POST' | 'PUT' | 'DELETE'; + description: string; + parameters?: Array<{ + name: string; + type: string; + required: boolean; + description: string; + defaultValue?: string; + }>; +} + +type Language = 'curl' | 'javascript' | 'python' | 'go'; + +const API_BASE_URL = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:3000'; +const API_KEY_STORAGE = 'banatie_docs_api_key'; + +const getMethodColor = (method: string): string => { + switch (method) { + case 'GET': + return 'from-cyan-500 to-cyan-600'; + case 'POST': + return 'from-purple-500 to-purple-600'; + case 'PUT': + return 'from-amber-500 to-amber-600'; + case 'DELETE': + return 'from-red-500 to-red-600'; + default: + return 'from-purple-500 to-cyan-500'; + } +}; + +export const InteractiveAPIWidgetC = ({ + endpoint, + method, + description, + parameters = [], +}: InteractiveAPIWidgetCProps) => { + const [language, setLanguage] = useState('curl'); + const [apiKey, setApiKey] = useState(''); + const [isExecuting, setIsExecuting] = useState(false); + const [response, setResponse] = useState(null); + const [error, setError] = useState(null); + const [paramValues, setParamValues] = useState>({}); + const [isExpanded, setIsExpanded] = useState(false); + + useEffect(() => { + const stored = localStorage.getItem(API_KEY_STORAGE); + if (stored) setApiKey(stored); + + const defaults: Record = {}; + parameters.forEach((param) => { + if (param.defaultValue) { + defaults[param.name] = param.defaultValue; + } + }); + setParamValues(defaults); + }, [parameters]); + + const handleApiKeyChange = (value: string) => { + setApiKey(value); + if (value) { + localStorage.setItem(API_KEY_STORAGE, value); + } else { + localStorage.removeItem(API_KEY_STORAGE); + } + }; + + const generateCode = (): string => { + const url = `${API_BASE_URL}${endpoint}`; + + switch (language) { + case 'curl': + return `curl -X ${method} "${url}" \\ + -H "X-API-Key: ${apiKey || 'YOUR_API_KEY'}" \\ + -H "Content-Type: application/json" \\ + -d '{ + "prompt": "a futuristic city at sunset", + "filename": "city", + "aspectRatio": "16:9" + }'`; + + case 'javascript': + return `const response = await fetch('${url}', { + method: '${method}', + headers: { + 'X-API-Key': '${apiKey || 'YOUR_API_KEY'}', + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ + prompt: 'a futuristic city at sunset', + filename: 'city', + aspectRatio: '16:9' + }) +}); + +const data = await response.json();`; + + case 'python': + return `import requests + +url = '${url}' +headers = { + 'X-API-Key': '${apiKey || 'YOUR_API_KEY'}', + 'Content-Type': 'application/json' +} +data = { + 'prompt': 'a futuristic city at sunset', + 'filename': 'city', + 'aspectRatio': '16:9' +} + +response = requests.${method.toLowerCase()}(url, headers=headers, json=data)`; + + case 'go': + return `package main + +import ( + "bytes" + "encoding/json" + "net/http" +) + +func main() { + url := "${url}" + data := map[string]interface{}{ + "prompt": "a futuristic city at sunset", + "filename": "city", + "aspectRatio": "16:9", + } + + jsonData, _ := json.Marshal(data) + req, _ := http.NewRequest("${method}", url, bytes.NewBuffer(jsonData)) + req.Header.Set("X-API-Key", "${apiKey || 'YOUR_API_KEY'}") + req.Header.Set("Content-Type", "application/json") + + client := &http.Client{} + resp, _ := client.Do(req) +}`; + + default: + return ''; + } + }; + + const executeRequest = async () => { + if (!apiKey) { + setError('Please enter your API key above ✨'); + return; + } + + setIsExecuting(true); + setError(null); + + try { + const body: Record = {}; + parameters.forEach((param) => { + if (paramValues[param.name]) { + body[param.name] = paramValues[param.name]; + } + }); + + const res = await fetch(`${API_BASE_URL}${endpoint}`, { + method, + headers: { + 'X-API-Key': apiKey, + 'Content-Type': 'application/json', + }, + body: method !== 'GET' ? JSON.stringify(body) : undefined, + }); + + const data = await res.json(); + setResponse(data); + } catch (err) { + setError(err instanceof Error ? err.message : 'Failed to execute request πŸ˜”'); + } finally { + setIsExecuting(false); + } + }; + + const copyCode = () => { + navigator.clipboard.writeText(generateCode()); + }; + + return ( +
+ {/* API Key Card - Large and Colorful */} +
+
+ πŸ”‘ + +
+
+ handleApiKeyChange(e.target.value)} + placeholder="Enter your API key (saved locally)" + className="flex-1 px-4 py-3 text-sm bg-slate-900/80 border-2 border-purple-500/30 rounded-xl text-white placeholder-gray-500 focus:outline-none focus:ring-2 focus:ring-purple-500 focus:border-purple-500/50 transition-all" + /> +
+ {apiKey ? 'βœ“ Ready' : '⚠️ Required'} +
+
+
+ + {/* Main Widget Card - Large Gradient Border */} +
+ {/* Header with Expand Button */} +
+
+
+ {method} +
+ {endpoint} +
+ +
+ +
+ {/* Left: Code Editor */} +
+ {/* Language Tabs - Colorful Pills */} +
+ {(['curl', 'javascript', 'python', 'go'] as Language[]).map((lang, idx) => { + const colors = ['purple', 'cyan', 'amber', 'purple']; + const color = colors[idx]; + return ( + + ); + })} +
+ + {/* Code Display - Gradient Border */} +
+
+ Code Example + +
+
+
+                  {generateCode()}
+                
+
+
+
+ + {/* Right: Response */} +
+

+ πŸ“¦ + Response +

+ +
+
+ {response && ( + + {response.success ? 'βœ“ Success' : 'βœ• Error'} + + )} +
+
+ {error ? ( +
+
+ ⚠️ +
+

Error

+

{error}

+
+
+
+ ) : response ? ( +
+                    {JSON.stringify(response, null, 2)}
+                  
+ ) : ( +
+
+

πŸš€

+

+ Click "Test Now" below to see the response +

+
+
+ )} +
+
+
+
+ + {/* Large Test Now Button */} +
+ +

{description}

+
+
+
+ ); +};