import React, { useEffect, useReducer, useState, useContext } from 'react' import openSocket from 'socket.io-client' import { Button, IconButton, makeStyles, Paper, Table, TableBody, TableCell, TableHead, TableRow, Typography, } from '@material-ui/core' import MainContainer from '../../components/MainContainer' import MainHeader from '../../components/MainHeader' import MainHeaderButtonsWrapper from '../../components/MainHeaderButtonsWrapper' import TableRowSkeleton from '../../components/TableRowSkeleton' import Title from '../../components/Title' import { i18n } from '../../translate/i18n' import toastError from '../../errors/toastError' import api from '../../services/api' import { DeleteOutline, Edit } from '@material-ui/icons' import QueueModal from '../../components/QueueModal' import { toast } from 'react-toastify' import ConfirmationModal from '../../components/ConfirmationModal' import { AuthContext } from '../../context/Auth/AuthContext' import { Can } from '../../components/Can' const useStyles = makeStyles((theme) => ({ mainPaper: { flex: 1, padding: theme.spacing(1), overflowY: 'scroll', ...theme.scrollbarStyles, }, customTableCell: { display: 'flex', alignItems: 'center', justifyContent: 'center', }, })) const reducer = (state, action) => { if (action.type === 'LOAD_QUEUES') { const queues = action.payload const newQueues = [] queues.forEach((queue) => { const queueIndex = state.findIndex((q) => q.id === queue.id) if (queueIndex !== -1) { state[queueIndex] = queue } else { newQueues.push(queue) } }) return [...state, ...newQueues] } if (action.type === 'UPDATE_QUEUES') { const queue = action.payload const queueIndex = state.findIndex((u) => u.id === queue.id) if (queueIndex !== -1) { state[queueIndex] = queue return [...state] } else { return [queue, ...state] } } if (action.type === 'DELETE_QUEUE') { const queueId = action.payload const queueIndex = state.findIndex((q) => q.id === queueId) if (queueIndex !== -1) { state.splice(queueIndex, 1) } return [...state] } if (action.type === 'RESET') { return [] } } const Queues = () => { const classes = useStyles() const { user } = useContext(AuthContext) const [queues, dispatch] = useReducer(reducer, []) const [loading, setLoading] = useState(false) const [queueModalOpen, setQueueModalOpen] = useState(false) const [selectedQueue, setSelectedQueue] = useState(null) const [confirmModalOpen, setConfirmModalOpen] = useState(false) const [settings, setSettings] = useState([]) useEffect(() => { ;(async () => { setLoading(true) try { const { data } = await api.get('/queue') dispatch({ type: 'LOAD_QUEUES', payload: data }) setLoading(false) } catch (err) { toastError(err) setLoading(false) } })() }, []) useEffect(() => { const fetchSession = async () => { try { const { data } = await api.get('/settings') setSettings(data) } catch (err) { toastError(err) } } fetchSession() }, []) const getSettingValue = (key) => { const { value } = settings.find((s) => s.key === key) return value } useEffect(() => { const socket = openSocket(process.env.REACT_APP_BACKEND_URL) socket.on('queue', (data) => { if (data.action === 'update' || data.action === 'create') { dispatch({ type: 'UPDATE_QUEUES', payload: data.queue }) } if (data.action === 'delete') { dispatch({ type: 'DELETE_QUEUE', payload: data.queueId }) } }) socket.on('settings', (data) => { if (data.action === 'update') { setSettings((prevState) => { const aux = [...prevState] const settingIndex = aux.findIndex((s) => s.key === data.setting.key) aux[settingIndex].value = data.setting.value return aux }) } }) return () => { socket.disconnect() } }, []) const handleOpenQueueModal = () => { setQueueModalOpen(true) setSelectedQueue(null) } const handleCloseQueueModal = () => { setQueueModalOpen(false) setSelectedQueue(null) } const handleEditQueue = (queue) => { setSelectedQueue(queue) setQueueModalOpen(true) } const handleCloseConfirmationModal = () => { setConfirmModalOpen(false) setSelectedQueue(null) } const handleDeleteQueue = async (queueId) => { try { await api.delete(`/queue/${queueId}`) toast.success(i18n.t('Queue deleted successfully!')) } catch (err) { toastError(err) } setSelectedQueue(null) } return ( <Can role={user.profile} perform="queues-view:show" yes={() => ( <MainContainer> <ConfirmationModal title={ selectedQueue && `${i18n.t('queues.confirmationModal.deleteTitle')} ${ selectedQueue.name }?` } open={confirmModalOpen} onClose={handleCloseConfirmationModal} onConfirm={() => handleDeleteQueue(selectedQueue.id)} > {i18n.t('queues.confirmationModal.deleteMessage')} </ConfirmationModal> <QueueModal open={queueModalOpen} onClose={handleCloseQueueModal} queueId={selectedQueue?.id} /> <MainHeader> <Title>{i18n.t('queues.title')}</Title> <Can role={user.profile} perform="show-icon-add-queue" yes={() => ( <MainHeaderButtonsWrapper> <Button variant="contained" color="primary" onClick={handleOpenQueueModal} > {i18n.t('queues.buttons.add')} </Button> </MainHeaderButtonsWrapper> )} /> </MainHeader> <Paper className={classes.mainPaper} variant="outlined"> <Table size="small"> <TableHead> <TableRow> <TableCell align="center"> {i18n.t('queues.table.name')} </TableCell> <TableCell align="center"> {i18n.t('queues.table.color')} </TableCell> <TableCell align="center"> {i18n.t('queues.table.greeting')} </TableCell> <TableCell align="center"> {i18n.t('queues.table.actions')} </TableCell> </TableRow> </TableHead> <TableBody> <> {queues.map((queue) => ( <TableRow key={queue.id}> <TableCell align="center">{queue.name}</TableCell> <TableCell align="center"> <div className={classes.customTableCell}> <span style={{ backgroundColor: queue.color, width: 60, height: 20, alignSelf: 'center', }} /> </div> </TableCell> <TableCell align="center"> <div className={classes.customTableCell}> <Typography style={{ width: 300, align: 'center' }} noWrap variant="body2" > {queue.greetingMessage} </Typography> </div> </TableCell> <TableCell align="center"> <Can role={user.profile} perform="show-icon-edit-queue" yes={() => ( <div style={{ margin: 0, padding: 0, border: 'none', display: 'inline', }} > {(settings && settings.length > 0 && getSettingValue('editQueue') && getSettingValue('editQueue') === 'enabled') | (user.profile === 'master') ? ( <IconButton size="small" onClick={() => handleEditQueue(queue)} > <Edit /> </IconButton> ) : ( <div></div> )} </div> // <IconButton // size="small" // onClick={() => handleEditQueue(queue)} // > // <Edit /> // </IconButton> )} /> <Can role={user.profile} perform="show-icon-delete-queue" yes={() => ( <IconButton size="small" onClick={() => { setSelectedQueue(queue) setConfirmModalOpen(true) }} > <DeleteOutline /> </IconButton> )} /> </TableCell> </TableRow> ))} {loading && <TableRowSkeleton columns={4} />} </> </TableBody> </Table> </Paper> </MainContainer> )} /> ) } export default Queues