feat: leave final variant

This commit is contained in:
Oleg Proskurin 2025-10-17 23:32:06 +07:00
parent bd46f63ac8
commit a272c8d74f
29 changed files with 247 additions and 5509 deletions

View File

@ -11,13 +11,13 @@
* - Simplified Next Steps * - Simplified Next Steps
*/ */
import { DocsLayoutFinal } from '@/components/docs/final/DocsLayoutFinal'; import { DocsLayout } from '@/components/docs/docs/DocsLayout';
import { DocsSidebarFinal } from '@/components/docs/final/DocsSidebarFinal'; import { DocsSidebar } from '@/components/docs/docs/DocsSidebar';
import { DocsTOCFinal } from '@/components/docs/final/DocsTOCFinal'; import { DocsTOC } from '@/components/docs/docs/DocsTOC';
import { SubsectionNav } from '@/components/shared/SubsectionNav'; import { SubsectionNav } from '@/components/shared/SubsectionNav';
import { TipBox } from '@/components/docs/shared/TipBox'; import { TipBox } from '@/components/docs/shared/TipBox';
import { Table } from '@/components/docs/shared/Table'; import { Table } from '@/components/docs/shared/Table';
import { InteractiveAPIWidgetFinal } from '@/components/docs/final/InteractiveAPIWidgetFinal'; import { InteractiveAPIWidget } from '@/components/docs/docs/InteractiveAPIWidget';
import { Breadcrumb } from '@/components/docs/shared/Breadcrumb'; import { Breadcrumb } from '@/components/docs/shared/Breadcrumb';
import { CodeBlock } from '@/components/docs/shared/CodeBlock'; import { CodeBlock } from '@/components/docs/shared/CodeBlock';
@ -32,9 +32,9 @@ const tocItems = [
]; ];
const navItems = [ const navItems = [
{ label: 'Documentation', href: '/docs/final' }, { label: 'Documentation', href: '/docs' },
{ label: 'Demo', href: '/demo' }, { label: 'Demo', href: '/demo' },
{ label: 'Examples', href: '/docs/final/examples' }, { label: 'Examples', href: '/docs/examples' },
]; ];
const parameters = [ const parameters = [
@ -50,18 +50,18 @@ export default function TextToImageAPIPage() {
{/* Subsection Navigation with API Key Input */} {/* Subsection Navigation with API Key Input */}
<SubsectionNav <SubsectionNav
items={navItems} items={navItems}
currentPath="/docs/final/api/text-to-image" currentPath="/docs/api/text-to-image"
showApiKeyInput={true} showApiKeyInput={true}
/> />
<DocsLayoutFinal <DocsLayout
sidebar={<DocsSidebarFinal currentPath="/docs/final/api/text-to-image" />} sidebar={<DocsSidebar currentPath="/docs/api/text-to-image" />}
toc={<DocsTOCFinal items={tocItems} />} toc={<DocsTOC items={tocItems} />}
> >
<Breadcrumb <Breadcrumb
items={[ items={[
{ label: 'Documentation', href: '/docs' }, { label: 'Documentation', href: '/docs' },
{ label: 'API Reference', href: '/docs/final/api' }, { label: 'API Reference', href: '/docs/api' },
{ label: 'Text to Image' }, { label: 'Text to Image' },
]} ]}
/> />
@ -210,7 +210,7 @@ export default function TextToImageAPIPage() {
Test the API directly from this page. Enter your API key and customize the parameters below. Test the API directly from this page. Enter your API key and customize the parameters below.
</p> </p>
<InteractiveAPIWidgetFinal <InteractiveAPIWidget
endpoint="/api/text-to-image" endpoint="/api/text-to-image"
method="POST" method="POST"
description="Generate an image from a text prompt" description="Generate an image from a text prompt"
@ -224,7 +224,7 @@ export default function TextToImageAPIPage() {
<div className="grid md:grid-cols-2 gap-4"> <div className="grid md:grid-cols-2 gap-4">
<a <a
href="/docs/final/api/upload" href="/docs/api/upload"
className="p-5 bg-gradient-to-br from-purple-500/10 to-transparent border border-slate-700/50 rounded-xl hover:border-purple-500/40 transition-colors group" className="p-5 bg-gradient-to-br from-purple-500/10 to-transparent border border-slate-700/50 rounded-xl hover:border-purple-500/40 transition-colors group"
> >
<h3 className="text-lg font-semibold text-white mb-2 group-hover:text-purple-400 transition-colors"> <h3 className="text-lg font-semibold text-white mb-2 group-hover:text-purple-400 transition-colors">
@ -236,7 +236,7 @@ export default function TextToImageAPIPage() {
</a> </a>
<a <a
href="/docs/final/guides/error-handling" href="/docs/guides/error-handling"
className="p-5 bg-gradient-to-br from-cyan-500/10 to-transparent border border-slate-700/50 rounded-xl hover:border-cyan-500/40 transition-colors group" className="p-5 bg-gradient-to-br from-cyan-500/10 to-transparent border border-slate-700/50 rounded-xl hover:border-cyan-500/40 transition-colors group"
> >
<h3 className="text-lg font-semibold text-white mb-2 group-hover:text-cyan-400 transition-colors"> <h3 className="text-lg font-semibold text-white mb-2 group-hover:text-cyan-400 transition-colors">
@ -248,7 +248,7 @@ export default function TextToImageAPIPage() {
</a> </a>
</div> </div>
</section> </section>
</DocsLayoutFinal> </DocsLayout>
</> </>
); );
} }

View File

@ -1,225 +0,0 @@
'use client';
/**
* Getting Started Page - Final Variant
*
* Production-ready documentation landing page
* Features:
* - SubsectionNav at top
* - Both TipBox styles (compact + prominent)
* - Enhanced tables
* - Simplified Next Steps (2 cards only)
* - Clean, accessible design
*/
import { DocsLayoutFinal } from '@/components/docs/final/DocsLayoutFinal';
import { DocsSidebarFinal } from '@/components/docs/final/DocsSidebarFinal';
import { DocsTOCFinal } from '@/components/docs/final/DocsTOCFinal';
import { SubsectionNav } from '@/components/shared/SubsectionNav';
import { TipBox } from '@/components/docs/shared/TipBox';
import { Table } from '@/components/docs/shared/Table';
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 },
];
const navItems = [
{ label: 'Documentation', href: '/docs/final' },
{ label: 'Demo', href: '/demo' },
{ label: 'Examples', href: '/docs/final/examples' },
];
export default function GettingStartedPageFinal() {
return (
<>
{/* Subsection Navigation */}
<SubsectionNav
items={navItems}
currentPath="/docs/final"
ctaText="Join Beta"
ctaHref="/signup"
/>
<DocsLayoutFinal
sidebar={<DocsSidebarFinal currentPath="/docs/final" />}
toc={<DocsTOCFinal items={tocItems} />}
>
<Breadcrumb items={[{ label: 'Documentation', href: '/docs' }, { label: 'Getting Started' }]} />
{/* Hero Section */}
<div className="mb-12">
<h1 className="text-4xl md:text-5xl font-bold text-white mb-4">Getting Started</h1>
<p className="text-xl text-gray-400 leading-relaxed">
Welcome to the Banatie API documentation. Learn how to integrate AI-powered image
generation into your applications in minutes.
</p>
</div>
{/* Introduction */}
<section id="introduction" className="mb-12">
<h2 className="text-3xl font-bold text-white mb-4">Introduction</h2>
<p className="text-gray-300 leading-relaxed mb-4">
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.
</p>
<p className="text-gray-300 leading-relaxed mb-6">
Whether you are building a content creation platform, e-commerce site, or creative tool,
Banatie provides the infrastructure you need to generate high-quality images at scale.
</p>
{/* Compact Tip Box */}
<TipBox variant="compact" type="info">
<strong>New to API integration?</strong> Start with our{' '}
<a href="/docs/final/examples" className="text-purple-400 hover:underline">
code examples
</a>{' '}
to see common use cases in action.
</TipBox>
</section>
{/* Quick Start */}
<section id="quick-start" className="mb-12">
<h2 className="text-3xl font-bold text-white mb-6">Quick Start</h2>
<div id="installation" className="mb-8">
<h3 className="text-xl font-semibold text-white mb-3">Installation</h3>
<p className="text-gray-300 leading-relaxed mb-4">
Banatie is a REST API, so you do not need to install any libraries. However, we provide
SDKs for popular languages to make integration easier.
</p>
<CodeBlock
code={`# Using npm (JavaScript/TypeScript)
npm install @banatie/sdk
# Using pip (Python)
pip install banatie
# Using Go
go get github.com/banatie/sdk-go`}
language="bash"
filename="Installation"
/>
</div>
<div id="authentication" className="mb-8">
<h3 className="text-xl font-semibold text-white mb-3">Authentication</h3>
<p className="text-gray-300 leading-relaxed mb-4">
All API requests require an API key. You can create an API key from your dashboard or
using the bootstrap endpoint for initial setup.
</p>
{/* Prominent Tip Box for Security Warning */}
<div className="mb-6">
<TipBox variant="prominent" type="warning">
<strong className="text-amber-300">Security Best Practice:</strong> 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.
</TipBox>
</div>
<CodeBlock
code={`# Create your first API key (one-time bootstrap)
curl -X POST https://api.banatie.com/api/bootstrap/initial-key
# Save the returned key securely
export BANATIE_API_KEY="bnt_your_key_here"`}
language="bash"
filename="Get API Key"
/>
</div>
</section>
{/* First Request */}
<section id="first-request" className="mb-12">
<h2 className="text-3xl font-bold text-white mb-4">Your First Request</h2>
<p className="text-gray-300 leading-relaxed mb-6">
Let's generate your first image! This example uses curl, but you can use any HTTP client
or our SDKs.
</p>
<CodeBlock
code={`curl -X POST https://api.banatie.com/api/text-to-image \\
-H "X-API-Key: YOUR_API_KEY" \\
-H "Content-Type: application/json" \\
-d '{
"prompt": "a serene mountain landscape at sunset",
"filename": "mountain_sunset",
"aspectRatio": "16:9",
"autoEnhance": true
}'`}
language="bash"
filename="Generate Image"
/>
<div className="mt-6">
<p className="text-sm font-semibold text-gray-300 mb-3">Expected Response:</p>
<div className="relative p-4 bg-green-500/5 border border-green-500/30 rounded-xl shadow-lg shadow-green-500/10">
<div className="absolute top-3 right-3">
<span className="px-2 py-1 text-xs bg-green-500/20 text-green-400 rounded-full">
200 Success
</span>
</div>
<pre className="text-xs text-gray-300 overflow-x-auto mt-6">
<code>{`{
"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..."
}
}
}`}</code>
</pre>
</div>
</div>
</section>
{/* Next Steps - Simplified to 2 Cards */}
<section id="next-steps" className="mb-12">
<h2 className="text-3xl font-bold text-white mb-6">Next Steps</h2>
<p className="text-gray-300 leading-relaxed mb-6">
Now that you have generated your first image, explore these resources to build more advanced integrations:
</p>
<div className="grid md:grid-cols-2 gap-4">
<a
href="/docs/final/api/text-to-image"
className="p-5 bg-gradient-to-br from-purple-500/10 to-transparent border border-slate-700/50 rounded-xl hover:border-purple-500/40 transition-colors group"
>
<h3 className="text-lg font-semibold text-white mb-2 group-hover:text-purple-400 transition-colors">
API Reference
</h3>
<p className="text-sm text-gray-400">
Explore all available endpoints, parameters, and response formats.
</p>
</a>
<a
href="/docs/final/guides/authentication"
className="p-5 bg-gradient-to-br from-cyan-500/10 to-transparent border border-slate-700/50 rounded-xl hover:border-cyan-500/40 transition-colors group"
>
<h3 className="text-lg font-semibold text-white mb-2 group-hover:text-cyan-400 transition-colors">
Authentication Guide
</h3>
<p className="text-sm text-gray-400">
Learn about API keys, rate limits, and security best practices.
</p>
</a>
</div>
</section>
</DocsLayoutFinal>
</>
);
}

View File

@ -11,9 +11,9 @@
* - Simplified Next Steps * - Simplified Next Steps
*/ */
import { DocsLayoutFinal } from '@/components/docs/final/DocsLayoutFinal'; import { DocsLayout } from '@/components/docs/docs/DocsLayout';
import { DocsSidebarFinal } from '@/components/docs/final/DocsSidebarFinal'; import { DocsSidebar } from '@/components/docs/docs/DocsSidebar';
import { DocsTOCFinal } from '@/components/docs/final/DocsTOCFinal'; import { DocsTOC } from '@/components/docs/docs/DocsTOC';
import { SubsectionNav } from '@/components/shared/SubsectionNav'; import { SubsectionNav } from '@/components/shared/SubsectionNav';
import { TipBox } from '@/components/docs/shared/TipBox'; import { TipBox } from '@/components/docs/shared/TipBox';
import { Table } from '@/components/docs/shared/Table'; import { Table } from '@/components/docs/shared/Table';
@ -32,9 +32,9 @@ const tocItems = [
]; ];
const navItems = [ const navItems = [
{ label: 'Documentation', href: '/docs/final' }, { label: 'Documentation', href: '/docs' },
{ label: 'Demo', href: '/demo' }, { label: 'Demo', href: '/demo' },
{ label: 'Examples', href: '/docs/final/examples' }, { label: 'Examples', href: '/docs/examples' },
]; ];
export default function AuthenticationGuidePage() { export default function AuthenticationGuidePage() {
@ -43,19 +43,19 @@ export default function AuthenticationGuidePage() {
{/* Subsection Navigation */} {/* Subsection Navigation */}
<SubsectionNav <SubsectionNav
items={navItems} items={navItems}
currentPath="/docs/final/guides/authentication" currentPath="/docs/guides/authentication"
ctaText="Join Beta" ctaText="Join Beta"
ctaHref="/signup" ctaHref="/signup"
/> />
<DocsLayoutFinal <DocsLayout
sidebar={<DocsSidebarFinal currentPath="/docs/final/guides/authentication" />} sidebar={<DocsSidebar currentPath="/docs/guides/authentication" />}
toc={<DocsTOCFinal items={tocItems} />} toc={<DocsTOC items={tocItems} />}
> >
<Breadcrumb <Breadcrumb
items={[ items={[
{ label: 'Documentation', href: '/docs' }, { label: 'Documentation', href: '/docs' },
{ label: 'Guides', href: '/docs/final/guides' }, { label: 'Guides', href: '/docs/guides' },
{ label: 'Authentication' }, { label: 'Authentication' },
]} ]}
/> />
@ -330,7 +330,7 @@ curl -X DELETE https://api.banatie.com/api/admin/keys/OLD_KEY_ID \\
</a> </a>
</div> </div>
</section> </section>
</DocsLayoutFinal> </DocsLayout>
</> </>
); );
} }

View File

