From b273003366e1b6295d095da63bad16a62fce349f Mon Sep 17 00:00:00 2001 From: Esteban Date: Mon, 2 Feb 2026 19:01:02 -0600 Subject: [PATCH] Meter tyoe logic for projects in concentrators page --- src/pages/concentrators/ConcentratorsPage.tsx | 26 +++++++-- .../concentrators/ConcentratorsSidebar.tsx | 57 +++++++++++------- src/pages/concentrators/useConcentrators.ts | 58 ++++++++++++++++++- 3 files changed, 111 insertions(+), 30 deletions(-) diff --git a/src/pages/concentrators/ConcentratorsPage.tsx b/src/pages/concentrators/ConcentratorsPage.tsx index e61021f..ff85954 100644 --- a/src/pages/concentrators/ConcentratorsPage.tsx +++ b/src/pages/concentrators/ConcentratorsPage.tsx @@ -170,6 +170,15 @@ export default function ConcentratorsPage() { projects={c.projectsData} onRefresh={c.loadConcentrators} refreshDisabled={c.loadingProjects} + meterTypes={c.meterTypes} + selectedMeterTypeId={c.selectedMeterTypeId} + onSelectMeterTypeId={(id: string) => { + c.setSelectedMeterTypeId(id); + c.setSelectedProject(""); + setActiveConcentrator(null); + setSearch(""); + }} + loadingMeterTypes={c.loadingMeterTypes} /> @@ -181,7 +190,9 @@ export default function ConcentratorsPage() {

Concentrator Management

- {c.selectedProject + {c.projectsData.length === 0 && c.selectedMeterTypeId + ? `No hay proyectos disponibles con el filtro seleccionado` + : c.selectedProject ? `Proyecto: ${c.selectedProject} • Tipo: ${c.sampleViewLabel}` : "Selecciona un proyecto desde el panel izquierdo"}

@@ -190,7 +201,7 @@ export default function ConcentratorsPage() {
setSearch(e.target.value)} - disabled={!c.selectedProject} + disabled={!c.selectedProject || c.projectsData.length === 0} />
@@ -236,7 +248,11 @@ export default function ConcentratorsPage() { activeRowId={activeConcentrator?.id} onRowClick={(row) => setActiveConcentrator(row)} emptyMessage={ - !c.selectedProject + c.projectsData.length === 0 && c.selectedMeterTypeId + ? `No hay proyectos con el tipo de toma seleccionado (${ + c.meterTypes.find((mt) => mt.id === c.selectedMeterTypeId)?.name ?? "desconocido" + }) que tengan concentradores.` + : !c.selectedProject ? "Selecciona un proyecto para ver los concentradores." : c.loadingConcentrators ? "Cargando concentradores..." diff --git a/src/pages/concentrators/ConcentratorsSidebar.tsx b/src/pages/concentrators/ConcentratorsSidebar.tsx index 694f256..e956e2d 100644 --- a/src/pages/concentrators/ConcentratorsSidebar.tsx +++ b/src/pages/concentrators/ConcentratorsSidebar.tsx @@ -1,7 +1,8 @@ // src/pages/concentrators/ConcentratorsSidebar.tsx import { useMemo } from "react"; -import { ChevronDown, Check, RefreshCcw } from "lucide-react"; +import { Check, RefreshCcw } from "lucide-react"; import type { ProjectCard, SampleView } from "./ConcentratorsPage"; +import type { MeterType } from "../../api/meterTypes"; type Props = { loadingProjects: boolean; @@ -23,6 +24,11 @@ type Props = { onRefresh: () => void; refreshDisabled: boolean; + + meterTypes: MeterType[]; + selectedMeterTypeId: string; + onSelectMeterTypeId: (id: string) => void; + loadingMeterTypes: boolean; }; export default function ConcentratorsSidebar({ @@ -30,13 +36,16 @@ export default function ConcentratorsSidebar({ sampleView, sampleViewLabel, typesMenuOpen, - setTypesMenuOpen, onChangeSampleView, selectedProject, onSelectProject, projects, onRefresh, refreshDisabled, + meterTypes, + selectedMeterTypeId, + onSelectMeterTypeId, + loadingMeterTypes, }: Props) { const options = useMemo( () => @@ -76,24 +85,7 @@ export default function ConcentratorsSidebar({
- {/* Tipos de tomas (dropdown) */}
- {typesMenuOpen && (
@@ -124,15 +116,36 @@ export default function ConcentratorsSidebar({ )}
+
+ + +
+ {/* List */}
{loadingProjects ? (
Loading projects...
) : projects.length === 0 ? (
- {sampleView === "GENERAL" - ? "No projects available. Please contact your administrator." - : `No projects with ${sampleViewLabel} concentrators found.` + {selectedMeterTypeId + ? `No hay proyectos con el tipo de toma seleccionado y concentradores ${sampleViewLabel}.` + : sampleView === "GENERAL" + ? "No hay proyectos con concentradores disponibles." + : `No hay proyectos con concentradores ${sampleViewLabel}.` }
) : ( diff --git a/src/pages/concentrators/useConcentrators.ts b/src/pages/concentrators/useConcentrators.ts index a138c48..a6775fe 100644 --- a/src/pages/concentrators/useConcentrators.ts +++ b/src/pages/concentrators/useConcentrators.ts @@ -5,6 +5,7 @@ import { type ConcentratorType, } from "../../api/concentrators"; import { fetchProjects, type Project } from "../../api/projects"; +import { fetchMeterTypes, type MeterType } from "../../api/meterTypes"; import type { ProjectCard, SampleView } from "./ConcentratorsPage"; type User = { @@ -17,10 +18,14 @@ export function useConcentrators(currentUser: User) { const [loadingProjects, setLoadingProjects] = useState(true); const [loadingConcentrators, setLoadingConcentrators] = useState(true); + const [loadingMeterTypes, setLoadingMeterTypes] = useState(true); const [projects, setProjects] = useState([]); const [allProjects, setAllProjects] = useState([]); const [selectedProject, setSelectedProject] = useState(""); + + const [meterTypes, setMeterTypes] = useState([]); + const [selectedMeterTypeId, setSelectedMeterTypeId] = useState(""); const [concentrators, setConcentrators] = useState([]); const [filteredConcentrators, setFilteredConcentrators] = useState< @@ -54,6 +59,19 @@ export function useConcentrators(currentUser: User) { [allProjects, currentUser.role, currentUser.project] ); + const loadMeterTypes = async () => { + setLoadingMeterTypes(true); + try { + const meterTypesData = await fetchMeterTypes(); + setMeterTypes(meterTypesData); + } catch (err) { + console.error("Error loading meter types:", err); + setMeterTypes([]); + } finally { + setLoadingMeterTypes(false); + } + }; + const loadProjects = async () => { setLoadingProjects(true); try { @@ -92,8 +110,8 @@ export function useConcentrators(currentUser: User) { } }; - // init - load projects and concentrators useEffect(() => { + loadMeterTypes(); loadProjects(); loadConcentrators(); // eslint-disable-next-line react-hooks/exhaustive-deps @@ -163,7 +181,21 @@ export function useConcentrators(currentUser: User) { const baseContact = "Operaciones"; const baseLastSync = "Hace 1 h"; - return visibleProjects.map((projectId) => ({ + let filteredProjects = visibleProjects; + + filteredProjects = filteredProjects.filter((projectId) => { + const count = counts[projectId] ?? 0; + return count > 0; + }); + + if (selectedMeterTypeId) { + filteredProjects = filteredProjects.filter((projectId) => { + const project = projects.find((p) => p.id === projectId); + return project?.meterTypeId === selectedMeterTypeId; + }); + } + + return filteredProjects.map((projectId) => ({ id: projectId, name: projectNameMap[projectId] ?? projectId, region: baseRegion, @@ -174,12 +206,27 @@ export function useConcentrators(currentUser: User) { contact: baseContact, status: "ACTIVO" as const, })); - }, [concentrators, visibleProjects, projects, isGeneral, sampleView]); + }, [concentrators, visibleProjects, projects, isGeneral, sampleView, selectedMeterTypeId]); const projectsData: ProjectCard[] = useMemo(() => { return projectsDataGeneral; }, [projectsDataGeneral]); + useEffect(() => { + if (projectsData.length > 0) { + const firstProject = projectsData[0]; + const currentProjectExists = projectsData.find((p) => p.id === selectedProject); + + if (!selectedProject || !currentProjectExists) { + setSelectedProject(firstProject.id); + } + } else { + if (selectedProject) { + setSelectedProject(""); + } + } + }, [projectsData]); + return { // view sampleView, @@ -190,6 +237,7 @@ export function useConcentrators(currentUser: User) { // loading loadingProjects, loadingConcentrators, + loadingMeterTypes, // projects allProjects, @@ -198,6 +246,10 @@ export function useConcentrators(currentUser: User) { selectedProject, setSelectedProject, + meterTypes, + selectedMeterTypeId, + setSelectedMeterTypeId, + // data concentrators, setConcentrators,