diff --git a/src/pages/Home.tsx b/src/pages/Home.tsx index 69c63f2..373c3b3 100644 --- a/src/pages/Home.tsx +++ b/src/pages/Home.tsx @@ -14,7 +14,7 @@ import { getAuditLogs, type AuditLog } from "../api/audit"; import { fetchNotifications, type Notification } from "../api/notifications"; import { getAllUsers, type User } from "../api/users"; import { fetchProjects, type Project } from "../api/projects"; -import { getCurrentUserRole } from "../api/auth"; +import { getCurrentUserRole, getCurrentUserProjectId } from "../api/auth"; import type { Page } from "../App"; import grhWatermark from "../assets/images/grhWatermark.png"; @@ -55,6 +55,7 @@ export default function Home({ }) { const userRole = useMemo(() => getCurrentUserRole(), []); + const userProjectId = useMemo(() => getCurrentUserProjectId(), []); const isOperator = userRole?.toUpperCase() === 'OPERATOR'; const isAdmin = userRole?.toUpperCase() === 'ADMIN'; @@ -166,6 +167,12 @@ export default function Home({ }, []); const filteredMeters = useMemo(() => { + // If user is OPERATOR, always filter by their assigned project + if (isOperator && userProjectId) { + return meters.filter((m) => m.projectId === userProjectId); + } + + // For ADMIN users with organism selector if (selectedOrganism === "Todos") { return meters; } @@ -176,7 +183,7 @@ export default function Home({ } return meters.filter((m) => m.projectId === selectedUser.project_id); - }, [meters, selectedOrganism, users]); + }, [meters, selectedOrganism, users, isOperator, userProjectId]); const filteredProjects = useMemo( () => [...new Set(filteredMeters.map((m) => m.projectName))].filter(Boolean) as string[], @@ -184,6 +191,13 @@ export default function Home({ ); const selectedUserProjectName = useMemo(() => { + // If user is OPERATOR, get their project name + if (isOperator && userProjectId) { + const project = projects.find(p => p.id === userProjectId); + return project?.name || null; + } + + // For ADMIN users with organism selector if (selectedOrganism === "Todos") return null; const selectedUser = users.find(u => u.id === selectedOrganism); @@ -191,9 +205,18 @@ export default function Home({ const project = projects.find(p => p.id === selectedUser.project_id); return project?.name || null; - }, [selectedOrganism, users, projects]); + }, [selectedOrganism, users, projects, isOperator, userProjectId]); const chartData = useMemo(() => { + // If user is OPERATOR, show only their project + if (isOperator && selectedUserProjectName) { + return [{ + name: selectedUserProjectName, + meterCount: filteredMeters.length, + }]; + } + + // For ADMIN users if (selectedOrganism === "Todos") { return filteredProjects.map((projectName) => ({ name: projectName, @@ -211,7 +234,7 @@ export default function Home({ } return []; - }, [selectedOrganism, filteredProjects, filteredMeters, selectedUserProjectName]); + }, [selectedOrganism, filteredProjects, filteredMeters, selectedUserProjectName, isOperator]); // eslint-disable-next-line @typescript-eslint/no-explicit-any const handleBarClick = (data: any) => { diff --git a/water-api/src/services/project.service.ts b/water-api/src/services/project.service.ts index 11916c1..7e4aa68 100644 --- a/water-api/src/services/project.service.ts +++ b/water-api/src/services/project.service.ts @@ -236,11 +236,21 @@ export async function update(id: string, data: UpdateProjectInput): Promise { + const userCheck = await query<{ count: string }>( + 'SELECT COUNT(*) as count FROM users WHERE project_id = $1', + [id] + ); + const userCount = parseInt(userCheck.rows[0]?.count || '0', 10); + + if (userCount > 0) { + throw new Error(`Cannot delete project: ${userCount} user(s) are assigned to this project`); + } + // Check for dependent meters const meterCheck = await query<{ count: string }>( 'SELECT COUNT(*) as count FROM meters WHERE project_id = $1',