@ -1,376 +1,224 @@
'use client'; 'use client';
/** /**
* Documentation Variants Comparison Page * Getting Started Page - Production Documentation
* *
* Landing page that introduces users to the three documentation design variants. * Main entry point for documentation
* Helps users choose the variant that best suits their preferences. * Features:
* * - SubsectionNav at top
* Three Variants: * - Both TipBox styles (compact + prominent)
* - Variant A: Clean & Minimal (Vercel-inspired) * - Enhanced tables
* - Variant B: Dense & Information-Rich (Next.js docs-inspired) * - Simplified Next Steps (2 cards only)
* - Variant C: Modern & Visual (Shopify-inspired) * - Clean, accessible design
*
* Design:
* - Hero section explaining the concept
* - Three large gradient-bordered cards
* - Visual preview descriptions
* - Clear CTAs to each variant
*/ */
export default function DocsIndexPage() { import { DocsLayout } from '@/components/docs/docs/DocsLayout';
import { DocsSidebar } from '@/components/docs/docs/DocsSidebar';
import { DocsTOC } from '@/components/docs/docs/DocsTOC';
import { SubsectionNav } from '@/components/shared/SubsectionNav';
import { TipBox } from '@/components/docs/shared/TipBox';
import { CodeBlock } from '@/components/docs/shared/CodeBlock';
import { Breadcrumb } from '@/components/docs/shared/Breadcrumb';
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 },
];
const navItems = [
{ label: 'Documentation', href: '/docs' },
{ label: 'Demo', href: '/demo' },
{ label: 'Examples', href: '/docs/examples' },
];
export default function GettingStartedPage() {
return ( return (
<div className="min-h-screen"> <>
{/* Header with back to home */} {/* Subsection Navigation */}
<div className="border-b border-white/10 bg-slate-950/80 backdrop-blur-sm"> <SubsectionNav
<div className="max-w-7xl mx-auto px-6 py-4 flex items-center justify-between"> items={navItems}
<a currentPath="/docs"
href="/" ctaText="Join Beta"
className="flex items-center gap-2 text-gray-400 hover:text-white transition-colors" ctaHref="/signup"
> />
<svg className="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M10 19l-7-7m0 0l7-7m-7 7h18" /> <DocsLayout
</svg> sidebar={<DocsSidebar currentPath="/docs" />}
<span className="text-sm">Back to Home</span> toc={<DocsTOC items={tocItems} />}
</a> >
<div className="text-sm text-gray-500">Choose Your Documentation Style</div> <Breadcrumb items={[{ label: 'Documentation', href: '/docs' }, { label: 'Getting Started' }]} />
</div>
</div>
<div className="max-w-7xl mx-auto px-6 py-16">
{/* Hero Section */} {/* Hero Section */}
<div className="text-center mb-16">
<div className="inline-flex items-center gap-2 px-4 py-2 rounded-full bg-gradient-to-r from-purple-500/20 to-cyan-500/20 border-2 border-purple-500/40 mb-6">
<span className="text-2xl">📚</span>
<span className="text-sm font-bold text-white">DOCUMENTATION</span>
</div>
<h1 className="text-5xl md:text-6xl font-bold text-white mb-6">
Choose Your Documentation Style
</h1>
<p className="text-xl text-gray-400 max-w-3xl mx-auto leading-relaxed">
We've created three distinct documentation designs. Pick the style that works best for
yousame content, different presentation.
</p>
</div>
{/* Final Variant - Recommended */}
<div className="mb-12"> <div className="mb-12">
<div className="text-center mb-6"> <h1 className="text-4xl md:text-5xl font-bold text-white mb-4">Getting Started</h1>
<span className="inline-block px-4 py-1.5 rounded-full bg-gradient-to-r from-purple-500 to-cyan-500 text-white text-sm font-semibold mb-2"> <p className="text-xl text-gray-400 leading-relaxed">
RECOMMENDED Welcome to the Banatie API documentation. Learn how to integrate AI-powered image
</span> generation into your applications in minutes.
<h2 className="text-2xl font-bold text-white">Production-Ready Design</h2>
</div>
<a
href="/docs/final"
className="group block p-10 bg-gradient-to-br from-purple-500/20 via-cyan-500/20 to-purple-500/20 border-4 border-purple-500/50 rounded-3xl hover:border-purple-500/80 transition-all duration-300 shadow-2xl hover:shadow-purple-500/40 hover:scale-[1.02]"
>
<div className="flex flex-col md:flex-row items-center gap-8">
<div className="flex-shrink-0 text-6xl"></div>
<div className="flex-1 text-center md:text-left">
<h3 className="text-3xl font-bold text-white mb-3 group-hover:text-purple-300 transition-colors">
Final Variant
</h3>
<h4 className="text-xl font-semibold text-purple-300 mb-4">
Best of All Worlds - Clean, Enhanced & Production-Ready
</h4>
<p className="text-base text-gray-300 mb-6 leading-relaxed max-w-3xl">
The perfect combination: Variant A's clean aesthetic enhanced with expandable code blocks, success/error response styling, clickable image URLs, two tip box styles, enhanced tables, and simplified navigation. This is the variant we recommend for production use.
</p>
<div className="grid md:grid-cols-3 gap-4 mb-6">
<div className="flex items-center gap-2 text-sm text-gray-300">
<svg className="w-5 h-5 text-purple-400" fill="currentColor" viewBox="0 0 20 20">
<path
fillRule="evenodd"
d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z"
clipRule="evenodd"
/>
</svg>
<span>Clean Variant A base</span>
</div>
<div className="flex items-center gap-2 text-sm text-gray-300">
<svg className="w-5 h-5 text-cyan-400" fill="currentColor" viewBox="0 0 20 20">
<path
fillRule="evenodd"
d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z"
clipRule="evenodd"
/>
</svg>
<span>Expandable code blocks</span>
</div>
<div className="flex items-center gap-2 text-sm text-gray-300">
<svg className="w-5 h-5 text-green-400" fill="currentColor" viewBox="0 0 20 20">
<path
fillRule="evenodd"
d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z"
clipRule="evenodd"
/>
</svg>
<span>Success/error styling</span>
</div>
<div className="flex items-center gap-2 text-sm text-gray-300">
<svg className="w-5 h-5 text-purple-400" fill="currentColor" viewBox="0 0 20 20">
<path
fillRule="evenodd"
d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z"
clipRule="evenodd"
/>
</svg>
<span>Two tip box styles</span>
</div>
<div className="flex items-center gap-2 text-sm text-gray-300">
<svg className="w-5 h-5 text-cyan-400" fill="currentColor" viewBox="0 0 20 20">
<path
fillRule="evenodd"
d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z"
clipRule="evenodd"
/>
</svg>
<span>Enhanced tables</span>
</div>
<div className="flex items-center gap-2 text-sm text-gray-300">
<svg className="w-5 h-5 text-green-400" fill="currentColor" viewBox="0 0 20 20">
<path
fillRule="evenodd"
d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z"
clipRule="evenodd"
/>
</svg>
<span>Reusable navigation</span>
</div>
</div>
<div className="flex items-center justify-center md:justify-start gap-3 text-purple-300 text-lg font-bold group-hover:gap-4 transition-all">
<span>Explore Final Variant</span>
<svg className="w-6 h-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={3} d="M9 5l7 7-7 7" />
</svg>
</div>
</div>
</div>
</a>
</div>
{/* Other Variants for Reference */}
<div className="text-center mb-8">
<h3 className="text-xl font-semibold text-gray-400 mb-2">Other Variants (Reference)</h3>
<p className="text-sm text-gray-500">
Explore the original variants that inspired the final design
</p> </p>
</div> </div>
{/* Variant Cards */} {/* Introduction */}
<div className="grid md:grid-cols-3 gap-8 mb-16"> <section id="introduction" className="mb-12">
{/* Variant A: Clean & Minimal */} <h2 className="text-3xl font-bold text-white mb-4">Introduction</h2>
<a <p className="text-gray-300 leading-relaxed mb-4">
href="/docs/variant-a" Banatie is a developer-first API for AI-powered image generation. Built on Google Gemini
className="group p-8 bg-gradient-to-br from-purple-500/10 to-transparent border-2 border-purple-500/30 rounded-2xl hover:border-purple-500/60 transition-all duration-300 shadow-xl hover:shadow-purple-500/30 hover:scale-105" 2.5 Flash and Imagen 4.0, it transforms text prompts and reference images into
> production-ready visuals.
<div className="text-4xl mb-6"></div> </p>
<h2 className="text-2xl font-bold text-white mb-4 group-hover:text-purple-400 transition-colors"> <p className="text-gray-300 leading-relaxed mb-6">
Variant A Whether you are building a content creation platform, e-commerce site, or creative tool,
</h2> Banatie provides the infrastructure you need to generate high-quality images at scale.
<h3 className="text-lg font-semibold text-purple-400 mb-4">Clean & Minimal</h3> </p>
<p className="text-sm text-gray-400 mb-6 leading-relaxed">
Vercel-inspired spacious layout with generous whitespace, focused reading experience, {/* Compact Tip Box */}
and subtle visual hierarchy. <TipBox variant="compact" type="info">
<strong>New to API integration?</strong> Start with our{' '}
<a href="/docs/examples" className="text-purple-400 hover:underline">
code examples
</a>{' '}
to see common use cases in action.
</TipBox>
</section>
{/* Quick Start */}
<section id="quick-start" className="mb-12">
<h2 className="text-3xl font-bold text-white mb-6">Quick Start</h2>
<div id="installation" className="mb-8">
<h3 className="text-xl font-semibold text-white mb-3">Installation</h3>
<p className="text-gray-300 leading-relaxed mb-4">
Banatie is a REST API, so you do not need to install any libraries. However, we provide
SDKs for popular languages to make integration easier.
</p> </p>
<div className="space-y-3 mb-6"> <CodeBlock
<div className="flex items-center gap-2 text-sm text-gray-500"> code={`# Using npm (JavaScript/TypeScript)
<svg className="w-4 h-4 text-purple-400" fill="currentColor" viewBox="0 0 20 20"> npm install @banatie/sdk
<path
fillRule="evenodd"
d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z"
clipRule="evenodd"
/>
</svg>
<span>Wide margins, comfortable reading</span>
</div>
<div className="flex items-center gap-2 text-sm text-gray-500">
<svg className="w-4 h-4 text-purple-400" fill="currentColor" viewBox="0 0 20 20">
<path
fillRule="evenodd"
d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z"
clipRule="evenodd"
/>
</svg>
<span>Subtle borders and minimal design</span>
</div>
<div className="flex items-center gap-2 text-sm text-gray-500">
<svg className="w-4 h-4 text-purple-400" fill="currentColor" viewBox="0 0 20 20">
<path
fillRule="evenodd"
d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z"
clipRule="evenodd"
/>
</svg>
<span>Focus on content clarity</span>
</div>
</div>
<div className="flex items-center gap-2 text-purple-400 font-semibold group-hover:gap-3 transition-all"> # Using pip (Python)
<span>Explore Variant A</span> pip install banatie
<svg className="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5l7 7-7 7" />
</svg>
</div>
</a>
{/* Variant B: Dense & Information-Rich */} # Using Go
<a go get github.com/banatie/sdk-go`}
href="/docs/variant-b" language="bash"
className="group p-8 bg-gradient-to-br from-cyan-500/10 to-transparent border-2 border-cyan-500/30 rounded-2xl hover:border-cyan-500/60 transition-all duration-300 shadow-xl hover:shadow-cyan-500/30 hover:scale-105" filename="Installation"
> />
<div className="text-4xl mb-6">📊</div> </div>
<h2 className="text-2xl font-bold text-white mb-4 group-hover:text-cyan-400 transition-colors">
Variant B <div id="authentication" className="mb-8">
</h2> <h3 className="text-xl font-semibold text-white mb-3">Authentication</h3>
<h3 className="text-lg font-semibold text-cyan-400 mb-4">Dense & Information-Rich</h3> <p className="text-gray-300 leading-relaxed mb-4">
<p className="text-sm text-gray-400 mb-6 leading-relaxed"> All API requests require an API key. You can create an API key from your dashboard or
Next.js docs-inspired compact layout with section numbers, nested navigation, and using the bootstrap endpoint for initial setup.
maximum information density per screen.
</p> </p>
<div className="space-y-3 mb-6"> {/* Prominent Tip Box for Security Warning */}
<div className="flex items-center gap-2 text-sm text-gray-500"> <div className="mb-6">
<svg className="w-4 h-4 text-cyan-400" fill="currentColor" viewBox="0 0 20 20"> <TipBox variant="prominent" type="warning">
<path <strong className="text-amber-300">Security Best Practice:</strong> Keep your API keys secure.
fillRule="evenodd" Never commit them to public repositories or expose them in client-side code. Use environment
d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" variables and server-side implementations for production applications.
clipRule="evenodd" </TipBox>
/>
</svg>
<span>Compact spacing, more content visible</span>
</div>
<div className="flex items-center gap-2 text-sm text-gray-500">
<svg className="w-4 h-4 text-cyan-400" fill="currentColor" viewBox="0 0 20 20">
<path
fillRule="evenodd"
d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z"
clipRule="evenodd"
/>
</svg>
<span>Section numbers (1., 2.1, etc.)</span>
</div>
<div className="flex items-center gap-2 text-sm text-gray-500">
<svg className="w-4 h-4 text-cyan-400" fill="currentColor" viewBox="0 0 20 20">
<path
fillRule="evenodd"
d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z"
clipRule="evenodd"
/>
</svg>
<span>Hierarchical nested tree navigation</span>
</div>
</div> </div>
<div className="flex items-center gap-2 text-cyan-400 font-semibold group-hover:gap-3 transition-all"> <CodeBlock
<span>Explore Variant B</span> code={`# Create your first API key (one-time bootstrap)
<svg className="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor"> curl -X POST https://api.banatie.com/api/bootstrap/initial-key
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5l7 7-7 7" />
</svg>
</div>
</a>
{/* Variant C: Modern & Visual */} # Save the returned key securely
<a export BANATIE_API_KEY="bnt_your_key_here"`}
href="/docs/variant-c" language="bash"
className="group p-8 bg-gradient-to-br from-amber-500/10 via-purple-500/10 to-cyan-500/10 border-2 border-amber-500/30 rounded-2xl hover:border-amber-500/60 transition-all duration-300 shadow-xl hover:shadow-amber-500/30 hover:scale-105" filename="Get API Key"
> />
<div className="text-4xl mb-6">🎨</div> </div>
<h2 className="text-2xl font-bold text-white mb-4 group-hover:text-amber-400 transition-colors"> </section>
Variant C
</h2>
<h3 className="text-lg font-semibold text-amber-400 mb-4">Modern & Visual</h3>
<p className="text-sm text-gray-400 mb-6 leading-relaxed">
Shopify-inspired colorful card-based design with large emoji icons, gradient borders,
and playful engaging visual style.
</p>
<div className="space-y-3 mb-6"> {/* First Request */}
<div className="flex items-center gap-2 text-sm text-gray-500"> <section id="first-request" className="mb-12">
<svg className="w-4 h-4 text-amber-400" fill="currentColor" viewBox="0 0 20 20"> <h2 className="text-3xl font-bold text-white mb-4">Your First Request</h2>
<path <p className="text-gray-300 leading-relaxed mb-6">
fillRule="evenodd" Let's generate your first image! This example uses curl, but you can use any HTTP client
d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" or our SDKs.
clipRule="evenodd" </p>
/>
</svg> <CodeBlock
<span>Colorful gradient borders everywhere</span> code={`curl -X POST https://api.banatie.com/api/text-to-image \\
-H "X-API-Key: YOUR_API_KEY" \\
-H "Content-Type: application/json" \\
-d '{
"prompt": "a serene mountain landscape at sunset",
"filename": "mountain_sunset",
"aspectRatio": "16:9",
"autoEnhance": true
}'`}
language="bash"
filename="Generate Image"
/>
<div className="mt-6">
<p className="text-sm font-semibold text-gray-300 mb-3">Expected Response:</p>
<div className="relative p-4 bg-green-500/5 border border-green-500/30 rounded-xl shadow-lg shadow-green-500/10">
<div className="absolute top-3 right-3">
<span className="px-2 py-1 text-xs bg-green-500/20 text-green-400 rounded-full">
200 Success
</span>
</div> </div>
<div className="flex items-center gap-2 text-sm text-gray-500"> <pre className="text-xs text-gray-300 overflow-x-auto mt-6">
<svg className="w-4 h-4 text-amber-400" fill="currentColor" viewBox="0 0 20 20"> <code>{`{
<path "success": true,
fillRule="evenodd" "data": {
d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" "url": "https://cdn.banatie.com/org/project/generated/2025-01/mountain_sunset.png",
clipRule="evenodd" "filepath": "org/project/generated/2025-01/mountain_sunset.png",
/> "width": 1920,
</svg> "height": 1080,
<span>Large emoji icons and visual elements</span> "promptEnhancement": {
</div> "enhancedPrompt": "A breathtaking mountain landscape..."
<div className="flex items-center gap-2 text-sm text-gray-500"> }
<svg className="w-4 h-4 text-amber-400" fill="currentColor" viewBox="0 0 20 20"> }
<path }`}</code>
fillRule="evenodd" </pre>
d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z"
clipRule="evenodd"
/>
</svg>
<span>Fun, engaging, playful design</span>
</div>
</div>
<div className="flex items-center gap-2 text-amber-400 font-semibold group-hover:gap-3 transition-all">
<span>Explore Variant C</span>
<svg className="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5l7 7-7 7" />
</svg>
</div>
</a>
</div>
{/* Feature Comparison */}
<div className="p-8 bg-slate-900/50 border-2 border-slate-700 rounded-2xl backdrop-blur-sm">
<h3 className="text-2xl font-bold text-white mb-6 text-center">
All Variants Include
</h3>
<div className="grid md:grid-cols-3 gap-6">
<div className="text-center">
<div className="text-3xl mb-3">📚</div>
<h4 className="text-base font-semibold text-white mb-2">Same Content</h4>
<p className="text-sm text-gray-400">
Identical API documentation, just styled differently
</p>
</div>
<div className="text-center">
<div className="text-3xl mb-3"></div>
<h4 className="text-base font-semibold text-white mb-2">Interactive Widgets</h4>
<p className="text-sm text-gray-400">
Live API testing with your own keys
</p>
</div>
<div className="text-center">
<div className="text-3xl mb-3">🔍</div>
<h4 className="text-base font-semibold text-white mb-2">Navigation & Search</h4>
<p className="text-sm text-gray-400">
Sidebar, TOC, and breadcrumb navigation
</p>
</div> </div>
</div> </div>
</div> </section>
{/* Footer CTA */} {/* Next Steps - Simplified to 2 Cards */}
<div className="mt-16 text-center"> <section id="next-steps" className="mb-12">
<p className="text-gray-400 mb-4"> <h2 className="text-3xl font-bold text-white mb-6">Next Steps</h2>
Not sure which to choose? Try all three and see which feels right! <p className="text-gray-300 leading-relaxed mb-6">
Now that you have generated your first image, explore these resources to build more advanced integrations:
</p> </p>
<p className="text-sm text-gray-500">
Each variant links to the same API contentpick your preferred reading experience. <div className="grid md:grid-cols-2 gap-4">
</p> <a
</div> href="/docs/api/text-to-image"
</div> className="p-5 bg-gradient-to-br from-purple-500/10 to-transparent border border-slate-700/50 rounded-xl hover:border-purple-500/40 transition-colors group"
</div> >
<h3 className="text-lg font-semibold text-white mb-2 group-hover:text-purple-400 transition-colors">
API Reference
</h3>
<p className="text-sm text-gray-400">
Explore all available endpoints, parameters, and response formats.
</p>
</a>
<a
href="/docs/guides/authentication"
className="p-5 bg-gradient-to-br from-cyan-500/10 to-transparent border border-slate-700/50 rounded-xl hover:border-cyan-500/40 transition-colors group"
>
<h3 className="text-lg font-semibold text-white mb-2 group-hover:text-cyan-400 transition-colors">
Authentication Guide
</h3>
<p className="text-sm text-gray-400">
Learn about API keys, rate limits, and security best practices.
</p>
</a>
</div>
</section>
</DocsLayout>
</>
); );
} }

View File

