import { useEffect, useMemo, useState } from "react"; import { fetchConcentrators, type Concentrator, type ConcentratorType, } from "../../api/concentrators"; import { fetchProjects, type Project } from "../../api/projects"; import type { ProjectCard, SampleView } from "./ConcentratorsPage"; type User = { role: "SUPER_ADMIN" | "USER"; project?: string; }; export function useConcentrators(currentUser: User) { const [sampleView, setSampleView] = useState("GENERAL"); const [loadingProjects, setLoadingProjects] = useState(true); const [loadingConcentrators, setLoadingConcentrators] = useState(true); const [projects, setProjects] = useState([]); const [allProjects, setAllProjects] = useState([]); const [selectedProject, setSelectedProject] = useState(""); const [concentrators, setConcentrators] = useState([]); const [filteredConcentrators, setFilteredConcentrators] = useState< Concentrator[] >([]); const isGeneral = sampleView === "GENERAL"; const sampleViewLabel = useMemo(() => { switch (sampleView) { case "GENERAL": return "General"; case "LORA": return "LoRa"; case "LORAWAN": return "LoRaWAN"; case "GRANDES": return "Grandes consumidores"; default: return "General"; } }, [sampleView]); const visibleProjects = useMemo( () => currentUser.role === "SUPER_ADMIN" ? allProjects : currentUser.project ? [currentUser.project] : [], [allProjects, currentUser.role, currentUser.project] ); const loadProjects = async () => { setLoadingProjects(true); try { const projectsData = await fetchProjects(); setProjects(projectsData); const projectIds = projectsData.map((p) => p.id); setAllProjects(projectIds); setSelectedProject((prev) => { if (prev) return prev; if (currentUser.role !== "SUPER_ADMIN" && currentUser.project) { return currentUser.project; } return projectIds[0] ?? ""; }); } catch (err) { console.error("Error loading projects:", err); setProjects([]); setAllProjects([]); } finally { setLoadingProjects(false); } }; const loadConcentrators = async () => { setLoadingConcentrators(true); try { const data = await fetchConcentrators(); setConcentrators(data); } catch (err) { console.error("Error loading concentrators:", err); setConcentrators([]); } finally { setLoadingConcentrators(false); } }; // init - load projects and concentrators useEffect(() => { loadProjects(); loadConcentrators(); // eslint-disable-next-line react-hooks/exhaustive-deps }, []); // view changes useEffect(() => { loadProjects(); loadConcentrators(); // eslint-disable-next-line react-hooks/exhaustive-deps }, [sampleView]); // auto select single visible project useEffect(() => { if (!isGeneral) return; if (!selectedProject && visibleProjects.length === 1) { setSelectedProject(visibleProjects[0]); } }, [visibleProjects, selectedProject, isGeneral]); useEffect(() => { let filtered = concentrators; if (selectedProject) { filtered = filtered.filter((c) => c.projectId === selectedProject); } if (!isGeneral) { const typeMap: Record, ConcentratorType> = { LORA: "LORA", LORAWAN: "LORAWAN", GRANDES: "GRANDES", }; const targetType = typeMap[sampleView as Exclude]; filtered = filtered.filter((c) => c.type === targetType); } setFilteredConcentrators(filtered); }, [selectedProject, concentrators, isGeneral, sampleView]); // sidebar cards (general) const projectsDataGeneral: ProjectCard[] = useMemo(() => { let concentratorsToCount = concentrators; if (!isGeneral) { const typeMap: Record, ConcentratorType> = { LORA: "LORA", LORAWAN: "LORAWAN", GRANDES: "GRANDES", }; const targetType = typeMap[sampleView as Exclude]; concentratorsToCount = concentrators.filter((c) => c.type === targetType); } const counts = concentratorsToCount.reduce>((acc, c) => { const project = c.projectId ?? "SIN PROYECTO"; acc[project] = (acc[project] ?? 0) + 1; return acc; }, {}); const projectNameMap = projects.reduce>((acc, p) => { acc[p.id] = p.name; return acc; }, {}); const baseRegion = "Baja California"; const baseContact = "Operaciones"; const baseLastSync = "Hace 1 h"; return visibleProjects.map((projectId) => ({ id: projectId, name: projectNameMap[projectId] ?? projectId, region: baseRegion, projects: 1, concentrators: counts[projectId] ?? 0, activeAlerts: 0, lastSync: baseLastSync, contact: baseContact, status: "ACTIVO" as const, })); }, [concentrators, visibleProjects, projects, isGeneral, sampleView]); const projectsData: ProjectCard[] = useMemo(() => { return projectsDataGeneral; }, [projectsDataGeneral]); return { // view sampleView, setSampleView, sampleViewLabel, isGeneral, // loading loadingProjects, loadingConcentrators, // projects allProjects, visibleProjects, projectsData, selectedProject, setSelectedProject, // data concentrators, setConcentrators, filteredConcentrators, // actions loadConcentrators, }; }