import React, { useState, useEffect } from 'react'; import { useUserStore } from '@/store/userStore'; import { getUserIdSync } from '@/utils/userId'; import { useLiveStore } from '@/store/liveStore'; import { motion, AnimatePresence } from 'framer-motion'; import { Info, Terminal, Key, Copy, Check, RefreshCw, Code, Globe, Settings, Shield, Eye, EyeOff, Box, Layers, Code2, Play, Loader, Sparkles, Activity, Server, Database, Zap, Trash2, TrendingUp, AlertTriangle, Clock, ChevronDown, ChevronUp, BarChart3 } from 'lucide-react'; import { AreaChart, Area, BarChart, Bar, XAxis, YAxis, Tooltip, ResponsiveContainer, CartesianGrid } from 'recharts'; const timeAgo = (dateStr?: string) => { if (!dateStr) return 'Never'; const diff = Date.now() - new Date(dateStr).getTime(); const mins = Math.floor(diff / 60000); if (mins < 1) return 'Just now'; if (mins < 60) return `${mins} mins ago`; const hours = Math.floor(mins / 60); if (hours < 24) return `${hours} hours ago`; return `${Math.floor(hours / 24)} days ago`; }; const Developer: React.FC = () => { const { isDark } = useUserStore(); const [apiKeys, setApiKeys] = useState([]); const [loading, setLoading] = useState(true); const [copied, setCopied] = useState(false); const [reveal, setReveal] = useState>({}); const [isGenerating, setIsGenerating] = useState(false); const [snippetLang, setSnippetLang] = useState('python'); const [webhooks, setWebhooks] = useState([]); const [newWebhook, setNewWebhook] = useState(''); // Enterprise: Usage Analytics const [usageData, setUsageData] = useState(null); const [usageLoading, setUsageLoading] = useState(false); const [showAnalytics, setShowAnalytics] = useState(true); const [analyticsView, setAnalyticsView] = useState<'hourly' | 'daily'>('hourly'); useEffect(() => { fetchKeys(); fetchWebhooks(); fetchUsageAnalytics(); }, []); const fetchUsageAnalytics = async () => { setUsageLoading(true); try { const res = await fetch('/api/v1/developer/usage-analytics', { headers: { 'X-User-ID': getUserIdSync() } }); if (res.ok) { const data = await res.json(); setUsageData(data); } } catch (e) { console.error('Failed to fetch usage analytics', e); } finally { setUsageLoading(false); } }; const fetchWebhooks = async () => { try { const res = await fetch('/api/v1/developer/webhooks', { headers: { 'X-User-ID': getUserIdSync() } }); if (res.ok) { const data = await res.json(); setWebhooks(data); } } catch (e) { console.error('Failed to fetch webhooks', e); } }; const addWebhook = async () => { if (!newWebhook.trim()) return; try { const res = await fetch('/api/v1/developer/webhooks', { method: 'POST', headers: { 'X-User-ID': getUserIdSync(), 'Content-Type': 'application/json' }, body: JSON.stringify({ url: newWebhook.trim() }) }); if (res.ok) { await fetchWebhooks(); setNewWebhook(''); } } catch (e) { console.error(e); } }; const deleteWebhook = async (webhookId: string) => { try { const res = await fetch(`/api/v1/developer/webhooks/${webhookId}`, { method: 'DELETE', headers: { 'X-User-ID': getUserIdSync() } }); if (res.ok) { await fetchWebhooks(); } } catch (e) { console.error('Failed to delete webhook', e); } }; const [pingingWebhook, setPingingWebhook] = useState(null); const [pingSuccess, setPingSuccess] = useState(null); const [deliveryLogs, setDeliveryLogs] = useState>({}); const [loadingLogs, setLoadingLogs] = useState>({}); const fetchDeliveryLogs = async (webhookId: string) => { if (deliveryLogs[webhookId]) { const newLogs = { ...deliveryLogs }; delete newLogs[webhookId]; setDeliveryLogs(newLogs); return; } setLoadingLogs(prev => ({...prev, [webhookId]: true})); try { const res = await fetch(`/api/v1/developer/webhooks/${webhookId}/deliveries`, { headers: { 'X-User-ID': getUserIdSync() } }); if (res.ok) { const data = await res.json(); setDeliveryLogs(prev => ({...prev, [webhookId]: data.deliveries || []})); } } catch (e) { console.error(e); } finally { setLoadingLogs(prev => ({...prev, [webhookId]: false})); } }; const handleTestWebhook = async (webhookId: string) => { setPingingWebhook(webhookId); try { const res = await fetch(`/api/v1/developer/webhooks/${webhookId}/test`, { method: 'POST', headers: { 'X-User-ID': getUserIdSync() } }); const data = await res.json(); if (data.success) { setPingSuccess(webhookId); setTimeout(() => setPingSuccess(null), 3000); } else { alert('Ping Failed: ' + data.message); } } catch (e) { console.error(e); alert('Network error while pinging.'); } finally { setPingingWebhook(null); } }; const handleDownloadStarterKit = () => { const key = apiKeys.length > 0 ? apiKeys[0].key : 'dv_live_your_key_here'; const code = getSnippetText(snippetLang || 'python'); const filename = snippetLang === 'python' ? 'datavision_starter.py' : snippetLang === 'js' ? 'datavision_starter.js' : 'datavision_starter.sh'; const blob = new Blob([code], { type: 'text/plain' }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = filename; document.body.appendChild(a); a.click(); document.body.removeChild(a); URL.revokeObjectURL(url); }; const fetchKeys = async () => { setLoading(true); try { const res = await fetch('/api/v1/developer/keys', { headers: { 'X-User-ID': getUserIdSync() } }); if (res.ok) { const data = await res.json(); setApiKeys(data); } } catch (e) { console.error('Failed to fetch keys', e); } finally { setLoading(false); } }; // Embed Builder State const [embedTheme, setEmbedTheme] = useState('dark'); const [embedWidget, setEmbedWidget] = useState('full-dashboard'); const [embedCopied, setEmbedCopied] = useState(false); // Playground state const [playgroundLoading, setPlaygroundLoading] = useState(false); const [playgroundResponse, setPlaygroundResponse] = useState(null); const handleCopy = (key: string) => { navigator.clipboard.writeText(key); setCopied(true); setTimeout(() => setCopied(false), 2000); }; const handleGenerateNewKey = async () => { setIsGenerating(true); try { const res = await fetch('/api/v1/developer/keys/generate', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-User-ID': getUserIdSync() } }); if (res.ok) { await fetchKeys(); } else { const errData = await res.json().catch(() => ({})); const msg = errData.detail || errData.message || 'Failed to generate API key'; alert(`Error: ${msg}`); console.error('Key generation failed:', msg); } } catch (e: any) { console.error('Key generation error:', e); alert(`Network error: ${e.message || 'Could not reach server'}`); } finally { setIsGenerating(false); } }; const handleRevokeKey = async (keyId: string) => { try { const res = await fetch(`/api/v1/developer/keys/${keyId}/revoke`, { method: 'POST', headers: { 'X-User-ID': getUserIdSync() } }); if (res.ok) { await fetchKeys(); } } catch (e) { console.error('Failed to revoke key', e); } }; const toggleReveal = (id: string) => { setReveal(prev => ({ ...prev, [id]: !prev[id] })); }; const embedCode = ``; const handleCopyEmbed = () => { navigator.clipboard.writeText(embedCode); setEmbedCopied(true); setTimeout(() => setEmbedCopied(false), 2000); }; const handleTestApi = async () => { setPlaygroundLoading(true); try { // Simulate real api call by hitting a known endpoint const res = await fetch('/api/v1/decisions/stats'); const data = await res.json(); setPlaygroundResponse(data); } catch (err) { setPlaygroundResponse({ error: "Failed to connect to API" }); } finally { setPlaygroundLoading(false); } }; const [snippetCopied, setSnippetCopied] = useState(false); const [aiSnippetPrompt, setAiSnippetPrompt] = useState(''); const [isGeneratingAiSnippet, setIsGeneratingAiSnippet] = useState(false); const [generatedSnippets, setGeneratedSnippets] = useState>({}); // Data-Driven Suggestions State const [suggestions, setSuggestions] = useState([]); const [suggestedDatasetName, setSuggestedDatasetName] = useState('YOUR_LOCAL_FILE.csv'); const [isFetchingSuggestions, setIsFetchingSuggestions] = useState(false); const handleSuggestGoals = async () => { setIsFetchingSuggestions(true); try { const res = await fetch('/api/v1/developer/suggest-goals', { headers: { 'X-User-ID': getUserIdSync() } }); const data = await res.json(); if (data.suggestions) { setSuggestions(data.suggestions); setSuggestedDatasetName(data.dataset || 'YOUR_LOCAL_FILE.csv'); } } catch (e) { console.error('Failed to fetch suggestions', e); } finally { setIsFetchingSuggestions(false); } }; const handleGenerateCode = async () => { if (!aiSnippetPrompt.trim()) return; setIsGeneratingAiSnippet(true); const key = apiKeys[0]?.key || 'dv_live_...'; try { const res = await fetch('/api/v1/developer/generate-code', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ prompt: aiSnippetPrompt, language: snippetLang, api_key: key, base_url: window.location.origin, dataset_name: suggestedDatasetName }) }); const data = await res.json(); if (data.code) { setGeneratedSnippets(prev => ({...prev, [snippetLang]: data.code})); } } catch (e) { console.error(e); } finally { setIsGeneratingAiSnippet(false); } }; const getSnippetText = (lang: string) => { if (generatedSnippets[lang]) { return generatedSnippets[lang]; } const key = apiKeys[0]?.key || 'dv_live_...'; // Use a clear placeholder so the external developer knows they must point to their own local file const datasetName = suggestedDatasetName; const baseUrl = window.location.origin; const userGoal = aiSnippetPrompt || 'Analyze this dataset and give me key insights'; if (lang === 'python') { return `import requests\nimport json\n\nheaders = {\n "Authorization": "Bearer ${key}"\n}\n\n# 1. Point this to ANY local CSV or Excel file on your server/laptop\nfiles = {'file': open('${datasetName}', 'rb')}\n\ndata = {'goal': '${userGoal}'}\n\n# 2. Send the request (stream=True is required for live AI updates!)\nresponse = requests.post(\n "${baseUrl}/api/v1/autopilot/run",\n headers=headers,\n files=files,\n data=data,\n stream=True\n)\n\n# 3. Read the live AI stream\nfor line in response.iter_lines():\n if line:\n decoded = line.decode('utf-8')\n if decoded.startswith('data: '):\n try:\n event_data = json.loads(decoded[6:])\n if event_data.get('type') == 'step_complete':\n safe_title = event_data['data']['step']['title'].encode('ascii', 'ignore').decode('ascii').strip()\n print(f"[SUCCESS] {safe_title}")\n elif event_data.get('type') == 'session_complete':\n print("\\n[COMPLETE] Analysis finished successfully.")\n except:\n pass`; } if (lang === 'curl') { return `curl -N -X POST ${baseUrl}/api/v1/autopilot/run \\\n -H "Authorization: Bearer ${key}" \\\n -F "file=@${datasetName}" \\\n -F "goal=${userGoal}"`; } if (lang === 'js') { return `const formData = new FormData();\nformData.append('file', fileInput.files[0]);\nformData.append('goal', '${userGoal}');\n\nfetch('${baseUrl}/api/v1/autopilot/run', {\n method: 'POST',\n headers: { 'Authorization': 'Bearer ${key}' },\n body: formData\n}).then(async res => {\n const reader = res.body.getReader();\n const decoder = new TextDecoder();\n while (true) {\n const {done, value} = await reader.read();\n if (done) break;\n console.log(decoder.decode(value));\n }\n});`; } return ''; }; const handleCopySnippet = () => { navigator.clipboard.writeText(getSnippetText(snippetLang)); setSnippetCopied(true); setTimeout(() => setSnippetCopied(false), 2000); }; return (
{/* Header */}

🔧 Developer & Embed Center

Manage API keys, test endpoints, and configure embedded SDK dashboards.

{/* Instructions Banner */}

How to use this page?

This section is designed for your software engineering team. You can generate an API Key here and use the Code Snippets below to automatically trigger Datavision's AI pipelines from your company's own backend servers. You can also configure Webhooks to receive notifications when long-running AI tasks finish.

{/* ═══ Enterprise API Usage Analytics ═══ */} {/* Clickable Header */} {showAnalytics && (
{/* KPI Cards */}

Total Calls

{usageData?.total_calls?.toLocaleString() || '—'}

= 0 ? 'text-emerald-500' : 'text-red-500'}`}> {(usageData?.week_change || 0) > 0 ? '+' : ''}{usageData?.week_change || 0}% this week

Latency P95

{usageData?.latency?.p95 || '—'}ms

P50: {usageData?.latency?.p50}ms · P99: {usageData?.latency?.p99}ms

Error Rate

5 ? 'text-red-500' : 'text-emerald-500'}`}>{usageData?.errors?.error_rate || '—'}%

4xx: {usageData?.errors?.total_4xx || 0} · 5xx: {usageData?.errors?.total_5xx || 0}

Rate Limit

{usageData?.rate_limit?.remaining?.toLocaleString() || '—'}

{usageData?.rate_limit?.current || 0} / {usageData?.rate_limit?.limit?.toLocaleString() || '1,000'} per min

{/* Charts Row */}
{/* Calls Chart */}

API Calls

{(['hourly', 'daily'] as const).map(v => ( ))}
{/* Top Endpoints */}

Top Endpoints

{(usageData?.top_endpoints || []).map((ep: any, i: number) => { const maxCalls = usageData?.top_endpoints?.[0]?.calls || 1; const pct = (ep.calls / maxCalls) * 100; const colors = ['bg-indigo-500', 'bg-purple-500', 'bg-teal-500', 'bg-amber-500', 'bg-pink-500']; return (
{ep.endpoint} {ep.calls.toLocaleString()}
); })}
)}
{/* Main developer tools */}
{/* API Key Management */} {/* Background Glow */}

