Tickets Manager in progress,
List of tickets update Organize and styled styled and input seach in function. Badge msg unread done, dating msg donepull/14/head^2
							parent
							
								
									edc249ac87
								
							
						
					
					
						commit
						1230348bb8
					
				
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 5.6 KiB | 
|  | @ -0,0 +1,13 @@ | ||||||
|  | import React from "react"; | ||||||
|  | import { BadgeComponentStyled } from "./BadgeComponent.style"; | ||||||
|  | 
 | ||||||
|  | const BadgeComponent = ({ counter, position, top, left, right, bottom }) => { | ||||||
|  |   return ( | ||||||
|  |     <BadgeComponentStyled position={position} top={top} left={left} right={right} bottom={bottom}> | ||||||
|  |       {counter} | ||||||
|  |     </BadgeComponentStyled> | ||||||
|  |   ); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | export default BadgeComponent; | ||||||
|  | 
 | ||||||
|  | @ -0,0 +1,22 @@ | ||||||
|  | import styled from "styled-components"; | ||||||
|  | import { color } from "../../../style/varibles"; | ||||||
|  | 
 | ||||||
|  | export const BadgeComponentStyled = styled.span` | ||||||
|  |   position: ${({ position }) => (position ? position : "relative")}; | ||||||
|  |   top: ${({ top }) => (top ? top : "initial")}; | ||||||
|  |   left: ${({ left }) => (left ? left : "initial")}; | ||||||
|  |   right: ${({ right }) => (right ? right : "initial")}; | ||||||
|  |   bottom: ${({ bottom }) => (bottom ? bottom : "initial")}; | ||||||
|  |   display: flex; | ||||||
|  |   justify-content: center; | ||||||
|  |   align-items: center; | ||||||
|  |   text-align: center; | ||||||
|  |   border-radius: 50px; | ||||||
|  |   object-fit: cover; | ||||||
|  |   width: 21px; | ||||||
|  |   height: 21px; | ||||||
|  |   font-size: 16px; | ||||||
|  |   color: ${color.pricinpal.blanco}; | ||||||
|  |   background-color: ${color.status.yes}; | ||||||
|  | `; | ||||||
|  | 
 | ||||||
|  | @ -45,6 +45,7 @@ const useStyles = makeStyles((theme) => ({ | ||||||
|     flexGrow: 1, |     flexGrow: 1, | ||||||
|     padding: "20px 20px 20px 20px", |     padding: "20px 20px 20px 20px", | ||||||
|     overflowY: "scroll", |     overflowY: "scroll", | ||||||
|  |     height: "50vh", | ||||||
|     [theme.breakpoints.down("sm")]: { |     [theme.breakpoints.down("sm")]: { | ||||||
|       paddingBottom: "90px", |       paddingBottom: "90px", | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|  | @ -0,0 +1,122 @@ | ||||||
|  | import React, { useState, useEffect } from "react"; | ||||||
|  | import { useParams, useHistory } from "react-router-dom"; | ||||||
|  | 
 | ||||||
|  | import { toast } from "react-toastify"; | ||||||
|  | import openSocket from "socket.io-client"; | ||||||
|  | import clsx from "clsx"; | ||||||
|  | 
 | ||||||
|  | import ContactDrawer from "../ContactDrawer"; | ||||||
|  | import MessageInput from "../MessageInput"; | ||||||
|  | import TicketHeader from "../TicketHeader"; | ||||||
|  | import TicketInfo from "../TicketInfo"; | ||||||
|  | import TicketActionButtons from "../TicketActionButtons"; | ||||||
|  | import MessagesList from "../MessagesList"; | ||||||
|  | import api from "../../services/api"; | ||||||
|  | import { ReplyMessageProvider } from "../../context/ReplyingMessage/ReplyingMessageContext"; | ||||||
|  | import toastError from "../../errors/toastError"; | ||||||
|  | 
 | ||||||
|  | const Ticket = () => { | ||||||
|  |   const { ticketId } = useParams(); | ||||||
|  |   const history = useHistory(); | ||||||
|  | 
 | ||||||
|  |   const [drawerOpen, setDrawerOpen] = useState(false); | ||||||
|  |   const [loading, setLoading] = useState(true); | ||||||
|  |   const [contact, setContact] = useState({}); | ||||||
|  |   const [ticket, setTicket] = useState({}); | ||||||
|  | 
 | ||||||
|  |   const [statusChatEnd, setStatusChatEnd] = useState({}); | ||||||
|  | 
 | ||||||
|  |   useEffect(() => { | ||||||
|  |     setLoading(true); | ||||||
|  |     const delayDebounceFn = setTimeout(() => { | ||||||
|  |       const fetchTicket = async () => { | ||||||
|  |         try { | ||||||
|  |           const { data } = await api.get("/tickets/" + ticketId); | ||||||
|  | 
 | ||||||
|  |           setContact(data.contact.contact); | ||||||
|  |           setTicket(data.contact); | ||||||
|  | 
 | ||||||
|  |           setStatusChatEnd(data.statusChatEnd); | ||||||
|  | 
 | ||||||
|  |           setLoading(false); | ||||||
|  |         } catch (err) { | ||||||
|  |           setLoading(false); | ||||||
|  |           toastError(err); | ||||||
|  |         } | ||||||
|  |       }; | ||||||
|  |       fetchTicket(); | ||||||
|  |     }, 500); | ||||||
|  |     return () => clearTimeout(delayDebounceFn); | ||||||
|  |   }, [ticketId, history]); | ||||||
|  | 
 | ||||||
|  |   useEffect(() => { | ||||||
|  |     const socket = openSocket(process.env.REACT_APP_BACKEND_URL); | ||||||
|  | 
 | ||||||
|  |     socket.on("connect", () => socket.emit("joinChatBox", ticketId)); | ||||||
|  | 
 | ||||||
|  |     socket.on("ticket", (data) => { | ||||||
|  |       if (data.action === "update") { | ||||||
|  |         setTicket(data.ticket); | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       if (data.action === "delete") { | ||||||
|  |         toast.success("Ticket deleted sucessfully."); | ||||||
|  |         history.push("/tickets"); | ||||||
|  |       } | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     socket.on("contact", (data) => { | ||||||
|  |       if (data.action === "update") { | ||||||
|  |         setContact((prevState) => { | ||||||
|  |           if (prevState.id === data.contact?.id) { | ||||||
|  |             return { ...prevState, ...data.contact }; | ||||||
|  |           } | ||||||
|  |           return prevState; | ||||||
|  |         }); | ||||||
|  |       } | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     return () => { | ||||||
|  |       socket.disconnect(); | ||||||
|  |     }; | ||||||
|  |   }, [ticketId, history]); | ||||||
|  | 
 | ||||||
|  |   const handleDrawerOpen = () => { | ||||||
|  |     setDrawerOpen(true); | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   const handleDrawerClose = () => { | ||||||
|  |     setDrawerOpen(false); | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   const style ={ | ||||||
|  |     height: "fit-content", | ||||||
|  |     width: "100%", | ||||||
|  |     position: "relative", | ||||||
|  |   } | ||||||
|  |   return ( | ||||||
|  |     <div className="test" style={style} > | ||||||
|  |       <TicketHeader loading={loading}> | ||||||
|  |         <div> | ||||||
|  |           <TicketInfo contact={contact} ticket={ticket} onClick={handleDrawerOpen} /> | ||||||
|  |         </div> | ||||||
|  |         <div> | ||||||
|  |           <TicketActionButtons ticket={ticket} statusChatEnd={statusChatEnd} /> | ||||||
|  |         </div> | ||||||
|  |       </TicketHeader> | ||||||
|  |       <ReplyMessageProvider> | ||||||
|  |         <MessagesList ticketId={ticketId} isGroup={ticket.isGroup}></MessagesList> | ||||||
|  |         <MessageInput ticketStatus={ticket.status} /> | ||||||
|  |       </ReplyMessageProvider> | ||||||
|  | 
 | ||||||
|  |       <ContactDrawer | ||||||
|  |         open={drawerOpen} | ||||||
|  |         handleDrawerClose={handleDrawerClose} | ||||||
|  |         contact={contact} | ||||||
|  |         loading={loading} | ||||||
|  |       /> | ||||||
|  |     </div> | ||||||
|  |   ); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | export default Ticket; | ||||||
|  | @ -2,26 +2,27 @@ import React, { useState, useEffect, useRef, useContext } from "react"; | ||||||
| 
 | 
 | ||||||
| import { useHistory, useParams } from "react-router-dom"; | import { useHistory, useParams } from "react-router-dom"; | ||||||
| import { parseISO, format, isSameDay } from "date-fns"; | import { parseISO, format, isSameDay } from "date-fns"; | ||||||
| import clsx from "clsx"; |  | ||||||
| 
 | 
 | ||||||
| import { i18n } from "../../translate/i18n"; | import { i18n } from "../../../translate/i18n"; | ||||||
| 
 | 
 | ||||||
| import api from "../../services/api"; | import api from "../../../services/api"; | ||||||
| import { AuthContext } from "../../context/Auth/AuthContext"; | import { AuthContext } from "../../../context/Auth/AuthContext"; | ||||||
| import toastError from "../../errors/toastError"; | import toastError from "../../../errors/toastError"; | ||||||
| import { | import { | ||||||
|   TicketDateStyled, |   TicketDateStyled, | ||||||
|   TicketImgStyled, |   TicketImgStyled, | ||||||
|   TicketListItemStyled, |   TicketListItemStyled, | ||||||
|   TicketTitleStyled, |   TicketTitleStyled, | ||||||
| } from "./TicketListItem.style"; | } from "./TicketListItem.style"; | ||||||
|  | import Loading from "../../LoadingScreen/Loading"; | ||||||
|  | import BadgeComponent from "../../Base/Badge/BadgeComponent"; | ||||||
|  | import DefaultUser from "../../../assets/images/User/clientDefault.png"; | ||||||
| 
 | 
 | ||||||
| const TicketListItem = ({ tickets }) => { | const TicketListItem = ({ tickets }) => { | ||||||
|   const history = useHistory(); |   const history = useHistory(); | ||||||
|   const [loading, setLoading] = useState(false); |   const [loading, setLoading] = React.useState(false); | ||||||
|   const { ticketId } = useParams(); |   const isMounted = React.useRef(true); | ||||||
|   const isMounted = useRef(true); |   const { user } = React.useContext(AuthContext); | ||||||
|   const { user } = useContext(AuthContext); |  | ||||||
| 
 | 
 | ||||||
|   useEffect(() => { |   useEffect(() => { | ||||||
|     return () => { |     return () => { | ||||||
|  | @ -33,7 +34,7 @@ const TicketListItem = ({ tickets }) => { | ||||||
|     setLoading(true); |     setLoading(true); | ||||||
|     try { |     try { | ||||||
|       await api.put(`/tickets/${id}`, { |       await api.put(`/tickets/${id}`, { | ||||||
|         status: "open", |         status: tickets.status, | ||||||
|         userId: user?.id, |         userId: user?.id, | ||||||
|       }); |       }); | ||||||
|     } catch (err) { |     } catch (err) { | ||||||
|  | @ -47,17 +48,32 @@ const TicketListItem = ({ tickets }) => { | ||||||
|   }; |   }; | ||||||
| 
 | 
 | ||||||
|   const handleSelectTicket = (id) => { |   const handleSelectTicket = (id) => { | ||||||
|     history.push(`/tickets/${id}`); |     history.push(`/tickets/${tickets.id}`); | ||||||
|   }; |   }; | ||||||
| 
 |   console.log(tickets); | ||||||
|   if (!tickets) return null; |   if (!tickets) return <Loading />; | ||||||
|   return ( |   return ( | ||||||
|     <React.Fragment key={tickets.id}> |     <React.Fragment key={tickets.id} > | ||||||
|       <TicketListItemStyled> |       <TicketListItemStyled queuecolor={tickets.queue} onClick={handleSelectTicket}> | ||||||
|         <TicketImgStyled src={tickets.contact.profilePicUrl} alt={tickets.id} /> |         {tickets.contact.profilePicUrl ? ( | ||||||
|  |           <TicketImgStyled src={tickets.contact.profilePicUrl} alt={tickets.id} /> | ||||||
|  |         ) : ( | ||||||
|  |           <TicketImgStyled src={DefaultUser} alt={tickets.id} /> | ||||||
|  |         )} | ||||||
|  | 
 | ||||||
|         <TicketTitleStyled> |         <TicketTitleStyled> | ||||||
|           <p>{tickets.contact.name}</p> |           <p>{tickets.contact.name}</p> | ||||||
|           <p>{tickets.lastMessage}</p> |           <p>{tickets.lastMessage}</p> | ||||||
|  |           {tickets.unreadMessages ? ( | ||||||
|  |             <BadgeComponent | ||||||
|  |               counter={tickets.unreadMessages} | ||||||
|  |               position="absolute" | ||||||
|  |               right="6px" | ||||||
|  |               top="6px" | ||||||
|  |             /> | ||||||
|  |           ) : ( | ||||||
|  |             "" | ||||||
|  |           )} | ||||||
|         </TicketTitleStyled> |         </TicketTitleStyled> | ||||||
|         <TicketDateStyled> |         <TicketDateStyled> | ||||||
|           {isSameDay(parseISO(tickets.updatedAt), new Date()) ? ( |           {isSameDay(parseISO(tickets.updatedAt), new Date()) ? ( | ||||||
|  | @ -65,9 +81,7 @@ const TicketListItem = ({ tickets }) => { | ||||||
|           ) : ( |           ) : ( | ||||||
|             <>{format(parseISO(tickets.updatedAt), "dd/MM/yyyy")}</> |             <>{format(parseISO(tickets.updatedAt), "dd/MM/yyyy")}</> | ||||||
|           )} |           )} | ||||||
|           <p>badge</p> |  | ||||||
|         </TicketDateStyled> |         </TicketDateStyled> | ||||||
| 
 |  | ||||||
|       </TicketListItemStyled> |       </TicketListItemStyled> | ||||||
|     </React.Fragment> |     </React.Fragment> | ||||||
|   ); |   ); | ||||||
|  | @ -0,0 +1,71 @@ | ||||||
|  | import styled from "styled-components"; | ||||||
|  | import { color } from "../../../style/varibles"; | ||||||
|  | 
 | ||||||
|  | export const TicketListItemStyled = styled.li` | ||||||
|  |   cursor: pointer; | ||||||
|  |   position: relative; | ||||||
|  |   background-color: ${color.complement.azulOscuro}; | ||||||
|  |   display: flex; | ||||||
|  |   align-items: center; | ||||||
|  |   padding: 0.5rem 6px; | ||||||
|  |   border-bottom: 1.5px solid ${color.gradient.border}; | ||||||
|  |   height: fit-content; | ||||||
|  |   transition: filter .2s linear; | ||||||
|  |   &:before { | ||||||
|  |     position: absolute; | ||||||
|  |     left: 0; | ||||||
|  |     content: ""; | ||||||
|  |     display: block; | ||||||
|  |     background-color: ${({ queuecolor }) => (queuecolor ? queuecolor : color.gradient.border)}; | ||||||
|  |     width: 4px; | ||||||
|  |     height: 55px; | ||||||
|  |   } | ||||||
|  |   &:nth-child(1) { | ||||||
|  |     margin-top: 6px; | ||||||
|  |   } | ||||||
|  |   &:hover{ | ||||||
|  |     filter: brightness(1.2); | ||||||
|  |     transition: filter .2s linear; | ||||||
|  |   } | ||||||
|  | `; | ||||||
|  | 
 | ||||||
|  | export const TicketTitleStyled = styled.div` | ||||||
|  |   position: relative; | ||||||
|  |   display: flex; | ||||||
|  |   flex-direction: column; | ||||||
|  |   flex-grow: 1; | ||||||
|  |   row-gap: 6px; | ||||||
|  |   & p { | ||||||
|  |     color: ${color.pricinpal.blanco}; | ||||||
|  |     width: 190px; | ||||||
|  |     font-size: 12px; | ||||||
|  |     font-family: "Helvetica55"; | ||||||
|  |     &:nth-child(1) { | ||||||
|  |       overflow: hidden; | ||||||
|  |       text-overflow: ellipsis; | ||||||
|  |       white-space: nowrap; | ||||||
|  |     } | ||||||
|  |     &:nth-child(2) { | ||||||
|  |       overflow: hidden; | ||||||
|  |       text-overflow: ellipsis; | ||||||
|  |       white-space: nowrap; | ||||||
|  |       color: ${color.gradient.text}; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | `; | ||||||
|  | export const TicketDateStyled = styled.div` | ||||||
|  |   color: ${color.pricinpal.blanco}; | ||||||
|  |   font-size: 12px; | ||||||
|  |   font-family: "Helvetica55"; | ||||||
|  |   display: block; | ||||||
|  |   color: white; | ||||||
|  | `; | ||||||
|  | 
 | ||||||
|  | export const TicketImgStyled = styled.img` | ||||||
|  |   width: 40px; | ||||||
|  |   height: 40px; | ||||||
|  |   object-fit: contain; | ||||||
|  |   border-radius: 50%; | ||||||
|  |   margin: 0 6px; | ||||||
|  | `; | ||||||
|  | 
 | ||||||
|  | @ -102,10 +102,10 @@ const useStyles = makeStyles(theme => ({ | ||||||
| })); | })); | ||||||
| 
 | 
 | ||||||
| const TicketListItem = ({ ticket }) => { | const TicketListItem = ({ ticket }) => { | ||||||
| 	const classes = ReactDOM.useStyles(); | 	const classes = useStyles(); | ||||||
| 	const history = ReactDOM.useHistory(); | 	const history = useHistory(); | ||||||
| 	const [loading, setLoading] = useState(false); | 	const [loading, setLoading] = useState(false); | ||||||
| 	const { ticketId } = ReactDOM.useParams(); | 	const { ticketId } = useParams(); | ||||||
| 	const isMounted = useRef(true); | 	const isMounted = useRef(true); | ||||||
| 	const { user } = useContext(AuthContext); | 	const { user } = useContext(AuthContext); | ||||||
| 
 | 
 | ||||||
|  | @ -0,0 +1,10 @@ | ||||||
|  | import React from 'react' | ||||||
|  | import TicketSearchInput from './TicketSearchInput/TicketSearchInput' | ||||||
|  | 
 | ||||||
|  | const TicketSearch = ({setNewTicketModalOpen, handleSearch}) => { | ||||||
|  |   return ( | ||||||
|  |     <TicketSearchInput setNewTicketModalOpen={setNewTicketModalOpen} handleSearch={handleSearch}/> | ||||||
|  |   ) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export default TicketSearch | ||||||
|  | @ -0,0 +1 @@ | ||||||
|  | 
 | ||||||
|  | @ -0,0 +1,10 @@ | ||||||
|  | import React from 'react'; | ||||||
|  | import {TicketSearchBtnStyled} from "./TicketSearchBtn.styled" | ||||||
|  | 
 | ||||||
|  | const TicketSearchBtn = ({setNewTicketModalOpen}) => { | ||||||
|  |   return ( | ||||||
|  |     <TicketSearchBtnStyled onClick={()=>setNewTicketModalOpen(true)}>+</TicketSearchBtnStyled> | ||||||
|  |   ) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export default TicketSearchBtn | ||||||
|  | @ -0,0 +1,12 @@ | ||||||
|  | import styled from "styled-components"; | ||||||
|  | import { color } from "../../../../style/varibles"; | ||||||
|  | 
 | ||||||
|  | export const TicketSearchBtnStyled = styled.button` | ||||||
|  |   cursor: pointer; | ||||||
|  |   background-color: transparent; | ||||||
|  |   color: ${color.pricinpal.blanco}; | ||||||
|  |   font-size: 26px; | ||||||
|  |   border: none; | ||||||
|  |   font-family: "Helvetica55"; | ||||||
|  | `; | ||||||
|  | 
 | ||||||
|  | @ -0,0 +1,15 @@ | ||||||
|  | import React from "react"; | ||||||
|  | import TicketSearchBtn from "../TicketSearchBtn/TicketSearchBtn"; | ||||||
|  | import { TicketSearchDivStyled, TicketSearchInputStyled } from "./TicketSearchInput.styled"; | ||||||
|  | 
 | ||||||
|  | const TicketSearchInput = ({ setNewTicketModalOpen, handleSearch }) => { | ||||||
|  |   return ( | ||||||
|  |     <TicketSearchDivStyled> | ||||||
|  |       <TicketSearchInputStyled onChange={handleSearch} /> | ||||||
|  |       <TicketSearchBtn setNewTicketModalOpen={setNewTicketModalOpen} /> | ||||||
|  |     </TicketSearchDivStyled> | ||||||
|  |   ); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | export default TicketSearchInput; | ||||||
|  | 
 | ||||||
|  | @ -0,0 +1,17 @@ | ||||||
|  | import styled from "styled-components"; | ||||||
|  | import { color } from "../../../../style/varibles"; | ||||||
|  | 
 | ||||||
|  | export const TicketSearchDivStyled = styled.div` | ||||||
|  |   padding: 0 6px; | ||||||
|  |   display: flex; | ||||||
|  |   flex-direction: row; | ||||||
|  | `; | ||||||
|  | export const TicketSearchInputStyled = styled.input` | ||||||
|  |   width: 100%; | ||||||
|  |   margin-right: 12px; | ||||||
|  |   background-color: ${color.complement.azulOscuro}; | ||||||
|  |   border: 2px solid ${color.pricinpal.blanco}; | ||||||
|  |   color: ${color.pricinpal.blanco}; | ||||||
|  |   border-radius: 4px; | ||||||
|  |   padding: 4px; | ||||||
|  | `; | ||||||
|  | @ -0,0 +1,9 @@ | ||||||
|  | import React from 'react' | ||||||
|  | 
 | ||||||
|  | const TicketSkeleton = () => { | ||||||
|  |   return ( | ||||||
|  |     <div>TicketSkeleton</div> | ||||||
|  |   ) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export default TicketSkeleton | ||||||
|  | @ -0,0 +1,4 @@ | ||||||
|  | import styled from "styled-components"; | ||||||
|  | import {color} from "../../../style/varibles" | ||||||
|  | 
 | ||||||
|  | export const TicketSkeletonStyled = styled.div``; | ||||||
|  | @ -2,20 +2,17 @@ import React from "react"; | ||||||
| import { useHistory } from "react-router-dom"; | import { useHistory } from "react-router-dom"; | ||||||
| import openSocket from "socket.io-client"; | import openSocket from "socket.io-client"; | ||||||
| 
 | 
 | ||||||
| import useTickets from "../../hooks/useTickets"; | import useTickets from "../../../../hooks/useTickets"; | ||||||
| import TicketListItem from "../TicketListItem/TicketListItem"; | import TicketListItem from "../../TicketListItem/TicketListItem"; | ||||||
| import TicketsListSkeleton from "../TicketsListSkeleton"; | import TicketsListSkeleton from "../../../TicketsListSkeleton"; | ||||||
| 
 | 
 | ||||||
| import { i18n } from "../../translate/i18n"; | import { i18n } from "../../../../translate/i18n"; | ||||||
| import { AuthContext } from "../../context/Auth/AuthContext"; | import { AuthContext } from "../../../../context/Auth/AuthContext"; | ||||||
| 
 | 
 | ||||||
| const reducer = (state, action) => { | const reducer = (state, action) => { | ||||||
|   if (action.type === "LOAD_TICKETS") { |   if (action.type === "LOAD_TICKETS") { | ||||||
|     const newTickets = action.payload; |     const newTickets = action.payload; | ||||||
| 
 |  | ||||||
|     newTickets.forEach((ticket) => { |     newTickets.forEach((ticket) => { | ||||||
|       // console.log("* ticket.unreadMessages: ", ticket.unreadMessages); |  | ||||||
| 
 |  | ||||||
|       const ticketIndex = state.findIndex((t) => t.id === ticket.id); |       const ticketIndex = state.findIndex((t) => t.id === ticket.id); | ||||||
|       if (ticketIndex !== -1) { |       if (ticketIndex !== -1) { | ||||||
|         state[ticketIndex] = ticket; |         state[ticketIndex] = ticket; | ||||||
|  | @ -26,7 +23,6 @@ const reducer = (state, action) => { | ||||||
|         state.push(ticket); |         state.push(ticket); | ||||||
|       } |       } | ||||||
|     }); |     }); | ||||||
| 
 |  | ||||||
|     return [...state]; |     return [...state]; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  | @ -37,22 +33,17 @@ const reducer = (state, action) => { | ||||||
|     if (ticketIndex !== -1) { |     if (ticketIndex !== -1) { | ||||||
|       state[ticketIndex].unreadMessages = 0; |       state[ticketIndex].unreadMessages = 0; | ||||||
|     } |     } | ||||||
| 
 |  | ||||||
|     return [...state]; |     return [...state]; | ||||||
|   } |   } | ||||||
| 
 |  | ||||||
|   if (action.type === "UPDATE_TICKET") { |   if (action.type === "UPDATE_TICKET") { | ||||||
|     const ticket = action.payload; |     const ticket = action.payload; | ||||||
| 
 | 
 | ||||||
|     // console.log('++++++++++++ UPDATE_TICKET: ',ticket) |  | ||||||
| 
 |  | ||||||
|     const ticketIndex = state.findIndex((t) => t.id === ticket.id); |     const ticketIndex = state.findIndex((t) => t.id === ticket.id); | ||||||
|     if (ticketIndex !== -1) { |     if (ticketIndex !== -1) { | ||||||
|       state[ticketIndex] = ticket; |       state[ticketIndex] = ticket; | ||||||
|     } else { |     } else { | ||||||
|       state.unshift(ticket); |       state.unshift(ticket); | ||||||
|     } |     } | ||||||
| 
 |  | ||||||
|     return [...state]; |     return [...state]; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  | @ -79,6 +70,7 @@ const reducer = (state, action) => { | ||||||
| 
 | 
 | ||||||
|   if (action.type === "UPDATE_TICKET_CONTACT") { |   if (action.type === "UPDATE_TICKET_CONTACT") { | ||||||
|     const contact = action.payload; |     const contact = action.payload; | ||||||
|  | 
 | ||||||
|     const ticketIndex = state.findIndex((t) => t.contactId === contact.id); |     const ticketIndex = state.findIndex((t) => t.contactId === contact.id); | ||||||
|     if (ticketIndex !== -1) { |     if (ticketIndex !== -1) { | ||||||
|       state[ticketIndex].contact = contact; |       state[ticketIndex].contact = contact; | ||||||
|  | @ -88,6 +80,7 @@ const reducer = (state, action) => { | ||||||
| 
 | 
 | ||||||
|   if (action.type === "DELETE_TICKET") { |   if (action.type === "DELETE_TICKET") { | ||||||
|     const ticketId = action.payload; |     const ticketId = 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.splice(ticketIndex, 1); |       state.splice(ticketIndex, 1); | ||||||
|  | @ -112,7 +105,6 @@ const TicketsList = ({ status, searchParam, showAll, selectedQueueIds, updateCou | ||||||
|     showAll, |     showAll, | ||||||
|     queueIds: JSON.stringify(selectedQueueIds), |     queueIds: JSON.stringify(selectedQueueIds), | ||||||
|   }); |   }); | ||||||
| 
 |  | ||||||
|   React.useEffect(() => { |   React.useEffect(() => { | ||||||
|     dispatch({ type: "RESET" }); |     dispatch({ type: "RESET" }); | ||||||
|     setPageNumber(1); |     setPageNumber(1); | ||||||
|  | @ -124,7 +116,7 @@ const TicketsList = ({ status, searchParam, showAll, selectedQueueIds, updateCou | ||||||
|       type: "LOAD_TICKETS", |       type: "LOAD_TICKETS", | ||||||
|       payload: tickets, |       payload: tickets, | ||||||
|     }); |     }); | ||||||
|   }, [tickets, status, searchParam]); |   }, [tickets, searchParam]); | ||||||
| 
 | 
 | ||||||
|   React.useEffect(() => { |   React.useEffect(() => { | ||||||
|     const socket = openSocket(process.env.REACT_APP_BACKEND_URL); |     const socket = openSocket(process.env.REACT_APP_BACKEND_URL); | ||||||
|  | @ -170,8 +162,6 @@ const TicketsList = ({ status, searchParam, showAll, selectedQueueIds, updateCou | ||||||
| 
 | 
 | ||||||
|     socket.on("appMessage", (data) => { |     socket.on("appMessage", (data) => { | ||||||
|       if (data.action === "create" && shouldUpdateTicket(data.ticket)) { |       if (data.action === "create" && shouldUpdateTicket(data.ticket)) { | ||||||
|         // console.log('((((((((((((((((((( DATA.MESSAGE: ', data.message) |  | ||||||
| 
 |  | ||||||
|         dispatch({ |         dispatch({ | ||||||
|           type: "UPDATE_TICKET_UNREAD_MESSAGES", |           type: "UPDATE_TICKET_UNREAD_MESSAGES", | ||||||
|           // payload: data.ticket, |           // payload: data.ticket, | ||||||
|  | @ -194,31 +184,14 @@ const TicketsList = ({ status, searchParam, showAll, selectedQueueIds, updateCou | ||||||
|     }; |     }; | ||||||
|   }, [status, showAll, user, selectedQueueIds]); |   }, [status, showAll, user, selectedQueueIds]); | ||||||
| 
 | 
 | ||||||
|   React.useEffect(() => { |  | ||||||
|     if (typeof updateCount === "function") { |  | ||||||
|       updateCount(ticketsList.length); |  | ||||||
|     } |  | ||||||
|     // eslint-disable-next-line react-hooks/exhaustive-deps |  | ||||||
|   }, [ticketsList]); |  | ||||||
| 
 | 
 | ||||||
|   const loadMore = () => { |   if (ticketsList <= 0) return <h1>carregando</h1>; | ||||||
|     setPageNumber((prevState) => prevState + 1); |  | ||||||
|   }; |  | ||||||
| 
 | 
 | ||||||
|   const handleScroll = (e) => { |  | ||||||
|     if (!hasMore || loading) return; |  | ||||||
| 
 |  | ||||||
|     const { scrollTop, scrollHeight, clientHeight } = e.currentTarget; |  | ||||||
| 
 |  | ||||||
|     if (scrollHeight - (scrollTop + 100) < clientHeight) { |  | ||||||
|       loadMore(); |  | ||||||
|     } |  | ||||||
|   }; |  | ||||||
|   console.log(ticketsList); |  | ||||||
|   return ( |   return ( | ||||||
|     <ul style={{backgroundColor: "#55A5DC3F", height:"100vh",marginTop:"16px"}}> |     <ul style={{ backgroundColor: "#55A5DC3F", height: "100vh", marginTop: "16px" }}> | ||||||
|       {ticketsList && |       {ticketsList.map((ticket) => ( | ||||||
|         ticketsList.map((ticket) => <TicketListItem tickets={ticket} key={ticket.id} />)} |         <TicketListItem tickets={ticket} status={status} key={ticket.id} /> | ||||||
|  |       ))} | ||||||
|     </ul> |     </ul> | ||||||
|   ); |   ); | ||||||
| }; | }; | ||||||
|  | @ -5,12 +5,12 @@ import { makeStyles } from "@material-ui/core/styles"; | ||||||
| import List from "@material-ui/core/List"; | import List from "@material-ui/core/List"; | ||||||
| import Paper from "@material-ui/core/Paper"; | import Paper from "@material-ui/core/Paper"; | ||||||
| 
 | 
 | ||||||
| import TicketListItem from "../TicketListItem"; | import TicketListItem from "../../../TicketListItem"; | ||||||
| import TicketsListSkeleton from "../TicketsListSkeleton"; | import TicketsListSkeleton from "../../../TicketsListSkeleton"; | ||||||
| 
 | 
 | ||||||
| import useTickets from "../../hooks/useTickets"; | import useTickets from "../../../../hooks/useTickets"; | ||||||
| import { i18n } from "../../translate/i18n"; | import { i18n } from "../../../../translate/i18n"; | ||||||
| import { AuthContext } from "../../context/Auth/AuthContext"; | import { AuthContext } from "../../../../context/Auth/AuthContext"; | ||||||
| 
 | 
 | ||||||
| const useStyles = makeStyles(theme => ({ | const useStyles = makeStyles(theme => ({ | ||||||
| 	ticketsListWrapper: { | 	ticketsListWrapper: { | ||||||
|  | @ -74,8 +74,6 @@ const useStyles = makeStyles(theme => ({ | ||||||
| const reducer = (state, action) => { | const reducer = (state, action) => { | ||||||
| 	if (action.type === "LOAD_TICKETS") { | 	if (action.type === "LOAD_TICKETS") { | ||||||
| 		const newTickets = action.payload;  | 		const newTickets = action.payload;  | ||||||
| 	 |  | ||||||
| 	  |  | ||||||
| 		newTickets.forEach(ticket => { | 		newTickets.forEach(ticket => { | ||||||
| 
 | 
 | ||||||
| 			// console.log('* ticket.unreadMessages: ',ticket.unreadMessages)
 | 			// console.log('* ticket.unreadMessages: ',ticket.unreadMessages)
 | ||||||
|  | @ -2,10 +2,11 @@ import React from "react"; | ||||||
| 
 | 
 | ||||||
| import TicketsManagerStyled from "./TicketsManager.style"; | import TicketsManagerStyled from "./TicketsManager.style"; | ||||||
| import TicketsTabs from "./TicketsTabs/TicketsTabs"; | import TicketsTabs from "./TicketsTabs/TicketsTabs"; | ||||||
| import TicketsList from "../../TicketsList/TicketsList"; | import TicketsList from "./TicketsList/TicketsList"; | ||||||
| import NewTicketModal from "../../NewTicketModal"; | import NewTicketModal from "../../NewTicketModal"; | ||||||
| 
 | 
 | ||||||
| import { AuthContext } from "../../../context/Auth/AuthContext"; | import { AuthContext } from "../../../context/Auth/AuthContext"; | ||||||
|  | import TicketSearch from "../TicketSearch/TicketSearch"; | ||||||
| 
 | 
 | ||||||
| const TicketsManager = () => { | const TicketsManager = () => { | ||||||
|   const [valueTab, setValueTab] = React.useState("open"); |   const [valueTab, setValueTab] = React.useState("open"); | ||||||
|  | @ -39,18 +40,13 @@ const TicketsManager = () => { | ||||||
|       setShowAllTickets(true); |       setShowAllTickets(true); | ||||||
|     } |     } | ||||||
|   }, [user.profile]); |   }, [user.profile]); | ||||||
| 
 |  | ||||||
|   return ( |   return ( | ||||||
|     <TicketsManagerStyled> |     <TicketsManagerStyled> | ||||||
|       <TicketsTabs setValueTab={setValueTab} valueTab={valueTab} /> |  | ||||||
|       {/*Input and add new call*/} |  | ||||||
|       <div style={{ display: "flex", flexDirection: "row", justifyContent: "center" }}> |  | ||||||
|         <input type="text" style={{ width: "100%", margin: "0 6px" }} onChange={handleSearch} /> |  | ||||||
|         <button onClick={() => setNewTicketModalOpen(true)}>+</button> |  | ||||||
|       </div> |  | ||||||
|       {/*Input and add new call*/} |  | ||||||
|   |   | ||||||
|  |       <TicketsTabs setValueTab={setValueTab} valueTab={valueTab} /> | ||||||
|  |       <TicketSearch handleSearch={handleSearch} setNewTicketModalOpen={setNewTicketModalOpen}/> | ||||||
|       <TicketsList |       <TicketsList | ||||||
|  |         showAll={showAllTickets} | ||||||
|         status={valueTab} |         status={valueTab} | ||||||
|         selectedQueueIds={selectedQueueIds} |         selectedQueueIds={selectedQueueIds} | ||||||
|         searchParam={searchParam} |         searchParam={searchParam} | ||||||
|  |  | ||||||
|  | @ -2,6 +2,7 @@ import styled from "styled-components"; | ||||||
| import {color} from "../../../style/varibles" | import {color} from "../../../style/varibles" | ||||||
| 
 | 
 | ||||||
| const TicketsManagerStyled = styled.div` | const TicketsManagerStyled = styled.div` | ||||||
|  | background-color: ${color.complement.azulOscuro}; | ||||||
|   display:flex; |   display:flex; | ||||||
|   flex-direction: column; |   flex-direction: column; | ||||||
|   width: 100%; |   width: 100%; | ||||||
|  |  | ||||||
|  | @ -5,6 +5,7 @@ export const TicketsTabStyled = styled.li` | ||||||
|   width: 100%; |   width: 100%; | ||||||
|   position: relative; |   position: relative; | ||||||
|   cursor: pointer; |   cursor: pointer; | ||||||
|  |   background-color: ${color.complement.azulOscuro}; | ||||||
|   color: ${color.pricinpal.blanco}; |   color: ${color.pricinpal.blanco}; | ||||||
|   font-size: 0.9rem; |   font-size: 0.9rem; | ||||||
|   text-transform: uppercase; |   text-transform: uppercase; | ||||||
|  |  | ||||||
|  | @ -8,7 +8,7 @@ const TicketsTabs = ({ setValueTab, valueTab }) => { | ||||||
|   return ( |   return ( | ||||||
|     <TicketTabsStyled> |     <TicketTabsStyled> | ||||||
|       <TicketsTab text="Aberto" id="open" setValueTab={setValueTab} valueTab={valueTab} /> |       <TicketsTab text="Aberto" id="open" setValueTab={setValueTab} valueTab={valueTab} /> | ||||||
|       <TicketsTab text="Pendente" id="pending" setValueTab={setValueTab} valueTab={valueTab} /> |       <TicketsTab text="Aguardando" id="pending" setValueTab={setValueTab} valueTab={valueTab} /> | ||||||
|       <TicketsTab text="Fechado" id="closed" setValueTab={setValueTab} valueTab={valueTab} /> |       <TicketsTab text="Fechado" id="closed" setValueTab={setValueTab} valueTab={valueTab} /> | ||||||
|     </TicketTabsStyled> |     </TicketTabsStyled> | ||||||
|   ); |   ); | ||||||
|  |  | ||||||
|  | @ -13,14 +13,14 @@ import FormControlLabel from "@material-ui/core/FormControlLabel"; | ||||||
| import Switch from "@material-ui/core/Switch"; | import Switch from "@material-ui/core/Switch"; | ||||||
| import { Button } from "@material-ui/core"; | import { Button } from "@material-ui/core"; | ||||||
| 
 | 
 | ||||||
| import NewTicketModal from "../NewTicketModal"; | import NewTicketModal from "../../NewTicketModal/index"; | ||||||
| import TicketsList from "../TicketsList"; | import TicketsList from "../../TicketsList"; | ||||||
| import TabPanel from "../TabPanel"; | import TabPanel from "../../TabPanel"; | ||||||
| 
 | 
 | ||||||
| import { i18n } from "../../translate/i18n"; | import { i18n } from "../../../translate/i18n"; | ||||||
| import { AuthContext } from "../../context/Auth/AuthContext"; | import { AuthContext } from "../../../context/Auth/AuthContext"; | ||||||
| import { Can } from "../Can"; | import { Can } from "../../Can"; | ||||||
| import TicketsQueueSelect from "../TicketsQueueSelect"; | import TicketsQueueSelect from "../../TicketsQueueSelect"; | ||||||
| 
 | 
 | ||||||
| const useStyles = makeStyles((theme) => ({ | const useStyles = makeStyles((theme) => ({ | ||||||
|   ticketsWrapper: { |   ticketsWrapper: { | ||||||
|  |  | ||||||
|  | @ -1,31 +0,0 @@ | ||||||
| import styled from "styled-components"; |  | ||||||
| import { color } from "../../style/varibles"; |  | ||||||
| 
 |  | ||||||
| export const TicketListItemStyled = styled.li` |  | ||||||
|   background-color: ${color.pricinpal.grisOscuro}; |  | ||||||
|   display: flex; |  | ||||||
|   align-items: center; |  | ||||||
|   padding: 0.5rem 6px; |  | ||||||
|   border-bottom: 1.5px solid ${color.gradient.border}; |  | ||||||
|   &:nth-child(1){ |  | ||||||
|     margin-top: 6px; |  | ||||||
|   } |  | ||||||
| `; |  | ||||||
| 
 |  | ||||||
| export const TicketTitleStyled = styled.div` |  | ||||||
|   display: flex; |  | ||||||
|   flex-direction: column; |  | ||||||
|   flex-grow: 1; |  | ||||||
| `; |  | ||||||
| export const TicketDateStyled = styled.div` |  | ||||||
|   display: block; |  | ||||||
|   color: white; |  | ||||||
| `; |  | ||||||
| 
 |  | ||||||
| export const TicketImgStyled = styled.img` |  | ||||||
|   width: 40px; |  | ||||||
|   height: 40px; |  | ||||||
|   object-fit: contain; |  | ||||||
|   border-radius: 50%; |  | ||||||
| `; |  | ||||||
| 
 |  | ||||||
|  | @ -4,7 +4,7 @@ import { useParams } from "react-router-dom"; | ||||||
| import TicketsStyled from "./Tickets.style"; | import TicketsStyled from "./Tickets.style"; | ||||||
| 
 | 
 | ||||||
| import TicketsManager from "../../components/Ticket/TicketsManager/TicketsManager"; | import TicketsManager from "../../components/Ticket/TicketsManager/TicketsManager"; | ||||||
| import Ticket from "../../components/Ticket/"; | import Ticket from "../../components/Ticket/Ticket"; | ||||||
| 
 | 
 | ||||||
| const Tickets = () => { | const Tickets = () => { | ||||||
|   const { ticketId } = useParams(); |   const { ticketId } = useParams(); | ||||||
|  |  | ||||||
|  | @ -4,7 +4,7 @@ import Grid from "@material-ui/core/Grid"; | ||||||
| import Paper from "@material-ui/core/Paper"; | import Paper from "@material-ui/core/Paper"; | ||||||
| import { makeStyles } from "@material-ui/core/styles"; | import { makeStyles } from "@material-ui/core/styles"; | ||||||
| 
 | 
 | ||||||
| import TicketsManager from "../../components/TicketsManager/"; | import TicketsManager from "../../components/Ticket/TicketsManager/index"; | ||||||
| import Ticket from "../../components/Ticket/"; | import Ticket from "../../components/Ticket/"; | ||||||
| 
 | 
 | ||||||
| import { i18n } from "../../translate/i18n"; | import { i18n } from "../../translate/i18n"; | ||||||
|  |  | ||||||
|  | @ -53,6 +53,7 @@ export const color = { | ||||||
|     bgOpacity: "#212f3cd7", |     bgOpacity: "#212f3cd7", | ||||||
|     placeholder: "#ffffff83", |     placeholder: "#ffffff83", | ||||||
|     border: "#55A5DC3F", |     border: "#55A5DC3F", | ||||||
|  |     text: "#AEBAC1", | ||||||
|   }, |   }, | ||||||
|   shadow: { |   shadow: { | ||||||
|     dark: "2px 2px 4px 2px", |     dark: "2px 2px 4px 2px", | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue