'use client'; import { useState, useEffect } from 'react'; import { Button } from '@/components/ui/button'; import { Tabs, TabsList, TabsTrigger, TabsContent } from '@/components/ui/tabs'; import { Shield, Monitor, Network, Apple, CheckCircle2, XCircle, AlertTriangle, RefreshCw, Loader2, Server, HardDrive, Cpu, Clock, } from 'lucide-react'; import { useUserTimezone } from '@/lib/hooks/use-user-timezone'; function StatusDot({ ok, warn }: { ok: boolean; warn?: boolean }) { if (!ok) return ; if (warn) return ; return ; } function StatCard({ label, value, sub, icon: Icon, cls }: { label: string; value: string | number; sub?: string; icon?: React.ElementType; cls?: string; }) { return (
{Icon && } {label}
{value}
{sub &&
{sub}
}
); } function fmtDate(d: string | null, tz: string) { if (!d) return 'Never'; return new Date(d).toLocaleString(undefined, { month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit', timeZone: tz }); } function VeeamTab({ data, onSync, syncing, tz }: { data: any; onSync: () => void; syncing: boolean; tz: string }) { if (!data) return
; const aj = data.agentJobs ?? {}; const bj = data.backupJobs ?? {}; const totalFailed = (aj.failed ?? 0) + (bj.failed ?? 0); const totalWarning = (aj.warning ?? 0) + (bj.warning ?? 0); const totalRunning = aj.running ?? 0; return (
0 || totalWarning > 0} />

{data.configured ? 'Connected to VSPC' : 'Not configured'}

Last sync: {fmtDate(data.lastSync, tz)}

0 ? 'border-blue-500/30 bg-blue-500/5' : ''} /> 0 ? 'border-red-500/30 bg-red-500/5' : ''} /> 0 ? 'border-yellow-500/30 bg-yellow-500/5' : ''} />
{(totalFailed > 0 || totalWarning > 0 || totalRunning > 0) && (

Attention Required

{totalFailed > 0 && (
{totalFailed} job{totalFailed !== 1 ? 's' : ''} failed
)} {totalWarning > 0 && (
{totalWarning} job{totalWarning !== 1 ? 's' : ''} completed with warnings
)} {totalRunning > 0 && (
{totalRunning} job{totalRunning !== 1 ? 's' : ''} running (stalled jobs appear here)
)}
)}
); } function DattoRmmTab({ data, onSync, syncing }: { data: any; onSync: () => void; syncing: boolean }) { if (!data) return
; const unlinked = Math.max(0, (data.totalConfigItems ?? 0) - (data.rmmLinkedDevices ?? 0)); return (

{data.configured ? 'Connected' : 'Not configured'}

{data.apiUrl}

0 ? 'border-yellow-500/30 bg-yellow-500/5' : ''} />
Datto RMM device data is queried live via the RMM API when investigating alerts. Device records link to Autotask Configuration Items via rmm_device_uid. Run an Autotask Configuration Items sync to refresh CI data.
); } function AuvikTab({ data }: { data: any }) { if (!data) return
; return (

{data.configured ? 'Connected' : 'Not configured'}

{data.apiUrl}

Auvik provides network topology and device data. The API is configured and accessible. Full sync and dashboard integration is planned — data is currently available via the Auvik API endpoints at /api/auvik/devices and /api/auvik/tenant-mappings.
); } function AddigyTab({ data }: { data: any }) { if (!data) return
; return (

{data.configured ? 'Connected' : 'Not configured'}

{data.apiUrl}

Addigy manages Apple (macOS/iOS) devices. The API is configured and accessible via token auth. Device and policy data is available via /api/addigy-devices and /api/addigy-policies. Full sync integration is planned.
); } export default function IntegrationStatusTabs() { const tz = useUserTimezone(); const [status, setStatus] = useState(null); const [loading, setLoading] = useState(true); const [veeamSyncing, setVeeamSyncing] = useState(false); const [rmmSyncing, setRmmSyncing] = useState(false); const fetchStatus = async () => { try { const res = await fetch('/api/integrations/status'); if (res.ok) setStatus(await res.json()); } catch (e) { console.error('Failed to fetch integration status:', e); } finally { setLoading(false); } }; useEffect(() => { fetchStatus(); }, []); const handleVeeamSync = async () => { setVeeamSyncing(true); try { await fetch('/api/veeam/sync', { method: 'POST', body: JSON.stringify({ syncType: 'full' }), headers: { 'Content-Type': 'application/json' } }); // Poll until done const poll = setInterval(async () => { const r = await fetch('/api/veeam/sync'); if (r.ok) { const d = await r.json(); if (!d.isSyncing) { clearInterval(poll); setVeeamSyncing(false); fetchStatus(); } } }, 3000); } catch { setVeeamSyncing(false); } }; const handleRmmSync = async () => { setRmmSyncing(true); try { await fetch('/api/sync/entity', { method: 'POST', body: JSON.stringify({ entities: ['configuration_items'] }), headers: { 'Content-Type': 'application/json' }, }); setTimeout(() => { setRmmSyncing(false); fetchStatus(); }, 5000); } catch { setRmmSyncing(false); } }; if (loading) { return (
); } return ( Veeam Datto RMM Auvik Addigy ); }