Project id for user
This commit is contained in:
@@ -11,6 +11,7 @@ import {
|
||||
} from "recharts";
|
||||
import { fetchMeters, type Meter } from "../api/meters";
|
||||
import { getAuditLogs, type AuditLog } from "../api/audit";
|
||||
import { fetchNotifications, type Notification } from "../api/notifications";
|
||||
import { getCurrentUserRole } from "../api/auth";
|
||||
import type { Page } from "../App";
|
||||
import grhWatermark from "../assets/images/grhWatermark.png";
|
||||
@@ -175,11 +176,62 @@ export default function Home({
|
||||
return organismsData.filter((o) => o.name.toLowerCase().includes(q));
|
||||
}, [organismQuery]);
|
||||
|
||||
const alerts: AlertItem[] = [
|
||||
{ company: "Empresa A", type: "Fuga", time: "Hace 2 horas" },
|
||||
{ company: "Empresa C", type: "Consumo alto", time: "Hace 5 horas" },
|
||||
{ company: "Empresa B", type: "Inactividad", time: "Hace 8 horas" },
|
||||
];
|
||||
const [notifications, setNotifications] = useState<Notification[]>([]);
|
||||
const [loadingNotifications, setLoadingNotifications] = useState(false);
|
||||
|
||||
const loadNotifications = async () => {
|
||||
setLoadingNotifications(true);
|
||||
try {
|
||||
const response = await fetchNotifications({ limit: 10, page: 1 });
|
||||
setNotifications(response.data);
|
||||
} catch (err) {
|
||||
console.error("Error loading notifications:", err);
|
||||
setNotifications([]);
|
||||
} finally {
|
||||
setLoadingNotifications(false);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (!isOperator) {
|
||||
loadNotifications();
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, []);
|
||||
|
||||
const formatNotificationType = (type: string): string => {
|
||||
const typeMap: Record<string, string> = {
|
||||
NEGATIVE_FLOW: "Flujo Negativo",
|
||||
SYSTEM_ALERT: "Alerta del Sistema",
|
||||
MAINTENANCE: "Mantenimiento",
|
||||
};
|
||||
return typeMap[type] || type;
|
||||
};
|
||||
|
||||
const formatNotificationTime = (dateString: string): string => {
|
||||
const date = new Date(dateString);
|
||||
const now = new Date();
|
||||
const diffMs = now.getTime() - date.getTime();
|
||||
const diffMins = Math.floor(diffMs / 60000);
|
||||
const diffHours = Math.floor(diffMs / 3600000);
|
||||
const diffDays = Math.floor(diffMs / 86400000);
|
||||
|
||||
if (diffMins < 1) return "Hace un momento";
|
||||
if (diffMins < 60) return `Hace ${diffMins} minuto${diffMins > 1 ? "s" : ""}`;
|
||||
if (diffHours < 24) return `Hace ${diffHours} hora${diffHours > 1 ? "s" : ""}`;
|
||||
if (diffDays < 7) return `Hace ${diffDays} día${diffDays > 1 ? "s" : ""}`;
|
||||
return date.toLocaleDateString();
|
||||
};
|
||||
|
||||
const alerts: AlertItem[] = useMemo(
|
||||
() =>
|
||||
notifications.map((n) => ({
|
||||
company: n.meter_serial_number || "Sistema",
|
||||
type: formatNotificationType(n.notification_type),
|
||||
time: formatNotificationTime(n.created_at),
|
||||
})),
|
||||
[notifications]
|
||||
);
|
||||
|
||||
const formatAuditAction = (action: string): string => {
|
||||
const actionMap: Record<string, string> = {
|
||||
@@ -547,20 +599,35 @@ export default function Home({
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Últimas alertas */}
|
||||
<div className="bg-white rounded-xl shadow p-6">
|
||||
<h2 className="text-lg font-semibold mb-4">Últimas Alertas</h2>
|
||||
<ul className="divide-y divide-gray-200">
|
||||
{alerts.map((a, i) => (
|
||||
<li key={i} className="py-2 flex justify-between">
|
||||
<span>
|
||||
{a.company} - {a.type}
|
||||
</span>
|
||||
<span className="text-red-500 font-medium">{a.time}</span>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
{!isOperator && (
|
||||
<div className="bg-white rounded-xl shadow p-6">
|
||||
<h2 className="text-lg font-semibold mb-4">Últimas Alertas</h2>
|
||||
{loadingNotifications ? (
|
||||
<div className="flex items-center justify-center py-8">
|
||||
<div className="animate-spin rounded-full h-8 w-8 border-b-2 border-blue-600"></div>
|
||||
</div>
|
||||
) : alerts.length === 0 ? (
|
||||
<p className="text-sm text-gray-500 text-center py-8">
|
||||
No hay alertas disponibles
|
||||
</p>
|
||||
) : (
|
||||
<ul className="divide-y divide-gray-200">
|
||||
{alerts.map((a, i) => (
|
||||
<li key={i} className="py-2 flex justify-between items-start">
|
||||
<div className="flex-1">
|
||||
<span className="text-sm text-gray-700">
|
||||
<span className="font-semibold">{a.company}</span> - {a.type}
|
||||
</span>
|
||||
</div>
|
||||
<span className="text-xs text-red-500 font-medium whitespace-nowrap ml-4">
|
||||
{a.time}
|
||||
</span>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user