mirror of
https://github.com/cheveguerra/whaticket-community.git
synced 2026-04-20 20:59:16 +00:00
improvement: moved notification logic to backend
This commit is contained in:
@@ -12,6 +12,7 @@ type IndexQuery = {
|
|||||||
status: string;
|
status: string;
|
||||||
date: string;
|
date: string;
|
||||||
showAll: string;
|
showAll: string;
|
||||||
|
withUnreadMessages: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
interface TicketData {
|
interface TicketData {
|
||||||
@@ -25,7 +26,8 @@ export const index = async (req: Request, res: Response): Promise<Response> => {
|
|||||||
status,
|
status,
|
||||||
date,
|
date,
|
||||||
searchParam,
|
searchParam,
|
||||||
showAll
|
showAll,
|
||||||
|
withUnreadMessages
|
||||||
} = req.query as IndexQuery;
|
} = req.query as IndexQuery;
|
||||||
|
|
||||||
const userId = req.user.id;
|
const userId = req.user.id;
|
||||||
@@ -36,7 +38,8 @@ export const index = async (req: Request, res: Response): Promise<Response> => {
|
|||||||
status,
|
status,
|
||||||
date,
|
date,
|
||||||
showAll,
|
showAll,
|
||||||
userId
|
userId,
|
||||||
|
withUnreadMessages
|
||||||
});
|
});
|
||||||
|
|
||||||
return res.status(200).json({ tickets, count, hasMore });
|
return res.status(200).json({ tickets, count, hasMore });
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ interface Request {
|
|||||||
date?: string;
|
date?: string;
|
||||||
showAll?: string;
|
showAll?: string;
|
||||||
userId: string;
|
userId: string;
|
||||||
|
withUnreadMessages?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Response {
|
interface Response {
|
||||||
@@ -26,24 +27,24 @@ const ListTicketsService = async ({
|
|||||||
status,
|
status,
|
||||||
date,
|
date,
|
||||||
showAll,
|
showAll,
|
||||||
userId
|
userId,
|
||||||
|
withUnreadMessages
|
||||||
}: Request): Promise<Response> => {
|
}: Request): Promise<Response> => {
|
||||||
let whereCondition: Filterable["where"];
|
let whereCondition: Filterable["where"] = {
|
||||||
|
[Op.or]: [{ userId }, { status: "pending" }]
|
||||||
|
};
|
||||||
let includeCondition: Includeable[];
|
let includeCondition: Includeable[];
|
||||||
|
|
||||||
includeCondition = [
|
includeCondition = [
|
||||||
{
|
{
|
||||||
model: Contact,
|
model: Contact,
|
||||||
as: "contact",
|
as: "contact",
|
||||||
attributes: ["id", "name", "number", "profilePicUrl"],
|
attributes: ["id", "name", "number", "profilePicUrl"]
|
||||||
include: ["extraInfo"]
|
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
if (showAll === "true") {
|
if (showAll === "true") {
|
||||||
whereCondition = {};
|
whereCondition = {};
|
||||||
} else {
|
|
||||||
whereCondition = { userId };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status) {
|
if (status) {
|
||||||
@@ -102,6 +103,21 @@ const ListTicketsService = async ({
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (withUnreadMessages === "true") {
|
||||||
|
includeCondition = [
|
||||||
|
...includeCondition,
|
||||||
|
{
|
||||||
|
model: Message,
|
||||||
|
as: "messages",
|
||||||
|
attributes: [],
|
||||||
|
where: {
|
||||||
|
read: false,
|
||||||
|
fromMe: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
const limit = 20;
|
const limit = 20;
|
||||||
const offset = limit * (+pageNumber - 1);
|
const offset = limit * (+pageNumber - 1);
|
||||||
|
|
||||||
|
|||||||
@@ -167,8 +167,6 @@ const wbotMessageListener = (whatsapp: Whatsapp): void => {
|
|||||||
const io = getIO();
|
const io = getIO();
|
||||||
|
|
||||||
wbot.on("message_create", async msg => {
|
wbot.on("message_create", async msg => {
|
||||||
console.log(msg.type);
|
|
||||||
|
|
||||||
if (!isValidMsg(msg)) {
|
if (!isValidMsg(msg)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ const NotificationsPopOver = () => {
|
|||||||
const ticketId = +history.location.pathname.split("/")[2];
|
const ticketId = +history.location.pathname.split("/")[2];
|
||||||
const anchorEl = useRef();
|
const anchorEl = useRef();
|
||||||
const [isOpen, setIsOpen] = useState(false);
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
const [notifications, setNotifications] = useState([]);
|
// const [notifications, setNotifications] = useState([]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!("Notification" in window)) {
|
if (!("Notification" in window)) {
|
||||||
@@ -81,30 +81,7 @@ const NotificationsPopOver = () => {
|
|||||||
};
|
};
|
||||||
}, [history, ticketId, userId]);
|
}, [history, ticketId, userId]);
|
||||||
|
|
||||||
const { tickets: openTickets } = useTickets({ status: "open" });
|
const { tickets: notifications } = useTickets({ withUnreadMessages: "true" });
|
||||||
const { tickets: pendingTickets } = useTickets({
|
|
||||||
status: "pending",
|
|
||||||
showAll: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (openTickets.length > 0 || pendingTickets.length > 0) {
|
|
||||||
let aux = [];
|
|
||||||
|
|
||||||
openTickets.forEach(ticket => {
|
|
||||||
if (ticket.unreadMessages > 0) {
|
|
||||||
aux.push(ticket);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
pendingTickets.forEach(ticket => {
|
|
||||||
if (ticket.unreadMessages > 0) {
|
|
||||||
aux.push(ticket);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
setNotifications(aux);
|
|
||||||
}
|
|
||||||
}, [openTickets, pendingTickets]);
|
|
||||||
|
|
||||||
const showDesktopNotification = ({ message, contact, ticket }) => {
|
const showDesktopNotification = ({ message, contact, ticket }) => {
|
||||||
const options = {
|
const options = {
|
||||||
@@ -176,6 +153,8 @@ const NotificationsPopOver = () => {
|
|||||||
<ListItemText>No tickets with unread messages.</ListItemText>
|
<ListItemText>No tickets with unread messages.</ListItemText>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
) : (
|
) : (
|
||||||
|
notifications &&
|
||||||
|
notifications.length > 0 &&
|
||||||
notifications.map(ticket => (
|
notifications.map(ticket => (
|
||||||
<NotificationTicket key={ticket.id}>
|
<NotificationTicket key={ticket.id}>
|
||||||
<TicketListItem ticket={ticket} />
|
<TicketListItem ticket={ticket} />
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ const reducer = (state, action) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (action.type === "UPDATE_TICKETS") {
|
if (action.type === "UPDATE_TICKETS") {
|
||||||
const { ticket, status, loggedUser } = action.payload;
|
const { ticket, status, loggedUser, withUnreadMessages } = action.payload;
|
||||||
|
|
||||||
const ticketIndex = state.findIndex(t => t.id === ticket.id);
|
const ticketIndex = state.findIndex(t => t.id === ticket.id);
|
||||||
if (ticketIndex !== -1) {
|
if (ticketIndex !== -1) {
|
||||||
@@ -41,6 +41,8 @@ const reducer = (state, action) => {
|
|||||||
ticket.status === "closed")
|
ticket.status === "closed")
|
||||||
) {
|
) {
|
||||||
state.unshift(ticket);
|
state.unshift(ticket);
|
||||||
|
} else if (withUnreadMessages) {
|
||||||
|
state.unshift(ticket);
|
||||||
}
|
}
|
||||||
return [...state];
|
return [...state];
|
||||||
}
|
}
|
||||||
@@ -56,11 +58,14 @@ const reducer = (state, action) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (action.type === "RESET_UNREAD") {
|
if (action.type === "RESET_UNREAD") {
|
||||||
const ticketId = action.payload;
|
const { ticketId, withUnreadMessages } = action.payload;
|
||||||
|
|
||||||
const ticketIndex = state.findIndex(t => t.id === ticketId);
|
const ticketIndex = state.findIndex(t => t.id === ticketId);
|
||||||
if (ticketIndex !== -1) {
|
if (ticketIndex !== -1) {
|
||||||
state[ticketIndex].unreadMessages = 0;
|
state[ticketIndex].unreadMessages = 0;
|
||||||
|
if (withUnreadMessages) {
|
||||||
|
state.splice(ticketIndex, 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return [...state];
|
return [...state];
|
||||||
}
|
}
|
||||||
@@ -70,7 +75,14 @@ const reducer = (state, action) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const useTickets = ({ searchParam, pageNumber, status, date, showAll }) => {
|
const useTickets = ({
|
||||||
|
searchParam,
|
||||||
|
pageNumber,
|
||||||
|
status,
|
||||||
|
date,
|
||||||
|
showAll,
|
||||||
|
withUnreadMessages,
|
||||||
|
}) => {
|
||||||
const userId = +localStorage.getItem("userId");
|
const userId = +localStorage.getItem("userId");
|
||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true);
|
||||||
const [hasMore, setHasMore] = useState(false);
|
const [hasMore, setHasMore] = useState(false);
|
||||||
@@ -79,7 +91,6 @@ const useTickets = ({ searchParam, pageNumber, status, date, showAll }) => {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
const delayDebounceFn = setTimeout(() => {
|
const delayDebounceFn = setTimeout(() => {
|
||||||
console.log(showAll);
|
|
||||||
const fetchTickets = async () => {
|
const fetchTickets = async () => {
|
||||||
try {
|
try {
|
||||||
const { data } = await api.get("/tickets", {
|
const { data } = await api.get("/tickets", {
|
||||||
@@ -89,6 +100,7 @@ const useTickets = ({ searchParam, pageNumber, status, date, showAll }) => {
|
|||||||
status,
|
status,
|
||||||
date,
|
date,
|
||||||
showAll,
|
showAll,
|
||||||
|
withUnreadMessages,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
dispatch({
|
dispatch({
|
||||||
@@ -107,7 +119,7 @@ const useTickets = ({ searchParam, pageNumber, status, date, showAll }) => {
|
|||||||
fetchTickets();
|
fetchTickets();
|
||||||
}, 500);
|
}, 500);
|
||||||
return () => clearTimeout(delayDebounceFn);
|
return () => clearTimeout(delayDebounceFn);
|
||||||
}, [searchParam, pageNumber, status, date, showAll]);
|
}, [searchParam, pageNumber, status, date, showAll, withUnreadMessages]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const socket = openSocket(process.env.REACT_APP_BACKEND_URL);
|
const socket = openSocket(process.env.REACT_APP_BACKEND_URL);
|
||||||
@@ -115,7 +127,13 @@ const useTickets = ({ searchParam, pageNumber, status, date, showAll }) => {
|
|||||||
|
|
||||||
socket.on("ticket", data => {
|
socket.on("ticket", data => {
|
||||||
if (data.action === "updateUnread") {
|
if (data.action === "updateUnread") {
|
||||||
dispatch({ type: "RESET_UNREAD", payload: data.ticketId });
|
dispatch({
|
||||||
|
type: "RESET_UNREAD",
|
||||||
|
payload: {
|
||||||
|
ticketId: data.ticketId,
|
||||||
|
withUnreadMessages: withUnreadMessages,
|
||||||
|
},
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.action === "updateStatus" || data.action === "create") {
|
if (data.action === "updateStatus" || data.action === "create") {
|
||||||
@@ -141,6 +159,7 @@ const useTickets = ({ searchParam, pageNumber, status, date, showAll }) => {
|
|||||||
payload: {
|
payload: {
|
||||||
ticket: data.ticket,
|
ticket: data.ticket,
|
||||||
status: status,
|
status: status,
|
||||||
|
withUnreadMessages: withUnreadMessages,
|
||||||
loggedUser: userId,
|
loggedUser: userId,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@@ -150,7 +169,7 @@ const useTickets = ({ searchParam, pageNumber, status, date, showAll }) => {
|
|||||||
return () => {
|
return () => {
|
||||||
socket.disconnect();
|
socket.disconnect();
|
||||||
};
|
};
|
||||||
}, [status, userId]);
|
}, [status, withUnreadMessages, userId]);
|
||||||
|
|
||||||
return { loading, tickets, hasMore, dispatch };
|
return { loading, tickets, hasMore, dispatch };
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user