@ -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 (
<DocsLayoutA
sidebar={<DocsSidebarA currentPath="/docs/variant-a/api/text-to-image" />}
toc={<DocsTOCA items={tocItems} />}
>
<Breadcrumb
items={[
{ label: 'Documentation', href: '/docs' },
{ label: 'API Reference', href: '/docs/variant-a/api' },
{ label: 'Text to Image' },
]}
/>
{/* Hero Section */}
<div className="mb-12">
<div className="inline-block px-3 py-1 rounded-full bg-purple-500/10 border border-purple-500/20 text-purple-300 text-xs font-medium mb-4">
POST
</div>
<h1 className="text-4xl md:text-5xl font-bold text-white mb-4">Text to Image</h1>
<p className="text-xl text-gray-400 leading-relaxed">
Generate high-quality images from text prompts using AI-powered models.
</p>
</div>
{/* Overview */}
<section id="overview" className="mb-12">
<h2 className="text-3xl font-bold text-white mb-4">Overview</h2>
<p className="text-gray-300 leading-relaxed mb-4">
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.
</p>
<div className="p-4 bg-cyan-500/10 border border-cyan-500/20 rounded-xl">
<p className="text-sm text-cyan-300">
<strong>Tip:</strong> Enable autoEnhance for better results. The AI will optimize your
prompt for higher quality outputs while preserving your intent.
</p>
</div>
</section>
{/* Endpoint */}
<section id="endpoint" className="mb-12">
<h2 className="text-3xl font-bold text-white mb-4">Endpoint</h2>
<div className="p-4 bg-slate-800/50 border border-slate-700 rounded-xl">
<code className="text-purple-400">POST</code>
<code className="ml-3 text-gray-300">https://api.banatie.com/api/text-to-image</code>
</div>
</section>
{/* Request */}
<section id="request" className="mb-12">
<h2 className="text-3xl font-bold text-white mb-6">Request</h2>
<div id="headers" className="mb-8">
<h3 className="text-xl font-semibold text-white mb-4">Headers</h3>
<div className="overflow-x-auto">
<table className="w-full text-sm">
<thead>
<tr className="border-b border-slate-700">
<th className="text-left py-3 px-4 text-gray-400 font-medium">Header</th>
<th className="text-left py-3 px-4 text-gray-400 font-medium">Value</th>
<th className="text-left py-3 px-4 text-gray-400 font-medium">Required</th>
</tr>
</thead>
<tbody className="text-gray-300">
<tr className="border-b border-slate-800">
<td className="py-3 px-4 font-mono text-purple-400">X-API-Key</td>
<td className="py-3 px-4">Your project API key</td>
<td className="py-3 px-4">
<span className="px-2 py-1 bg-red-500/20 text-red-400 rounded text-xs">Yes</span>
</td>
</tr>
<tr className="border-b border-slate-800">
<td className="py-3 px-4 font-mono text-purple-400">Content-Type</td>
<td className="py-3 px-4">application/json</td>
<td className="py-3 px-4">
<span className="px-2 py-1 bg-red-500/20 text-red-400 rounded text-xs">Yes</span>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div id="body" className="mb-8">
<h3 className="text-xl font-semibold text-white mb-4">Body Parameters</h3>
<div className="overflow-x-auto">
<table className="w-full text-sm">
<thead>
<tr className="border-b border-slate-700">
<th className="text-left py-3 px-4 text-gray-400 font-medium">Parameter</th>
<th className="text-left py-3 px-4 text-gray-400 font-medium">Type</th>
<th className="text-left py-3 px-4 text-gray-400 font-medium">Description</th>
<th className="text-left py-3 px-4 text-gray-400 font-medium">Required</th>
</tr>
</thead>
<tbody className="text-gray-300">
<tr className="border-b border-slate-800">
<td className="py-3 px-4 font-mono text-purple-400">prompt</td>
<td className="py-3 px-4">string</td>
<td className="py-3 px-4">Text description of the image to generate</td>
<td className="py-3 px-4">
<span className="px-2 py-1 bg-red-500/20 text-red-400 rounded text-xs">Yes</span>
</td>
</tr>
<tr className="border-b border-slate-800">
<td className="py-3 px-4 font-mono text-purple-400">filename</td>
<td className="py-3 px-4">string</td>
<td className="py-3 px-4">Name for the generated image file</td>
<td className="py-3 px-4">
<span className="px-2 py-1 bg-red-500/20 text-red-400 rounded text-xs">Yes</span>
</td>
</tr>
<tr className="border-b border-slate-800">
<td className="py-3 px-4 font-mono text-purple-400">aspectRatio</td>
<td className="py-3 px-4">string</td>
<td className="py-3 px-4">
Image aspect ratio. Options: 1:1, 3:4, 4:3, 9:16, 16:9, 21:9
</td>
<td className="py-3 px-4">
<span className="px-2 py-1 bg-gray-500/20 text-gray-400 rounded text-xs">No</span>
</td>
</tr>
<tr className="border-b border-slate-800">
<td className="py-3 px-4 font-mono text-purple-400">autoEnhance</td>
<td className="py-3 px-4">boolean</td>
<td className="py-3 px-4">Enable automatic prompt enhancement (default: true)</td>
<td className="py-3 px-4">
<span className="px-2 py-1 bg-gray-500/20 text-gray-400 rounded text-xs">No</span>
</td>
</tr>
<tr className="border-b border-slate-800">
<td className="py-3 px-4 font-mono text-purple-400">enhancementOptions</td>
<td className="py-3 px-4">object</td>
<td className="py-3 px-4">Template and enhancement settings</td>
<td className="py-3 px-4">
<span className="px-2 py-1 bg-gray-500/20 text-gray-400 rounded text-xs">No</span>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</section>
{/* Interactive API Widget */}
<InteractiveAPIWidgetA
endpoint="/api/text-to-image"
method="POST"
description="Try generating an image with your own API key"
parameters={[
{
name: 'prompt',
type: 'string',
required: true,
description: 'Image description',
defaultValue: 'a futuristic city at sunset',
},
{
name: 'filename',
type: 'string',
required: true,
description: 'Output filename',
defaultValue: 'city',
},
{
name: 'aspectRatio',
type: 'string',
required: false,
description: 'Aspect ratio',
defaultValue: '16:9',
},
]}
/>
{/* Response */}
<section id="response" className="mb-12">
<h2 className="text-3xl font-bold text-white mb-4">Response</h2>
<p className="text-gray-300 leading-relaxed mb-4">
Returns a JSON object with the generated image URL and metadata.
</p>
<div className="p-4 bg-slate-800/50 border border-slate-700 rounded-xl">
<pre className="text-xs text-gray-300 overflow-x-auto">
<code>{`{
"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"
}
}`}</code>
</pre>
</div>
</section>
{/* Examples */}
<section id="examples" className="mb-12">
<h2 className="text-3xl font-bold text-white mb-6">Examples</h2>
<div className="space-y-6">
<div>
<h4 className="text-lg font-semibold text-white mb-3">Basic Image Generation</h4>
<p className="text-sm text-gray-400 mb-3">Generate a simple image with default settings</p>
<div className="p-4 bg-slate-950/50 border border-slate-700 rounded-xl">
<pre className="text-xs text-gray-300 overflow-x-auto">
<code>{`{
"prompt": "a serene mountain landscape",
"filename": "mountain"
}`}</code>
</pre>
</div>
</div>
<div>
<h4 className="text-lg font-semibold text-white mb-3">Custom Aspect Ratio</h4>
<p className="text-sm text-gray-400 mb-3">Generate a widescreen image</p>
<div className="p-4 bg-slate-950/50 border border-slate-700 rounded-xl">
<pre className="text-xs text-gray-300 overflow-x-auto">
<code>{`{
"prompt": "cinematic space battle scene",
"filename": "space_battle",
"aspectRatio": "21:9"
}`}</code>
</pre>
</div>
</div>
</div>
</section>
{/* Error Codes */}
<section id="errors" className="mb-12">
<h2 className="text-3xl font-bold text-white mb-4">Error Codes</h2>
<div className="overflow-x-auto">
<table className="w-full text-sm">
<thead>
<tr className="border-b border-slate-700">
<th className="text-left py-3 px-4 text-gray-400 font-medium">Code</th>
<th className="text-left py-3 px-4 text-gray-400 font-medium">Description</th>
</tr>
</thead>
<tbody className="text-gray-300">
<tr className="border-b border-slate-800">
<td className="py-3 px-4 font-mono text-red-400">400</td>
<td className="py-3 px-4">Invalid request parameters</td>
</tr>
<tr className="border-b border-slate-800">
<td className="py-3 px-4 font-mono text-red-400">401</td>
<td className="py-3 px-4">Missing or invalid API key</td>
</tr>
<tr className="border-b border-slate-800">
<td className="py-3 px-4 font-mono text-red-400">429</td>
<td className="py-3 px-4">Rate limit exceeded</td>
</tr>
<tr className="border-b border-slate-800">
<td className="py-3 px-4 font-mono text-red-400">500</td>
<td className="py-3 px-4">Internal server error</td>
</tr>
</tbody>
</table>
</div>
</section>
</DocsLayoutA>
);
}

View File

@ -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 (
<DocsLayoutA
sidebar={<DocsSidebarA currentPath="/docs/variant-a/guides/authentication" />}
toc={<DocsTOCA items={tocItems} />}
>
<Breadcrumb
items={[
{ label: 'Documentation', href: '/docs' },
{ label: 'Guides', href: '/docs/variant-a/guides' },
{ label: 'Authentication' },
]}
/>
{/* Hero Section */}
<div className="mb-12">
<div className="inline-block px-3 py-1 rounded-full bg-cyan-500/10 border border-cyan-500/20 text-cyan-300 text-xs font-medium mb-4">
GUIDE
</div>
<h1 className="text-4xl md:text-5xl font-bold text-white mb-4">Authentication</h1>
<p className="text-xl text-gray-400 leading-relaxed">
Learn how to authenticate your requests and manage API keys securely.
</p>
</div>
{/* Overview */}
<section id="overview" className="mb-12">
<h2 className="text-3xl font-bold text-white mb-4">Overview</h2>
<p className="text-gray-300 leading-relaxed mb-4">
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.
</p>
<div className="p-4 bg-purple-500/10 border border-purple-500/20 rounded-xl">
<p className="text-sm text-purple-300">
<strong>Security First:</strong> Never expose your API keys in client-side code, public
repositories, or logs. Treat them like passwords.
</p>
</div>
</section>
{/* API Keys */}
<section id="api-keys" className="mb-12">
<h2 className="text-3xl font-bold text-white mb-6">API Keys</h2>
<div id="key-types" className="mb-8">
<h3 className="text-xl font-semibold text-white mb-4">Key Types</h3>
<p className="text-gray-300 leading-relaxed mb-6">
Banatie provides two types of API keys, each with different permissions and use cases:
</p>
<div className="space-y-4">
<div className="p-6 bg-slate-800/50 border border-slate-700 rounded-xl">
<div className="flex items-start gap-4">
<div className="flex-shrink-0 w-10 h-10 rounded-lg bg-purple-500/20 flex items-center justify-center text-xl">
🔑
</div>
<div className="flex-1">
<h4 className="text-lg font-semibold text-white mb-2">Master Keys</h4>
<p className="text-sm text-gray-400 mb-3">
Full administrative access to your organization. Can create and revoke other
keys, access all projects, and manage settings.
</p>
<ul className="text-sm text-gray-400 space-y-1">
<li> Never expire</li>
<li> Full API access</li>
<li> One per organization (initially)</li>
<li> Should be kept extremely secure</li>
</ul>
</div>
</div>
</div>
<div className="p-6 bg-slate-800/50 border border-slate-700 rounded-xl">
<div className="flex items-start gap-4">
<div className="flex-shrink-0 w-10 h-10 rounded-lg bg-cyan-500/20 flex items-center justify-center text-xl">
🎫
</div>
<div className="flex-1">
<h4 className="text-lg font-semibold text-white mb-2">Project Keys</h4>
<p className="text-sm text-gray-400 mb-3">
Scoped to a specific project. Used for image generation and resource access
within that project only.
</p>
<ul className="text-sm text-gray-400 space-y-1">
<li> Expire after 90 days</li>
<li> Project-specific access</li>
<li> Rate limited</li>
<li> Safe for production use</li>
</ul>
</div>
</div>
</div>
</div>
</div>
<div id="creating-keys" className="mb-8">
<h3 className="text-xl font-semibold text-white mb-4">Creating Keys</h3>
<div className="mb-6">
<h4 className="text-base font-semibold text-white mb-3">Bootstrap Your First Key</h4>
<p className="text-gray-300 text-sm leading-relaxed mb-3">
When setting up Banatie for the first time, create your initial master key using the
bootstrap endpoint:
</p>
<CodeBlock
code={`curl -X POST https://api.banatie.com/api/bootstrap/initial-key
# Response
{
"success": true,
"key": "bnt_master_abc123...",
"message": "Master key created successfully"
}`}
language="bash"
filename="Create Master Key"
/>
<div className="mt-3 p-3 bg-amber-500/10 border border-amber-500/20 rounded-lg">
<p className="text-xs text-amber-300">
<strong>Important:</strong> This endpoint can only be used once. Save the returned
key immediately - it will never be shown again.
</p>
</div>
</div>
<div className="mb-6">
<h4 className="text-base font-semibold text-white mb-3">Create Project Keys</h4>
<p className="text-gray-300 text-sm leading-relaxed mb-3">
Use your master key to create project-specific keys:
</p>
<CodeBlock
code={`curl -X POST https://api.banatie.com/api/admin/keys \\
-H "X-API-Key: YOUR_MASTER_KEY" \\
-H "Content-Type: application/json" \\
-d '{
"type": "project",
"projectId": "my-project",
"name": "Production Key"
}'
# Response
{
"success": true,
"key": "bnt_project_xyz789...",
"keyId": "key_abc123",
"expiresAt": "2025-04-15T10:30:00Z"
}`}
language="bash"
filename="Create Project Key"
/>
</div>
</div>
</section>
{/* Using Keys */}
<section id="using-keys" className="mb-12">
<h2 className="text-3xl font-bold text-white mb-4">Using API Keys</h2>
<p className="text-gray-300 leading-relaxed mb-6">
Include your API key in every request using the X-API-Key header:
</p>
<CodeBlock
code={`# Using curl
curl -X POST https://api.banatie.com/api/text-to-image \\
-H "X-API-Key: YOUR_PROJECT_KEY" \\
-H "Content-Type: application/json" \\
-d '{"prompt": "sunset", "filename": "test"}'
# Using JavaScript fetch
const response = await fetch('https://api.banatie.com/api/text-to-image', {
method: 'POST',
headers: {
'X-API-Key': 'YOUR_PROJECT_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
prompt: 'sunset',
filename: 'test'
})
});`}
language="bash"
filename="API Request Example"
/>
</section>
{/* Security */}
<section id="security" className="mb-12">
<h2 className="text-3xl font-bold text-white mb-6">Security Best Practices</h2>
<div className="space-y-4">
<div className="flex gap-4 p-4 bg-slate-800/50 border border-slate-700 rounded-xl">
<div className="flex-shrink-0 text-2xl">🔒</div>
<div>
<h4 className="text-sm font-semibold text-white mb-1">Never Commit Keys</h4>
<p className="text-sm text-gray-400">
Use environment variables or secret management tools. Never commit keys to version
control.
</p>
</div>
</div>
<div className="flex gap-4 p-4 bg-slate-800/50 border border-slate-700 rounded-xl">
<div className="flex-shrink-0 text-2xl">🔄</div>
<div>
<h4 className="text-sm font-semibold text-white mb-1">Rotate Keys Regularly</h4>
<p className="text-sm text-gray-400">
Project keys expire after 90 days. Plan for rotation and implement graceful
handling.
</p>
</div>
</div>
<div className="flex gap-4 p-4 bg-slate-800/50 border border-slate-700 rounded-xl">
<div className="flex-shrink-0 text-2xl">🚫</div>
<div>
<h4 className="text-sm font-semibold text-white mb-1">Server-Side Only</h4>
<p className="text-sm text-gray-400">
Never use API keys in client-side code. Always make requests from your backend.
</p>
</div>
</div>
<div className="flex gap-4 p-4 bg-slate-800/50 border border-slate-700 rounded-xl">
<div className="flex-shrink-0 text-2xl">👁</div>
<div>
<h4 className="text-sm font-semibold text-white mb-1">Monitor Usage</h4>
<p className="text-sm text-gray-400">
Track API key usage patterns. Unusual activity may indicate a compromised key.
</p>
</div>
</div>
</div>
</section>
{/* Rate Limits */}
<section id="rate-limits" className="mb-12">
<h2 className="text-3xl font-bold text-white mb-4">Rate Limits</h2>
<p className="text-gray-300 leading-relaxed mb-6">
To ensure fair usage and system stability, all API keys are subject to rate limits:
</p>
<div className="overflow-x-auto">
<table className="w-full text-sm">
<thead>
<tr className="border-b border-slate-700">
<th className="text-left py-3 px-4 text-gray-400 font-medium">Key Type</th>
<th className="text-left py-3 px-4 text-gray-400 font-medium">Limit</th>
<th className="text-left py-3 px-4 text-gray-400 font-medium">Window</th>
</tr>
</thead>
<tbody className="text-gray-300">
<tr className="border-b border-slate-800">
<td className="py-3 px-4">Master Key</td>
<td className="py-3 px-4 font-mono">500 requests</td>
<td className="py-3 px-4">per hour</td>
</tr>
<tr className="border-b border-slate-800">
<td className="py-3 px-4">Project Key</td>
<td className="py-3 px-4 font-mono">100 requests</td>
<td className="py-3 px-4">per hour</td>
</tr>
</tbody>
</table>
</div>
<div className="mt-6 p-4 bg-cyan-500/10 border border-cyan-500/20 rounded-xl">
<p className="text-sm text-cyan-300">
<strong>Need Higher Limits?</strong> Contact our sales team to discuss enterprise plans
with custom rate limits.
</p>
</div>
</section>
</DocsLayoutA>
);
}

View File

@ -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 (
<DocsLayoutA
sidebar={<DocsSidebarA currentPath="/docs/variant-a" />}
toc={<DocsTOCA items={tocItems} />}
>
<Breadcrumb items={[{ label: 'Documentation', href: '/docs' }, { label: 'Getting Started' }]} />
{/* Hero Section */}
<div className="mb-12">
<h1 className="text-4xl md:text-5xl font-bold text-white mb-4">Getting Started</h1>
<p className="text-xl text-gray-400 leading-relaxed">
Welcome to the Banatie API documentation. Learn how to integrate AI-powered image
generation into your applications in minutes.
</p>
</div>
{/* Introduction */}
<section id="introduction" className="mb-12">
<h2 className="text-3xl font-bold text-white mb-4">Introduction</h2>
<p className="text-gray-300 leading-relaxed mb-4">
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.
</p>
<p className="text-gray-300 leading-relaxed">
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.
</p>
</section>
{/* Quick Start */}
<section id="quick-start" className="mb-12">
<h2 className="text-3xl font-bold text-white mb-6">Quick Start</h2>
<div id="installation" className="mb-8">
<h3 className="text-xl font-semibold text-white mb-3">Installation</h3>
<p className="text-gray-300 leading-relaxed mb-4">
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.
</p>
<CodeBlock
code={`# Using npm (JavaScript/TypeScript)
npm install @banatie/sdk
# Using pip (Python)
pip install banatie
# Using Go
go get github.com/banatie/sdk-go`}
language="bash"
filename="Installation"
/>
</div>
<div id="authentication" className="mb-8">
<h3 className="text-xl font-semibold text-white mb-3">Authentication</h3>
<p className="text-gray-300 leading-relaxed mb-4">
All API requests require an API key. You can create an API key from your dashboard or
using the bootstrap endpoint for initial setup.
</p>
<div className="p-4 bg-purple-500/10 border border-purple-500/20 rounded-xl mb-4">
<p className="text-sm text-purple-300">
<strong>Note:</strong> Keep your API keys secure. Never commit them to public
repositories or expose them in client-side code.
</p>
</div>
<CodeBlock
code={`# Create your first API key (one-time bootstrap)
curl -X POST https://api.banatie.com/api/bootstrap/initial-key
# Save the returned key securely
export BANATIE_API_KEY="bnt_your_key_here"`}
language="bash"
filename="Get API Key"
/>
</div>
</section>
{/* First Request */}
<section id="first-request" className="mb-12">
<h2 className="text-3xl font-bold text-white mb-4">Your First Request</h2>
<p className="text-gray-300 leading-relaxed mb-6">
Let's generate your first image! This example uses curl, but you can use any HTTP client
or our SDKs.
</p>
<CodeBlock
code={`curl -X POST https://api.banatie.com/api/text-to-image \\
-H "X-API-Key: YOUR_API_KEY" \\
-H "Content-Type: application/json" \\
-d '{
"prompt": "a serene mountain landscape at sunset",
"filename": "mountain_sunset",
"aspectRatio": "16:9",
"autoEnhance": true
}'`}
language="bash"
filename="Generate Image"
/>
<div className="mt-6 p-4 bg-slate-800/50 border border-slate-700 rounded-xl">
<p className="text-sm font-semibold text-gray-300 mb-2">Response:</p>
<pre className="text-xs text-gray-400 overflow-x-auto">
<code>{`{
"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..."
}
}
}`}</code>
</pre>
</div>
</section>
{/* Next Steps */}
<section id="next-steps" className="mb-12">
<h2 className="text-3xl font-bold text-white mb-6">Next Steps</h2>
<div className="grid md:grid-cols-2 gap-4">
<a
href="/docs/variant-a/api/text-to-image"
className="p-6 bg-gradient-to-br from-purple-500/10 to-transparent border border-purple-500/20 rounded-xl hover:border-purple-500/40 transition-colors group"
>
<div className="text-2xl mb-3">📚</div>
<h3 className="text-lg font-semibold text-white mb-2 group-hover:text-purple-400 transition-colors">
API Reference
</h3>
<p className="text-sm text-gray-400">
Explore all available endpoints, parameters, and response formats.
</p>
</a>
<a
href="/docs/variant-a/guides/authentication"
className="p-6 bg-gradient-to-br from-cyan-500/10 to-transparent border border-cyan-500/20 rounded-xl hover:border-cyan-500/40 transition-colors group"
>
<div className="text-2xl mb-3">🔐</div>
<h3 className="text-lg font-semibold text-white mb-2 group-hover:text-cyan-400 transition-colors">
Authentication Guide
</h3>
<p className="text-sm text-gray-400">
Learn about API keys, rate limits, and security best practices.
</p>
</a>
<a
href="/docs/variant-a/examples"
className="p-6 bg-gradient-to-br from-purple-500/10 to-transparent border border-purple-500/20 rounded-xl hover:border-purple-500/40 transition-colors group"
>
<div className="text-2xl mb-3">💡</div>
<h3 className="text-lg font-semibold text-white mb-2 group-hover:text-purple-400 transition-colors">
Examples
</h3>
<p className="text-sm text-gray-400">
Browse code examples and use cases for common scenarios.
</p>
</a>
<a
href="/docs/variant-a/guides/error-handling"
className="p-6 bg-gradient-to-br from-cyan-500/10 to-transparent border border-cyan-500/20 rounded-xl hover:border-cyan-500/40 transition-colors group"
>
<div className="text-2xl mb-3"></div>
<h3 className="text-lg font-semibold text-white mb-2 group-hover:text-cyan-400 transition-colors">
Error Handling
</h3>
<p className="text-sm text-gray-400">
Understand error codes and how to handle failures gracefully.
</p>
</a>
</div>
</section>
</DocsLayoutA>
);
}

