Duffer Derek
"use client";
import React, {
createContext,
useContext,
useState,
useEffect,
ReactNode,
useCallback,
} from "react";
import axios from "axios";
import Cookies from "js-cookie";
import { usePathname } from "next/navigation";
interface NotificationItem {
id: number;
title: string;
icon: string;
category: string;
description: string;
action: any;
dismiss: any;
unit_id: number;
unit_number: number;
group_id: number | null;
link: any;
}
interface FocusCenterContextType {
focusCenterData: NotificationItem[];
focusCenterCount: number;
refreshFocusCenter: () => Promise<void>;
isLoading: boolean;
/** Timestamp (ms) when dashboard data was last updated (Focus Center, units, etc.). Used for breadcrumb "Updated HH:mm". */
lastUpdatedAt: number | null;
setLastUpdated: (timestamp: number) => void;
}
const FocusCenterContext = createContext<FocusCenterContextType | undefined>(undefined);
import useUserPermission from "@/hooks/useUserPermission";
export const useFocusCenter = () => {
const context = useContext(FocusCenterContext);
if (context === undefined) {
throw new Error("useFocusCenter must be used within a FocusCenterProvider");
}
return context;
};
interface FocusCenterProviderProps {
children: ReactNode;
}
export const FocusCenterProvider: React.FC<FocusCenterProviderProps> = ({ children }) => {
const focusCenterHandlingPermission = useUserPermission(["focus_center:handling"]);
const [focusCenterData, setFocusCenterData] = useState<NotificationItem[]>([]);
const [isLoading, setIsLoading] = useState(false);
const [lastFetchTime, setLastFetchTime] = useState<number>(0);
const [lastUpdatedAt, setLastUpdatedAt] = useState<number | null>(null);
const pathname = usePathname();
const setLastUpdated = useCallback((timestamp: number) => {
setLastUpdatedAt(timestamp);
}, []);
const fetchFocusCenterData = useCallback(async () => {
try {
setIsLoading(true);
const baseUrl = process.env.NEXT_PUBLIC_API_BASE_URL;
const authToken = Cookies.get("authToken");
if (!authToken || !focusCenterHandlingPermission) {
return;
}
const response = await axios.get(`${baseUrl}/focus-centers`, {
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${authToken}`,
},
});
const data = Array.isArray(response.data) ? response.data : [];
const now = Date.now();
setFocusCenterData(data);
setLastFetchTime(now);
setLastUpdatedAt(now);
} catch (error) {
console.error("Failed to load focus center data:", error);
} finally {
setIsLoading(false);
}
}, [focusCenterHandlingPermission]);
const refreshFocusCenter = useCallback(async () => {
await fetchFocusCenterData();
}, [fetchFocusCenterData]);
// Initial load: set last updated on mount so breadcrumb shows a time immediately
useEffect(() => {
setLastUpdatedAt(Date.now());
}, []);
useEffect(() => {
if (focusCenterHandlingPermission) {
fetchFocusCenterData();
}
}, [focusCenterHandlingPermission]);
// Auto-refresh on route changes
useEffect(() => {
// Refresh focus center data when navigating to any dashboard route
const dashboardRoutes = [
"/dashboard",
"/sites",
"/live-view",
"/reporting",
"/hybrid-reporting",
"/users",
"/fleet",
];
const isDashboardRoute =
pathname && dashboardRoutes.some((route) => pathname.startsWith(route));
if (isDashboardRoute && focusCenterHandlingPermission) {
// Only fetch if we haven't fetched in the last 2 seconds to prevent excessive API calls
const now = Date.now();
if (now - lastFetchTime > 2000) {
fetchFocusCenterData();
}
}
}, [pathname, lastFetchTime, focusCenterHandlingPermission, fetchFocusCenterData]);
// Auto-refresh every 1 minute (60 seconds)
useEffect(() => {
if (!focusCenterHandlingPermission) {
return;
}
const intervalId = setInterval(() => {
fetchFocusCenterData();
}, 60000); // 60 seconds = 1 minute
return () => clearInterval(intervalId);
}, [focusCenterHandlingPermission, fetchFocusCenterData]);
// Auto-refresh when app becomes visible or regains focus (PWA open/return)
useEffect(() => {
if (!focusCenterHandlingPermission) {
return;
}
const handleVisibilityChange = () => {
if (!document.hidden) {
// Only fetch if we haven't fetched in the last 2 seconds to prevent excessive API calls
const now = Date.now();
if (now - lastFetchTime > 2000) {
fetchFocusCenterData();
}
}
};
const handleFocus = () => {
// Only fetch if we haven't fetched in the last 2 seconds to prevent excessive API calls
const now = Date.now();
if (now - lastFetchTime > 2000) {
fetchFocusCenterData();
}
};
document.addEventListener("visibilitychange", handleVisibilityChange);
window.addEventListener("focus", handleFocus);
return () => {
document.removeEventListener("visibilitychange", handleVisibilityChange);
window.removeEventListener("focus", handleFocus);
};
}, [focusCenterHandlingPermission, lastFetchTime, fetchFocusCenterData]);
const value: FocusCenterContextType = {
focusCenterData,
focusCenterCount: focusCenterData.length,
refreshFocusCenter,
isLoading,
lastUpdatedAt,
setLastUpdated,
};
return <FocusCenterContext.Provider value={value}>{children}</FocusCenterContext.Provider>;
};
Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists