import { useState, useEffect, useCallback } from 'react' import { Save, RotateCcw, RefreshCw, Check } from 'lucide-react' import { MeshMonitorSection, MeshSourcesSection, type MeshMonitorConfig, type MeshSourceConfig, } from './Config' import { notifyRestartRequired } from '@/components/RestartBanner' import { fetchConfig as apiFetchConfig, updateConfig as apiUpdateConfig } from '@/lib/api' export default function MeshtasticSources() { const [meshmonitor, setMeshmonitor] = useState(null) const [originalMeshmonitor, setOriginalMeshmonitor] = useState(null) const [meshSources, setMeshSources] = useState(null) const [originalMeshSources, setOriginalMeshSources] = useState(null) const [loading, setLoading] = useState(true) const [saving, setSaving] = useState(false) const [error, setError] = useState(null) const [success, setSuccess] = useState(null) const [hasChanges, setHasChanges] = useState(false) const fetchData = useCallback(async () => { setLoading(true) try { const [mm, ms] = await Promise.all([ apiFetchConfig('meshmonitor') as Promise, apiFetchConfig('mesh_sources') as Promise, ]) setMeshmonitor(mm) setOriginalMeshmonitor(JSON.parse(JSON.stringify(mm))) setMeshSources(ms) setOriginalMeshSources(JSON.parse(JSON.stringify(ms))) setHasChanges(false) setError(null) } catch (err) { setError(err instanceof Error ? err.message : 'Unknown error') } finally { setLoading(false) } }, []) useEffect(() => { document.title = 'Meshtastic Sources - MeshAI' fetchData() }, [fetchData]) useEffect(() => { if (meshmonitor && originalMeshmonitor && meshSources && originalMeshSources) { const mmChanged = JSON.stringify(meshmonitor) !== JSON.stringify(originalMeshmonitor) const msChanged = JSON.stringify(meshSources) !== JSON.stringify(originalMeshSources) setHasChanges(mmChanged || msChanged) } }, [meshmonitor, originalMeshmonitor, meshSources, originalMeshSources]) const saveConfig = async () => { if (!meshmonitor || !meshSources) return setSaving(true) setError(null) setSuccess(null) try { const [mmResult, msResult] = await Promise.all([ apiUpdateConfig('meshmonitor', meshmonitor), apiUpdateConfig('mesh_sources', meshSources), ]) setOriginalMeshmonitor(JSON.parse(JSON.stringify(meshmonitor))) setOriginalMeshSources(JSON.parse(JSON.stringify(meshSources))) setHasChanges(false) setSuccess('Meshtastic sources saved successfully') if (mmResult.restart_required || msResult.restart_required) { notifyRestartRequired([]) } setTimeout(() => setSuccess(null), 3000) } catch (err) { setError(err instanceof Error ? err.message : 'Save failed') } finally { setSaving(false) } } const discardChanges = () => { if (originalMeshmonitor) setMeshmonitor(JSON.parse(JSON.stringify(originalMeshmonitor))) if (originalMeshSources) setMeshSources(JSON.parse(JSON.stringify(originalMeshSources))) setHasChanges(false) } if (loading) { return (
Loading Meshtastic sources...
) } if (!meshmonitor || !meshSources) { return (
Failed to load sources config
) } return (
{/* Header */}

MeshMonitor integration and mesh awareness data sources.

{/* Status messages */} {error && (
{error}
)} {success && (
{success}
)} {/* MeshMonitor card */}
{/* Mesh Sources card */}
) }