+
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.
-
-
-
-
-
-
Compact spacing, more content visible
-
-
-
-
-
-
Section numbers (1., 2.1, etc.)
-
-
-
-
-
-
Hierarchical nested tree navigation
-
+ {/* Prominent Tip Box for Security Warning */}
+
+
+ Security Best Practice: Keep your API keys secure.
+ Never commit them to public repositories or expose them in client-side code. Use environment
+ variables and server-side implementations for production applications.
+
-
-
Explore Variant B
-
-
-
-
-
+
- π¨
-
- Variant C
-
- Modern & Visual
-
- Shopify-inspired colorful card-based design with large emoji icons, gradient borders,
- and playful engaging visual style.
-
+# Save the returned key securely
+export BANATIE_API_KEY="bnt_your_key_here"`}
+ language="bash"
+ filename="Get API Key"
+ />
+
+
-
-
-
-
-
-
Colorful gradient borders everywhere
+ {/* 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:
+
+
+
+ β 200 Success
+
-
-
-
-
-
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
-
+
+ {`{
+ "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..."
+ }
+ }
+}`}
+
-
+
- {/* Footer CTA */}
-
-
- Not sure which to choose? Try all three and see which feels right!
+ {/* Next Steps - Simplified to 2 Cards */}
+
+ Next Steps
+
+ Now that you have generated your first image, explore these resources to build more advanced integrations:
-
- 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
deleted file mode 100644
index 61e796c..0000000
--- a/apps/landing/src/app/docs/variant-a/api/text-to-image/page.tsx
+++ /dev/null
@@ -1,299 +0,0 @@
-'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
-
-
-
-
-
Body Parameters
-
-
-
-
- Parameter
- Type
- Description
- Required
-
-
-
-
- prompt
- string
- Text description of the image to generate
-
- Yes
-
-
-
- filename
- string
- Name for the generated image file
-
- Yes
-
-
-
- aspectRatio
- string
-
- Image aspect ratio. Options: 1:1, 3:4, 4:3, 9:16, 16:9, 21:9
-
-
- No
-
-
-
- autoEnhance
- boolean
- Enable automatic prompt enhancement (default: true)
-
- No
-
-
-
- enhancementOptions
- object
- Template 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
-
-
-
-
- Code
- Description
-
-
-
-
- 400
- Invalid request parameters
-
-
- 401
- Missing or invalid API key
-
-
- 429
- Rate limit exceeded
-
-
- 500
- Internal 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
deleted file mode 100644
index 535e8bb..0000000
--- a/apps/landing/src/app/docs/variant-a/guides/authentication/page.tsx
+++ /dev/null
@@ -1,300 +0,0 @@
-'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 Type
- Limit
- Window
-
-
-
-
- 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-a/page.tsx b/apps/landing/src/app/docs/variant-a/page.tsx
deleted file mode 100644
index 972c2e6..0000000
--- a/apps/landing/src/app/docs/variant-a/page.tsx
+++ /dev/null
@@ -1,208 +0,0 @@
-'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 */}
-
-
- );
-}
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
deleted file mode 100644
index 3c830bd..0000000
--- a/apps/landing/src/app/docs/variant-b/api/text-to-image/page.tsx
+++ /dev/null
@@ -1,304 +0,0 @@
-'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.2 Body Parameters
-
-
-
-
- Parameter
- Type
- Description
- Required
-
-
-
-
- prompt
- string
- Text description of the image to generate
-
- Yes
-
-
-
- filename
- string
- Name for the generated image file
-
- Yes
-
-
-
- aspectRatio
- string
-
- Image aspect ratio. Options: 1:1, 3:4, 4:3, 9:16, 16:9, 21:9
-
-
- No
-
-
-
- autoEnhance
- boolean
- Enable automatic prompt enhancement (default: true)
-
- No
-
-
-
- enhancementOptions
- object
- Template 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
-
-
-
-
- Code
- Description
-
-
-
-
- 400
- Invalid request parameters
-
-
- 401
- Missing or invalid API key
-
-
- 429
- Rate limit exceeded
-
-
- 500
- Internal 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
deleted file mode 100644
index a4b8ffb..0000000
--- a/apps/landing/src/app/docs/variant-b/guides/authentication/page.tsx
+++ /dev/null
@@ -1,305 +0,0 @@
-'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 Type
- Limit
- Window
-
-
-
-
- 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-b/page.tsx b/apps/landing/src/app/docs/variant-b/page.tsx
deleted file mode 100644
index c8320e6..0000000
--- a/apps/landing/src/app/docs/variant-b/page.tsx
+++ /dev/null
@@ -1,211 +0,0 @@
-'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 */}
-
-
- );
-}
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
deleted file mode 100644
index 83665b8..0000000
--- a/apps/landing/src/app/docs/variant-c/api/text-to-image/page.tsx
+++ /dev/null
@@ -1,369 +0,0 @@
-'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
-
-
-
-
-
-
- βοΈ
-
Body Parameters
-
-
-
-
-
- Parameter
- Type
- Description
- Required
-
-
-
-
- prompt
- string
- Text description of the image to generate
-
-
- Required
-
-
-
-
- filename
- string
- Name for the generated image file
-
-
- Required
-
-
-
-
- aspectRatio
- string
-
- Image aspect ratio. Options: 1:1, 3:4, 4:3, 9:16, 16:9, 21:9
-
-
-
- Optional
-
-
-
-
- autoEnhance
- boolean
- Enable automatic prompt enhancement (default: true)
-
-
- Optional
-
-
-
-
- enhancementOptions
- object
- Template 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
-
-
-
-
-
- Code
- Description
-
-
-
-
- 400
- Invalid request parameters
-
-
- 401
- Missing or invalid API key
-
-
- 429
- Rate limit exceeded
-
-
- 500
- Internal 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
deleted file mode 100644
index 1e9b3ef..0000000
--- a/apps/landing/src/app/docs/variant-c/guides/authentication/page.tsx
+++ /dev/null
@@ -1,370 +0,0 @@
-'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 Type
- Limit
- Window
-
-
-
-
- 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
deleted file mode 100644
index b80157e..0000000
--- a/apps/landing/src/app/docs/variant-c/page.tsx
+++ /dev/null
@@ -1,268 +0,0 @@
-'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
-
-
-
-
-
- {/* 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/final/DocsLayoutFinal.tsx b/apps/landing/src/components/docs/docs/DocsLayout.tsx
similarity index 92%
rename from apps/landing/src/components/docs/final/DocsLayoutFinal.tsx
rename to apps/landing/src/components/docs/docs/DocsLayout.tsx
index db66cc7..10bde15 100644
--- a/apps/landing/src/components/docs/final/DocsLayoutFinal.tsx
+++ b/apps/landing/src/components/docs/docs/DocsLayout.tsx
@@ -1,7 +1,7 @@
'use client';
/**
- * Documentation Layout - Final Variant
+ * Documentation Layout - Production Version
*
* Based on Variant A: Clean & Minimal with enhancements
* This is the production-ready version combining the best aspects
@@ -26,13 +26,13 @@
import { ReactNode } from 'react';
-interface DocsLayoutFinalProps {
+interface DocsLayoutProps {
sidebar: ReactNode;
children: ReactNode;
toc: ReactNode;
}
-export const DocsLayoutFinal = ({ sidebar, children, toc }: DocsLayoutFinalProps) => {
+export const DocsLayout = ({ sidebar, children, toc }: DocsLayoutProps) => {
return (
{/* Animated gradient background (matching landing page) */}
diff --git a/apps/landing/src/components/docs/final/DocsSidebarFinal.tsx b/apps/landing/src/components/docs/docs/DocsSidebar.tsx
similarity index 84%
rename from apps/landing/src/components/docs/final/DocsSidebarFinal.tsx
rename to apps/landing/src/components/docs/docs/DocsSidebar.tsx
index 7c4e60c..b5e6d6a 100644
--- a/apps/landing/src/components/docs/final/DocsSidebarFinal.tsx
+++ b/apps/landing/src/components/docs/docs/DocsSidebar.tsx
@@ -1,7 +1,7 @@
'use client';
/**
- * Documentation Sidebar - Final Variant
+ * Documentation Sidebar - Production Version
*
* Based on Variant A with FIXED active states
*
@@ -33,44 +33,44 @@ interface NavItem {
children?: NavItem[];
}
-interface DocsSidebarFinalProps {
+interface DocsSidebarProps {
currentPath: string;
}
const navigationItems: NavItem[] = [
{
label: 'Getting Started',
- href: '/docs/final',
+ href: '/docs',
icon: 'π',
},
{
label: 'API Reference',
- href: '/docs/final/api',
+ href: '/docs/api',
icon: 'π',
children: [
- { label: 'Text to Image', href: '/docs/final/api/text-to-image' },
- { label: 'Upload', href: '/docs/final/api/upload' },
- { label: 'Images', href: '/docs/final/api/images' },
+ { label: 'Text to Image', href: '/docs/api/text-to-image' },
+ { label: 'Upload', href: '/docs/api/upload' },
+ { label: 'Images', href: '/docs/api/images' },
],
},
{
label: 'Guides',
- href: '/docs/final/guides',
+ href: '/docs/guides',
icon: 'π',
children: [
- { label: 'Authentication', href: '/docs/final/guides/authentication' },
- { label: 'Error Handling', href: '/docs/final/guides/error-handling' },
- { label: 'Rate Limits', href: '/docs/final/guides/rate-limits' },
+ { label: 'Authentication', href: '/docs/guides/authentication' },
+ { label: 'Error Handling', href: '/docs/guides/error-handling' },
+ { label: 'Rate Limits', href: '/docs/guides/rate-limits' },
],
},
{
label: 'Examples',
- href: '/docs/final/examples',
+ href: '/docs/examples',
icon: 'π‘',
},
];
-export const DocsSidebarFinal = ({ currentPath }: DocsSidebarFinalProps) => {
+export const DocsSidebar = ({ currentPath }: DocsSidebarProps) => {
const [expandedSections, setExpandedSections] = useState
(['API Reference', 'Guides']);
const toggleSection = (label: string) => {
@@ -87,7 +87,7 @@ export const DocsSidebarFinal = ({ currentPath }: DocsSidebarFinalProps) => {
{/* Logo/Title */}
Documentation
-
Final: Production
+
API Reference
{/* Navigation Items */}
@@ -170,8 +170,8 @@ export const DocsSidebarFinal = ({ currentPath }: DocsSidebarFinalProps) => {
diff --git a/apps/landing/src/components/docs/final/DocsTOCFinal.tsx b/apps/landing/src/components/docs/docs/DocsTOC.tsx
similarity index 95%
rename from apps/landing/src/components/docs/final/DocsTOCFinal.tsx
rename to apps/landing/src/components/docs/docs/DocsTOC.tsx
index 0a25277..5b0ca3d 100644
--- a/apps/landing/src/components/docs/final/DocsTOCFinal.tsx
+++ b/apps/landing/src/components/docs/docs/DocsTOC.tsx
@@ -1,7 +1,7 @@
'use client';
/**
- * Table of Contents - Final Variant
+ * Table of Contents - Production Version
*
* Based on Variant A: Clean & Minimal (no changes needed)
*
@@ -26,11 +26,11 @@ interface TocItem {
level: number;
}
-interface DocsTOCFinalProps {
+interface DocsTOCProps {
items: TocItem[];
}
-export const DocsTOCFinal = ({ items }: DocsTOCFinalProps) => {
+export const DocsTOC = ({ items }: DocsTOCProps) => {
const [activeId, setActiveId] = useState
('');
useEffect(() => {
diff --git a/apps/landing/src/components/docs/final/InteractiveAPIWidgetFinal.tsx b/apps/landing/src/components/docs/docs/InteractiveAPIWidget.tsx
similarity index 98%
rename from apps/landing/src/components/docs/final/InteractiveAPIWidgetFinal.tsx
rename to apps/landing/src/components/docs/docs/InteractiveAPIWidget.tsx
index a146cb6..8b91a4d 100644
--- a/apps/landing/src/components/docs/final/InteractiveAPIWidgetFinal.tsx
+++ b/apps/landing/src/components/docs/docs/InteractiveAPIWidget.tsx
@@ -1,9 +1,9 @@
'use client';
/**
- * Interactive API Widget - Final Variant (Redesigned)
+ * Interactive API Widget - Production Version
*
- * Minimized layout inspired by Variant C with Final variant design system:
+ * Minimized layout with clean design system:
* - No inline API key input (uses DocsApiKeyInput component)
* - Clean header with method badge, endpoint, and expand button
* - Full-width code snippet area
@@ -13,7 +13,7 @@
import { useState, useEffect } from 'react';
-interface InteractiveAPIWidgetFinalProps {
+interface InteractiveAPIWidgetProps {
endpoint: string;
method: 'GET' | 'POST' | 'PUT' | 'DELETE';
description: string;
@@ -46,12 +46,12 @@ const getMethodBadgeStyle = (method: string): string => {
}
};
-export const InteractiveAPIWidgetFinal = ({
+export const InteractiveAPIWidget = ({
endpoint,
method,
description,
parameters = [],
-}: InteractiveAPIWidgetFinalProps) => {
+}: InteractiveAPIWidgetProps) => {
const [language, setLanguage] = useState('curl');
const [apiKey, setApiKey] = useState('');
const [isExecuting, setIsExecuting] = useState(false);
diff --git a/apps/landing/src/components/docs/variant-a/DocsLayoutA.tsx b/apps/landing/src/components/docs/variant-a/DocsLayoutA.tsx
deleted file mode 100644
index 66f33e5..0000000
--- a/apps/landing/src/components/docs/variant-a/DocsLayoutA.tsx
+++ /dev/null
@@ -1,62 +0,0 @@
-'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
deleted file mode 100644
index 34bb8d4..0000000
--- a/apps/landing/src/components/docs/variant-a/DocsSidebarA.tsx
+++ /dev/null
@@ -1,178 +0,0 @@
-'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 (
-
- {/* Logo/Title */}
-
-
Documentation
-
Variant A: Clean
-
-
- {/* Navigation Items */}
-
- {navigationItems.map((item) => {
- const hasChildren = item.children && item.children.length > 0;
- const expanded = isExpanded(item.label);
- const active = isActive(item.href);
-
- return (
-
- {/* Parent Item */}
-
-
- {/* Children Items */}
- {hasChildren && expanded && (
-
- {item.children!.map((child) => {
- const childActive = isActive(child.href);
- return (
-
-
- {child.label}
-
-
- );
- })}
-
- )}
-
- );
- })}
-
-
- {/* Bottom Links */}
-
-
- );
-};
diff --git a/apps/landing/src/components/docs/variant-a/DocsTOCA.tsx b/apps/landing/src/components/docs/variant-a/DocsTOCA.tsx
deleted file mode 100644
index 330edf9..0000000
--- a/apps/landing/src/components/docs/variant-a/DocsTOCA.tsx
+++ /dev/null
@@ -1,102 +0,0 @@
-'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 (
-
-
- On This Page
-
-
-
- {items.map((item) => {
- const isActive = activeId === item.id;
- const isH3 = item.level === 3;
-
- return (
-
- scrollToSection(item.id)}
- className={`
- flex items-start gap-2 text-left w-full transition-colors group
- ${isActive ? 'text-purple-400' : 'text-gray-500 hover:text-gray-300'}
- `}
- >
- {/* Indicator dot */}
-
- {item.text}
-
-
- );
- })}
-
-
- );
-};
diff --git a/apps/landing/src/components/docs/variant-a/InteractiveAPIWidgetA.tsx b/apps/landing/src/components/docs/variant-a/InteractiveAPIWidgetA.tsx
deleted file mode 100644
index a1d443a..0000000
--- a/apps/landing/src/components/docs/variant-a/InteractiveAPIWidgetA.tsx
+++ /dev/null
@@ -1,293 +0,0 @@
-'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) => (
- setLanguage(lang)}
- className={`px-3 py-1 text-xs rounded transition-colors ${
- language === lang
- ? 'bg-slate-700 text-white'
- : 'text-gray-400 hover:text-white'
- }`}
- >
- {lang === 'javascript' ? 'JavaScript' : lang.charAt(0).toUpperCase() + lang.slice(1)}
-
- ))}
-
-
- Copy
-
-
-
- {/* Code Display */}
-
-
- {/* Try It Button */}
-
-
- {isExecuting ? 'Executing...' : 'Try It'}
-
-
-
- {/* 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
deleted file mode 100644
index c019a9e..0000000
--- a/apps/landing/src/components/docs/variant-b/DocsLayoutB.tsx
+++ /dev/null
@@ -1,62 +0,0 @@
-'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
deleted file mode 100644
index 8f55dcf..0000000
--- a/apps/landing/src/components/docs/variant-b/DocsSidebarB.tsx
+++ /dev/null
@@ -1,205 +0,0 @@
-'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 (
-
- {/* Header */}
-
-
Documentation
-
Variant B: Dense
-
-
- {/* Search (placeholder) */}
-
-
- {/* Navigation Tree */}
-
-
- {/* Bottom Links */}
-
-
- );
-};
diff --git a/apps/landing/src/components/docs/variant-b/DocsTOCB.tsx b/apps/landing/src/components/docs/variant-b/DocsTOCB.tsx
deleted file mode 100644
index 4d6c274..0000000
--- a/apps/landing/src/components/docs/variant-b/DocsTOCB.tsx
+++ /dev/null
@@ -1,141 +0,0 @@
-'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 (
-
- {/* Header with Progress */}
-
-
- On This Page
-
- {/* Progress Bar */}
-
-
{Math.round(scrollProgress)}% read
-
-
- {/* TOC Items with Numbers */}
-
- {items.map((item, index) => {
- const isActive = activeId === item.id;
- const isH3 = item.level === 3;
- const number = isH3 ? `${Math.floor(index / 2)}.${index % 2 + 1}` : `${index + 1}`;
-
- return (
-
- scrollToSection(item.id)}
- className={`
- flex items-start gap-2 text-left w-full transition-colors py-1 px-2 rounded-md
- ${isActive ? 'bg-purple-500/20 text-purple-300 font-semibold' : 'text-gray-500 hover:text-gray-300 hover:bg-slate-800/30'}
- `}
- >
- {/* Section number */}
-
- {isH3 ? 'β³' : number}
-
- {item.text}
-
-
- );
- })}
-
-
- {/* Back to Top Button */}
- {scrollProgress > 20 && (
- window.scrollTo({ top: 0, behavior: 'smooth' })}
- className="mt-6 w-full px-3 py-2 text-xs bg-slate-800/50 hover:bg-slate-800 text-gray-400 hover:text-white rounded-lg transition-colors flex items-center justify-center gap-2"
- >
-
-
-
- Back to top
-
- )}
-
- );
-};
diff --git a/apps/landing/src/components/docs/variant-b/InteractiveAPIWidgetB.tsx b/apps/landing/src/components/docs/variant-b/InteractiveAPIWidgetB.tsx
deleted file mode 100644
index 21c543d..0000000
--- a/apps/landing/src/components/docs/variant-b/InteractiveAPIWidgetB.tsx
+++ /dev/null
@@ -1,291 +0,0 @@
-'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 */}
-
-
- API Key:
- 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) => (
- setLanguage(lang)}
- className={`px-2 py-1 text-xs rounded transition-colors ${
- language === lang ? 'bg-slate-700 text-white' : 'text-gray-500 hover:text-white'
- }`}
- >
- {lang === 'javascript' ? 'JS' : lang.toUpperCase()}
-
- ))}
-
-
- Copy
-
-
-
- {/* Code Display */}
-
-
-
- {/* Right Column: Response */}
-
-
-
Response
-
-
-
- {error ? (
-
- {error}
-
- ) : response ? (
-
- {JSON.stringify(response, null, 2)}
-
- ) : (
-
- Click "Execute Request" to see the response
-
- )}
-
-
-
-
- {/* Try It Button - Full Width */}
-
- {isExecuting ? 'Executing...' : 'βΆ Execute Request'}
-
-
-
{description}
-
- );
-};
diff --git a/apps/landing/src/components/docs/variant-c/DocsLayoutC.tsx b/apps/landing/src/components/docs/variant-c/DocsLayoutC.tsx
deleted file mode 100644
index 435ee90..0000000
--- a/apps/landing/src/components/docs/variant-c/DocsLayoutC.tsx
+++ /dev/null
@@ -1,74 +0,0 @@
-'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
deleted file mode 100644
index 7b96844..0000000
--- a/apps/landing/src/components/docs/variant-c/DocsSidebarC.tsx
+++ /dev/null
@@ -1,238 +0,0 @@
-'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 (
-
- {/* Header - Colorful */}
-
-
- π
-
Documentation
-
-
Variant C: Modern & Visual
-
-
- {/* Search (placeholder) - Colorful border */}
-
-
- {/* Navigation Cards */}
-
-
- {/* Bottom Links - Colorful Card */}
-
-
- );
-};
diff --git a/apps/landing/src/components/docs/variant-c/DocsTOCC.tsx b/apps/landing/src/components/docs/variant-c/DocsTOCC.tsx
deleted file mode 100644
index d23f756..0000000
--- a/apps/landing/src/components/docs/variant-c/DocsTOCC.tsx
+++ /dev/null
@@ -1,212 +0,0 @@
-'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 (
-
- {/* Floating Card with Gradient Border */}
-
- {/* Header with Icon and Progress */}
-
-
- π
-
- On This Page
-
-
-
- {/* Rainbow Progress Bar */}
-
-
-
{Math.round(scrollProgress)}% complete
-
- {items.findIndex((item) => item.id === activeId) + 1}/{items.length}
-
-
-
-
- {/* TOC Items with Colorful Dots */}
-
- {items.map((item, index) => {
- const isActive = activeId === item.id;
- const isH3 = item.level === 3;
- const color = getColorForIndex(index);
- const cleanText = item.text.replace(/^\d+\.?\s*/, '');
-
- return (
-
- scrollToSection(item.id)}
- className={`
- flex items-start gap-3 text-left w-full transition-all duration-300 py-2 px-3 rounded-lg
- ${
- isActive
- ? 'bg-gradient-to-br from-purple-500/20 to-cyan-500/20 text-white font-semibold shadow-lg scale-105'
- : 'text-gray-400 hover:text-white hover:bg-slate-800/50 hover:scale-102'
- }
- `}
- >
- {/* Colorful Dot Indicator */}
-
- {isH3 ? (
- β³
- ) : (
-
- )}
-
-
- {/* Text */}
- {cleanText}
-
-
- );
- })}
-
-
- {/* Back to Top Button - Colorful */}
- {scrollProgress > 20 && (
-
-
window.scrollTo({ top: 0, behavior: 'smooth' })}
- className="w-full px-4 py-3 text-sm bg-gradient-to-r from-purple-600/30 to-cyan-600/30 hover:from-purple-600/50 hover:to-cyan-600/50 text-white rounded-xl transition-all duration-300 flex items-center justify-center gap-2 border-2 border-purple-500/40 hover:border-purple-500/60 shadow-lg hover:shadow-purple-500/30 hover:scale-105"
- >
-
-
-
- Back to top
-
-
- )}
-
-
- {/* Fun Floating Tip Card */}
-
-
-
π‘
-
- Tip: Click any item to jump directly to that section!
-
-
-
-
- );
-};
diff --git a/apps/landing/src/components/docs/variant-c/InteractiveAPIWidgetC.tsx b/apps/landing/src/components/docs/variant-c/InteractiveAPIWidgetC.tsx
deleted file mode 100644
index c2c6ad9..0000000
--- a/apps/landing/src/components/docs/variant-c/InteractiveAPIWidgetC.tsx
+++ /dev/null
@@ -1,393 +0,0 @@
-'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 */}
-
-
- π
- Your API Key
-
-
-
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}
-
-
setIsExpanded(!isExpanded)}
- className="px-4 py-2 bg-cyan-600/20 hover:bg-cyan-600/30 text-cyan-400 rounded-lg transition-all text-sm font-semibold border-2 border-cyan-500/40 hover:border-cyan-500/60"
- >
- {isExpanded ? 'β Close' : 'βΆ Expand'}
-
-
-
-
- {/* 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 (
- setLanguage(lang)}
- className={`px-4 py-2 text-sm rounded-xl font-semibold transition-all border-2 ${
- language === lang
- ? color === 'purple'
- ? 'bg-purple-500/30 text-white border-purple-500/60 shadow-lg shadow-purple-500/30'
- : color === 'cyan'
- ? 'bg-cyan-500/30 text-white border-cyan-500/60 shadow-lg shadow-cyan-500/30'
- : 'bg-amber-500/30 text-white border-amber-500/60 shadow-lg shadow-amber-500/30'
- : 'bg-slate-800/30 text-gray-400 border-slate-700 hover:border-slate-600 hover:text-white'
- }`}
- >
- {lang === 'javascript' ? 'JS' : lang.toUpperCase()}
-
- );
- })}
-
-
- {/* Code Display - Gradient Border */}
-
-
- Code Example
-
- π Copy
-
-
-
-
-
-
- {/* Right: Response */}
-
-
- π¦
- Response
-
-
-
-
- {response && (
-
- {response.success ? 'β Success' : 'β Error'}
-
- )}
-
-
- {error ? (
-
- ) : response ? (
-
- {JSON.stringify(response, null, 2)}
-
- ) : (
-
-
-
π
-
- Click "Test Now" below to see the response
-
-
-
- )}
-
-
-
-
-
- {/* Large Test Now Button */}
-
-
- {isExecuting ? (
- <>
- β‘
- Executing...
- >
- ) : (
- <>
- β‘
- Test Now
- >
- )}
-
-
{description}
-
-
-
- );
-};