348 lines
8.5 KiB
JavaScript
348 lines
8.5 KiB
JavaScript
import React, { useState, useEffect, useRef, useContext } from "react"
|
|
|
|
import { useHistory, useParams } from "react-router-dom"
|
|
import { parseISO, format, isSameDay } from "date-fns"
|
|
import clsx from "clsx"
|
|
|
|
import { makeStyles } from "@material-ui/core/styles"
|
|
import { green } from "@material-ui/core/colors"
|
|
import ListItem from "@material-ui/core/ListItem"
|
|
import ListItemText from "@material-ui/core/ListItemText"
|
|
import ListItemAvatar from "@material-ui/core/ListItemAvatar"
|
|
import Typography from "@material-ui/core/Typography"
|
|
import Avatar from "@material-ui/core/Avatar"
|
|
import Divider from "@material-ui/core/Divider"
|
|
import Badge from "@material-ui/core/Badge"
|
|
|
|
import { i18n } from "../../translate/i18n"
|
|
|
|
import api from "../../services/api"
|
|
import ButtonWithSpinner from "../ButtonWithSpinner"
|
|
import MarkdownWrapper from "../MarkdownWrapper"
|
|
import { Tooltip } from "@material-ui/core"
|
|
import { AuthContext } from "../../context/Auth/AuthContext"
|
|
import toastError from "../../errors/toastError"
|
|
//import openSocket from 'socket.io-client'
|
|
import { socket } from "../../services/socket"
|
|
|
|
const useStyles = makeStyles(theme => ({
|
|
ticket: {
|
|
position: "relative",
|
|
},
|
|
|
|
pendingTicket: {
|
|
cursor: "unset",
|
|
},
|
|
|
|
noTicketsDiv: {
|
|
display: "flex",
|
|
height: "100px",
|
|
margin: 40,
|
|
flexDirection: "column",
|
|
alignItems: "center",
|
|
justifyContent: "center",
|
|
},
|
|
|
|
noTicketsText: {
|
|
textAlign: "center",
|
|
color: "rgb(104, 121, 146)",
|
|
fontSize: "14px",
|
|
lineHeight: "1.4",
|
|
},
|
|
|
|
noTicketsTitle: {
|
|
textAlign: "center",
|
|
fontSize: "16px",
|
|
fontWeight: "600",
|
|
margin: "0px",
|
|
},
|
|
|
|
contactNameWrapper: {
|
|
display: "flex",
|
|
justifyContent: "space-between",
|
|
},
|
|
|
|
lastMessageTime: {
|
|
justifySelf: "flex-end",
|
|
},
|
|
|
|
closedBadge: {
|
|
alignSelf: "center",
|
|
justifySelf: "flex-end",
|
|
marginRight: 32,
|
|
marginLeft: "auto",
|
|
},
|
|
|
|
contactLastMessage: {
|
|
paddingRight: 20,
|
|
},
|
|
|
|
newMessagesCount: {
|
|
alignSelf: "center",
|
|
marginRight: 8,
|
|
marginLeft: "auto",
|
|
},
|
|
|
|
badgeStyle: {
|
|
color: "white",
|
|
backgroundColor: green[500],
|
|
},
|
|
|
|
acceptButton: {
|
|
position: "absolute",
|
|
left: "50%",
|
|
},
|
|
|
|
ticketQueueColor: {
|
|
flex: "none",
|
|
width: "8px",
|
|
height: "100%",
|
|
position: "absolute",
|
|
top: "0%",
|
|
left: "0%",
|
|
},
|
|
}))
|
|
|
|
const TicketListItem = ({ ticket, remoteTicketsControll, settings }) => {
|
|
const classes = useStyles()
|
|
const history = useHistory()
|
|
const [loading, setLoading] = useState(false)
|
|
const { ticketId } = useParams()
|
|
const isMounted = useRef(true)
|
|
const { user, getSettingValue } = useContext(AuthContext)
|
|
const [_remoteTicketsControll, setRemoteTicketsControll] = useState([])
|
|
const [_settings, setSettings] = useState(null)
|
|
|
|
useEffect(() => {
|
|
return () => {
|
|
isMounted.current = false
|
|
}
|
|
}, [])
|
|
|
|
useEffect(() => {
|
|
setSettings(settings)
|
|
}, [settings])
|
|
|
|
useEffect(() => {
|
|
setRemoteTicketsControll(remoteTicketsControll)
|
|
}, [remoteTicketsControll, settings])
|
|
|
|
const handleAcepptTicket = async id => {
|
|
setLoading(true)
|
|
try {
|
|
|
|
await api.put(`/tickets/${id}`, {
|
|
status: "open",
|
|
userId: user?.id,
|
|
})
|
|
} catch (err) {
|
|
setLoading(false)
|
|
toastError(err)
|
|
}
|
|
if (isMounted.current) {
|
|
setLoading(false)
|
|
}
|
|
|
|
history.push(`/tickets/${id}`)
|
|
}
|
|
|
|
const handleSelectTicket = id => {
|
|
history.push(`/tickets/${id}`)
|
|
}
|
|
|
|
|
|
useEffect(() => {
|
|
//const socket = openSocket(process.env.REACT_APP_BACKEND_URL)
|
|
|
|
const onRemoteTickesControllTicketListItem = (data) => {
|
|
console.log('REMOTE TICKETS CONTROLL UPDATE2: ', data.tickets)
|
|
if (data.action === 'update') {
|
|
setRemoteTicketsControll(data.tickets)
|
|
}
|
|
}
|
|
|
|
socket.on('remoteTickesControll', onRemoteTickesControllTicketListItem)
|
|
|
|
const onSettingsTicketListItem = (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
|
|
})
|
|
}
|
|
}
|
|
|
|
socket.on('settings', onSettingsTicketListItem)
|
|
|
|
return () => {
|
|
socket.off('remoteTickesControll', onRemoteTickesControllTicketListItem);
|
|
socket.off('settings', onSettingsTicketListItem);
|
|
}
|
|
}, [])
|
|
|
|
return (
|
|
<React.Fragment key={ticket.id}>
|
|
<Tooltip
|
|
arrow
|
|
placement="right"
|
|
title={
|
|
(ticket?.isRemote && ticket?.remoteDone && ticket.status === 'pending') ? "Mensagem de campanha enviada" : (ticket?.isRemote && ticket.status === 'pending') ? "Mensagem de campanha ainda não enviada" :
|
|
""
|
|
}
|
|
|
|
>
|
|
<ListItem
|
|
dense
|
|
button
|
|
onClick={e => {
|
|
if (ticket.status === "pending") return
|
|
handleSelectTicket(ticket.id)
|
|
}}
|
|
selected={ticketId && +ticketId === ticket.id}
|
|
className={clsx(classes.ticket, {
|
|
[classes.pendingTicket]: ticket.status === "pending",
|
|
})}
|
|
|
|
style={((ticket.status === "open" || ticket.status === "closed") && ticket?.isRemote) ? {
|
|
border: (ticket.status === "open" || ticket.status === "closed") ? "1px solid rgba(121,123,127,0.9)" : "1px solid transparent",
|
|
} : {}}
|
|
|
|
>
|
|
<Tooltip
|
|
arrow
|
|
placement="right"
|
|
title={ticket.queue?.name || "Sem fila"}
|
|
>
|
|
<span
|
|
style={{ backgroundColor: ticket.queue?.color || "#7C7C7C" }}
|
|
className={classes.ticketQueueColor}
|
|
></span>
|
|
</Tooltip>
|
|
<ListItemAvatar>
|
|
<Avatar src={ticket?.contact?.profilePicUrl} />
|
|
</ListItemAvatar>
|
|
<ListItemText
|
|
disableTypography
|
|
primary={
|
|
<span className={classes.contactNameWrapper}>
|
|
<Typography
|
|
noWrap
|
|
component="span"
|
|
variant="body2"
|
|
color="textPrimary"
|
|
>
|
|
{ticket?.contact?.name}
|
|
</Typography>
|
|
{ticket.status === "closed" && (
|
|
<Badge
|
|
className={classes.closedBadge}
|
|
badgeContent={"closed"}
|
|
color="primary"
|
|
/>
|
|
)}
|
|
{ticket.lastMessage && (
|
|
<Typography
|
|
className={classes.lastMessageTime}
|
|
component="span"
|
|
variant="body2"
|
|
color="textSecondary"
|
|
>
|
|
{ticket?.phoneNumberId && <span style={{ 'fontWeight': 'bold' }}>Oficial</span>}{" "}
|
|
{isSameDay(parseISO(ticket.updatedAt), new Date()) ? (
|
|
<>{format(parseISO(ticket.updatedAt), "HH:mm")}</>
|
|
) : (
|
|
<>{format(parseISO(ticket.updatedAt), "dd/MM/yyyy")}</>
|
|
)}
|
|
</Typography>
|
|
)}
|
|
</span>
|
|
}
|
|
secondary={
|
|
<span className={classes.contactNameWrapper}>
|
|
<Typography
|
|
className={classes.contactLastMessage}
|
|
noWrap
|
|
component="span"
|
|
variant="body2"
|
|
color="textSecondary"
|
|
>
|
|
{ticket.lastMessage ? (
|
|
<MarkdownWrapper>{ticket.lastMessage}</MarkdownWrapper>
|
|
) : (
|
|
<br />
|
|
)}
|
|
</Typography>
|
|
|
|
<Badge
|
|
className={classes.newMessagesCount}
|
|
badgeContent={+ticket.unreadMessages}
|
|
classes={{
|
|
badge: classes.badgeStyle,
|
|
}}
|
|
/>
|
|
|
|
{/* <Badge
|
|
className={classes.newMessagesCount}
|
|
badgeContent={ticket.unreadMessages}
|
|
classes={{
|
|
badge: classes.badgeStyle,
|
|
}}
|
|
/> */}
|
|
</span>
|
|
}
|
|
/>
|
|
{ticket.status === "pending" && (
|
|
|
|
|
|
<ButtonWithSpinner
|
|
// color="primary"
|
|
|
|
{...((ticket?.isRemote) ?
|
|
((settings &&
|
|
settings.length > 0 &&
|
|
getSettingValue('remoteTicketSendControll') &&
|
|
getSettingValue('remoteTicketSendControll') === 'enabled') && !ticket?.remoteDone && !_remoteTicketsControll?.includes(+ticket.id)) ?
|
|
{ style: { backgroundColor: "rgba(121,123,127,0.5)", color: "white" } } :
|
|
{ style: { backgroundColor: "rgba(121,123,127,0.9)", color: "white" } } :
|
|
|
|
{ color: "primary" })}
|
|
|
|
variant="contained"
|
|
|
|
disabled={true ? ((settings &&
|
|
settings.length > 0 &&
|
|
getSettingValue('remoteTicketSendControll') &&
|
|
getSettingValue('remoteTicketSendControll') === 'enabled') && ticket?.isRemote && !ticket?.remoteDone && !_remoteTicketsControll?.includes(+ticket.id)) : false}
|
|
|
|
className={classes.acceptButton}
|
|
size="small"
|
|
loading={loading}
|
|
onClick={e => handleAcepptTicket(ticket.id)}
|
|
>
|
|
|
|
<>
|
|
{(ticket?.isRemote && !ticket?.remoteDone) ? (
|
|
<>{i18n.t("ticketsList.buttons.accept")}<br />CAMPANHA</>
|
|
) : (
|
|
<>{i18n.t("ticketsList.buttons.accept")}</>
|
|
)}
|
|
|
|
</>
|
|
|
|
</ButtonWithSpinner>
|
|
|
|
|
|
|
|
)}
|
|
|
|
</ListItem>
|
|
</Tooltip>
|
|
<Divider variant="inset" component="li" />
|
|
</React.Fragment>
|
|
)
|
|
}
|
|
|
|
export default TicketListItem
|