From 820e14463cd709a270ae073509dfad22c14d40ae Mon Sep 17 00:00:00 2001 From: Esteban Date: Mon, 22 Dec 2025 00:19:09 -0600 Subject: [PATCH] Meter edit and create logic form & concentrators project select option --- src/pages/concentrators/ConcentratorsPage.tsx | 21 +- src/pages/meters/MeterPage.tsx | 626 +++++++++++++----- 2 files changed, 454 insertions(+), 193 deletions(-) diff --git a/src/pages/concentrators/ConcentratorsPage.tsx b/src/pages/concentrators/ConcentratorsPage.tsx index 0734845..af0284c 100644 --- a/src/pages/concentrators/ConcentratorsPage.tsx +++ b/src/pages/concentrators/ConcentratorsPage.tsx @@ -1,7 +1,6 @@ import { useState, useEffect, useMemo } from "react"; import { Plus, Trash2, Pencil, RefreshCcw } from "lucide-react"; import MaterialTable from "@material-table/core"; -import { fetchProjectNames } from "../../api/projects"; import { fetchConcentrators, createConcentrator, @@ -40,22 +39,6 @@ export default function ConcentratorsPage() { const [loadingProjects, setLoadingProjects] = useState(true); const [loadingConcentrators, setLoadingConcentrators] = useState(true); - useEffect(() => { - const loadProjects = async () => { - try { - const projects = await fetchProjectNames(); - setAllProjects(projects); - } catch (error) { - console.error('Error loading projects:', error); - setAllProjects([]); - } finally { - setLoadingProjects(false); - } - }; - - loadProjects(); - }, []); - // Proyectos visibles según el usuario const visibleProjects = useMemo(() => currentUser.role === "SUPER_ADMIN" @@ -79,12 +62,16 @@ export default function ConcentratorsPage() { setLoadingConcentrators(true); try { const data = await fetchConcentrators(); + const projectsArray = data.map((record) => record["Area Name"]); + setAllProjects(projectsArray); setConcentrators(data); } catch (error) { console.error("Error loading concentrators:", error); + setAllProjects([]); setConcentrators([]); } finally { setLoadingConcentrators(false); + setLoadingProjects(false); } }; diff --git a/src/pages/meters/MeterPage.tsx b/src/pages/meters/MeterPage.tsx index 3223e31..b380e67 100644 --- a/src/pages/meters/MeterPage.tsx +++ b/src/pages/meters/MeterPage.tsx @@ -18,6 +18,14 @@ interface User { project?: string; // asignado si no es superadmin } +interface DeviceData { + "Device ID": number; + "Device EUI": string; + "Join EUI": string; + "AppKey": string; + meterId?: string; +} + /* ================= COMPONENT ================= */ export default function MeterManagement() { // Simulación de usuario actual @@ -94,7 +102,16 @@ export default function MeterManagement() { installedTime: new Date().toISOString(), }; + const emptyDeviceData: DeviceData = { + "Device ID": 0, + "Device EUI": "", + "Join EUI": "", + "AppKey": "", + }; + const [form, setForm] = useState>(emptyMeter); + const [deviceForm, setDeviceForm] = useState(emptyDeviceData); + const [errors, setErrors] = useState<{ [key: string]: boolean }>({}); const loadMeters = async () => { setLoadingMeters(true); @@ -113,8 +130,49 @@ export default function MeterManagement() { loadMeters(); }, []); + const createOrUpdateDevice = async (deviceData: DeviceData): Promise => { + //await fetch('/api/devices', { method: 'POST', body: JSON.stringify(deviceData) }) + + return new Promise((resolve) => { + setTimeout(() => { + console.log('Device data that would be sent to API:', deviceData); + resolve(); + }, 500); + }); + }; + + const validateForm = (): boolean => { + const newErrors: { [key: string]: boolean } = {}; + + if (!form.meterName.trim()) newErrors["meterName"] = true; + if (!form.meterSerialNumber.trim()) newErrors["meterSerialNumber"] = true; + if (!form.areaName.trim()) newErrors["areaName"] = true; + if (!form.deviceName.trim()) newErrors["deviceName"] = true; + if (!form.deviceType.trim()) newErrors["deviceType"] = true; + if (!form.protocolType.trim()) newErrors["protocolType"] = true; + if (!form.supplyTypes.trim()) newErrors["supplyTypes"] = true; + if (!form.usageAnalysisType.trim()) newErrors["usageAnalysisType"] = true; + if (!form.installedTime) newErrors["installedTime"] = true; + + if (!deviceForm["Device ID"] || deviceForm["Device ID"] === 0) { + newErrors["Device ID"] = true; + } + if (!deviceForm["Device EUI"].trim()) newErrors["Device EUI"] = true; + if (!deviceForm["Join EUI"].trim()) newErrors["Join EUI"] = true; + if (!deviceForm["AppKey"].trim()) newErrors["AppKey"] = true; + + setErrors(newErrors); + return Object.keys(newErrors).length === 0; + }; + const handleSave = async () => { + if (!validateForm()) { + return; + } + try { + let savedMeter: Meter; + if (editingId) { const meterToUpdate = meters.find(m => m.id === editingId); if (!meterToUpdate) { @@ -127,13 +185,30 @@ export default function MeterManagement() { m.id === editingId ? updatedMeter : m ) ); + savedMeter = updatedMeter; } else { const newMeter = await createMeter(form); setMeters((prev) => [...prev, newMeter]); + savedMeter = newMeter; } + + try { + const deviceDataWithRef = { + ...deviceForm, + meterId: savedMeter.id, + }; + await createOrUpdateDevice(deviceDataWithRef); + console.log('Device data saved successfully'); + } catch (deviceError) { + console.error('Error saving device data:', deviceError); + alert('Meter saved, but there was an error saving device data.'); + } + setShowModal(false); setEditingId(null); setForm(emptyMeter); + setDeviceForm(emptyDeviceData); + setErrors({}); setActiveMeter(null); } catch (error) { console.error('Error saving meter:', error); @@ -236,6 +311,8 @@ export default function MeterManagement() { + Cancel +