View File

@ -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 (
<DocsLayoutB
sidebar={<DocsSidebarB currentPath="/docs/variant-b/api/text-to-image" />}
toc={<DocsTOCB items={tocItems} />}
>
<Breadcrumb
items={[
{ label: 'Documentation', href: '/docs' },
{ label: 'API Reference', href: '/docs/variant-b/api' },
{ label: 'Text to Image' },
]}
/>
{/* Hero Section - More compact */}
<div className="mb-10">
<div className="inline-block px-2.5 py-1 rounded-full bg-purple-500/10 border border-purple-500/20 text-purple-300 text-xs font-medium mb-3">
POST
</div>
<h1 className="text-4xl md:text-5xl font-bold text-white mb-3">Text to Image</h1>
<p className="text-lg text-gray-400 leading-relaxed">
Generate high-quality images from text prompts using AI-powered models.
</p>
</div>
{/* Overview */}
<section id="overview" className="mb-8">
<h2 className="text-2xl font-bold text-white mb-3">1. Overview</h2>
<p className="text-gray-300 leading-relaxed mb-3 text-sm">
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.
</p>
<div className="p-3 bg-cyan-500/10 border border-cyan-500/20 rounded-lg">
<p className="text-xs text-cyan-300">
<strong>Tip:</strong> Enable autoEnhance for better results. The AI will optimize your
prompt for higher quality outputs while preserving your intent.
</p>
</div>
</section>
{/* Endpoint */}
<section id="endpoint" className="mb-8">
<h2 className="text-2xl font-bold text-white mb-3">2. Endpoint</h2>
<div className="p-3 bg-slate-800/50 border border-slate-700 rounded-lg">
<code className="text-purple-400 text-sm">POST</code>
<code className="ml-3 text-gray-300 text-sm">https://api.banatie.com/api/text-to-image</code>
</div>
</section>
{/* Request */}
<section id="request" className="mb-8">
<h2 className="text-2xl font-bold text-white mb-5">3. Request</h2>
<div id="headers" className="mb-6">
<h3 className="text-lg font-semibold text-white mb-3">3.1 Headers</h3>
<div className="overflow-x-auto">
<table className="w-full text-xs">
<thead>
<tr className="border-b border-slate-700">
<th className="text-left py-2 px-3 text-gray-400 font-medium">Header</th>
<th className="text-left py-2 px-3 text-gray-400 font-medium">Value</th>
<th className="text-left py-2 px-3 text-gray-400 font-medium">Required</th>
</tr>
</thead>
<tbody className="text-gray-300">
<tr className="border-b border-slate-800">
<td className="py-2 px-3 font-mono text-purple-400">X-API-Key</td>
<td className="py-2 px-3">Your project API key</td>
<td className="py-2 px-3">
<span className="px-1.5 py-0.5 bg-red-500/20 text-red-400 rounded text-xs">Yes</span>
</td>
</tr>
<tr className="border-b border-slate-800">
<td className="py-2 px-3 font-mono text-purple-400">Content-Type</td>
<td className="py-2 px-3">application/json</td>
<td className="py-2 px-3">
<span className="px-1.5 py-0.5 bg-red-500/20 text-red-400 rounded text-xs">Yes</span>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div id="body" className="mb-6">
<h3 className="text-lg font-semibold text-white mb-3">3.2 Body Parameters</h3>
<div className="overflow-x-auto">
<table className="w-full text-xs">
<thead>
<tr className="border-b border-slate-700">
<th className="text-left py-2 px-3 text-gray-400 font-medium">Parameter</th>
<th className="text-left py-2 px-3 text-gray-400 font-medium">Type</th>
<th className="text-left py-2 px-3 text-gray-400 font-medium">Description</th>
<th className="text-left py-2 px-3 text-gray-400 font-medium">Required</th>
</tr>
</thead>
<tbody className="text-gray-300">
<tr className="border-b border-slate-800">
<td className="py-2 px-3 font-mono text-purple-400">prompt</td>
<td className="py-2 px-3">string</td>
<td className="py-2 px-3">Text description of the image to generate</td>
<td className="py-2 px-3">
<span className="px-1.5 py-0.5 bg-red-500/20 text-red-400 rounded text-xs">Yes</span>
</td>
</tr>
<tr className="border-b border-slate-800">
<td className="py-2 px-3 font-mono text-purple-400">filename</td>
<td className="py-2 px-3">string</td>
<td className="py-2 px-3">Name for the generated image file</td>
<td className="py-2 px-3">
<span className="px-1.5 py-0.5 bg-red-500/20 text-red-400 rounded text-xs">Yes</span>
</td>
</tr>
<tr className="border-b border-slate-800">
<td className="py-2 px-3 font-mono text-purple-400">aspectRatio</td>
<td className="py-2 px-3">string</td>
<td className="py-2 px-3">
Image aspect ratio. Options: 1:1, 3:4, 4:3, 9:16, 16:9, 21:9
</td>
<td className="py-2 px-3">
<span className="px-1.5 py-0.5 bg-gray-500/20 text-gray-400 rounded text-xs">No</span>
</td>
</tr>
<tr className="border-b border-slate-800">
<td className="py-2 px-3 font-mono text-purple-400">autoEnhance</td>
<td className="py-2 px-3">boolean</td>
<td className="py-2 px-3">Enable automatic prompt enhancement (default: true)</td>
<td className="py-2 px-3">
<span className="px-1.5 py-0.5 bg-gray-500/20 text-gray-400 rounded text-xs">No</span>
</td>
</tr>
<tr className="border-b border-slate-800">
<td className="py-2 px-3 font-mono text-purple-400">enhancementOptions</td>
<td className="py-2 px-3">object</td>
<td className="py-2 px-3">Template and enhancement settings</td>
<td className="py-2 px-3">
<span className="px-1.5 py-0.5 bg-gray-500/20 text-gray-400 rounded text-xs">No</span>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</section>
{/* Interactive API Widget */}
<InteractiveAPIWidgetB
endpoint="/api/text-to-image"
method="POST"
description="Try generating an image with your own API key"
parameters={[
{
name: 'prompt',
type: 'string',
required: true,
description: 'Image description',
defaultValue: 'a futuristic city at sunset',
},
{
name: 'filename',
type: 'string',
required: true,
description: 'Output filename',
defaultValue: 'city',
},
{
name: 'aspectRatio',
type: 'string',
required: false,
description: 'Aspect ratio',
defaultValue: '16:9',
},
]}
/>
{/* Response */}
<section id="response" className="mb-8">
<h2 className="text-2xl font-bold text-white mb-3">4. Response</h2>
<p className="text-gray-300 leading-relaxed mb-3 text-sm">
Returns a JSON object with the generated image URL and metadata.
</p>
<div className="p-3 bg-slate-800/50 border border-slate-700 rounded-lg">
<pre className="text-xs text-gray-300 overflow-x-auto">
<code>{`{
"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"
}
}`}</code>
</pre>
</div>
</section>
{/* Examples */}
<section id="examples" className="mb-8">
<h2 className="text-2xl font-bold text-white mb-5">5. Examples</h2>
<div className="space-y-4">
<div>
<h4 className="text-base font-semibold text-white mb-2">5.1 Basic Image Generation</h4>
<p className="text-xs text-gray-400 mb-2">Generate a simple image with default settings</p>
<div className="p-3 bg-slate-950/50 border border-slate-700 rounded-lg">
<pre className="text-xs text-gray-300 overflow-x-auto">
<code>{`{
"prompt": "a serene mountain landscape",
"filename": "mountain"
}`}</code>
</pre>
</div>
</div>
<div>
<h4 className="text-base font-semibold text-white mb-2">5.2 Custom Aspect Ratio</h4>
<p className="text-xs text-gray-400 mb-2">Generate a widescreen image</p>
<div className="p-3 bg-slate-950/50 border border-slate-700 rounded-lg">
<pre className="text-xs text-gray-300 overflow-x-auto">
<code>{`{
"prompt": "cinematic space battle scene",
"filename": "space_battle",
"aspectRatio": "21:9"
}`}</code>
</pre>
</div>
</div>
</div>
</section>
{/* Error Codes */}
<section id="errors" className="mb-8">
<h2 className="text-2xl font-bold text-white mb-3">6. Error Codes</h2>
<div className="overflow-x-auto">
<table className="w-full text-xs">
<thead>
<tr className="border-b border-slate-700">
<th className="text-left py-2 px-3 text-gray-400 font-medium">Code</th>
<th className="text-left py-2 px-3 text-gray-400 font-medium">Description</th>
</tr>
</thead>
<tbody className="text-gray-300">
<tr className="border-b border-slate-800">
<td className="py-2 px-3 font-mono text-red-400">400</td>
<td className="py-2 px-3">Invalid request parameters</td>
</tr>
<tr className="border-b border-slate-800">
<td className="py-2 px-3 font-mono text-red-400">401</td>
<td className="py-2 px-3">Missing or invalid API key</td>
</tr>
<tr className="border-b border-slate-800">
<td className="py-2 px-3 font-mono text-red-400">429</td>
<td className="py-2 px-3">Rate limit exceeded</td>
</tr>
<tr className="border-b border-slate-800">
<td className="py-2 px-3 font-mono text-red-400">500</td>
<td className="py-2 px-3">Internal server error</td>
</tr>
</tbody>
</table>
</div>
</section>
</DocsLayoutB>
);
}

View File

@ -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 (
<DocsLayoutB
sidebar={<DocsSidebarB currentPath="/docs/variant-b/guides/authentication" />}
toc={<DocsTOCB items={tocItems} />}
>
<Breadcrumb
items={[
{ label: 'Documentation', href: '/docs' },
{ label: 'Guides', href: '/docs/variant-b/guides' },
{ label: 'Authentication' },
]}
/>
{/* Hero Section - More compact */}
<div className="mb-10">
<div className="inline-block px-2.5 py-1 rounded-full bg-cyan-500/10 border border-cyan-500/20 text-cyan-300 text-xs font-medium mb-3">
GUIDE
</div>
<h1 className="text-4xl md:text-5xl font-bold text-white mb-3">Authentication</h1>
<p className="text-lg text-gray-400 leading-relaxed">
Learn how to authenticate your requests and manage API keys securely.
</p>
</div>
{/* Overview */}
<section id="overview" className="mb-8">
<h2 className="text-2xl font-bold text-white mb-3">1. Overview</h2>
<p className="text-gray-300 leading-relaxed mb-3 text-sm">
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.
</p>
<div className="p-3 bg-purple-500/10 border border-purple-500/20 rounded-lg">
<p className="text-xs text-purple-300">
<strong>Security First:</strong> Never expose your API keys in client-side code, public
repositories, or logs. Treat them like passwords.
</p>
</div>
</section>
{/* API Keys */}
<section id="api-keys" className="mb-8">
<h2 className="text-2xl font-bold text-white mb-5">2. API Keys</h2>
<div id="key-types" className="mb-6">
<h3 className="text-lg font-semibold text-white mb-3">2.1 Key Types</h3>
<p className="text-gray-300 leading-relaxed mb-4 text-sm">
Banatie provides two types of API keys, each with different permissions and use cases:
</p>
<div className="space-y-3">
<div className="p-4 bg-slate-800/50 border border-slate-700 rounded-lg">
<div className="flex items-start gap-3">
<div className="flex-shrink-0 w-8 h-8 rounded-lg bg-purple-500/20 flex items-center justify-center text-lg">
🔑
</div>
<div className="flex-1">
<h4 className="text-base font-semibold text-white mb-1.5">Master Keys</h4>
<p className="text-xs text-gray-400 mb-2">
Full administrative access to your organization. Can create and revoke other
keys, access all projects, and manage settings.
</p>
<ul className="text-xs text-gray-400 space-y-0.5">
<li> Never expire</li>
<li> Full API access</li>
<li> One per organization (initially)</li>
<li> Should be kept extremely secure</li>
</ul>
</div>
</div>
</div>
<div className="p-4 bg-slate-800/50 border border-slate-700 rounded-lg">
<div className="flex items-start gap-3">
<div className="flex-shrink-0 w-8 h-8 rounded-lg bg-cyan-500/20 flex items-center justify-center text-lg">
🎫
</div>
<div className="flex-1">
<h4 className="text-base font-semibold text-white mb-1.5">Project Keys</h4>
<p className="text-xs text-gray-400 mb-2">
Scoped to a specific project. Used for image generation and resource access
within that project only.
</p>
<ul className="text-xs text-gray-400 space-y-0.5">
<li> Expire after 90 days</li>
<li> Project-specific access</li>
<li> Rate limited</li>
<li> Safe for production use</li>
</ul>
</div>
</div>
</div>
</div>
</div>
<div id="creating-keys" className="mb-6">
<h3 className="text-lg font-semibold text-white mb-3">2.2 Creating Keys</h3>
<div className="mb-5">
<h4 className="text-sm font-semibold text-white mb-2">2.2.1 Bootstrap Your First Key</h4>
<p className="text-gray-300 text-xs leading-relaxed mb-2">
When setting up Banatie for the first time, create your initial master key using the
bootstrap endpoint:
</p>
<CodeBlock
code={`curl -X POST https://api.banatie.com/api/bootstrap/initial-key
# Response
{
"success": true,
"key": "bnt_master_abc123...",
"message": "Master key created successfully"
}`}
language="bash"
filename="Create Master Key"
/>
<div className="mt-2 p-2.5 bg-amber-500/10 border border-amber-500/20 rounded-lg">
<p className="text-xs text-amber-300">
<strong>Important:</strong> This endpoint can only be used once. Save the returned
key immediately - it will never be shown again.
</p>
</div>
</div>
<div className="mb-5">
<h4 className="text-sm font-semibold text-white mb-2">2.2.2 Create Project Keys</h4>
<p className="text-gray-300 text-xs leading-relaxed mb-2">
Use your master key to create project-specific keys:
</p>
<CodeBlock
code={`curl -X POST https://api.banatie.com/api/admin/keys \\
-H "X-API-Key: YOUR_MASTER_KEY" \\
-H "Content-Type: application/json" \\
-d '{
"type": "project",
"projectId": "my-project",
"name": "Production Key"
}'
# Response
{
"success": true,
"key": "bnt_project_xyz789...",
"keyId": "key_abc123",
"expiresAt": "2025-04-15T10:30:00Z"
}`}
language="bash"
filename="Create Project Key"
/>
</div>
</div>
</section>
{/* Using Keys */}
<section id="using-keys" className="mb-8">
<h2 className="text-2xl font-bold text-white mb-3">3. Using API Keys</h2>
<p className="text-gray-300 leading-relaxed mb-4 text-sm">
Include your API key in every request using the X-API-Key header:
</p>
<CodeBlock
code={`# Using curl
curl -X POST https://api.banatie.com/api/text-to-image \\
-H "X-API-Key: YOUR_PROJECT_KEY" \\
-H "Content-Type: application/json" \\
-d '{"prompt": "sunset", "filename": "test"}'
# Using JavaScript fetch
const response = await fetch('https://api.banatie.com/api/text-to-image', {
method: 'POST',
headers: {
'X-API-Key': 'YOUR_PROJECT_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
prompt: 'sunset',
filename: 'test'
})
});`}
language="bash"
filename="API Request Example"
/>
</section>
{/* Security */}
<section id="security" className="mb-8">
<h2 className="text-2xl font-bold text-white mb-5">4. Security Best Practices</h2>
<div className="space-y-3">
<div className="flex gap-3 p-3 bg-slate-800/50 border border-slate-700 rounded-lg">
<div className="flex-shrink-0 text-xl">🔒</div>
<div>
<h4 className="text-xs font-semibold text-white mb-0.5">Never Commit Keys</h4>
<p className="text-xs text-gray-400">
Use environment variables or secret management tools. Never commit keys to version
control.
</p>
</div>
</div>
<div className="flex gap-3 p-3 bg-slate-800/50 border border-slate-700 rounded-lg">
<div className="flex-shrink-0 text-xl">🔄</div>
<div>
<h4 className="text-xs font-semibold text-white mb-0.5">Rotate Keys Regularly</h4>
<p className="text-xs text-gray-400">
Project keys expire after 90 days. Plan for rotation and implement graceful
handling.
</p>
</div>
</div>
<div className="flex gap-3 p-3 bg-slate-800/50 border border-slate-700 rounded-lg">
<div className="flex-shrink-0 text-xl">🚫</div>
<div>
<h4 className="text-xs font-semibold text-white mb-0.5">Server-Side Only</h4>
<p className="text-xs text-gray-400">
Never use API keys in client-side code. Always make requests from your backend.
</p>
</div>
</div>
<div className="flex gap-3 p-3 bg-slate-800/50 border border-slate-700 rounded-lg">
<div className="flex-shrink-0 text-xl">👁</div>
<div>
<h4 className="text-xs font-semibold text-white mb-0.5">Monitor Usage</h4>
<p className="text-xs text-gray-400">
Track API key usage patterns. Unusual activity may indicate a compromised key.
</p>
</div>
</div>
</div>
</section>
{/* Rate Limits */}
<section id="rate-limits" className="mb-8">
<h2 className="text-2xl font-bold text-white mb-3">5. Rate Limits</h2>
<p className="text-gray-300 leading-relaxed mb-4 text-sm">
To ensure fair usage and system stability, all API keys are subject to rate limits:
</p>
<div className="overflow-x-auto">
<table className="w-full text-xs">
<thead>
<tr className="border-b border-slate-700">
<th className="text-left py-2 px-3 text-gray-400 font-medium">Key Type</th>
<th className="text-left py-2 px-3 text-gray-400 font-medium">Limit</th>
<th className="text-left py-2 px-3 text-gray-400 font-medium">Window</th>
</tr>
</thead>
<tbody className="text-gray-300">
<tr className="border-b border-slate-800">
<td className="py-2 px-3">Master Key</td>
<td className="py-2 px-3 font-mono">500 requests</td>
<td className="py-2 px-3">per hour</td>
</tr>
<tr className="border-b border-slate-800">
<td className="py-2 px-3">Project Key</td>
<td className="py-2 px-3 font-mono">100 requests</td>
<td className="py-2 px-3">per hour</td>
</tr>
</tbody>
</table>
</div>
<div className="mt-4 p-3 bg-cyan-500/10 border border-cyan-500/20 rounded-lg">
<p className="text-xs text-cyan-300">
<strong>Need Higher Limits?</strong> Contact our sales team to discuss enterprise plans
with custom rate limits.
</p>
</div>
</section>
</DocsLayoutB>
);
}

