"use client"; import { useState, useEffect } from "react"; import { useRouter } from "next/navigation"; import { getAgents, updateAgent } from "@/lib/actions/agents"; import { Agent } from "@/lib/actions/agentsCore"; import { getAdminUsers, startViewAs, getViewAsHeaders, type ManagedUser } from "@/lib/admin-api"; import { useTimeFilter } from "@/contexts/TimeFilterContext"; import { usePollingKey } from "@/lib/usePolling"; export function useAgentsData() { const router = useRouter(); const [role, setRole] = useState(null); const [myAgentUuids, setMyAgentUuids] = useState([]); const [agents, setAgents] = useState([]); const [uptimeMap, setUptimeMap] = useState>({}); const [storageMap, setStorageMap] = useState>({}); const [isLoading, setIsLoading] = useState(true); const [error, setError] = useState(""); const [isCreateOpen, setIsCreateOpen] = useState(false); const [isDeleteOpen, setIsDeleteOpen] = useState(false); const [detailAgent, setDetailAgent] = useState(null); const [managedUsers, setManagedUsers] = useState([]); const [accountModalOpen, setAccountModalOpen] = useState(false); const [accountModalAgent, setAccountModalAgent] = useState<{ uuid: string; label: string } | null>(null); const [externalModalOpen, setExternalModalOpen] = useState(false); const [externalModalUser, setExternalModalUser] = useState(null); const [targetSiteUuid, setTargetSiteUuid] = useState(null); const [targetCreatedBy, setTargetCreatedBy] = useState(null); const [selectedSite, setSelectedSite] = useState("6681452d_9cae_4ff4_8ae8_0d504774265e"); const [locations, setLocations] = useState([]); const [isLocModalOpen, setIsLocModalOpen] = useState(false); const [locModalAgentUuid, setLocModalAgentUuid] = useState(""); const [locModalAgentLabel, setLocModalAgentLabel] = useState(""); const [locModalCurrentLoc, setLocModalCurrentLoc] = useState(null); useEffect(() => { if (typeof window !== 'undefined') { const stored = localStorage.getItem('backone_site_uuid'); if (stored) setSelectedSite(stored); } }, []); const [viewAsLoading, setViewAsLoading] = useState(null); const [selectedAgent, setSelectedAgent] = useState(null); const { timeRange } = useTimeFilter(); const refreshKey = usePollingKey(60000); // Auto-refresh every 60 seconds (1 minute) const loadUptime = async () => { try { const res = await fetch(`/api/dashboard/agents/uptime?timeRange=${timeRange}`, { headers: getViewAsHeaders() }); if (res.ok) { const json = await res.json(); if (json.ok && json.uptime) setUptimeMap(json.uptime); } } catch (err) { console.error("Failed to load uptime stats:", err); } }; const loadStorage = async () => { try { const res = await fetch('/api/dashboard/agents/storage', { headers: getViewAsHeaders() }); if (res.ok) { const json = await res.json(); if (json.ok && json.storage) setStorageMap(json.storage); } } catch (err) { console.error("Failed to load agent storage stats:", err); } }; const loadLocations = async () => { try { const res = await fetch("/api/dashboard/agent-locations", { headers: getViewAsHeaders(), }); if (res.ok) { const json = await res.json(); if (json.ok && json.data) setLocations(json.data); } } catch (err) { console.error("Failed to load locations:", err); } }; const loadAgents = async (allowedUuids?: string[], currentRole?: string) => { setIsLoading(true); try { const siteUuid = localStorage.getItem("backone_site_uuid") || undefined; const [agentData, userData] = await Promise.allSettled([ getAgents(siteUuid), getAdminUsers(), ]); if (agentData.status === 'fulfilled') { let allAgents = agentData.value; // Filter agents untuk COMPANY_ADMIN dan COMPANY_OPERATOR — hanya tampilkan yang di-assign const uuids = allowedUuids ?? myAgentUuids; const r = currentRole ?? role; if ((r === 'COMPANY_ADMIN' || r === 'COMPANY_OPERATOR') && uuids.length > 0) { allAgents = allAgents.filter(a => uuids.includes(a.uuid || a.serial)); } setAgents(allAgents); } else { setError((agentData.reason as Error).message); } if (userData.status === 'fulfilled') setManagedUsers(userData.value); await loadUptime(); await loadLocations(); } catch (e: any) { setError(e.message); } setIsLoading(false); }; const handleViewAs = async (agentUuid: string, agentLabel: string) => { setViewAsLoading(agentUuid); try { await startViewAs(agentUuid, agentLabel); router.refresh(); window.location.reload(); } catch (err: any) { alert('Failed to enter View As mode: ' + err.message); } finally { setViewAsLoading(null); } }; useEffect(() => { fetch('/api/auth/me', { headers: getViewAsHeaders() }) .then(res => res.json()) .then(data => { if (data.user) { const userRole = data.user.role || null; const uuids: string[] = data.user.agent_uuids || []; setRole(userRole); setMyAgentUuids(uuids); const allowed = ['SUPER_ADMIN', 'TENANT_ADMIN', 'EXECUTIVE', 'COMPANY_ADMIN', 'COMPANY_OPERATOR']; if (!allowed.includes(userRole || '')) { router.push('/'); } else { loadAgents(uuids, userRole); } } else { setIsLoading(false); } }) .catch(err => { console.error("Auth check failed:", err); setIsLoading(false); }); }, [router]); useEffect(() => { if (role && role !== 'AGENT_VIEWER') loadUptime(); }, [timeRange]); useEffect(() => { if (role === 'SUPER_ADMIN') { loadStorage(); } if (role && role !== 'AGENT_VIEWER') { loadLocations(); } }, [role]); useEffect(() => { if (role && role !== 'AGENT_VIEWER' && refreshKey > 0) { loadAgents(); if (role === 'SUPER_ADMIN') { loadStorage(); } } }, [refreshKey, role]); const openDelete = (agent: Agent) => { setSelectedAgent(agent); setIsDeleteOpen(true); }; const handleEditLocation = (agentUuid: string, agentLabel: string) => { const loc = locations.find(l => l.agent_uuid === agentUuid) || null; setLocModalAgentUuid(agentUuid); setLocModalAgentLabel(agentLabel); setLocModalCurrentLoc(loc); setIsLocModalOpen(true); }; const handleEditLabel = async (agentUuid: string, currentLabel: string) => { const newLabel = window.prompt("Masukkan label baru untuk agent ini:", currentLabel); if (newLabel !== null && newLabel.trim() !== "" && newLabel !== currentLabel) { try { const result = await updateAgent(agentUuid, newLabel.trim()); if (result.success) { // Update local state without waiting for full refresh to feel snappy setAgents(prev => prev.map(a => (a.uuid === agentUuid || a.serial === agentUuid) ? { ...a, label: newLabel.trim() } : a )); } else { window.alert("Gagal mengubah label: " + result.message); } } catch (err: any) { window.alert("Terjadi kesalahan: " + err.message); } } }; return { role, agents, uptimeMap, storageMap, isLoading, error, isCreateOpen, setIsCreateOpen, isDeleteOpen, setIsDeleteOpen, detailAgent, setDetailAgent, managedUsers, accountModalOpen, setAccountModalOpen, accountModalAgent, setAccountModalAgent, externalModalOpen, setExternalModalOpen, externalModalUser, setExternalModalUser, targetSiteUuid, setTargetSiteUuid, targetCreatedBy, setTargetCreatedBy, locations, isLocModalOpen, setIsLocModalOpen, locModalAgentUuid, setLocModalAgentUuid, locModalAgentLabel, setLocModalAgentLabel, locModalCurrentLoc, setLocModalCurrentLoc, viewAsLoading, selectedAgent, loadAgents, loadLocations, handleViewAs, openDelete, handleEditLocation, handleEditLabel, }; }