Authentication Keys

Use this key to securely authenticate requests to the DataVision API. Keep it secret.

{apiKeys.length > 0 && ( <> Last used: {timeAgo(apiKeys[0].last_used || apiKeys[0].created_at)}
{apiKeys[0].is_active ? 'Active' : 'Revoked'}
)}
{loading ? (
Loading keys...
) : Array.isArray(apiKeys) && apiKeys.length === 0 ? (
No API keys found.
) : Array.isArray(apiKeys) ? ( apiKeys.map((keyObj) => (
{reveal[keyObj.id] ? keyObj.key : '••••••••••••••••••••••••••••••••••••••••'}
)) ) : null}

Never share this key in client-side code. Use environment variables.

{/* Code Snippets */}

API Integration

{['python', 'curl', 'js'].map(lang => ( ))}

Generate code to programmatically run Agentic Autopilot from your servers.

setAiSnippetPrompt(e.target.value)} placeholder="e.g. Write a script to analyze sales.csv and predict revenue" className={`flex-1 px-3 py-2 text-sm rounded-lg border outline-none focus:ring-1 focus:ring-indigo-500 ${isDark ? 'bg-black/50 border-white/10 text-white' : 'bg-white border-gray-300 text-black'}`} onKeyDown={(e) => e.key === 'Enter' && handleGenerateCode()} />
{/* Auto-Suggest Pills */}
{suggestions.map((s, i) => ( ))}
                
                  {getSnippetText(snippetLang)}
                
              
{/* SDK Install Guide */}

