Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Sabrina Dantas] whatickets #659

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions backend/.wwebjs_cache/2.3000.1017202422.html

Large diffs are not rendered by default.

52 changes: 52 additions & 0 deletions backend/.wwebjs_cache/2.3000.1017228115.html

Large diffs are not rendered by default.

52 changes: 52 additions & 0 deletions backend/.wwebjs_cache/2.3000.1017262717.html

Large diffs are not rendered by default.

5 changes: 4 additions & 1 deletion backend/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,15 @@
"target": "es6",
"module": "commonjs",
"outDir": "./dist",
"rootDir": "./src",
"strict": true,
"strictPropertyInitialization": false,
"esModuleInterop": true,
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true
}
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}
4 changes: 2 additions & 2 deletions frontend/src/components/MessageInput/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ const useStyles = makeStyles((theme) => ({
},

newMessageBox: {
background: "#eee",
background: theme.palette.background.default,
width: "100%",
display: "flex",
padding: "7px",
Expand All @@ -64,7 +64,7 @@ const useStyles = makeStyles((theme) => ({
messageInputWrapper: {
padding: 6,
marginRight: 7,
background: "#fff",
background: theme.palette.background.paper,
display: "flex",
borderRadius: 20,
flex: 1,
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/TicketHeader/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { useHistory } from "react-router-dom";
const useStyles = makeStyles((theme) => ({
ticketHeader: {
display: "flex",
backgroundColor: "#eee",
backgroundColor: theme.palette.background.default,
flex: "none",
borderBottom: "1px solid rgba(0, 0, 0, 0.12)",
[theme.breakpoints.down("sm")]: {
Expand Down
4 changes: 3 additions & 1 deletion frontend/src/components/TicketListItem/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ import toastError from "../../errors/toastError";
const useStyles = makeStyles(theme => ({
ticket: {
position: "relative",
backgroundColor: theme.palette.background.paper,
color: theme.palette.text.primary,
},

pendingTicket: {
Expand All @@ -43,7 +45,7 @@ const useStyles = makeStyles(theme => ({

noTicketsText: {
textAlign: "center",
color: "rgb(104, 121, 146)",
color: theme.palette.text.secondary,
fontSize: "14px",
lineHeight: "1.4",
},
Expand Down
13 changes: 7 additions & 6 deletions frontend/src/components/TicketsList/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,35 +21,36 @@ const useStyles = makeStyles(theme => ({
overflow: "hidden",
borderTopRightRadius: 0,
borderBottomRightRadius: 0,
backgroundColor: theme.palette.background.default,
},

ticketsList: {
flex: 1,
overflowY: "scroll",
...theme.scrollbarStyles,
borderTop: "2px solid rgba(0, 0, 0, 0.12)",
borderTop: "2px solid rgba(255, 255, 255, 0.12)",
},

ticketsListHeader: {
color: "rgb(67, 83, 105)",
color: theme.palette.text.primary,
zIndex: 2,
backgroundColor: "white",
borderBottom: "1px solid rgba(0, 0, 0, 0.12)",
backgroundColor: theme.palette.background.paper,
borderBottom: "1px solid rgba(255, 255, 255, 0.12)",
display: "flex",
alignItems: "center",
justifyContent: "space-between",
},

ticketsCount: {
fontWeight: "normal",
color: "rgb(104, 121, 146)",
color: theme.palette.text.secondary,
marginLeft: "8px",
fontSize: "14px",
},

noTicketsText: {
textAlign: "center",
color: "rgb(104, 121, 146)",
color: theme.palette.text.secondary,
fontSize: "14px",
lineHeight: "1.4",
},
Expand Down
8 changes: 5 additions & 3 deletions frontend/src/components/TicketsManager/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,12 @@ const useStyles = makeStyles((theme) => ({
overflow: "hidden",
borderTopRightRadius: 0,
borderBottomRightRadius: 0,
backgroundColor: theme.palette.background.paper,
},

tabsHeader: {
flex: "none",
backgroundColor: "#eee",
backgroundColor: theme.palette.background.paper,
},

settingsIcon: {
Expand All @@ -54,13 +55,13 @@ const useStyles = makeStyles((theme) => ({
display: "flex",
justifyContent: "space-between",
alignItems: "center",
background: "#fafafa",
background: theme.palette.background.default,
padding: theme.spacing(1),
},

serachInputWrapper: {
flex: 1,
background: "#fff",
background: theme.palette.background.default,
display: "flex",
borderRadius: 40,
padding: 4,
Expand All @@ -78,6 +79,7 @@ const useStyles = makeStyles((theme) => ({
flex: 1,
border: "none",
borderRadius: 30,
color: theme.palette.text.primary,
},

badge: {
Expand Down
126 changes: 99 additions & 27 deletions frontend/src/hooks/useTickets/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { useState, useEffect } from "react";
import { getHoursCloseTicketsAuto } from "../../config";
import toastError from "../../errors/toastError";

import api from "../../services/api";

const useTickets = ({
Expand All @@ -17,11 +16,16 @@ const useTickets = ({
const [hasMore, setHasMore] = useState(false);
const [tickets, setTickets] = useState([]);
const [count, setCount] = useState(0);
const [ticketsByUser, setTicketsByUser] = useState({});
const [ticketsByConnection, setTicketsByConnection] = useState({});
const [ticketsByQueue, setTicketsByQueue] = useState({});
const [newContactsByDay, setNewContactsByDay] = useState({});
const [contactsWithTicketsByDay, setContactsWithTicketsByDay] = useState({});

useEffect(() => {
setLoading(true);
const delayDebounceFn = setTimeout(() => {
const fetchTickets = async() => {
const fetchTickets = async () => {
try {
const { data } = await api.get("/tickets", {
params: {
Expand All @@ -33,45 +37,103 @@ const useTickets = ({
queueIds,
withUnreadMessages,
},
})
setTickets(data.tickets)
});
setTickets(data.tickets);
// Contagem de contatos que criaram tickets por dia
const contactsByDay = data.tickets.reduce((acc, ticket) => {
const contactName = ticket.contact?.name || "Contato desconhecido";
const createdAtDate = new Date(ticket.createdAt).toLocaleDateString();

if (!acc[createdAtDate]) {
acc[createdAtDate] = new Set();
}
acc[createdAtDate].add(contactName);

return acc;
}, {});

const contactsWithTicketsByDay = Object.entries(contactsByDay).map(
([date, contacts]) => ({
date,
count: contacts.size,
})
);

let horasFecharAutomaticamente = getHoursCloseTicketsAuto();
setContactsWithTicketsByDay(contactsWithTicketsByDay);

if (status === "open" && horasFecharAutomaticamente && horasFecharAutomaticamente !== "" &&
horasFecharAutomaticamente !== "0" && Number(horasFecharAutomaticamente) > 0) {
// Lógica para calcular os contatos novos por dia
const contactsPerDay = data.tickets.reduce((acc, ticket) => {
const createdDate = new Date(ticket.createdAt).toLocaleDateString();
acc[createdDate] = acc[createdDate] ? acc[createdDate] + 1 : 1;
return acc;
}, {});
setNewContactsByDay(contactsPerDay);

let dataLimite = new Date()
dataLimite.setHours(dataLimite.getHours() - Number(horasFecharAutomaticamente))
// Contagem de tickets por fila
const ticketsCountByQueue = data.tickets.reduce((acc, ticket) => {
const queueName = ticket.queue?.name || "Fila desconhecida";
acc[queueName] = acc[queueName] ? acc[queueName] + 1 : 1;
return acc;
}, {});
setTicketsByQueue(ticketsCountByQueue);


// Contagem de tickets por conexão
const ticketsCountByConnection = data.tickets.reduce((acc, ticket) => {
const connectionName = ticket.connection?.name || "Conexão desconhecida";
acc[connectionName] = acc[connectionName] ? acc[connectionName] + 1 : 1;
return acc;
}, {});
setTicketsByConnection(ticketsCountByConnection);

// Contagem de tickets por usuário usando o nome
const ticketsCountByUser = data.tickets.reduce((acc, ticket) => {
const userName = ticket.user?.name || "Usuário desconhecido";
acc[userName] = acc[userName] ? acc[userName] + 1 : 1;
return acc;
}, {});
setTicketsByUser(ticketsCountByUser);

// Fechamento automático de tickets
let horasFecharAutomaticamente = getHoursCloseTicketsAuto();
if (
status === "open" &&
horasFecharAutomaticamente &&
horasFecharAutomaticamente !== "" &&
horasFecharAutomaticamente !== "0" &&
Number(horasFecharAutomaticamente) > 0
) {
let dataLimite = new Date();
dataLimite.setHours(dataLimite.getHours() - Number(horasFecharAutomaticamente));

data.tickets.forEach(ticket => {
if (ticket.status !== "closed") {
let dataUltimaInteracaoChamado = new Date(ticket.updatedAt)
let dataUltimaInteracaoChamado = new Date(ticket.updatedAt);
if (dataUltimaInteracaoChamado < dataLimite)
closeTicket(ticket)
closeTicket(ticket);
}
})
});
}

setHasMore(data.hasMore)
setCount(data.count)
setLoading(false)
setHasMore(data.hasMore);
setCount(data.count);
setLoading(false);
} catch (err) {
setLoading(false)
toastError(err)
setLoading(false);
toastError(err);
}
}
};

const closeTicket = async(ticket) => {
const closeTicket = async (ticket) => {
await api.put(`/tickets/${ticket.id}`, {
status: "closed",
userId: ticket.userId || null,
})
}
});
};

fetchTickets()
}, 500)
return () => clearTimeout(delayDebounceFn)
fetchTickets();
}, 500);
return () => clearTimeout(delayDebounceFn);
}, [
searchParam,
pageNumber,
Expand All @@ -80,9 +142,19 @@ const useTickets = ({
showAll,
queueIds,
withUnreadMessages,
])
]);

return { tickets, loading, hasMore, count };
return {
tickets,
loading,
hasMore,
count,
ticketsByUser,
ticketsByConnection,
ticketsByQueue,
newContactsByDay,
contactsWithTicketsByDay,
};
};

export default useTickets;
export default useTickets;
Loading