import React, { useEffect, useReducer, useState, useContext } from "react"; import { makeStyles } from "@material-ui/core/styles"; import toastError from "../../errors/toastError"; import Popover from "@material-ui/core/Popover"; import AnnouncementIcon from "@material-ui/icons/Announcement"; import Notifications from "@material-ui/icons/Notifications" import { Avatar, Badge, IconButton, List, ListItem, ListItemAvatar, ListItemText, Dialog, Paper, Typography, DialogTitle, DialogContent, DialogActions, Button, DialogContentText, } from "@material-ui/core"; import api from "../../services/api"; import { isArray } from "lodash"; import moment from "moment"; import { SocketContext } from "../../context/Socket/SocketContext"; const useStyles = makeStyles((theme) => ({ mainPaper: { flex: 1, maxHeight: 3000, maxWidth: 5000, padding: theme.spacing(1), overflowY: "scroll", ...theme.scrollbarStyles, }, })); function AnnouncementDialog({ announcement, open, handleClose }) { const getMediaPath = (filename) => { return `${process.env.REACT_APP_BACKEND_URL}/public/${filename}`; }; return ( handleClose()} aria-labelledby="alert-dialog-title" aria-describedby="alert-dialog-description" > {announcement.title} {announcement.mediaPath && (
)} {announcement.text}
); } const reducer = (state, action) => { if (action.type === "LOAD_ANNOUNCEMENTS") { const announcements = action.payload; const newAnnouncements = []; if (isArray(announcements)) { announcements.forEach((announcement) => { const announcementIndex = state.findIndex( (u) => u.id === announcement.id ); if (announcementIndex !== -1) { state[announcementIndex] = announcement; } else { newAnnouncements.push(announcement); } }); } return [...state, ...newAnnouncements]; } if (action.type === "UPDATE_ANNOUNCEMENTS") { const announcement = action.payload; const announcementIndex = state.findIndex((u) => u.id === announcement.id); if (announcementIndex !== -1) { state[announcementIndex] = announcement; return [...state]; } else { return [announcement, ...state]; } } if (action.type === "DELETE_ANNOUNCEMENT") { const announcementId = action.payload; const announcementIndex = state.findIndex((u) => u.id === announcementId); if (announcementIndex !== -1) { state.splice(announcementIndex, 1); } return [...state]; } if (action.type === "RESET") { return []; } }; export default function AnnouncementsPopover() { const classes = useStyles(); const [loading, setLoading] = useState(false); const [anchorEl, setAnchorEl] = useState(null); const [pageNumber, setPageNumber] = useState(1); const [hasMore, setHasMore] = useState(false); const [searchParam] = useState(""); const [announcements, dispatch] = useReducer(reducer, []); const [invisible, setInvisible] = useState(false); const [announcement, setAnnouncement] = useState({}); const [showAnnouncementDialog, setShowAnnouncementDialog] = useState(false); const socketManager = useContext(SocketContext); useEffect(() => { dispatch({ type: "RESET" }); setPageNumber(1); }, [searchParam]); useEffect(() => { setLoading(true); const delayDebounceFn = setTimeout(() => { fetchAnnouncements(); }, 500); return () => clearTimeout(delayDebounceFn); // eslint-disable-next-line react-hooks/exhaustive-deps }, [searchParam, pageNumber]); useEffect(() => { const companyId = localStorage.getItem("companyId"); const socket = socketManager.getSocket(companyId); if (!socket) { return () => {}; } socket.on(`company-announcement`, (data) => { if (data.action === "update" || data.action === "create") { dispatch({ type: "UPDATE_ANNOUNCEMENTS", payload: data.record }); setInvisible(false); } if (data.action === "delete") { dispatch({ type: "DELETE_ANNOUNCEMENT", payload: +data.id }); } }); return () => { socket.disconnect(); }; }, [socketManager]); const fetchAnnouncements = async () => { try { const { data } = await api.get("/announcements/", { params: { searchParam, pageNumber }, }); dispatch({ type: "LOAD_ANNOUNCEMENTS", payload: data.records }); setHasMore(data.hasMore); setLoading(false); } catch (err) { toastError(err); } }; const loadMore = () => { setPageNumber((prevState) => prevState + 1); }; const handleScroll = (e) => { if (!hasMore || loading) return; const { scrollTop, scrollHeight, clientHeight } = e.currentTarget; if (scrollHeight - (scrollTop + 100) < clientHeight) { loadMore(); } }; const handleClick = (event) => { setAnchorEl(event.currentTarget); setInvisible(true); }; const handleClose = () => { setAnchorEl(null); }; const borderPriority = (priority) => { if (priority === 1) { return "4px solid #b81111"; } if (priority === 2) { return "4px solid orange"; } if (priority === 3) { return "4px solid grey"; } }; const getMediaPath = (filename) => { return `${process.env.REACT_APP_BACKEND_URL}/public/${filename}`; }; const handleShowAnnouncementDialog = (record) => { setAnnouncement(record); setShowAnnouncementDialog(true); setAnchorEl(null); }; const open = Boolean(anchorEl); const id = open ? "simple-popover" : undefined; return (
setShowAnnouncementDialog(false)} /> {isArray(announcements) && announcements.map((item, key) => ( handleShowAnnouncementDialog(item)} > {item.mediaPath && ( )} {moment(item.createdAt).format("DD/MM/YYYY")} {item.text} } /> ))} {isArray(announcements) && announcements.length === 0 && ( )}
); }