View File

@ -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 (
<DocsLayoutB
sidebar={<DocsSidebarB currentPath="/docs/variant-b" />}
toc={<DocsTOCB items={tocItems} />}
>
<Breadcrumb items={[{ label: 'Documentation', href: '/docs' }, { label: 'Getting Started' }]} />
{/* Hero Section - More compact */}
<div className="mb-10">
<h1 className="text-4xl md:text-5xl font-bold text-white mb-3">Getting Started</h1>
<p className="text-lg text-gray-400 leading-relaxed">
Welcome to the Banatie API documentation. Learn how to integrate AI-powered image
generation into your applications in minutes.
</p>
</div>
{/* Introduction */}
<section id="introduction" className="mb-10">
<h2 className="text-2xl font-bold text-white mb-3">1. Introduction</h2>
<p className="text-gray-300 leading-relaxed mb-3">
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.
</p>
<p className="text-gray-300 leading-relaxed">
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.
</p>
</section>
{/* Quick Start */}
<section id="quick-start" className="mb-10">
<h2 className="text-2xl font-bold text-white mb-5">2. Quick Start</h2>
<div id="installation" className="mb-6">
<h3 className="text-lg font-semibold text-white mb-2">2.1 Installation</h3>
<p className="text-gray-300 leading-relaxed mb-3 text-sm">
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.
</p>
<CodeBlock
code={`# Using npm (JavaScript/TypeScript)
npm install @banatie/sdk
# Using pip (Python)
pip install banatie
# Using Go
go get github.com/banatie/sdk-go`}
language="bash"
filename="Installation"
/>
</div>
<div id="authentication" className="mb-6">
<h3 className="text-lg font-semibold text-white mb-2">2.2 Authentication</h3>
<p className="text-gray-300 leading-relaxed mb-3 text-sm">
All API requests require an API key. You can create an API key from your dashboard or
using the bootstrap endpoint for initial setup.
</p>
<div className="p-3 bg-purple-500/10 border border-purple-500/20 rounded-lg mb-3">
<p className="text-xs text-purple-300">
<strong>Note:</strong> Keep your API keys secure. Never commit them to public
repositories or expose them in client-side code.
</p>
</div>
<CodeBlock
code={`# Create your first API key (one-time bootstrap)
curl -X POST https://api.banatie.com/api/bootstrap/initial-key
# Save the returned key securely
export BANATIE_API_KEY="bnt_your_key_here"`}
language="bash"
filename="Get API Key"
/>
</div>
</section>
{/* First Request */}
<section id="first-request" className="mb-10">
<h2 className="text-2xl font-bold text-white mb-3">3. Your First Request</h2>
<p className="text-gray-300 leading-relaxed mb-4 text-sm">
Let's generate your first image! This example uses curl, but you can use any HTTP client
or our SDKs.
</p>
<CodeBlock
code={`curl -X POST https://api.banatie.com/api/text-to-image \\
-H "X-API-Key: YOUR_API_KEY" \\
-H "Content-Type: application/json" \\
-d '{
"prompt": "a serene mountain landscape at sunset",
"filename": "mountain_sunset",
"aspectRatio": "16:9",
"autoEnhance": true
}'`}
language="bash"
filename="Generate Image"
/>
<div className="mt-4 p-3 bg-slate-800/50 border border-slate-700 rounded-lg">
<p className="text-xs font-semibold text-gray-300 mb-2">Response:</p>
<pre className="text-xs text-gray-400 overflow-x-auto">
<code>{`{
"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..."
}
}
}`}</code>
</pre>
</div>
</section>
{/* Next Steps */}
<section id="next-steps" className="mb-10">
<h2 className="text-2xl font-bold text-white mb-5">4. Next Steps</h2>
<div className="grid md:grid-cols-2 gap-3">
<a
href="/docs/variant-b/api/text-to-image"
className="p-4 bg-gradient-to-br from-purple-500/10 to-transparent border border-purple-500/20 rounded-lg hover:border-purple-500/40 transition-colors group"
>
<div className="text-xl mb-2">📚</div>
<h3 className="text-base font-semibold text-white mb-1 group-hover:text-purple-400 transition-colors">
API Reference
</h3>
<p className="text-xs text-gray-400">
Explore all available endpoints, parameters, and response formats.
</p>
</a>
<a
href="/docs/variant-b/guides/authentication"
className="p-4 bg-gradient-to-br from-cyan-500/10 to-transparent border border-cyan-500/20 rounded-lg hover:border-cyan-500/40 transition-colors group"
>
<div className="text-xl mb-2">🔐</div>
<h3 className="text-base font-semibold text-white mb-1 group-hover:text-cyan-400 transition-colors">
Authentication Guide
</h3>
<p className="text-xs text-gray-400">
Learn about API keys, rate limits, and security best practices.
</p>
</a>
<a
href="/docs/variant-b/examples"
className="p-4 bg-gradient-to-br from-purple-500/10 to-transparent border border-purple-500/20 rounded-lg hover:border-purple-500/40 transition-colors group"
>
<div className="text-xl mb-2">💡</div>
<h3 className="text-base font-semibold text-white mb-1 group-hover:text-purple-400 transition-colors">
Examples
</h3>
<p className="text-xs text-gray-400">
Browse code examples and use cases for common scenarios.
</p>
</a>
<a
href="/docs/variant-b/guides/error-handling"
className="p-4 bg-gradient-to-br from-cyan-500/10 to-transparent border border-cyan-500/20 rounded-lg hover:border-cyan-500/40 transition-colors group"
>
<div className="text-xl mb-2"></div>
<h3 className="text-base font-semibold text-white mb-1 group-hover:text-cyan-400 transition-colors">
Error Handling
</h3>
<p className="text-xs text-gray-400">
Understand error codes and how to handle failures gracefully.
</p>
</a>
</div>
</section>
</DocsLayoutB>
);
}

View File

@ -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 (
<DocsLayoutC
sidebar={<DocsSidebarC currentPath="/docs/variant-c/api/text-to-image" />}
toc={<DocsTOCC items={tocItems} />}
>
<Breadcrumb
items={[
{ label: 'Documentation', href: '/docs' },
{ label: 'API Reference', href: '/docs/variant-c/api' },
{ label: 'Text to Image' },
]}
/>
{/* Hero Section - Large and Colorful */}
<div className="mb-12">
<div className="inline-flex items-center gap-2 px-4 py-2 rounded-full bg-gradient-to-r from-purple-500/30 to-purple-600/30 border-2 border-purple-500/50 shadow-lg shadow-purple-500/30 mb-6">
<span className="text-lg font-bold text-white">POST</span>
</div>
<h1 className="text-5xl md:text-6xl font-bold text-white mb-6 bg-gradient-to-r from-purple-400 to-cyan-400 bg-clip-text text-transparent">
Text to Image
</h1>
<p className="text-xl text-gray-300 leading-relaxed">
Generate high-quality images from text prompts using AI-powered models.
</p>
</div>
{/* Overview */}
<section id="overview" className="mb-12">
<div className="flex items-center gap-3 mb-6">
<span className="text-3xl">📖</span>
<h2 className="text-3xl font-bold text-white">Overview</h2>
</div>
<div className="p-6 bg-gradient-to-br from-purple-500/10 to-transparent border-2 border-purple-500/30 rounded-2xl shadow-xl shadow-purple-500/20">
<p className="text-gray-300 leading-relaxed mb-4">
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.
</p>
<div className="p-4 bg-cyan-500/10 border-2 border-cyan-500/30 rounded-xl">
<div className="flex items-start gap-3">
<span className="text-2xl">💡</span>
<div>
<p className="text-sm font-bold text-cyan-300 mb-1">Pro Tip</p>
<p className="text-sm text-cyan-200">
Enable autoEnhance for better results. The AI will optimize your prompt for higher
quality outputs while preserving your intent.
</p>
</div>
</div>
</div>
</div>
</section>
{/* Endpoint */}
<section id="endpoint" className="mb-12">
<div className="flex items-center gap-3 mb-6">
<span className="text-3xl">🔗</span>
<h2 className="text-3xl font-bold text-white">Endpoint</h2>
</div>
<div className="p-6 bg-gradient-to-br from-slate-900/80 to-slate-950/80 border-2 border-purple-500/30 rounded-2xl shadow-xl">
<div className="flex flex-wrap items-center gap-3">
<span className="px-3 py-1.5 bg-gradient-to-r from-purple-500 to-purple-600 text-white rounded-lg font-bold text-sm shadow-lg">
POST
</span>
<code className="text-purple-400 font-mono">https://api.banatie.com/api/text-to-image</code>
</div>
</div>
</section>
{/* Request */}
<section id="request" className="mb-12">
<div className="flex items-center gap-3 mb-8">
<span className="text-3xl">📤</span>
<h2 className="text-3xl font-bold text-white">Request</h2>
</div>
<div id="headers" className="mb-8">
<div className="flex items-center gap-2 mb-4">
<span className="text-2xl">🏷</span>
<h3 className="text-2xl font-semibold text-white">Headers</h3>
</div>
<div className="overflow-hidden border-2 border-cyan-500/30 rounded-2xl shadow-lg">
<table className="w-full">
<thead>
<tr className="bg-slate-950/80 border-b-2 border-cyan-500/20">
<th className="text-left py-4 px-6 text-cyan-400 font-bold text-sm">Header</th>
<th className="text-left py-4 px-6 text-cyan-400 font-bold text-sm">Value</th>
<th className="text-left py-4 px-6 text-cyan-400 font-bold text-sm">Required</th>
</tr>
</thead>
<tbody className="text-gray-300 bg-slate-900/50">
<tr className="border-b border-slate-800">
<td className="py-4 px-6 font-mono text-purple-400 font-semibold">X-API-Key</td>
<td className="py-4 px-6">Your project API key</td>
<td className="py-4 px-6">
<span className="px-3 py-1.5 bg-red-500/20 text-red-400 rounded-lg text-xs font-bold border-2 border-red-500/40">
Required
</span>
</td>
</tr>
<tr className="border-b border-slate-800">
<td className="py-4 px-6 font-mono text-purple-400 font-semibold">Content-Type</td>
<td className="py-4 px-6">application/json</td>
<td className="py-4 px-6">
<span className="px-3 py-1.5 bg-red-500/20 text-red-400 rounded-lg text-xs font-bold border-2 border-red-500/40">
Required
</span>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div id="body" className="mb-8">
<div className="flex items-center gap-2 mb-4">
<span className="text-2xl"></span>
<h3 className="text-2xl font-semibold text-white">Body Parameters</h3>
</div>
<div className="overflow-hidden border-2 border-purple-500/30 rounded-2xl shadow-lg">
<table className="w-full">
<thead>
<tr className="bg-slate-950/80 border-b-2 border-purple-500/20">
<th className="text-left py-4 px-6 text-purple-400 font-bold text-sm">Parameter</th>
<th className="text-left py-4 px-6 text-purple-400 font-bold text-sm">Type</th>
<th className="text-left py-4 px-6 text-purple-400 font-bold text-sm">Description</th>
<th className="text-left py-4 px-6 text-purple-400 font-bold text-sm">Required</th>
</tr>
</thead>
<tbody className="text-gray-300 bg-slate-900/50">
<tr className="border-b border-slate-800">
<td className="py-4 px-6 font-mono text-cyan-400 font-semibold">prompt</td>
<td className="py-4 px-6 text-sm">string</td>
<td className="py-4 px-6 text-sm">Text description of the image to generate</td>
<td className="py-4 px-6">
<span className="px-3 py-1.5 bg-red-500/20 text-red-400 rounded-lg text-xs font-bold border-2 border-red-500/40">
Required
</span>
</td>
</tr>
<tr className="border-b border-slate-800">
<td className="py-4 px-6 font-mono text-cyan-400 font-semibold">filename</td>
<td className="py-4 px-6 text-sm">string</td>
<td className="py-4 px-6 text-sm">Name for the generated image file</td>
<td className="py-4 px-6">
<span className="px-3 py-1.5 bg-red-500/20 text-red-400 rounded-lg text-xs font-bold border-2 border-red-500/40">
Required
</span>
</td>
</tr>
<tr className="border-b border-slate-800">
<td className="py-4 px-6 font-mono text-cyan-400 font-semibold">aspectRatio</td>
<td className="py-4 px-6 text-sm">string</td>
<td className="py-4 px-6 text-sm">
Image aspect ratio. Options: 1:1, 3:4, 4:3, 9:16, 16:9, 21:9
</td>
<td className="py-4 px-6">
<span className="px-3 py-1.5 bg-gray-500/20 text-gray-400 rounded-lg text-xs font-bold border-2 border-gray-500/30">
Optional
</span>
</td>
</tr>
<tr className="border-b border-slate-800">
<td className="py-4 px-6 font-mono text-cyan-400 font-semibold">autoEnhance</td>
<td className="py-4 px-6 text-sm">boolean</td>
<td className="py-4 px-6 text-sm">Enable automatic prompt enhancement (default: true)</td>
<td className="py-4 px-6">
<span className="px-3 py-1.5 bg-gray-500/20 text-gray-400 rounded-lg text-xs font-bold border-2 border-gray-500/30">
Optional
</span>
</td>
</tr>
<tr className="border-b border-slate-800">
<td className="py-4 px-6 font-mono text-cyan-400 font-semibold">enhancementOptions</td>
<td className="py-4 px-6 text-sm">object</td>
<td className="py-4 px-6 text-sm">Template and enhancement settings</td>
<td className="py-4 px-6">
<span className="px-3 py-1.5 bg-gray-500/20 text-gray-400 rounded-lg text-xs font-bold border-2 border-gray-500/30">
Optional
</span>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</section>
{/* Interactive API Widget */}
<InteractiveAPIWidgetC
endpoint="/api/text-to-image"
method="POST"
description="Try generating an image with your own API key"
parameters={[
{
name: 'prompt',
type: 'string',
required: true,
description: 'Image description',
defaultValue: 'a futuristic city at sunset',
},
{
name: 'filename',
type: 'string',
required: true,
description: 'Output filename',
defaultValue: 'city',
},
{
name: 'aspectRatio',
type: 'string',
required: false,
description: 'Aspect ratio',
defaultValue: '16:9',
},
]}
/>
{/* Response */}
<section id="response" className="mb-12">
<div className="flex items-center gap-3 mb-6">
<span className="text-3xl">📦</span>
<h2 className="text-3xl font-bold text-white">Response</h2>
</div>
<p className="text-gray-300 leading-relaxed mb-6">
Returns a JSON object with the generated image URL and metadata.
</p>
<div className="p-6 bg-gradient-to-br from-slate-900/80 to-slate-950/80 border-2 border-green-500/30 rounded-2xl shadow-xl shadow-green-500/20">
<div className="flex items-center gap-2 mb-4">
<span className="px-3 py-1.5 bg-green-500/20 text-green-400 rounded-lg text-xs font-bold border-2 border-green-500/40">
200 Success
</span>
</div>
<pre className="text-sm text-gray-300 overflow-x-auto">
<code>{`{
"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"
}
}`}</code>
</pre>
</div>
</section>
{/* Examples */}
<section id="examples" className="mb-12">
<div className="flex items-center gap-3 mb-8">
<span className="text-3xl">💡</span>
<h2 className="text-3xl font-bold text-white">Examples</h2>
</div>
<div className="space-y-6">
<div className="p-6 bg-gradient-to-br from-purple-500/10 to-transparent border-2 border-purple-500/30 rounded-2xl shadow-lg">
<div className="flex items-center gap-2 mb-3">
<span className="text-xl">🎨</span>
<h4 className="text-xl font-bold text-white">Basic Image Generation</h4>
</div>
<p className="text-sm text-gray-400 mb-4">Generate a simple image with default settings</p>
<div className="p-4 bg-slate-950/50 border-2 border-purple-500/20 rounded-xl">
<pre className="text-sm text-gray-300 overflow-x-auto">
<code>{`{
"prompt": "a serene mountain landscape",
"filename": "mountain"
}`}</code>
</pre>
</div>
</div>
<div className="p-6 bg-gradient-to-br from-cyan-500/10 to-transparent border-2 border-cyan-500/30 rounded-2xl shadow-lg">
<div className="flex items-center gap-2 mb-3">
<span className="text-xl">🎬</span>
<h4 className="text-xl font-bold text-white">Custom Aspect Ratio</h4>
</div>
<p className="text-sm text-gray-400 mb-4">Generate a widescreen image</p>
<div className="p-4 bg-slate-950/50 border-2 border-cyan-500/20 rounded-xl">
<pre className="text-sm text-gray-300 overflow-x-auto">
<code>{`{
"prompt": "cinematic space battle scene",
"filename": "space_battle",
"aspectRatio": "21:9"
}`}</code>
</pre>
</div>
</div>
</div>
</section>
{/* Error Codes */}
<section id="errors" className="mb-12">
<div className="flex items-center gap-3 mb-6">
<span className="text-3xl"></span>
<h2 className="text-3xl font-bold text-white">Error Codes</h2>
</div>
<div className="overflow-hidden border-2 border-red-500/30 rounded-2xl shadow-xl shadow-red-500/20">
<table className="w-full">
<thead>
<tr className="bg-slate-950/80 border-b-2 border-red-500/20">
<th className="text-left py-4 px-6 text-red-400 font-bold text-sm">Code</th>
<th className="text-left py-4 px-6 text-red-400 font-bold text-sm">Description</th>
</tr>
</thead>
<tbody className="text-gray-300 bg-slate-900/50">
<tr className="border-b border-slate-800">
<td className="py-4 px-6 font-mono text-red-400 font-bold text-lg">400</td>
<td className="py-4 px-6">Invalid request parameters</td>
</tr>
<tr className="border-b border-slate-800">
<td className="py-4 px-6 font-mono text-red-400 font-bold text-lg">401</td>
<td className="py-4 px-6">Missing or invalid API key</td>
</tr>
<tr className="border-b border-slate-800">
<td className="py-4 px-6 font-mono text-red-400 font-bold text-lg">429</td>
<td className="py-4 px-6">Rate limit exceeded</td>
</tr>
<tr className="border-b border-slate-800">
<td className="py-4 px-6 font-mono text-red-400 font-bold text-lg">500</td>
<td className="py-4 px-6">Internal server error</td>
</tr>
</tbody>
</table>
</div>
</section>
</DocsLayoutC>
);
}

View File

