import React, { useCallback, useEffect, useRef, useState } from 'react'; import { __ } from '@wordpress/i18n'; import { head, isEmpty, pathOr } from 'ramda'; import SockJS from 'sockjs-client'; import { Stomp } from '@stomp/stompjs'; // store import { storeGet, useStoreValue } from '../../store'; // api import NotificationService from '../../service/notification-service'; // tools import set404FromErrorResponse from '../../helpers/set404FromErrorResponse'; // components import { Badge } from 'primereact/badge'; import { Sidebar } from 'primereact/sidebar'; import { TabPanel, TabView } from 'primereact/tabview'; import NotificationItem from './components/NotificationItem'; import NotificationItemChosen from './components/NotificationItemChosen'; import PaginatorBasic from '../PaginatorBasic'; const socketUrl = process.env.REACT_APP_API_ADDRESS_WS; const NotificationsSidebar = () => { const chosenCompanyId = useStoreValue('chosenCompanyId'); const userData = useStoreValue('userData'); const [activeIndex, setActiveIndex] = useState(0); const [loading, setLoading] = useState(false); const [notificationsVisible, setNotificationsVisible] = useState(false); const [notifications, setNotifications] = useState([]); const [notificationsRead, setNotificationsRead] = useState([]); const [chosenMsg, setChosenMsg] = useState({}); const socket = useRef(null); const stomp = useRef(null); const [currentSubscription, setCurrentSubscription] = useState(null); const [isConnected, setIsConnected] = useState(false); const [currentPage, setCurrentPage] = useState(1); const [totalRecordsNum, setTotalRecordsNum] = useState(0); const [totalPagesNum, setTotalPagesNum] = useState(0); const perPage = 10; // Handle tab change const handleTabChange = (e) => { if (e.index === activeIndex) { return } setTotalRecordsNum(0); setTotalPagesNum(0); setChosenMsg({}); setActiveIndex(e.index); setCurrentPage(1); }; const chooseNotification = (id) => { const properItems = activeIndex === 0 ? notifications : notificationsRead; const chosen = head(properItems.filter(o => o.id === id)); if (chosen) { setChosenMsg(chosen); } } const closeChosenMsg = () => { setChosenMsg({}); } const getPaginationQuery = (status = 'UNREAD', curPage = 1) => { return { 'globalFilters': { 'page': curPage, 'limit': perPage, 'sortBy': { 'columnName': 'id', 'sortDesc': true } }, 'status': [ status ] } } const fetchMessages = useCallback((status = 'UNREAD') => { const chosenCompanyId = storeGet('chosenCompanyId'); const userData = storeGet('userData'); const role = pathOr('', ['role', 'roleType'], userData); const bodyParams = getPaginationQuery(status, currentPage); if (currentSubscription) { currentSubscription.unsubscribe(); setCurrentSubscription(null); } if (userData.id && chosenCompanyId !== 0 && role === 'ROLE_BENEFICIARY') { setLoading(true); NotificationService.getNotificationsByCompanyIdPagination( userData.id, chosenCompanyId, bodyParams, status === 'UNREAD' ? getNotificationsPagi : getNotificationsReadPagi, errGetNotifications ); if (isConnected && socket.current) { subscribeTo(`/topic/notifications_user_${userData.id}_company_${chosenCompanyId}`) } } else if (userData.id && role !== 'ROLE_BENEFICIARY') { setLoading(true); NotificationService.getNotificationsPagination( userData.id, bodyParams, status === 'UNREAD' ? getNotificationsPagi : getNotificationsReadPagi, errGetNotifications ); if (isConnected && socket.current) { subscribeTo(`/topic/notifications_user_${userData.id}`) } } }, [currentPage]); const getNotificationsPagi = (resp) => { if (resp.status === 'SUCCESS') { const { body, totalRecords, currentPage, totalPages } = resp.data; setNotifications(body); setTotalRecordsNum(totalRecords); setTotalPagesNum(totalPages); if (currentPage > totalPages) { setCurrentPage(totalPages); } } set404FromErrorResponse(resp); setLoading(false); } const getNotificationsReadPagi = (resp) => { if (resp.status === 'SUCCESS') { const { body, totalRecords, currentPage, totalPages } = resp.data; setNotificationsRead(body); setTotalRecordsNum(totalRecords); setTotalPagesNum(totalPages); if (currentPage > totalPages) { setCurrentPage(totalPages); } } set404FromErrorResponse(resp); setLoading(false); } const errGetNotifications = (resp) => { set404FromErrorResponse(resp); setLoading(false); } const makeNotificationRead = (id) => { NotificationService.notificationMakeRead(id, makeReadCallback, makeReadErrorCallback) } const makeReadCallback = (resp) => { if (resp.status === 'SUCCESS') { if (0 === activeIndex) { const msgs = notifications.map(o => o.id === resp.data.id ? resp.data : o); setNotifications(msgs); } else { const msgs = notificationsRead.map(o => o.id === resp.data.id ? resp.data : o); setNotificationsRead(msgs); } setTotalRecordsNum(totalRecordsNum - 1); } set404FromErrorResponse(resp); } const makeReadErrorCallback = (resp) => { set404FromErrorResponse(resp); } const connectWebSocket = () => { // BFLOWS: consenti di disabilitare WSS via env (sandbox senza RabbitMQ) if (process.env.REACT_APP_ENABLE_WEBSOCKET === '0') { return; } socket.current = new SockJS(socketUrl, null, { transports: [ 'websocket', 'xhr-streaming', 'xhr-polling' ] } ); stomp.current = Stomp.over(socket.current); stomp.current.configure({ debug: function (str) { //console.log(str); }, reconnectDelay: 5000, heartbeatIncoming: 20000, heartbeatOutgoing: 20000 }); stomp.current.connect( {}, () => { //console.log('Websocket connected'); setIsConnected(true); }, (error) => { //console.error('WebSocket Connection Error:', error); setIsConnected(false); setTimeout(connectWebSocket, 5000); } ); }; const subscribeTo = (topic) => { const subscription = stomp.current.subscribe( topic, (message) => { try { const notification = JSON.parse(message.body); setNotifications(prev => [notification, ...prev]); } catch (error) { console.error('Error parsing notification:', error); } } ); setCurrentSubscription(subscription); } const onPageChange = (num) => { setCurrentPage(num); }; useEffect(() => { if (userData && userData.id) { fetchMessages(); } }, [chosenCompanyId, userData.id, isConnected]); useEffect(() => { if (0 === activeIndex) { fetchMessages(); } else { fetchMessages('READ'); } }, [currentPage, activeIndex]); useEffect(() => { connectWebSocket(); return () => { if (currentSubscription) { currentSubscription.unsubscribe(); setCurrentSubscription(null); } if (stomp.current) { stomp.current.disconnect(() => { //console.log('WebSocket Disconnected'); }); } }; }, []); return ( <> setNotificationsVisible(true)}> setNotificationsVisible(false)}> {loading ?
: !isEmpty(chosenMsg) ? : (notifications.length > 0 ? <>
    {notifications.map(o => )}
:
{__('Vuoto', 'gepafin')}
)}
{loading ?
: !isEmpty(chosenMsg) ? : (notificationsRead.length > 0 ? <>
    {notificationsRead.map(o => )}
:
{__('Vuoto', 'gepafin')}
)}
) } export default NotificationsSidebar;