/** * Integrations Panel Component * * Third-party integration management: * - View all integrations * - Configure API keys * - Enable/disable integrations * - Run health checks */ import React, { useState, useEffect, useCallback } from 'react'; import { Link2, RefreshCw, Settings, Check, XCircle, AlertTriangle, Eye, EyeOff, Save, Power, Activity, Zap, Cloud, Mail, CreditCard, Bot, Brain, Server } from 'lucide-react'; import { getToken } from '../../services/api'; const API_BASE = import.meta.env.VITE_API_URL || ''; // Integration icons mapping const getIntegrationIcon = (name) => { const icons = { openai: Zap, aws_s3: Cloud, sendgrid: Mail, stripe: CreditCard }; return icons[name] || Server; }; // Status indicator const StatusIndicator = ({ connected, enabled }) => { if (!enabled) { return ( Disabled ); } return connected ? ( Connected ) : ( Not Connected ); }; // Integration card component const IntegrationCard = ({ integration, onUpdate, onHealthCheck }) => { const [editing, setEditing] = useState(false); const [apiKey, setApiKey] = useState(''); const [apiSecret, setApiSecret] = useState(''); const [showKey, setShowKey] = useState(false); const [showSecret, setShowSecret] = useState(false); const [saving, setSaving] = useState(false); const [checking, setChecking] = useState(false); const [healthResult, setHealthResult] = useState(null); const Icon = getIntegrationIcon(integration.name); const handleSave = async () => { setSaving(true); try { const updates = { is_enabled: integration.is_enabled }; if (apiKey) updates.api_key = apiKey; if (apiSecret) updates.api_secret = apiSecret; await onUpdate(integration.id, updates); setEditing(false); setApiKey(''); setApiSecret(''); } catch (err) { console.error('Error saving:', err); } finally { setSaving(false); } }; const handleToggle = async () => { setSaving(true); try { await onUpdate(integration.id, { is_enabled: !integration.is_enabled }); } catch (err) { console.error('Error toggling:', err); } finally { setSaving(false); } }; const handleHealthCheck = async () => { setChecking(true); setHealthResult(null); try { const result = await onHealthCheck(integration.name); setHealthResult(result); } catch (err) { setHealthResult({ status: 'error', message: err.message }); } finally { setChecking(false); } }; return (

{integration.display_name}

{integration.description}

API Key: {integration.api_key_preview || 'Not configured'}
{integration.config && Object.keys(integration.config).length > 0 && (
Config: {JSON.stringify(integration.config)}
)}
{editing && (
setApiKey(e.target.value)} placeholder="Enter new API key..." />
{integration.name !== 'openai' && (
setApiSecret(e.target.value)} placeholder="Enter API secret (if required)..." />
)}
)} {healthResult && (
{healthResult.status === 'healthy' ? ( ) : ( )} {healthResult.message || healthResult.status}
)}
{editing ? ( <> ) : ( )}
); }; function IntegrationsPanel() { const [integrations, setIntegrations] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); // Fetch integrations const fetchIntegrations = useCallback(async () => { setLoading(true); setError(null); try { const token = getToken(); const response = await fetch(`${API_BASE}/api/admin/integrations`, { headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' } }); if (!response.ok) throw new Error('Failed to fetch integrations'); const data = await response.json(); if (data.success) { setIntegrations(data.integrations); } } catch (err) { setError(err.message); } finally { setLoading(false); } }, []); // Update integration const updateIntegration = async (integrationId, updates) => { const token = getToken(); const response = await fetch(`${API_BASE}/api/admin/integrations/${integrationId}`, { method: 'PUT', headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' }, body: JSON.stringify(updates) }); if (!response.ok) throw new Error('Failed to update integration'); fetchIntegrations(); }; // Health check const healthCheck = async (integrationName) => { const token = getToken(); const response = await fetch(`${API_BASE}/api/admin/integrations/${integrationName}/health-check`, { method: 'POST', headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' } }); if (!response.ok) throw new Error('Health check failed'); const data = await response.json(); return data.health; }; // Initial fetch useEffect(() => { fetchIntegrations(); }, [fetchIntegrations]); if (loading) { return (

Loading integrations...

); } return (
{/* Header */}

Third-Party Integrations

{/* Stats */}
{integrations.filter(i => i.is_enabled).length} Enabled
{integrations.filter(i => i.is_configured).length} Configured
{integrations.length} Total
{/* Integrations Grid */}
{integrations.map((integration) => ( ))}
{integrations.length === 0 && (

No integrations configured

)}
); } export default IntegrationsPanel;