project service
This commit is contained in:
@@ -14,7 +14,7 @@ import { getAuditLogs, type AuditLog } from "../api/audit";
|
|||||||
import { fetchNotifications, type Notification } from "../api/notifications";
|
import { fetchNotifications, type Notification } from "../api/notifications";
|
||||||
import { getAllUsers, type User } from "../api/users";
|
import { getAllUsers, type User } from "../api/users";
|
||||||
import { fetchProjects, type Project } from "../api/projects";
|
import { fetchProjects, type Project } from "../api/projects";
|
||||||
import { getCurrentUserRole } from "../api/auth";
|
import { getCurrentUserRole, getCurrentUserProjectId } from "../api/auth";
|
||||||
import type { Page } from "../App";
|
import type { Page } from "../App";
|
||||||
import grhWatermark from "../assets/images/grhWatermark.png";
|
import grhWatermark from "../assets/images/grhWatermark.png";
|
||||||
|
|
||||||
@@ -55,6 +55,7 @@ export default function Home({
|
|||||||
}) {
|
}) {
|
||||||
|
|
||||||
const userRole = useMemo(() => getCurrentUserRole(), []);
|
const userRole = useMemo(() => getCurrentUserRole(), []);
|
||||||
|
const userProjectId = useMemo(() => getCurrentUserProjectId(), []);
|
||||||
const isOperator = userRole?.toUpperCase() === 'OPERATOR';
|
const isOperator = userRole?.toUpperCase() === 'OPERATOR';
|
||||||
const isAdmin = userRole?.toUpperCase() === 'ADMIN';
|
const isAdmin = userRole?.toUpperCase() === 'ADMIN';
|
||||||
|
|
||||||
@@ -166,6 +167,12 @@ export default function Home({
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const filteredMeters = useMemo(() => {
|
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") {
|
if (selectedOrganism === "Todos") {
|
||||||
return meters;
|
return meters;
|
||||||
}
|
}
|
||||||
@@ -176,7 +183,7 @@ export default function Home({
|
|||||||
}
|
}
|
||||||
|
|
||||||
return meters.filter((m) => m.projectId === selectedUser.project_id);
|
return meters.filter((m) => m.projectId === selectedUser.project_id);
|
||||||
}, [meters, selectedOrganism, users]);
|
}, [meters, selectedOrganism, users, isOperator, userProjectId]);
|
||||||
|
|
||||||
const filteredProjects = useMemo(
|
const filteredProjects = useMemo(
|
||||||
() => [...new Set(filteredMeters.map((m) => m.projectName))].filter(Boolean) as string[],
|
() => [...new Set(filteredMeters.map((m) => m.projectName))].filter(Boolean) as string[],
|
||||||
@@ -184,6 +191,13 @@ export default function Home({
|
|||||||
);
|
);
|
||||||
|
|
||||||
const selectedUserProjectName = useMemo(() => {
|
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;
|
if (selectedOrganism === "Todos") return null;
|
||||||
|
|
||||||
const selectedUser = users.find(u => u.id === selectedOrganism);
|
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);
|
const project = projects.find(p => p.id === selectedUser.project_id);
|
||||||
return project?.name || null;
|
return project?.name || null;
|
||||||
}, [selectedOrganism, users, projects]);
|
}, [selectedOrganism, users, projects, isOperator, userProjectId]);
|
||||||
|
|
||||||
const chartData = useMemo(() => {
|
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") {
|
if (selectedOrganism === "Todos") {
|
||||||
return filteredProjects.map((projectName) => ({
|
return filteredProjects.map((projectName) => ({
|
||||||
name: projectName,
|
name: projectName,
|
||||||
@@ -211,7 +234,7 @@ export default function Home({
|
|||||||
}
|
}
|
||||||
|
|
||||||
return [];
|
return [];
|
||||||
}, [selectedOrganism, filteredProjects, filteredMeters, selectedUserProjectName]);
|
}, [selectedOrganism, filteredProjects, filteredMeters, selectedUserProjectName, isOperator]);
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
const handleBarClick = (data: any) => {
|
const handleBarClick = (data: any) => {
|
||||||
|
|||||||
@@ -236,11 +236,21 @@ export async function update(id: string, data: UpdateProjectInput): Promise<Proj
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete a project by ID
|
* Delete a project by ID
|
||||||
* Checks for dependent meters/concentrators before deletion
|
* Checks for dependent meters/concentrators/users before deletion
|
||||||
* @param id - Project UUID
|
* @param id - Project UUID
|
||||||
* @returns True if deleted, throws error if has dependencies
|
* @returns True if deleted, throws error if has dependencies
|
||||||
*/
|
*/
|
||||||
export async function deleteProject(id: string): Promise<boolean> {
|
export async function deleteProject(id: string): Promise<boolean> {
|
||||||
|
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
|
// Check for dependent meters
|
||||||
const meterCheck = await query<{ count: string }>(
|
const meterCheck = await query<{ count: string }>(
|
||||||
'SELECT COUNT(*) as count FROM meters WHERE project_id = $1',
|
'SELECT COUNT(*) as count FROM meters WHERE project_id = $1',
|
||||||
|
|||||||
Reference in New Issue
Block a user