@ -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 (
<DocsLayoutC
sidebar={<DocsSidebarC currentPath="/docs/variant-c/guides/authentication" />}
toc={<DocsTOCC items={tocItems} />}
>
<Breadcrumb
items={[
{ label: 'Documentation', href: '/docs' },
{ label: 'Guides', href: '/docs/variant-c/guides' },
{ label: 'Authentication' },
]}
/>
{/* Hero Section - Large and Colorful */}
<div className="mb-12">
<div className="inline-flex items-center gap-2 px-4 py-2 rounded-full bg-gradient-to-r from-cyan-500/20 to-cyan-600/20 border-2 border-cyan-500/50 shadow-lg shadow-cyan-500/30 mb-6">
<span className="text-2xl">📚</span>
<span className="text-sm font-bold text-white">GUIDE</span>
</div>
<h1 className="text-5xl md:text-6xl font-bold text-white mb-6 bg-gradient-to-r from-cyan-400 to-purple-400 bg-clip-text text-transparent">
Authentication
</h1>
<p className="text-xl text-gray-300 leading-relaxed">
Learn how to authenticate your requests and manage API keys securely.
</p>
</div>
{/* Overview */}
<section id="overview" className="mb-12">
<div className="flex items-center gap-3 mb-6">
<span className="text-3xl">🔐</span>
<h2 className="text-3xl font-bold text-white">Overview</h2>
</div>
<div className="p-6 bg-gradient-to-br from-purple-500/10 to-transparent border-2 border-purple-500/30 rounded-2xl shadow-xl shadow-purple-500/20">
<p className="text-gray-300 leading-relaxed mb-4">
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.
</p>
<div className="p-4 bg-red-500/10 border-2 border-red-500/30 rounded-xl">
<div className="flex items-start gap-3">
<span className="text-2xl">🛡</span>
<div>
<p className="text-sm font-bold text-red-300 mb-1">Security First</p>
<p className="text-sm text-red-200">
Never expose your API keys in client-side code, public repositories, or logs. Treat
them like passwords.
</p>
</div>
</div>
</div>
</div>
</section>
{/* API Keys */}
<section id="api-keys" className="mb-12">
<div className="flex items-center gap-3 mb-8">
<span className="text-3xl">🔑</span>
<h2 className="text-3xl font-bold text-white">API Keys</h2>
</div>
<div id="key-types" className="mb-8">
<div className="flex items-center gap-2 mb-6">
<span className="text-2xl">🏷</span>
<h3 className="text-2xl font-semibold text-white">Key Types</h3>
</div>
<p className="text-gray-300 leading-relaxed mb-6">
Banatie provides two types of API keys, each with different permissions and use cases:
</p>
<div className="space-y-6">
<div className="p-6 bg-gradient-to-br from-purple-500/10 to-transparent border-2 border-purple-500/30 rounded-2xl shadow-xl shadow-purple-500/20 hover:scale-105 transition-transform duration-300">
<div className="flex items-start gap-4">
<div className="flex-shrink-0 w-16 h-16 rounded-2xl bg-gradient-to-br from-purple-500/30 to-purple-600/30 border-2 border-purple-500/50 flex items-center justify-center text-3xl shadow-lg">
🔑
</div>
<div className="flex-1">
<h4 className="text-2xl font-bold text-white mb-3">Master Keys</h4>
<p className="text-sm text-gray-400 mb-4">
Full administrative access to your organization. Can create and revoke other
keys, access all projects, and manage settings.
</p>
<ul className="text-sm text-gray-400 space-y-2">
<li className="flex items-center gap-2">
<span className="text-purple-400"></span> Never expire
</li>
<li className="flex items-center gap-2">
<span className="text-purple-400"></span> Full API access
</li>
<li className="flex items-center gap-2">
<span className="text-purple-400"></span> One per organization (initially)
</li>
<li className="flex items-center gap-2">
<span className="text-purple-400"></span> Should be kept extremely secure
</li>
</ul>
</div>
</div>
</div>
<div className="p-6 bg-gradient-to-br from-cyan-500/10 to-transparent border-2 border-cyan-500/30 rounded-2xl shadow-xl shadow-cyan-500/20 hover:scale-105 transition-transform duration-300">
<div className="flex items-start gap-4">
<div className="flex-shrink-0 w-16 h-16 rounded-2xl bg-gradient-to-br from-cyan-500/30 to-cyan-600/30 border-2 border-cyan-500/50 flex items-center justify-center text-3xl shadow-lg">
🎫
</div>
<div className="flex-1">
<h4 className="text-2xl font-bold text-white mb-3">Project Keys</h4>
<p className="text-sm text-gray-400 mb-4">
Scoped to a specific project. Used for image generation and resource access
within that project only.
</p>
<ul className="text-sm text-gray-400 space-y-2">
<li className="flex items-center gap-2">
<span className="text-cyan-400"></span> Expire after 90 days
</li>
<li className="flex items-center gap-2">
<span className="text-cyan-400"></span> Project-specific access
</li>
<li className="flex items-center gap-2">
<span className="text-cyan-400"></span> Rate limited
</li>
<li className="flex items-center gap-2">
<span className="text-cyan-400"></span> Safe for production use
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
<div id="creating-keys" className="mb-8">
<div className="flex items-center gap-2 mb-6">
<span className="text-2xl"></span>
<h3 className="text-2xl font-semibold text-white">Creating Keys</h3>
</div>
<div className="mb-8 p-6 bg-gradient-to-br from-amber-500/10 to-transparent border-2 border-amber-500/30 rounded-2xl shadow-xl shadow-amber-500/20">
<div className="flex items-center gap-2 mb-4">
<span className="text-2xl">🚀</span>
<h4 className="text-xl font-bold text-white">Bootstrap Your First Key</h4>
</div>
<p className="text-gray-300 text-sm leading-relaxed mb-4">
When setting up Banatie for the first time, create your initial master key using the
bootstrap endpoint:
</p>
<CodeBlock
code={`curl -X POST https://api.banatie.com/api/bootstrap/initial-key
# Response
{
"success": true,
"key": "bnt_master_abc123...",
"message": "Master key created successfully"
}`}
language="bash"
filename="Create Master Key"
/>
<div className="mt-4 p-4 bg-red-500/10 border-2 border-red-500/30 rounded-xl">
<div className="flex items-start gap-2">
<span className="text-xl"></span>
<div>
<p className="text-xs font-bold text-red-300 mb-1">Important</p>
<p className="text-xs text-red-200">
This endpoint can only be used once. Save the returned key immediately - it will
never be shown again.
</p>
</div>
</div>
</div>
</div>
<div className="p-6 bg-gradient-to-br from-purple-500/10 to-transparent border-2 border-purple-500/30 rounded-2xl shadow-xl shadow-purple-500/20">
<div className="flex items-center gap-2 mb-4">
<span className="text-2xl">🎨</span>
<h4 className="text-xl font-bold text-white">Create Project Keys</h4>
</div>
<p className="text-gray-300 text-sm leading-relaxed mb-4">
Use your master key to create project-specific keys:
</p>
<CodeBlock
code={`curl -X POST https://api.banatie.com/api/admin/keys \\
-H "X-API-Key: YOUR_MASTER_KEY" \\
-H "Content-Type: application/json" \\
-d '{
"type": "project",
"projectId": "my-project",
"name": "Production Key"
}'
# Response
{
"success": true,
"key": "bnt_project_xyz789...",
"keyId": "key_abc123",
"expiresAt": "2025-04-15T10:30:00Z"
}`}
language="bash"
filename="Create Project Key"
/>
</div>
</div>
</section>
{/* Using Keys */}
<section id="using-keys" className="mb-12">
<div className="flex items-center gap-3 mb-6">
<span className="text-3xl">💻</span>
<h2 className="text-3xl font-bold text-white">Using API Keys</h2>
</div>
<p className="text-gray-300 leading-relaxed mb-6">
Include your API key in every request using the X-API-Key header:
</p>
<CodeBlock
code={`# Using curl
curl -X POST https://api.banatie.com/api/text-to-image \\
-H "X-API-Key: YOUR_PROJECT_KEY" \\
-H "Content-Type: application/json" \\
-d '{"prompt": "sunset", "filename": "test"}'
# Using JavaScript fetch
const response = await fetch('https://api.banatie.com/api/text-to-image', {
method: 'POST',
headers: {
'X-API-Key': 'YOUR_PROJECT_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
prompt: 'sunset',
filename: 'test'
})
});`}
language="bash"
filename="API Request Example"
/>
</section>
{/* Security */}
<section id="security" className="mb-12">
<div className="flex items-center gap-3 mb-8">
<span className="text-3xl">🛡</span>
<h2 className="text-3xl font-bold text-white">Security Best Practices</h2>
</div>
<div className="grid md:grid-cols-2 gap-6">
<div className="p-6 bg-gradient-to-br from-red-500/10 to-transparent border-2 border-red-500/30 rounded-2xl shadow-lg hover:shadow-red-500/30 hover:scale-105 transition-all">
<div className="text-3xl mb-4">🔒</div>
<h4 className="text-lg font-bold text-white mb-2">Never Commit Keys</h4>
<p className="text-sm text-gray-400">
Use environment variables or secret management tools. Never commit keys to version
control.
</p>
</div>
<div className="p-6 bg-gradient-to-br from-amber-500/10 to-transparent border-2 border-amber-500/30 rounded-2xl shadow-lg hover:shadow-amber-500/30 hover:scale-105 transition-all">
<div className="text-3xl mb-4">🔄</div>
<h4 className="text-lg font-bold text-white mb-2">Rotate Keys Regularly</h4>
<p className="text-sm text-gray-400">
Project keys expire after 90 days. Plan for rotation and implement graceful handling.
</p>
</div>
<div className="p-6 bg-gradient-to-br from-purple-500/10 to-transparent border-2 border-purple-500/30 rounded-2xl shadow-lg hover:shadow-purple-500/30 hover:scale-105 transition-all">
<div className="text-3xl mb-4">🚫</div>
<h4 className="text-lg font-bold text-white mb-2">Server-Side Only</h4>
<p className="text-sm text-gray-400">
Never use API keys in client-side code. Always make requests from your backend.
</p>
</div>
<div className="p-6 bg-gradient-to-br from-cyan-500/10 to-transparent border-2 border-cyan-500/30 rounded-2xl shadow-lg hover:shadow-cyan-500/30 hover:scale-105 transition-all">
<div className="text-3xl mb-4">👁</div>
<h4 className="text-lg font-bold text-white mb-2">Monitor Usage</h4>
<p className="text-sm text-gray-400">
Track API key usage patterns. Unusual activity may indicate a compromised key.
</p>
</div>
</div>
</section>
{/* Rate Limits */}
<section id="rate-limits" className="mb-12">
<div className="flex items-center gap-3 mb-6">
<span className="text-3xl"></span>
<h2 className="text-3xl font-bold text-white">Rate Limits</h2>
</div>
<p className="text-gray-300 leading-relaxed mb-6">
To ensure fair usage and system stability, all API keys are subject to rate limits:
</p>
<div className="overflow-hidden border-2 border-purple-500/30 rounded-2xl shadow-xl shadow-purple-500/20">
<table className="w-full">
<thead>
<tr className="bg-slate-950/80 border-b-2 border-purple-500/20">
<th className="text-left py-4 px-6 text-purple-400 font-bold">Key Type</th>
<th className="text-left py-4 px-6 text-purple-400 font-bold">Limit</th>
<th className="text-left py-4 px-6 text-purple-400 font-bold">Window</th>
</tr>
</thead>
<tbody className="text-gray-300 bg-slate-900/50">
<tr className="border-b border-slate-800">
<td className="py-4 px-6 font-semibold">Master Key</td>
<td className="py-4 px-6">
<span className="px-3 py-1.5 bg-purple-500/20 text-purple-400 rounded-lg font-mono font-bold border-2 border-purple-500/40">
500 requests
</span>
</td>
<td className="py-4 px-6">per hour</td>
</tr>
<tr className="border-b border-slate-800">
<td className="py-4 px-6 font-semibold">Project Key</td>
<td className="py-4 px-6">
<span className="px-3 py-1.5 bg-cyan-500/20 text-cyan-400 rounded-lg font-mono font-bold border-2 border-cyan-500/40">
100 requests
</span>
</td>
<td className="py-4 px-6">per hour</td>
</tr>
</tbody>
</table>
</div>
<div className="mt-6 p-6 bg-gradient-to-br from-cyan-500/10 to-transparent border-2 border-cyan-500/30 rounded-2xl shadow-xl shadow-cyan-500/20">
<div className="flex items-start gap-3">
<span className="text-2xl">💬</span>
<div>
<p className="text-sm font-bold text-cyan-300 mb-1">Need Higher Limits?</p>
<p className="text-sm text-cyan-200">
Contact our sales team to discuss enterprise plans with custom rate limits.
</p>
</div>
</div>
</div>
</section>
</DocsLayoutC>
);
}

View File

@ -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 (
<DocsLayoutC
sidebar={<DocsSidebarC currentPath="/docs/variant-c" />}
toc={<DocsTOCC items={tocItems} />}
>
<Breadcrumb items={[{ label: 'Documentation', href: '/docs' }, { label: 'Getting Started' }]} />
{/* Hero Section - Large and Colorful */}
<div className="mb-12">
<div className="inline-flex items-center gap-2 px-4 py-2 rounded-full bg-gradient-to-r from-purple-500/20 to-cyan-500/20 border-2 border-purple-500/40 mb-6">
<span className="text-2xl">🚀</span>
<span className="text-sm font-bold text-white">START HERE</span>
</div>
<h1 className="text-5xl md:text-6xl font-bold text-white mb-6 bg-gradient-to-r from-purple-400 to-cyan-400 bg-clip-text text-transparent">
Getting Started
</h1>
<p className="text-xl text-gray-300 leading-relaxed">
Welcome to the Banatie API documentation. Learn how to integrate AI-powered image
generation into your applications in minutes.
</p>
</div>
{/* Introduction */}
<section id="introduction" className="mb-12">
<div className="flex items-center gap-3 mb-6">
<span className="text-3xl">👋</span>
<h2 className="text-3xl font-bold text-white">Introduction</h2>
</div>
<div className="p-6 bg-gradient-to-br from-purple-500/10 to-transparent border-2 border-purple-500/30 rounded-2xl shadow-xl shadow-purple-500/20">
<p className="text-gray-300 leading-relaxed mb-4">
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.
</p>
<p className="text-gray-300 leading-relaxed">
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.
</p>
</div>
</section>
{/* Quick Start */}
<section id="quick-start" className="mb-12">
<div className="flex items-center gap-3 mb-6">
<span className="text-3xl"></span>
<h2 className="text-3xl font-bold text-white">Quick Start</h2>
</div>
<div id="installation" className="mb-8">
<div className="flex items-center gap-2 mb-4">
<span className="text-2xl">📦</span>
<h3 className="text-2xl font-semibold text-white">Installation</h3>
</div>
<p className="text-gray-300 leading-relaxed mb-6">
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.
</p>
<CodeBlock
code={`# Using npm (JavaScript/TypeScript)
npm install @banatie/sdk
# Using pip (Python)
pip install banatie
# Using Go
go get github.com/banatie/sdk-go`}
language="bash"
filename="Installation"
/>
</div>
<div id="authentication" className="mb-8">
<div className="flex items-center gap-2 mb-4">
<span className="text-2xl">🔑</span>
<h3 className="text-2xl font-semibold text-white">Authentication</h3>
</div>
<p className="text-gray-300 leading-relaxed mb-6">
All API requests require an API key. You can create an API key from your dashboard or
using the bootstrap endpoint for initial setup.
</p>
<div className="p-6 bg-gradient-to-br from-amber-500/10 to-transparent border-2 border-amber-500/40 rounded-2xl mb-6 shadow-xl shadow-amber-500/20">
<div className="flex items-start gap-3">
<span className="text-2xl">💡</span>
<div>
<p className="text-sm font-bold text-amber-300 mb-2">Security Tip</p>
<p className="text-sm text-amber-200">
Keep your API keys secure. Never commit them to public repositories or expose them
in client-side code.
</p>
</div>
</div>
</div>
<CodeBlock
code={`# Create your first API key (one-time bootstrap)
curl -X POST https://api.banatie.com/api/bootstrap/initial-key
# Save the returned key securely
export BANATIE_API_KEY="bnt_your_key_here"`}
language="bash"
filename="Get API Key"
/>
</div>
</section>
{/* First Request */}
<section id="first-request" className="mb-12">
<div className="flex items-center gap-3 mb-6">
<span className="text-3xl">🎨</span>
<h2 className="text-3xl font-bold text-white">Your First Request</h2>
</div>
<p className="text-gray-300 leading-relaxed mb-6">
Let's generate your first image! This example uses curl, but you can use any HTTP client
or our SDKs.
</p>
<CodeBlock
code={`curl -X POST https://api.banatie.com/api/text-to-image \\
-H "X-API-Key: YOUR_API_KEY" \\
-H "Content-Type: application/json" \\
-d '{
"prompt": "a serene mountain landscape at sunset",
"filename": "mountain_sunset",
"aspectRatio": "16:9",
"autoEnhance": true
}'`}
language="bash"
filename="Generate Image"
/>
<div className="mt-6 p-6 bg-gradient-to-br from-cyan-500/10 to-transparent border-2 border-cyan-500/30 rounded-2xl shadow-xl shadow-cyan-500/20">
<div className="flex items-start gap-3 mb-4">
<span className="text-2xl"></span>
<p className="text-sm font-bold text-cyan-300">Expected Response:</p>
</div>
<pre className="text-sm text-gray-300 overflow-x-auto bg-slate-950/50 p-4 rounded-xl border-2 border-cyan-500/20">
<code>{`{
"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..."
}
}
}`}</code>
</pre>
</div>
</section>
{/* Next Steps */}
<section id="next-steps" className="mb-12">
<div className="flex items-center gap-3 mb-8">
<span className="text-3xl">🎯</span>
<h2 className="text-3xl font-bold text-white">Next Steps</h2>
</div>
<div className="grid md:grid-cols-2 gap-6">
<a
href="/docs/variant-c/api/text-to-image"
className="group p-6 bg-gradient-to-br from-purple-500/10 to-transparent border-2 border-purple-500/30 rounded-2xl hover:border-purple-500/60 transition-all duration-300 shadow-lg hover:shadow-purple-500/30 hover:scale-105"
>
<div className="text-3xl mb-4">📚</div>
<h3 className="text-xl font-bold text-white mb-3 group-hover:text-purple-400 transition-colors">
API Reference
</h3>
<p className="text-sm text-gray-400">
Explore all available endpoints, parameters, and response formats.
</p>
</a>
<a
href="/docs/variant-c/guides/authentication"
className="group p-6 bg-gradient-to-br from-cyan-500/10 to-transparent border-2 border-cyan-500/30 rounded-2xl hover:border-cyan-500/60 transition-all duration-300 shadow-lg hover:shadow-cyan-500/30 hover:scale-105"
>
<div className="text-3xl mb-4">🔐</div>
<h3 className="text-xl font-bold text-white mb-3 group-hover:text-cyan-400 transition-colors">
Authentication Guide
</h3>
<p className="text-sm text-gray-400">
Learn about API keys, rate limits, and security best practices.
</p>
</a>
<a
href="/docs/variant-c/examples"
className="group p-6 bg-gradient-to-br from-amber-500/10 to-transparent border-2 border-amber-500/30 rounded-2xl hover:border-amber-500/60 transition-all duration-300 shadow-lg hover:shadow-amber-500/30 hover:scale-105"
>
<div className="text-3xl mb-4">💡</div>
<h3 className="text-xl font-bold text-white mb-3 group-hover:text-amber-400 transition-colors">
Examples
</h3>
<p className="text-sm text-gray-400">
Browse code examples and use cases for common scenarios.
</p>
</a>
<a
href="/docs/variant-c/guides/error-handling"
className="group p-6 bg-gradient-to-br from-purple-500/10 to-transparent border-2 border-purple-500/30 rounded-2xl hover:border-purple-500/60 transition-all duration-300 shadow-lg hover:shadow-purple-500/30 hover:scale-105"
>
<div className="text-3xl mb-4"></div>
<h3 className="text-xl font-bold text-white mb-3 group-hover:text-purple-400 transition-colors">
Error Handling
</h3>
<p className="text-sm text-gray-400">
Understand error codes and how to handle failures gracefully.
</p>
</a>
</div>
</section>
{/* Fun CTA Card */}
<div className="mt-12 p-8 bg-gradient-to-br from-purple-500/20 via-cyan-500/20 to-amber-500/20 border-2 border-purple-500/40 rounded-2xl shadow-2xl shadow-purple-500/30 text-center">
<div className="text-4xl mb-4">🎉</div>
<h3 className="text-2xl font-bold text-white mb-3">Ready to Build Something Amazing?</h3>
<p className="text-gray-300 mb-6">
Start creating stunning AI-generated images for your applications today!
</p>
<a
href="/docs/variant-c/api/text-to-image"
className="inline-flex items-center gap-2 px-8 py-4 bg-gradient-to-r from-purple-600 to-cyan-600 hover:from-purple-500 hover:to-cyan-500 text-white font-bold rounded-xl transition-all duration-300 shadow-lg hover:shadow-purple-500/50 hover:scale-105"
>
<span></span>
<span>Explore the API</span>
</a>
</div>
</DocsLayoutC>
);
}

