Duffer Derek

Current Path : /var/www/sitesecurity.bitkit.dk/httpdocs/src/contexts/
Upload File :
Current File : /var/www/sitesecurity.bitkit.dk/httpdocs/src/contexts/FocusCenterContext.tsx

"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