import React, { useState, useCallback } from 'react'; import { RefreshCw, Settings, Save, AlertCircle, CheckCircle } from 'lucide-react'; export default function ElasticRecorderDashboard() { const [apiKey, setApiKey] = useState(''); const [baseUrl, setBaseUrl] = useState('https://us-east-1.gvampp.com'); const [channels, setChannels] = useState([]); const [loading, setLoading] = useState(false); const [authenticated, setAuthenticated] = useState(false); const [error, setError] = useState(''); const [success, setSuccess] = useState(''); const [editingId, setEditingId] = useState(null); const [editForm, setEditForm] = useState({}); // Get auth token const getToken = useCallback(async () => { try { const [username, password] = atob(apiKey).split(':'); const response = await fetch(`${baseUrl}/identity/connect/token`, { method: 'POST', headers: { 'Authorization': `Basic ${apiKey}`, 'Content-Type': 'application/x-www-form-urlencoded', }, body: new URLSearchParams({ grant_type: 'client_credentials', scope: 'platform' }) }); if (!response.ok) { throw new Error(`Authentication failed: ${response.statusText}`); } const data = await response.json(); return data.access_token; } catch (err) { throw new Error(`Token error: ${err.message}`); } }, [apiKey, baseUrl]); // Fetch channels const fetchChannels = useCallback(async () => { setLoading(true); setError(''); try { const token = await getToken(); const response = await fetch(`${baseUrl}/api/store/channel/v1/channels`, { headers: { 'Authorization': `Bearer ${token}` } }); if (!response.ok) { throw new Error(`Failed to fetch channels: ${response.statusText}`); } const data = await response.json(); setChannels(data); setAuthenticated(true); setSuccess(`Loaded ${data.length} channels`); setTimeout(() => setSuccess(''), 3000); } catch (err) { setError(err.message); setAuthenticated(false); } finally { setLoading(false); } }, [getToken, baseUrl]); // Handle login const handleLogin = (e) => { e.preventDefault(); if (apiKey && baseUrl) { fetchChannels(); } }; // Start editing a channel const startEdit = (channel) => { setEditingId(channel['channel:id']); setEditForm({ 'source:text': channel['source:text'] || '', 'destinationId:int': channel['destinationId:int'] || '', 'name:text': channel['name:text'] || '' }); }; // Cancel edit const cancelEdit = () => { setEditingId(null); setEditForm({}); }; // Save changes const saveChanges = async () => { setLoading(true); setError(''); try { const token = await getToken(); const updateData = { 'source:text': editForm['source:text'], 'destinationId:int': editForm['destinationId:int'] ? parseInt(editForm['destinationId:int']) : null }; const response = await fetch(`${baseUrl}/api/store/channel/v1/channels/${editingId}`, { method: 'PATCH', headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' }, body: JSON.stringify(updateData) }); if (!response.ok) { throw new Error(`Failed to update channel: ${response.statusText}`); } setSuccess('Channel updated successfully'); setEditingId(null); setTimeout(() => fetchChannels(), 500); } catch (err) { setError(err.message); } finally { setLoading(false); } }; // Login form if (!authenticated) { return (
Manage recording settings and folder assignments
Manage {channels.length} recorders
{channel['channel:id'].substring(0, 20)}...
{channel['source:text'] || '—'}
{channel['destinationId:int'] || '—'}
{channel['elasticRecorder']['workloadId:text']?.substring(0, 16)}...
No channels found. Try refreshing or check your connection.