View File

@ -1,7 +1,7 @@
'use client'; 'use client';
/** /**
* Documentation Layout - Final Variant * Documentation Layout - Production Version
* *
* Based on Variant A: Clean & Minimal with enhancements * Based on Variant A: Clean & Minimal with enhancements
* This is the production-ready version combining the best aspects * This is the production-ready version combining the best aspects
@ -26,13 +26,13 @@
import { ReactNode } from 'react'; import { ReactNode } from 'react';
interface DocsLayoutFinalProps { interface DocsLayoutProps {
sidebar: ReactNode; sidebar: ReactNode;
children: ReactNode; children: ReactNode;
toc: ReactNode; toc: ReactNode;
} }
export const DocsLayoutFinal = ({ sidebar, children, toc }: DocsLayoutFinalProps) => { export const DocsLayout = ({ sidebar, children, toc }: DocsLayoutProps) => {
return ( return (
<div className="min-h-screen bg-gradient-to-br from-slate-950 via-slate-900 to-slate-950"> <div className="min-h-screen bg-gradient-to-br from-slate-950 via-slate-900 to-slate-950">
{/* Animated gradient background (matching landing page) */} {/* Animated gradient background (matching landing page) */}

View File

@ -1,7 +1,7 @@
'use client'; 'use client';
/** /**
* Documentation Sidebar - Final Variant * Documentation Sidebar - Production Version
* *
* Based on Variant A with FIXED active states * Based on Variant A with FIXED active states
* *
@ -33,44 +33,44 @@ interface NavItem {
children?: NavItem[]; children?: NavItem[];
} }
interface DocsSidebarFinalProps { interface DocsSidebarProps {
currentPath: string; currentPath: string;
} }
const navigationItems: NavItem[] = [ const navigationItems: NavItem[] = [
{ {
label: 'Getting Started', label: 'Getting Started',
href: '/docs/final', href: '/docs',
icon: '🚀', icon: '🚀',
}, },
{ {
label: 'API Reference', label: 'API Reference',
href: '/docs/final/api', href: '/docs/api',
icon: '📚', icon: '📚',
children: [ children: [
{ label: 'Text to Image', href: '/docs/final/api/text-to-image' }, { label: 'Text to Image', href: '/docs/api/text-to-image' },
{ label: 'Upload', href: '/docs/final/api/upload' }, { label: 'Upload', href: '/docs/api/upload' },
{ label: 'Images', href: '/docs/final/api/images' }, { label: 'Images', href: '/docs/api/images' },
], ],
}, },
{ {
label: 'Guides', label: 'Guides',
href: '/docs/final/guides', href: '/docs/guides',
icon: '📖', icon: '📖',
children: [ children: [
{ label: 'Authentication', href: '/docs/final/guides/authentication' }, { label: 'Authentication', href: '/docs/guides/authentication' },
{ label: 'Error Handling', href: '/docs/final/guides/error-handling' }, { label: 'Error Handling', href: '/docs/guides/error-handling' },
{ label: 'Rate Limits', href: '/docs/final/guides/rate-limits' }, { label: 'Rate Limits', href: '/docs/guides/rate-limits' },
], ],
}, },
{ {
label: 'Examples', label: 'Examples',
href: '/docs/final/examples', href: '/docs/examples',
icon: '💡', icon: '💡',
}, },
]; ];
export const DocsSidebarFinal = ({ currentPath }: DocsSidebarFinalProps) => { export const DocsSidebar = ({ currentPath }: DocsSidebarProps) => {
const [expandedSections, setExpandedSections] = useState<string[]>(['API Reference', 'Guides']); const [expandedSections, setExpandedSections] = useState<string[]>(['API Reference', 'Guides']);
const toggleSection = (label: string) => { const toggleSection = (label: string) => {
@ -87,7 +87,7 @@ export const DocsSidebarFinal = ({ currentPath }: DocsSidebarFinalProps) => {
{/* Logo/Title */} {/* Logo/Title */}
<div className="mb-8"> <div className="mb-8">
<h2 className="text-lg font-semibold text-white">Documentation</h2> <h2 className="text-lg font-semibold text-white">Documentation</h2>
<p className="text-xs text-gray-500 mt-1">Final: Production</p> <p className="text-xs text-gray-500 mt-1">API Reference</p>
</div> </div>
{/* Navigation Items */} {/* Navigation Items */}
@ -170,8 +170,8 @@ export const DocsSidebarFinal = ({ currentPath }: DocsSidebarFinalProps) => {
<div className="mt-12 pt-6 border-t border-slate-800"> <div className="mt-12 pt-6 border-t border-slate-800">
<ul className="space-y-2 text-sm"> <ul className="space-y-2 text-sm">
<li> <li>
<a href="/docs" className="text-gray-500 hover:text-gray-300 transition-colors"> <a href="/" className="text-gray-500 hover:text-gray-300 transition-colors">
Back to variants Back to home
</a> </a>
</li> </li>
</ul> </ul>

View File

@ -1,7 +1,7 @@
'use client'; 'use client';
/** /**
* Table of Contents - Final Variant * Table of Contents - Production Version
* *
* Based on Variant A: Clean & Minimal (no changes needed) * Based on Variant A: Clean & Minimal (no changes needed)
* *
@ -26,11 +26,11 @@ interface TocItem {
level: number; level: number;
} }
interface DocsTOCFinalProps { interface DocsTOCProps {
items: TocItem[]; items: TocItem[];
} }
export const DocsTOCFinal = ({ items }: DocsTOCFinalProps) => { export const DocsTOC = ({ items }: DocsTOCProps) => {
const [activeId, setActiveId] = useState<string>(''); const [activeId, setActiveId] = useState<string>('');
useEffect(() => { useEffect(() => {

View File

@ -1,9 +1,9 @@
'use client'; '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) * - No inline API key input (uses DocsApiKeyInput component)
* - Clean header with method badge, endpoint, and expand button * - Clean header with method badge, endpoint, and expand button
* - Full-width code snippet area * - Full-width code snippet area
@ -13,7 +13,7 @@
import { useState, useEffect } from 'react'; import { useState, useEffect } from 'react';
interface InteractiveAPIWidgetFinalProps { interface InteractiveAPIWidgetProps {
endpoint: string; endpoint: string;
method: 'GET' | 'POST' | 'PUT' | 'DELETE'; method: 'GET' | 'POST' | 'PUT' | 'DELETE';
description: string; description: string;
@ -46,12 +46,12 @@ const getMethodBadgeStyle = (method: string): string => {
} }
}; };
export const InteractiveAPIWidgetFinal = ({ export const InteractiveAPIWidget = ({
endpoint, endpoint,
method, method,
description, description,
parameters = [], parameters = [],
}: InteractiveAPIWidgetFinalProps) => { }: InteractiveAPIWidgetProps) => {
const [language, setLanguage] = useState<Language>('curl'); const [language, setLanguage] = useState<Language>('curl');
const [apiKey, setApiKey] = useState(''); const [apiKey, setApiKey] = useState('');
const [isExecuting, setIsExecuting] = useState(false); const [isExecuting, setIsExecuting] = useState(false);

View File

@ -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 (
<div className="min-h-screen bg-gradient-to-br from-slate-950 via-slate-900 to-slate-950">
{/* Animated gradient background (matching landing page) */}
<div className="fixed inset-0 overflow-hidden pointer-events-none">
<div className="absolute top-1/4 -left-1/4 w-96 h-96 bg-purple-600/10 rounded-full blur-3xl animate-pulse"></div>
<div className="absolute bottom-1/4 -right-1/4 w-96 h-96 bg-cyan-600/10 rounded-full blur-3xl animate-pulse delay-700"></div>
</div>
<div className="relative z-10 flex">
{/* Left Sidebar - Thin, minimal design */}
<aside className="hidden lg:block w-64 border-r border-white/10 bg-slate-950/50 backdrop-blur-sm sticky top-0 h-screen overflow-y-auto">
{sidebar}
</aside>
{/* Main Content Area - Wide margins for comfortable reading */}
<main className="flex-1 min-w-0">
<div className="max-w-3xl mx-auto px-6 lg:px-12 py-12">
{children}
</div>
</main>
{/* Right TOC - Subtle and unobtrusive */}
<aside className="hidden xl:block w-56 border-l border-white/10 bg-slate-950/30 backdrop-blur-sm sticky top-0 h-screen overflow-y-auto">
{toc}
</aside>
</div>
</div>
);
};

View File

@ -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<string[]>(['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 (
<nav className="p-6" aria-label="Documentation navigation">
{/* Logo/Title */}
<div className="mb-8">
<h2 className="text-lg font-semibold text-white">Documentation</h2>
<p className="text-xs text-gray-500 mt-1">Variant A: Clean</p>
</div>
{/* Navigation Items */}
<ul className="space-y-1">
{navigationItems.map((item) => {
const hasChildren = item.children && item.children.length > 0;
const expanded = isExpanded(item.label);
const active = isActive(item.href);
return (
<li key={item.label}>
{/* Parent Item */}
<div className="relative">
{active && (
<div className="absolute left-0 top-0 bottom-0 w-0.5 bg-purple-500 rounded-r"></div>
)}
<a
href={item.href}
onClick={
hasChildren
? (e) => {
e.preventDefault();
toggleSection(item.label);
}
: undefined
}
className={`
flex items-center justify-between px-3 py-2 rounded-lg text-sm transition-colors
${active ? 'bg-purple-500/10 text-white font-medium' : 'text-gray-400 hover:text-white hover:bg-white/5'}
`}
>
<span className="flex items-center gap-2">
{item.icon && <span className="text-base">{item.icon}</span>}
<span>{item.label}</span>
</span>
{hasChildren && (
<svg
className={`w-4 h-4 transition-transform ${expanded ? 'rotate-90' : ''}`}
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5l7 7-7 7" />
</svg>
)}
</a>
</div>
{/* Children Items */}
{hasChildren && expanded && (
<ul className="ml-6 mt-1 space-y-1 border-l border-slate-800">
{item.children!.map((child) => {
const childActive = isActive(child.href);
return (
<li key={child.label}>
<a
href={child.href}
className={`
block px-3 py-1.5 text-sm rounded-lg transition-colors -ml-px
${childActive ? 'text-white font-medium border-l-2 border-purple-500' : 'text-gray-500 hover:text-gray-300 border-l-2 border-transparent'}
`}
>
{child.label}
</a>
</li>
);
})}
</ul>
)}
</li>
);
})}
</ul>
{/* Bottom Links */}
<div className="mt-12 pt-6 border-t border-slate-800">
<ul className="space-y-2 text-sm">
<li>
<a href="/docs" className="text-gray-500 hover:text-gray-300 transition-colors">
Back to variants
</a>
</li>
</ul>
</div>
</nav>
);
};

View File

@ -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<string>('');
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 (
<nav className="p-6 sticky top-6" aria-label="Table of contents">
<h3 className="text-xs font-semibold text-gray-500 uppercase tracking-wider mb-4">
On This Page
</h3>
<ul className="space-y-2.5 text-sm">
{items.map((item) => {
const isActive = activeId === item.id;
const isH3 = item.level === 3;
return (
<li key={item.id} className={isH3 ? 'ml-4' : ''}>
<button
onClick={() => 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 */}
<span
className={`
flex-shrink-0 w-1 h-1 rounded-full mt-2 transition-colors
${isActive ? 'bg-purple-400' : 'bg-gray-600 group-hover:bg-gray-400'}
`}
></span>
<span className="line-clamp-2">{item.text}</span>
</button>
</li>
);
})}
</ul>
</nav>
);
};

View File

@ -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<Language>('curl');
const [apiKey, setApiKey] = useState('');
const [isExecuting, setIsExecuting] = useState(false);
const [viewMode, setViewMode] = useState<ViewMode>('code');
const [response, setResponse] = useState<any>(null);
const [error, setError] = useState<string | null>(null);
// Parameter values
const [paramValues, setParamValues] = useState<Record<string, string>>({});
// Load API key from localStorage
useEffect(() => {
const stored = localStorage.getItem(API_KEY_STORAGE);
if (stored) setApiKey(stored);
// Initialize parameter default values
const defaults: Record<string, string> = {};
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<string, any> = {};
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 (
<div className="my-8 bg-slate-900/50 backdrop-blur-sm border border-slate-700 rounded-2xl overflow-hidden">
{/* Header with API Key Input */}
<div className="p-4 border-b border-slate-700 bg-slate-900/80">
<div className="flex flex-col md:flex-row gap-3 items-start md:items-center justify-between">
<div>
<h3 className="text-sm font-semibold text-white mb-1">Try it out</h3>
<p className="text-xs text-gray-500">{description}</p>
</div>
<div className="flex-shrink-0 w-full md:w-64">
<input
type="password"
value={apiKey}
onChange={(e) => 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"
/>
</div>
</div>
</div>
{/* Language Tabs */}
<div className="flex items-center justify-between bg-slate-950/50 px-4 py-2 border-b border-slate-700">
<div className="flex gap-2">
{(['curl', 'javascript', 'python', 'go'] as Language[]).map((lang) => (
<button
key={lang}
onClick={() => 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)}
</button>
))}
</div>
<button
onClick={copyCode}
className="px-3 py-1 text-xs bg-purple-600/20 hover:bg-purple-600/30 text-purple-400 rounded transition-colors"
>
Copy
</button>
</div>
{/* Code Display */}
<div className="p-4 bg-slate-950/50">
<pre className="text-xs text-gray-300 overflow-x-auto">
<code>{generateCode()}</code>
</pre>
</div>
{/* Try It Button */}
<div className="p-4 border-t border-slate-700 bg-slate-900/50">
<button
onClick={executeRequest}
disabled={!apiKey || isExecuting}
className="w-full px-4 py-2.5 rounded-lg bg-gradient-to-r from-purple-600 to-cyan-600 text-white text-sm font-semibold hover:from-purple-500 hover:to-cyan-500 transition-all disabled:opacity-50 disabled:cursor-not-allowed"
>
{isExecuting ? 'Executing...' : 'Try It'}
</button>
</div>
{/* Response Section */}
{(response || error) && (
<div className="border-t border-slate-700">
<div className="p-4 bg-slate-900/80">
<h4 className="text-sm font-semibold text-white mb-3">Response</h4>
{error ? (
<div className="p-3 bg-red-500/10 border border-red-500/20 rounded-lg text-red-400 text-xs">
{error}
</div>
) : (
<pre className="p-3 bg-slate-950/50 rounded-lg text-xs text-gray-300 overflow-x-auto">
<code>{JSON.stringify(response, null, 2)}</code>
</pre>
)}
</div>
</div>
)}
</div>
);
};

View File

@ -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 (
<div className="min-h-screen bg-gradient-to-br from-slate-950 via-slate-900 to-slate-950">
{/* Animated gradient background (matching landing page) */}
<div className="fixed inset-0 overflow-hidden pointer-events-none">
<div className="absolute top-1/4 -left-1/4 w-96 h-96 bg-purple-600/10 rounded-full blur-3xl animate-pulse"></div>
<div className="absolute bottom-1/4 -right-1/4 w-96 h-96 bg-cyan-600/10 rounded-full blur-3xl animate-pulse delay-700"></div>
</div>
<div className="relative z-10 flex">
{/* Left Sidebar - Wider with nested structure */}
<aside className="hidden lg:block w-72 border-r border-white/10 bg-slate-950/80 backdrop-blur-sm sticky top-0 h-screen overflow-y-auto">
{sidebar}
</aside>
{/* Main Content Area - Narrower margins for more content */}
<main className="flex-1 min-w-0">
<div className="max-w-4xl mx-auto px-6 lg:px-8 py-10">
{children}
</div>
</main>
{/* Right TOC - Prominent with progress */}
<aside className="hidden xl:block w-60 border-l border-white/10 bg-slate-950/50 backdrop-blur-sm sticky top-0 h-screen overflow-y-auto">
{toc}
</aside>
</div>
</div>
);
};

View File

@ -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<string[]>(['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 (
<nav className="p-4" aria-label="Documentation navigation">
{/* Header */}
<div className="mb-6 pb-4 border-b border-slate-800">
<h2 className="text-base font-bold text-white mb-1">Documentation</h2>
<p className="text-xs text-gray-500">Variant B: Dense</p>
</div>
{/* Search (placeholder) */}
<div className="mb-4">
<div className="relative">
<input
type="text"
placeholder="Search docs..."
className="w-full px-3 py-2 pl-9 text-sm bg-slate-800/50 border border-slate-700 rounded-lg text-white placeholder-gray-500 focus:outline-none focus:ring-2 focus:ring-purple-500 focus:border-transparent"
/>
<svg
className="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-gray-500"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"
/>
</svg>
</div>
</div>
{/* Navigation Tree */}
<ul className="space-y-0.5">
{navigationItems.map((item) => {
const hasChildren = item.children && item.children.length > 0;
const expanded = isExpanded(item.label);
const active = isActive(item.href);
return (
<li key={item.label}>
{/* Parent Item */}
<a
href={item.href}
onClick={
hasChildren
? (e) => {
e.preventDefault();
toggleSection(item.label);
}
: undefined
}
className={`
flex items-center justify-between px-3 py-2 rounded-md text-sm transition-colors
${active ? 'bg-purple-500/20 text-white font-semibold' : 'text-gray-400 hover:text-white hover:bg-slate-800/50'}
`}
>
<span className="flex items-center gap-2">
<span className="text-xs font-mono text-gray-500">{item.number}</span>
<span>{item.label}</span>
</span>
{hasChildren && (
<svg
className={`w-3.5 h-3.5 transition-transform ${expanded ? 'rotate-90' : ''}`}
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5l7 7-7 7" />
</svg>
)}
</a>
{/* Children Items - Indented */}
{hasChildren && expanded && (
<ul className="ml-6 mt-0.5 space-y-0.5 border-l border-slate-800 pl-2">
{item.children!.map((child) => {
const childActive = isActive(child.href);
return (
<li key={child.label}>
<a
href={child.href}
className={`
flex items-center gap-2 px-3 py-1.5 text-sm rounded-md transition-colors
${childActive ? 'bg-purple-500/20 text-white font-semibold' : 'text-gray-500 hover:text-gray-300 hover:bg-slate-800/30'}
`}
>
<span className="text-xs font-mono text-gray-600">{child.number}</span>
<span>{child.label}</span>
</a>
</li>
);
})}
</ul>
)}
</li>
);
})}
</ul>
{/* Bottom Links */}
<div className="mt-8 pt-4 border-t border-slate-800">
<ul className="space-y-1.5 text-sm">
<li>
<a
href="/docs"
className="flex items-center gap-2 px-3 py-1.5 text-gray-500 hover:text-gray-300 transition-colors"
>
<svg className="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M10 19l-7-7m0 0l7-7m-7 7h18" />
</svg>
<span>All variants</span>
</a>
</li>
</ul>
</div>
</nav>
);
};

