File "PushNotification-20260606084507.jsx"

Full Path: /home/trinadezambia/public_html/student_panel/src/lib/firebase/PushNotification-20260606084507.jsx
File size: 3.98 KB
MIME-type: text/x-java
Charset: utf-8

'use client';

import React from 'react';
import { useForegroundNotifications } from '@/lib/firebase/useForegroundNotifications';
import { useSyncFCMToken } from '@/lib/firebase/useSyncFCMToken';
import ServiceWorkerNavigationListener from '@/lib/firebase/ServiceWorkerNavigationListener';
import {
  NotificationProvider,
  useNotification,
} from '@/lib/firebase/NotificationContext';
import { useQueryClient } from '@tanstack/react-query';
import { useGetSchoolSettings } from '@/lib/api/student/queryHooks';
import { showNotificationIfNeeded } from './notificationHelper';

/**
 * Inner component to use the hook inside the provider
 */

const PushNotificationContent = ({ children, onNotificationReceived }) => {
  const { setLastNotification } = useNotification();
  const queryClient = useQueryClient();
  const { data: settingsData } = useGetSchoolSettings();
  const logoUrl = settingsData?.data?.settings?.favicon;

  const handleNotification = React.useCallback(
    (payload) => {
      // Check if this is a navigation message (from clicked notification)
      // Navigation messages should NOT trigger a new notification
      const isNavigationMessage =
        payload.action === 'navigate' || payload.type === 'NAVIGATE';

      // If it's a navigation message, skip notification display
      if (isNavigationMessage) {
        // console.log('[PushNotification] Navigation message received, skipping notification display');
        return;
      }

      // Update the context
      setLastNotification(payload);

      // Show notification if needed (e.g. not on chat page)
      showNotificationIfNeeded(payload, logoUrl);

      // Invalidate queries based on notification type to ensure fresh data
      const type = payload.data?.type || payload.notification?.type;
      const lowerType = type?.toLowerCase();

      // Always invalidate notifications list
      queryClient.invalidateQueries({ queryKey: ['student', 'notifications'] });

      if (lowerType) {
        if (lowerType === 'assignment') {
          queryClient.invalidateQueries({
            queryKey: ['student', 'assignments'],
          });
        } else if (lowerType === 'message') {
          // ChatWindow handles this, but good to have backup
          queryClient.invalidateQueries({ queryKey: ['chat', 'messages'] });
        } else if (
          lowerType === 'exam' ||
          lowerType === 'exam result' ||
          lowerType === 'result'
        ) {
          queryClient.invalidateQueries({ queryKey: ['online-exam-list'] });
          queryClient.invalidateQueries({ queryKey: ['offline-exam-list'] });
          queryClient.invalidateQueries({
            queryKey: ['online-exam-result-list'],
          });
        } else if (lowerType === 'lesson') {
          queryClient.invalidateQueries({ queryKey: ['lessons'] });
          queryClient.invalidateQueries({ queryKey: ['subject-details'] });
        } else if (lowerType === 'attendance') {
          queryClient.invalidateQueries({ queryKey: ['attendance'] });
        } else if (lowerType === 'class section') {
          queryClient.invalidateQueries({ queryKey: ['subject-details'] });
        }
      }

      // Call the original prop if provided
      if (onNotificationReceived) {
        onNotificationReceived(payload);
      }
    },
    [setLastNotification, queryClient, onNotificationReceived, logoUrl]
  );

  useForegroundNotifications(handleNotification);
  useSyncFCMToken();

  return (
    <>
      <ServiceWorkerNavigationListener onMessage={handleNotification} />
      {children}
    </>
  );
};

/**
 * PushNotificationLayout centralizes all notification-related hooks.
 * It keeps hooks alive and renders the service worker listener once.
 */
const PushNotificationLayout = ({
  children,
  onNotificationReceived = () => {},
}) => {
  return (
    <NotificationProvider>
      <PushNotificationContent onNotificationReceived={onNotificationReceived}>
        {children}
      </PushNotificationContent>
    </NotificationProvider>
  );
};

export default PushNotificationLayout;