Environment Setup

Download the starter script, install the dependencies, and run it locally to see real AI predictions stream to your Webhook.

1. Install Dependencies

{snippetLang === 'python' ? 'pip install requests httpx' : snippetLang === 'js' ? 'npm install node-fetch form-data' : 'apt-get install curl'}

2. Secure API Key (.env)

DATAVISION_API_KEY={(apiKeys[0]?.key || 'dv_live_...').substring(0, 16)}...
{/* Embedded Widget Tool */} {/* Background Glow */}

Embedded Dashboards

                {"{'\n'}
                  src="{window.location.origin}/embed/{embedWidget}?theme={embedTheme}&token={apiKeys[0]?.key || 'dv_live_...'}"{'\n'}
                  width="100%"{'\n'}
                  height="600px"{'\n'}
                  frameBorder="0"{'\n'}
                  style="border-radius: 12px;"{'\n'}
                {">"}
              
{/* Webhooks and Webhooks Sidebar */}

Webhook Management

Get real-time HTTP callbacks when async jobs complete.

{Array.isArray(webhooks) && webhooks.map(wh => (
{wh.url} {wh.status}
{Array.isArray(wh.events) && wh.events.map((ev: string) => ( {ev} ))}
{deliveryLogs[wh.id] && (
{deliveryLogs[wh.id].length === 0 ? (
No deliveries yet.
) : ( deliveryLogs[wh.id].map((log: any) => (
{log.status_code || (log.success ? '200' : 'ERR')} {log.event}
{timeAgo(log.timestamp)}
)) )}
)}
))}
setNewWebhook(e.target.value)} placeholder="https://your-domain.com/webhook" className={`w-full px-3 py-2 text-xs rounded-lg border mb-2 outline-none focus:ring-1 focus:ring-indigo-500 ${isDark ? 'bg-black/50 border-white/10 text-white' : 'bg-white border-gray-300 text-black'}`} />

Interactive API Docs

Explore the full OpenAPI 3.0 specification.

Open Swagger UI
); }; export default Developer;