View File

@ -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<string>('');
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 (
<nav className="p-5 sticky top-6" aria-label="Table of contents">
{/* Header with Progress */}
<div className="mb-4 pb-4 border-b border-slate-800">
<h3 className="text-xs font-bold text-white uppercase tracking-wider mb-3">
On This Page
</h3>
{/* Progress Bar */}
<div className="relative h-1 bg-slate-800 rounded-full overflow-hidden">
<div
className="absolute top-0 left-0 h-full bg-gradient-to-r from-purple-500 to-cyan-500 transition-all duration-300"
style={{ width: `${scrollProgress}%` }}
></div>
</div>
<p className="text-xs text-gray-500 mt-2">{Math.round(scrollProgress)}% read</p>
</div>
{/* TOC Items with Numbers */}
<ul className="space-y-1.5 text-sm">
{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 (
<li key={item.id} className={isH3 ? 'ml-4' : ''}>
<button
onClick={() => 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 */}
<span className="flex-shrink-0 font-mono text-xs mt-0.5 opacity-60">
{isH3 ? '↳' : number}
</span>
<span className="line-clamp-2">{item.text}</span>
</button>
</li>
);
})}
</ul>
{/* Back to Top Button */}
{scrollProgress > 20 && (
<button
onClick={() => 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"
>
<svg className="w-3.5 h-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M5 10l7-7m0 0l7 7m-7-7v18" />
</svg>
Back to top
</button>
)}
</nav>
);
};

View File

@ -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<Language>('curl');
const [apiKey, setApiKey] = useState('');
const [isExecuting, setIsExecuting] = useState(false);
const [response, setResponse] = useState<any>(null);
const [error, setError] = useState<string | null>(null);
const [paramValues, setParamValues] = useState<Record<string, string>>({});
// Load API key from localStorage
useEffect(() => {
const stored = localStorage.getItem(API_KEY_STORAGE);
if (stored) setApiKey(stored);
// Initialize parameter default values
const defaults: Record<string, string> = {};
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<string, any> = {};
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 (
<div className="my-6">
{/* API Key Bar - Persistent at top */}
<div className="mb-3 p-3 bg-slate-900/80 backdrop-blur-sm border border-slate-700 rounded-lg">
<div className="flex items-center gap-3">
<label className="text-xs font-semibold text-gray-400 whitespace-nowrap">API Key:</label>
<input
type="password"
value={apiKey}
onChange={(e) => 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"
/>
<span className={`text-xs ${apiKey ? 'text-green-400' : 'text-gray-500'}`}>
{apiKey ? '✓ Set' : 'Not set'}
</span>
</div>
</div>
{/* Main Widget - Two Column Layout */}
<div className="grid md:grid-cols-2 gap-3 bg-slate-900/50 backdrop-blur-sm border border-slate-700 rounded-lg overflow-hidden">
{/* Left Column: Code */}
<div className="border-r border-slate-700">
{/* Language Tabs */}
<div className="flex items-center justify-between bg-slate-950/50 px-3 py-2 border-b border-slate-700">
<div className="flex gap-1.5">
{(['curl', 'javascript', 'python', 'go'] as Language[]).map((lang) => (
<button
key={lang}
onClick={() => 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()}
</button>
))}
</div>
<button
onClick={copyCode}
className="px-2 py-1 text-xs bg-purple-600/20 hover:bg-purple-600/30 text-purple-400 rounded transition-colors"
>
Copy
</button>
</div>
{/* Code Display */}
<div className="p-3 bg-slate-950/50 h-64 overflow-auto">
<pre className="text-xs text-gray-300">
<code>{generateCode()}</code>
</pre>
</div>
</div>
{/* Right Column: Response */}
<div>
<div className="bg-slate-950/50 px-3 py-2 border-b border-slate-700">
<h4 className="text-xs font-semibold text-white">Response</h4>
</div>
<div className="p-3 bg-slate-950/50 h-64 overflow-auto">
{error ? (
<div className="p-2 bg-red-500/10 border border-red-500/20 rounded text-red-400 text-xs">
{error}
</div>
) : response ? (
<pre className="text-xs text-gray-300">
<code>{JSON.stringify(response, null, 2)}</code>
</pre>
) : (
<p className="text-xs text-gray-500 italic">
Click "Execute Request" to see the response
</p>
)}
</div>
</div>
</div>
{/* Try It Button - Full Width */}
<button
onClick={executeRequest}
disabled={!apiKey || isExecuting}
className="mt-3 w-full px-4 py-2 rounded-lg bg-gradient-to-r from-purple-600 to-cyan-600 text-white text-sm font-semibold hover:from-purple-500 hover:to-cyan-500 transition-all disabled:opacity-50 disabled:cursor-not-allowed"
>
{isExecuting ? 'Executing...' : '▶ Execute Request'}
</button>
<p className="mt-2 text-xs text-gray-500 text-center">{description}</p>
</div>
);
};

View File

@ -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 (
<div className="min-h-screen bg-gradient-to-br from-slate-950 via-slate-900 to-slate-950">
{/* Animated gradient background - More colorful */}
<div className="fixed inset-0 overflow-hidden pointer-events-none">
<div className="absolute top-1/4 -left-1/4 w-[600px] h-[600px] bg-purple-600/20 rounded-full blur-3xl animate-pulse"></div>
<div className="absolute bottom-1/4 -right-1/4 w-[600px] h-[600px] bg-cyan-600/20 rounded-full blur-3xl animate-pulse delay-700"></div>
<div className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-[400px] h-[400px] bg-amber-600/10 rounded-full blur-3xl animate-pulse delay-1000"></div>
</div>
<div className="relative z-10 flex">
{/* Left Sidebar - Wide with card-style navigation */}
<aside className="hidden lg:block w-80 border-r-2 border-purple-500/20 bg-slate-950/80 backdrop-blur-sm sticky top-0 h-screen overflow-y-auto">
{sidebar}
</aside>
{/* Main Content Area - Wide with generous padding */}
<main className="flex-1 min-w-0">
<div className="max-w-5xl mx-auto px-8 lg:px-12 py-12">
{children}
</div>
</main>
{/* Right TOC - Floating card with gradient border */}
<aside className="hidden xl:block w-72 border-l-2 border-cyan-500/20 bg-slate-950/60 backdrop-blur-md sticky top-0 h-screen overflow-y-auto">
{toc}
</aside>
</div>
</div>
);
};

View File

@ -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<string[]>(['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 (
<nav className="p-6" aria-label="Documentation navigation">
{/* Header - Colorful */}
<div className="mb-8 pb-6 border-b-2 border-gradient-to-r from-purple-500/30 to-cyan-500/30">
<div className="inline-flex items-center gap-2 px-4 py-2 rounded-full bg-gradient-to-r from-purple-500/20 to-cyan-500/20 border-2 border-purple-500/40 mb-3">
<span className="text-xl">📖</span>
<h2 className="text-base font-bold text-white">Documentation</h2>
</div>
<p className="text-xs text-gray-400 mt-2 ml-1">Variant C: Modern & Visual</p>
</div>
{/* Search (placeholder) - Colorful border */}
<div className="mb-6">
<div className="relative">
<input
type="text"
placeholder="Search docs..."
className="w-full px-4 py-3 pl-11 text-sm bg-slate-900/50 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"
/>
<svg
className="absolute left-4 top-1/2 -translate-y-1/2 w-4 h-4 text-purple-400"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"
/>
</svg>
</div>
</div>
{/* Navigation Cards */}
<ul className="space-y-4">
{navigationItems.map((item) => {
const hasChildren = item.children && item.children.length > 0;
const expanded = isExpanded(item.label);
const active = isActive(item.href);
return (
<li key={item.label}>
{/* Parent Item - Large Card */}
<a
href={item.href}
onClick={
hasChildren
? (e) => {
e.preventDefault();
toggleSection(item.label);
}
: undefined
}
className={`
flex items-center justify-between p-4 rounded-xl transition-all duration-300
${getGradientClasses(item.color, active)}
${active ? 'text-white font-bold' : 'text-gray-300 hover:text-white'}
`}
>
<span className="flex items-center gap-3">
<span className="text-2xl">{item.icon}</span>
<span className="text-base">{item.label}</span>
</span>
{hasChildren && (
<svg
className={`w-5 h-5 transition-transform duration-300 ${expanded ? 'rotate-90' : ''}`}
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5l7 7-7 7" />
</svg>
)}
</a>
{/* Children Items - Smaller Cards with Indent */}
{hasChildren && expanded && (
<ul className="ml-6 mt-3 space-y-2 border-l-2 border-purple-500/20 pl-4">
{item.children!.map((child) => {
const childActive = isActive(child.href);
return (
<li key={child.label}>
<a
href={child.href}
className={`
flex items-center gap-3 p-3 rounded-lg transition-all duration-300
${getGradientClasses(child.color, childActive)}
${childActive ? 'text-white font-semibold' : 'text-gray-400 hover:text-white'}
`}
>
<span className="text-xl">{child.icon}</span>
<span className="text-sm">{child.label}</span>
</a>
</li>
);
})}
</ul>
)}
</li>
);
})}
</ul>
{/* Bottom Links - Colorful Card */}
<div className="mt-8 pt-6 border-t-2 border-purple-500/20">
<a
href="/docs"
className="flex items-center gap-3 px-4 py-3 text-sm text-gray-400 hover:text-white transition-colors rounded-xl border-2 border-cyan-500/30 hover:border-cyan-500/50 hover:bg-cyan-500/10"
>
<svg className="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M10 19l-7-7m0 0l7-7m-7 7h18" />
</svg>
<span>View all variants</span>
</a>
</div>
</nav>
);
};

View File

@ -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<string>('');
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 (
<nav className="p-6 sticky top-6" aria-label="Table of contents">
{/* Floating Card with Gradient Border */}
<div className="rounded-2xl border-2 border-purple-500/40 bg-slate-900/60 backdrop-blur-md shadow-xl shadow-purple-500/20 overflow-hidden">
{/* Header with Icon and Progress */}
<div className="p-6 pb-4 border-b-2 border-purple-500/20">
<div className="flex items-center gap-3 mb-4">
<span className="text-2xl">📍</span>
<h3 className="text-sm font-bold text-white uppercase tracking-wider">
On This Page
</h3>
</div>
{/* Rainbow Progress Bar */}
<div className="relative h-2 bg-slate-800 rounded-full overflow-hidden">
<div
className="absolute top-0 left-0 h-full bg-gradient-to-r from-purple-500 via-cyan-500 to-amber-500 transition-all duration-300 shadow-lg"
style={{ width: `${scrollProgress}%` }}
></div>
</div>
<div className="mt-2 flex items-center justify-between">
<p className="text-xs text-gray-400">{Math.round(scrollProgress)}% complete</p>
<span className="text-xs text-purple-400 font-semibold">
{items.findIndex((item) => item.id === activeId) + 1}/{items.length}
</span>
</div>
</div>
{/* TOC Items with Colorful Dots */}
<ul className="p-6 space-y-3">
{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 (
<li key={item.id} className={isH3 ? 'ml-6' : ''}>
<button
onClick={() => 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 */}
<span className="mt-1.5">
{isH3 ? (
<span className="text-gray-600 text-xs ml-0.5"></span>
) : (
<span className={getDotClasses(color, isActive)}></span>
)}
</span>
{/* Text */}
<span className="flex-1 text-base leading-relaxed">{cleanText}</span>
</button>
</li>
);
})}
</ul>
{/* Back to Top Button - Colorful */}
{scrollProgress > 20 && (
<div className="p-6 pt-0">
<button
onClick={() => 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"
>
<svg className="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M5 10l7-7m0 0l7 7m-7-7v18" />
</svg>
<span className="font-semibold">Back to top</span>
</button>
</div>
)}
</div>
{/* Fun Floating Tip Card */}
<div className="mt-6 p-4 rounded-xl bg-gradient-to-br from-amber-500/10 to-transparent border-2 border-amber-500/30 shadow-lg">
<div className="flex items-start gap-2">
<span className="text-xl">💡</span>
<p className="text-xs text-amber-300">
<strong>Tip:</strong> Click any item to jump directly to that section!
</p>
</div>
</div>
</nav>
);
};

View File

@ -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<Language>('curl');
const [apiKey, setApiKey] = useState('');
const [isExecuting, setIsExecuting] = useState(false);
const [response, setResponse] = useState<any>(null);
const [error, setError] = useState<string | null>(null);
const [paramValues, setParamValues] = useState<Record<string, string>>({});
const [isExpanded, setIsExpanded] = useState(false);
useEffect(() => {
const stored = localStorage.getItem(API_KEY_STORAGE);
if (stored) setApiKey(stored);
const defaults: Record<string, string> = {};
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<string, any> = {};
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 (
<div className="my-12">
{/* API Key Card - Large and Colorful */}
<div className="mb-6 p-6 bg-gradient-to-br from-purple-500/10 to-cyan-500/10 backdrop-blur-sm border-2 border-purple-500/40 rounded-2xl shadow-xl shadow-purple-500/20">
<div className="flex items-center gap-4 mb-3">
<span className="text-2xl">🔑</span>
<label className="text-sm font-bold text-white">Your API Key</label>
</div>
<div className="flex items-center gap-3">
<input
type="password"
value={apiKey}
onChange={(e) => 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"
/>
<div
className={`px-4 py-3 rounded-xl font-semibold text-sm transition-all ${
apiKey
? 'bg-green-500/20 text-green-400 border-2 border-green-500/40 shadow-lg shadow-green-500/20'
: 'bg-gray-500/20 text-gray-400 border-2 border-gray-500/20'
}`}
>
{apiKey ? '✓ Ready' : '⚠️ Required'}
</div>
</div>
</div>
{/* Main Widget Card - Large Gradient Border */}
<div
className={`bg-gradient-to-br from-slate-900/80 to-slate-950/80 backdrop-blur-sm border-2 border-purple-500/40 rounded-2xl overflow-hidden shadow-2xl shadow-purple-500/30 transition-all duration-500 ${
isExpanded ? 'fixed inset-4 z-50' : ''
}`}
>
{/* Header with Expand Button */}
<div className="flex items-center justify-between bg-slate-950/80 px-6 py-4 border-b-2 border-purple-500/30">
<div className="flex items-center gap-3">
<div className={`px-3 py-1.5 rounded-lg bg-gradient-to-r ${getMethodColor(method)} text-white text-sm font-bold shadow-lg`}>
{method}
</div>
<span className="text-sm text-gray-400">{endpoint}</span>
</div>
<button
onClick={() => 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'}
</button>
</div>
<div className="grid md:grid-cols-2 gap-6 p-6">
{/* Left: Code Editor */}
<div>
{/* Language Tabs - Colorful Pills */}
<div className="flex items-center gap-2 mb-4">
{(['curl', 'javascript', 'python', 'go'] as Language[]).map((lang, idx) => {
const colors = ['purple', 'cyan', 'amber', 'purple'];
const color = colors[idx];
return (
<button
key={lang}
onClick={() => 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()}
</button>
);
})}
</div>
{/* Code Display - Gradient Border */}
<div className="border-2 border-cyan-500/30 rounded-xl overflow-hidden shadow-lg">
<div className="flex items-center justify-between bg-slate-950/80 px-4 py-3 border-b-2 border-cyan-500/20">
<span className="text-xs text-cyan-400 font-semibold">Code Example</span>
<button
onClick={copyCode}
className="px-3 py-1.5 text-xs bg-purple-600/30 hover:bg-purple-600/50 text-purple-300 rounded-lg transition-all font-semibold"
>
📋 Copy
</button>
</div>
<div className="p-4 bg-slate-950/50 h-80 overflow-auto">
<pre className="text-xs text-gray-300 leading-relaxed">
<code>{generateCode()}</code>
</pre>
</div>
</div>
</div>
{/* Right: Response */}
<div>
<h4 className="text-sm font-bold text-white mb-4 flex items-center gap-2">
<span className="text-xl">📦</span>
Response
</h4>
<div className="border-2 border-purple-500/30 rounded-xl overflow-hidden shadow-lg">
<div className="bg-slate-950/80 px-4 py-3 border-b-2 border-purple-500/20">
{response && (
<span
className={`inline-flex items-center gap-2 px-3 py-1.5 rounded-lg text-xs font-bold ${
response.success
? 'bg-green-500/20 text-green-400 border-2 border-green-500/40 shadow-lg shadow-green-500/20'
: 'bg-red-500/20 text-red-400 border-2 border-red-500/40 shadow-lg shadow-red-500/20'
}`}
>
{response.success ? '✓ Success' : '✕ Error'}
</span>
)}
</div>
<div className="p-4 bg-slate-950/50 h-80 overflow-auto">
{error ? (
<div className="p-4 bg-red-500/10 border-2 border-red-500/40 rounded-xl text-red-400 text-sm shadow-lg shadow-red-500/20">
<div className="flex items-start gap-2">
<span className="text-xl"></span>
<div>
<p className="font-semibold mb-1">Error</p>
<p className="text-xs">{error}</p>
</div>
</div>
</div>
) : response ? (
<pre className="text-xs text-gray-300 leading-relaxed">
<code>{JSON.stringify(response, null, 2)}</code>
</pre>
) : (
<div className="flex items-center justify-center h-full">
<div className="text-center">
<p className="text-2xl mb-3">🚀</p>
<p className="text-sm text-gray-500">
Click <strong className="text-purple-400">"Test Now"</strong> below to see the response
</p>
</div>
</div>
)}
</div>
</div>
</div>
</div>
{/* Large Test Now Button */}
<div className="px-6 pb-6">
<button
onClick={executeRequest}
disabled={!apiKey || isExecuting}
className="w-full px-8 py-4 rounded-xl bg-gradient-to-r from-purple-600 to-cyan-600 text-white text-base font-bold hover:from-purple-500 hover:to-cyan-500 transition-all disabled:opacity-50 disabled:cursor-not-allowed shadow-2xl hover:shadow-purple-500/50 hover:scale-105 flex items-center justify-center gap-3 border-2 border-purple-500/50"
>
{isExecuting ? (
<>
<span className="animate-spin"></span>
<span>Executing...</span>
</>
) : (
<>
<span></span>
<span>Test Now</span>
</>
)}
</button>
<p className="mt-3 text-xs text-gray-500 text-center">{description}</p>
</div>
</div>
</div>
);
};