'use client'; /** * Interactive API Widget - Variant C: Modern & Visual (Shopify-inspired) * * Design Philosophy: Floating, expandable card with colorful visual feedback * * Features: * - Full-screen expandable mode toggle button * - Large gradient-bordered card with shadow glow * - Prominent "Test Now ⚡" button (larger, more visual) * - Response in colorful gradient-bordered card * - Success/error states with vibrant colored badges * - More visual feedback and animations * - Large emoji icons throughout * - Colorful code syntax highlighting hints * - Floating shadow effects * * Layout: * - Top: Large colorful API key input card * - Main: Expandable code editor with rainbow gradient border * - Language tabs as colorful pills * - Large prominent "Test Now" button with gradient * - Response card with colored status indicators * * Visual Elements: * - Purple/cyan/amber gradients everywhere * - Large shadows with colored glows * - Scale and hover animations * - Success: Green gradient with glow * - Error: Red gradient with glow */ import { useState, useEffect } from 'react'; interface InteractiveAPIWidgetCProps { endpoint: string; method: 'GET' | 'POST' | 'PUT' | 'DELETE'; description: string; parameters?: Array<{ name: string; type: string; required: boolean; description: string; defaultValue?: string; }>; } type Language = 'curl' | 'javascript' | 'python' | 'go'; const API_BASE_URL = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:3000'; const API_KEY_STORAGE = 'banatie_docs_api_key'; const getMethodColor = (method: string): string => { switch (method) { case 'GET': return 'from-cyan-500 to-cyan-600'; case 'POST': return 'from-purple-500 to-purple-600'; case 'PUT': return 'from-amber-500 to-amber-600'; case 'DELETE': return 'from-red-500 to-red-600'; default: return 'from-purple-500 to-cyan-500'; } }; export const InteractiveAPIWidgetC = ({ endpoint, method, description, parameters = [], }: InteractiveAPIWidgetCProps) => { const [language, setLanguage] = useState('curl'); const [apiKey, setApiKey] = useState(''); const [isExecuting, setIsExecuting] = useState(false); const [response, setResponse] = useState(null); const [error, setError] = useState(null); const [paramValues, setParamValues] = useState>({}); const [isExpanded, setIsExpanded] = useState(false); useEffect(() => { const stored = localStorage.getItem(API_KEY_STORAGE); if (stored) setApiKey(stored); const defaults: Record = {}; parameters.forEach((param) => { if (param.defaultValue) { defaults[param.name] = param.defaultValue; } }); setParamValues(defaults); }, [parameters]); const handleApiKeyChange = (value: string) => { setApiKey(value); if (value) { localStorage.setItem(API_KEY_STORAGE, value); } else { localStorage.removeItem(API_KEY_STORAGE); } }; const generateCode = (): string => { const url = `${API_BASE_URL}${endpoint}`; switch (language) { case 'curl': return `curl -X ${method} "${url}" \\ -H "X-API-Key: ${apiKey || 'YOUR_API_KEY'}" \\ -H "Content-Type: application/json" \\ -d '{ "prompt": "a futuristic city at sunset", "filename": "city", "aspectRatio": "16:9" }'`; case 'javascript': return `const response = await fetch('${url}', { method: '${method}', headers: { 'X-API-Key': '${apiKey || 'YOUR_API_KEY'}', 'Content-Type': 'application/json' }, body: JSON.stringify({ prompt: 'a futuristic city at sunset', filename: 'city', aspectRatio: '16:9' }) }); const data = await response.json();`; case 'python': return `import requests url = '${url}' headers = { 'X-API-Key': '${apiKey || 'YOUR_API_KEY'}', 'Content-Type': 'application/json' } data = { 'prompt': 'a futuristic city at sunset', 'filename': 'city', 'aspectRatio': '16:9' } response = requests.${method.toLowerCase()}(url, headers=headers, json=data)`; case 'go': return `package main import ( "bytes" "encoding/json" "net/http" ) func main() { url := "${url}" data := map[string]interface{}{ "prompt": "a futuristic city at sunset", "filename": "city", "aspectRatio": "16:9", } jsonData, _ := json.Marshal(data) req, _ := http.NewRequest("${method}", url, bytes.NewBuffer(jsonData)) req.Header.Set("X-API-Key", "${apiKey || 'YOUR_API_KEY'}") req.Header.Set("Content-Type", "application/json") client := &http.Client{} resp, _ := client.Do(req) }`; default: return ''; } }; const executeRequest = async () => { if (!apiKey) { setError('Please enter your API key above ✨'); return; } setIsExecuting(true); setError(null); try { const body: Record = {}; parameters.forEach((param) => { if (paramValues[param.name]) { body[param.name] = paramValues[param.name]; } }); const res = await fetch(`${API_BASE_URL}${endpoint}`, { method, headers: { 'X-API-Key': apiKey, 'Content-Type': 'application/json', }, body: method !== 'GET' ? JSON.stringify(body) : undefined, }); const data = await res.json(); setResponse(data); } catch (err) { setError(err instanceof Error ? err.message : 'Failed to execute request 😔'); } finally { setIsExecuting(false); } }; const copyCode = () => { navigator.clipboard.writeText(generateCode()); }; return (
{/* API Key Card - Large and Colorful */}
🔑
handleApiKeyChange(e.target.value)} placeholder="Enter your API key (saved locally)" className="flex-1 px-4 py-3 text-sm bg-slate-900/80 border-2 border-purple-500/30 rounded-xl text-white placeholder-gray-500 focus:outline-none focus:ring-2 focus:ring-purple-500 focus:border-purple-500/50 transition-all" />
{apiKey ? '✓ Ready' : '⚠️ Required'}
{/* Main Widget Card - Large Gradient Border */}
{/* Header with Expand Button */}
{method}
{endpoint}
{/* Left: Code Editor */}
{/* Language Tabs - Colorful Pills */}
{(['curl', 'javascript', 'python', 'go'] as Language[]).map((lang, idx) => { const colors = ['purple', 'cyan', 'amber', 'purple']; const color = colors[idx]; return ( ); })}
{/* Code Display - Gradient Border */}
Code Example
                  {generateCode()}
                
{/* Right: Response */}

📦 Response

{response && ( {response.success ? '✓ Success' : '✕ Error'} )}
{error ? (
⚠️

Error

{error}

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

🚀

Click "Test Now" below to see the response

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

{description}

); };