Dashboard logic

This commit is contained in:
2025-12-22 15:40:29 -06:00
parent ee35944c44
commit bbc86bb2d8
3 changed files with 61 additions and 9 deletions

View File

@@ -19,13 +19,20 @@ export type Page =
export default function App() { export default function App() {
const [page, setPage] = useState<Page>("home"); const [page, setPage] = useState<Page>("home");
const [subPage, setSubPage] = useState<string>("default");
const [selectedProject, setSelectedProject] = useState<string>("");
const navigateToMetersWithProject = (projectName: string) => {
setSelectedProject(projectName);
setPage("meters");
};
const renderPage = () => { const renderPage = () => {
switch (page) { switch (page) {
case "projects": case "projects":
return <ProjectsPage />; return <ProjectsPage />;
case "meters": case "meters":
return <MetersPage />; return <MetersPage selectedProject={selectedProject} />;
case "concentrators": case "concentrators":
return <ConcentratorsPage />; return <ConcentratorsPage />;
case "users": case "users":
@@ -34,7 +41,7 @@ export default function App() {
return <RolesPage />; return <RolesPage />;
case "home": case "home":
default: default:
return <Home setPage={setPage} />; return <Home setPage={setPage} navigateToMetersWithProject={navigateToMetersWithProject} />;
} }
}; };
@@ -42,7 +49,7 @@ export default function App() {
<div className="flex h-screen"> <div className="flex h-screen">
<Sidebar setPage={setPage} /> <Sidebar setPage={setPage} />
<div className="flex-1 flex flex-col"> <div className="flex-1 flex flex-col">
<TopMenu /> <TopMenu page={page} subPage={subPage} setSubPage={setSubPage} />
<main className="flex-1 overflow-auto"> <main className="flex-1 overflow-auto">
{renderPage()} {renderPage()}
</main> </main>

View File

@@ -1,4 +1,5 @@
import { Cpu, Settings, BarChart3, Bell } from "lucide-react"; import { Cpu, Settings, BarChart3, Bell } from "lucide-react";
import { useEffect, useState } from "react";
import { import {
BarChart, BarChart,
Bar, Bar,
@@ -8,9 +9,42 @@ import {
ResponsiveContainer, ResponsiveContainer,
CartesianGrid, CartesianGrid,
} from "recharts"; } from "recharts";
import { fetchMeters, Meter } from "../api/meters";
import { Page } from "../App"; import { Page } from "../App";
export default function Home({ setPage }: { setPage: (page: Page) => void }) { export default function Home({
setPage,
navigateToMetersWithProject
}: {
setPage: (page: Page) => void;
navigateToMetersWithProject: (projectName: string) => void;
}) {
const [allProjects, setAllProjects] = useState<string[]>([]);
const [meters, setMeters] = useState<Meter[]>([]);
const loadMeters = async () => {
const data = await fetchMeters();
setMeters(data);
const projectsArray = [...new Set(data.map((record: Meter) => record["areaName"]))];
setAllProjects(projectsArray);
}
useEffect(() => {
loadMeters();
}, []);
const chartData = allProjects.map((projectName) => ({
name: projectName,
meterCount: meters.filter((meter) => meter.areaName === projectName).length,
}));
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const handleBarClick = (data: any) => {
if (data.activeLabel) {
navigateToMetersWithProject(data.activeLabel);
}
};
// Datos de ejemplo para empresas // Datos de ejemplo para empresas
const companies = [ const companies = [
{ name: "Empresa A", tomas: 12, alerts: 2, consumption: 320 }, { name: "Empresa A", tomas: 12, alerts: 2, consumption: 320 },
@@ -119,19 +153,24 @@ export default function Home({ setPage }: { setPage: (page: Page) => void }) {
{/* Gráfica de consumo */} {/* Gráfica de consumo */}
<div className="bg-white rounded-xl shadow p-6"> <div className="bg-white rounded-xl shadow p-6">
<h2 className="text-lg font-semibold mb-4"> <h2 className="text-lg font-semibold mb-4">
Consumo de Agua por Empresa Número de Medidores por Proyecto
</h2> </h2>
<div className="h-60"> <div className="h-60">
<ResponsiveContainer width="100%" height="100%"> <ResponsiveContainer width="100%" height="100%">
<BarChart <BarChart
data={companies} data={chartData}
margin={{ top: 5, right: 20, left: 0, bottom: 5 }} margin={{ top: 5, right: 20, left: 0, bottom: 5 }}
onClick={handleBarClick}
> >
<CartesianGrid strokeDasharray="3 3" /> <CartesianGrid strokeDasharray="3 3" />
<XAxis dataKey="name" /> <XAxis dataKey="name" />
<YAxis /> <YAxis />
<Tooltip /> <Tooltip />
<Bar dataKey="consumption" fill="#4c5f9e" /> <Bar
dataKey="meterCount"
fill="#4c5f9e"
cursor="pointer"
/>
</BarChart> </BarChart>
</ResponsiveContainer> </ResponsiveContainer>
</div> </div>

View File

@@ -18,12 +18,12 @@ interface DeviceData {
} }
/* ================= COMPONENT ================= */ /* ================= COMPONENT ================= */
export default function MeterManagement() { export default function MeterManagement({ selectedProject: initialProject }: { selectedProject?: string } = {}) {
const [allProjects, setAllProjects] = useState<string[]>([]); const [allProjects, setAllProjects] = useState<string[]>([]);
const [loadingProjects, setLoadingProjects] = useState(true); const [loadingProjects, setLoadingProjects] = useState(true);
const [selectedProject, setSelectedProject] = useState(""); const [selectedProject, setSelectedProject] = useState(initialProject || "");
const [meters, setMeters] = useState<Meter[]>([]); const [meters, setMeters] = useState<Meter[]>([]);
const [filteredMeters, setFilteredMeters] = useState<Meter[]>([]); const [filteredMeters, setFilteredMeters] = useState<Meter[]>([]);
@@ -97,6 +97,12 @@ export default function MeterManagement() {
loadMeters(); loadMeters();
}, []); }, []);
useEffect(() => {
if (initialProject) {
setSelectedProject(initialProject);
}
}, [initialProject]);
const createOrUpdateDevice = async (deviceData: DeviceData): Promise<void> => { const createOrUpdateDevice = async (deviceData: DeviceData): Promise<void> => {
//await fetch('/api/devices', { method: 'POST', body: JSON.stringify(deviceData) }) //await fetch('/api/devices', { method: 'POST', body: JSON.stringify(deviceData) })