git commit -m "feat: Implement online/offline status handling and enhance ticket creation"
parent
605e4035b9
commit
52619bfd26
|
@ -8,18 +8,19 @@ import ShowContactService from "../services/ContactServices/ShowContactService";
|
|||
import UpdateContactService from "../services/ContactServices/UpdateContactService";
|
||||
import DeleteContactService from "../services/ContactServices/DeleteContactService";
|
||||
|
||||
import CheckContactNumber from "../services/WbotServices/CheckNumber"
|
||||
import CheckContactNumber from "../services/WbotServices/CheckNumber";
|
||||
import CheckIsValidContact from "../services/WbotServices/CheckIsValidContact";
|
||||
import GetProfilePicUrl from "../services/WbotServices/GetProfilePicUrl";
|
||||
import AppError from "../errors/AppError";
|
||||
|
||||
|
||||
import { searchContactCache, insertContactsCache, escapeCharCache } from '../helpers/ContactsCache'
|
||||
import {
|
||||
searchContactCache,
|
||||
insertContactsCache,
|
||||
escapeCharCache
|
||||
} from "../helpers/ContactsCache";
|
||||
|
||||
import { off } from "process";
|
||||
|
||||
|
||||
|
||||
type IndexQuery = {
|
||||
searchParam: string;
|
||||
pageNumber: string;
|
||||
|
@ -39,42 +40,46 @@ interface ContactData {
|
|||
export const index = async (req: Request, res: Response): Promise<Response> => {
|
||||
let { searchParam, pageNumber } = req.query as IndexQuery;
|
||||
|
||||
console.log('PAGE NUMBER CONTACT: ', pageNumber)
|
||||
console.log("PAGE NUMBER CONTACT: ", pageNumber);
|
||||
|
||||
if (pageNumber === undefined || pageNumber.trim().length == 0) {
|
||||
pageNumber = '1'
|
||||
pageNumber = "1";
|
||||
}
|
||||
|
||||
// TEST DEL
|
||||
if (searchParam && searchParam.trim().length > 0 && process.env.CACHE) {
|
||||
|
||||
try {
|
||||
|
||||
const offset = 20 * (+pageNumber - 1);
|
||||
|
||||
searchParam = searchParam.replace(/\s+/g, ' ').trim().toLowerCase();
|
||||
searchParam = searchParam.replace(/\s+/g, " ").trim().toLowerCase();
|
||||
|
||||
const data = await searchContactCache(searchParam, offset, 20)
|
||||
const data = await searchContactCache(searchParam, offset, 20);
|
||||
|
||||
if (data) {
|
||||
console.log("QUERY CONTACTS FROM CACHE SEARCH PARAM: ", searchParam);
|
||||
|
||||
console.log('QUERY CONTACTS FROM CACHE SEARCH PARAM: ', searchParam)
|
||||
console.log("QUERY CONTACTS FROM CACHE QUERY LENGTH: ", data.length);
|
||||
|
||||
console.log('QUERY CONTACTS FROM CACHE QUERY LENGTH: ', data.length)
|
||||
|
||||
return res.json({ contacts: data, count: data.length, hasMore: data.length > 0 ? true : false });
|
||||
return res.json({
|
||||
contacts: data,
|
||||
count: data.length,
|
||||
hasMore: data.length > 0 ? true : false
|
||||
});
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.log('There was an error on search ContactController.ts search cache: ', error)
|
||||
console.log(
|
||||
"There was an error on search ContactController.ts search cache: ",
|
||||
error
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
console.log('QUERY CONTACTS FROM DATABASE SEARCH PARAM: ', searchParam)
|
||||
console.log("QUERY CONTACTS FROM DATABASE SEARCH PARAM: ", searchParam);
|
||||
|
||||
const { contacts, count, hasMore } = await ListContactsService({ searchParam, pageNumber });
|
||||
const { contacts, count, hasMore } = await ListContactsService({
|
||||
searchParam,
|
||||
pageNumber
|
||||
});
|
||||
|
||||
return res.json({ contacts, count, hasMore });
|
||||
};
|
||||
|
@ -83,6 +88,8 @@ export const store = async (req: Request, res: Response): Promise<Response> => {
|
|||
const newContact: ContactData = req.body;
|
||||
newContact.number = newContact.number.replace("-", "").replace(" ", "");
|
||||
|
||||
throw new AppError("ERR_NO_ADD_CONTACT");
|
||||
|
||||
const schema = Yup.object().shape({
|
||||
name: Yup.string().required(),
|
||||
number: Yup.string()
|
||||
|
@ -109,25 +116,24 @@ export const store = async (req: Request, res: Response): Promise<Response> => {
|
|||
|
||||
const profilePicUrl = await GetProfilePicUrl(validNumber);
|
||||
|
||||
console.log('xxxxxxxxxxx profilePicUrl: ', profilePicUrl)
|
||||
|
||||
console.log("xxxxxxxxxxx profilePicUrl: ", profilePicUrl);
|
||||
|
||||
// console.log(`newContact.name: ${newContact.name}\n
|
||||
// newContact.number: ${newContact.number}\n
|
||||
// newContact.email: ${newContact.email}\n
|
||||
// newContact.extraInfo: ${newContact.extraInfo}`)
|
||||
|
||||
let name = newContact.name
|
||||
let number = validNumber
|
||||
let email = newContact.email
|
||||
let extraInfo = newContact.extraInfo
|
||||
let name = newContact.name;
|
||||
let number = validNumber;
|
||||
let email = newContact.email;
|
||||
let extraInfo = newContact.extraInfo;
|
||||
|
||||
const contact = await CreateContactService({
|
||||
name,
|
||||
number,
|
||||
email,
|
||||
profilePicUrl: profilePicUrl,
|
||||
extraInfo,
|
||||
extraInfo
|
||||
});
|
||||
|
||||
const io = getIO();
|
||||
|
@ -155,8 +161,10 @@ export const update = async (
|
|||
|
||||
const schema = Yup.object().shape({
|
||||
name: Yup.string(),
|
||||
number: Yup.string()
|
||||
.matches(/^\d+$/, "Invalid number format. Only numbers is allowed.")
|
||||
number: Yup.string().matches(
|
||||
/^\d+$/,
|
||||
"Invalid number format. Only numbers is allowed."
|
||||
)
|
||||
// .matches(/^55\d+$/, "The number must start with 55.")
|
||||
});
|
||||
|
||||
|
@ -200,13 +208,14 @@ export const remove = async (
|
|||
return res.status(200).json({ message: "Contact deleted" });
|
||||
};
|
||||
|
||||
|
||||
|
||||
export const contacsBulkInsertOnQueue = async (req: Request, res: Response): Promise<Response> => {
|
||||
|
||||
export const contacsBulkInsertOnQueue = async (
|
||||
req: Request,
|
||||
res: Response
|
||||
): Promise<Response> => {
|
||||
// console.log('THE BODY: ', req.body)
|
||||
|
||||
const { adminId, identifier, queueStatus, file, contacts_inserted } = req.body
|
||||
const { adminId, identifier, queueStatus, file, contacts_inserted } =
|
||||
req.body;
|
||||
|
||||
const io = getIO();
|
||||
io.emit("contactsBulkInsertOnQueueStatus", {
|
||||
|
@ -219,24 +228,19 @@ export const contacsBulkInsertOnQueue = async (req: Request, res: Response): Pro
|
|||
}
|
||||
});
|
||||
|
||||
|
||||
if (process.env.CACHE && contacts_inserted) {
|
||||
|
||||
await insertContactsCache(contacts_inserted)
|
||||
|
||||
await insertContactsCache(contacts_inserted);
|
||||
}
|
||||
|
||||
return res.status(200).json({ message: 'ok' })
|
||||
return res.status(200).json({ message: "ok" });
|
||||
};
|
||||
|
||||
function addStartPhoneNumber(phoneNumber: string) {
|
||||
|
||||
const regex = /^55/;
|
||||
|
||||
if (!regex.test(phoneNumber)) {
|
||||
phoneNumber = '55' + phoneNumber;
|
||||
phoneNumber = "55" + phoneNumber;
|
||||
}
|
||||
|
||||
return phoneNumber
|
||||
return phoneNumber;
|
||||
}
|
||||
|
||||
|
|
|
@ -5,6 +5,8 @@ import AuthUserService from "../services/UserServices/AuthUserService";
|
|||
import { SendRefreshToken } from "../helpers/SendRefreshToken";
|
||||
import { RefreshTokenService } from "../services/AuthServices/RefreshTokenService";
|
||||
|
||||
import createOrUpdateOnlineUserService from "../services/UserServices/CreateOrUpdateOnlineUserService";
|
||||
|
||||
export const store = async (req: Request, res: Response): Promise<Response> => {
|
||||
const { email, password } = req.body;
|
||||
|
||||
|
@ -13,6 +15,13 @@ export const store = async (req: Request, res: Response): Promise<Response> => {
|
|||
password
|
||||
});
|
||||
|
||||
console.log("serializedUser.id: ", serializedUser.id);
|
||||
|
||||
const userOnline = await createOrUpdateOnlineUserService({
|
||||
userId: serializedUser.id,
|
||||
status: "online"
|
||||
});
|
||||
|
||||
SendRefreshToken(res, refreshToken);
|
||||
|
||||
return res.status(200).json({
|
||||
|
@ -47,5 +56,11 @@ export const remove = async (
|
|||
): Promise<Response> => {
|
||||
res.clearCookie("jrt");
|
||||
|
||||
const { userId } = req.params;
|
||||
|
||||
const userOnline = await createOrUpdateOnlineUserService({
|
||||
userId,
|
||||
status: "offline"
|
||||
});
|
||||
return res.send();
|
||||
};
|
||||
|
|
|
@ -108,7 +108,7 @@ const monitor = async () => {
|
|||
el.onlineTime = userOnline.onlineTime
|
||||
el.updatedAt = userOnline.updatedAt,
|
||||
|
||||
console.log(' * CREATED OR UPDATED USER TO ONLINE: ', userOnline.userId)
|
||||
console.log('* CREATED OR UPDATED USER TO ONLINE: ', userOnline.userId)
|
||||
|
||||
lstOnline.push({ 'id': el.id, 'status': 'online' })
|
||||
}
|
||||
|
|
|
@ -47,12 +47,6 @@ export const initIO = (httpServer: Server): SocketIO => {
|
|||
io.on("connection", socket => {
|
||||
logger.info("Client Connected");
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
socket.on("joinWhatsSession", (whatsappId: string) => {
|
||||
logger.info(`A client joined a joinWhatsSession channel: ${whatsappId}`);
|
||||
socket.join(`session_${whatsappId}`);
|
||||
|
@ -82,15 +76,6 @@ export const initIO = (httpServer: Server): SocketIO => {
|
|||
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
socket.on("online", (userId: any) => {
|
||||
|
||||
// console.log('userId: ', userId)
|
||||
|
@ -179,6 +164,8 @@ export const initIO = (httpServer: Server): SocketIO => {
|
|||
|
||||
e.try += 1
|
||||
|
||||
console.log("try.......: ", e.try);
|
||||
|
||||
if (e.try > 1) {
|
||||
e.status = 'waiting...'
|
||||
}
|
||||
|
|
|
@ -11,6 +11,6 @@ authRoutes.post("/login", SessionController.store);
|
|||
|
||||
authRoutes.post("/refresh_token", SessionController.update);
|
||||
|
||||
authRoutes.delete("/logout", isAuth, SessionController.remove);
|
||||
authRoutes.delete("/logout/:userId", isAuth, SessionController.remove);
|
||||
|
||||
export default authRoutes;
|
||||
|
|
|
@ -1,26 +1,26 @@
|
|||
import React, { useState, useEffect, useRef } from "react";
|
||||
import React, { useState, useEffect, useRef } from "react"
|
||||
|
||||
import * as Yup from "yup";
|
||||
import { Formik, FieldArray, Form, Field } from "formik";
|
||||
import { toast } from "react-toastify";
|
||||
import * as Yup from "yup"
|
||||
import { Formik, FieldArray, Form, Field } from "formik"
|
||||
import { toast } from "react-toastify"
|
||||
|
||||
import { makeStyles } from "@material-ui/core/styles";
|
||||
import { green } from "@material-ui/core/colors";
|
||||
import Button from "@material-ui/core/Button";
|
||||
import TextField from "@material-ui/core/TextField";
|
||||
import Dialog from "@material-ui/core/Dialog";
|
||||
import DialogActions from "@material-ui/core/DialogActions";
|
||||
import DialogContent from "@material-ui/core/DialogContent";
|
||||
import DialogTitle from "@material-ui/core/DialogTitle";
|
||||
import Typography from "@material-ui/core/Typography";
|
||||
import IconButton from "@material-ui/core/IconButton";
|
||||
import DeleteOutlineIcon from "@material-ui/icons/DeleteOutline";
|
||||
import CircularProgress from "@material-ui/core/CircularProgress";
|
||||
import { makeStyles } from "@material-ui/core/styles"
|
||||
import { green } from "@material-ui/core/colors"
|
||||
import Button from "@material-ui/core/Button"
|
||||
import TextField from "@material-ui/core/TextField"
|
||||
import Dialog from "@material-ui/core/Dialog"
|
||||
import DialogActions from "@material-ui/core/DialogActions"
|
||||
import DialogContent from "@material-ui/core/DialogContent"
|
||||
import DialogTitle from "@material-ui/core/DialogTitle"
|
||||
import Typography from "@material-ui/core/Typography"
|
||||
import IconButton from "@material-ui/core/IconButton"
|
||||
import DeleteOutlineIcon from "@material-ui/icons/DeleteOutline"
|
||||
import CircularProgress from "@material-ui/core/CircularProgress"
|
||||
|
||||
import { i18n } from "../../translate/i18n";
|
||||
import { i18n } from "../../translate/i18n"
|
||||
|
||||
import api from "../../services/api";
|
||||
import toastError from "../../errors/toastError";
|
||||
import api from "../../services/api"
|
||||
import toastError from "../../errors/toastError"
|
||||
|
||||
const useStyles = makeStyles(theme => ({
|
||||
root: {
|
||||
|
@ -50,7 +50,7 @@ const useStyles = makeStyles(theme => ({
|
|||
marginTop: -12,
|
||||
marginLeft: -12,
|
||||
},
|
||||
}));
|
||||
}))
|
||||
|
||||
const ContactSchema = Yup.object().shape({
|
||||
name: Yup.string()
|
||||
|
@ -63,29 +63,29 @@ const ContactSchema = Yup.object().shape({
|
|||
.max(50, "Too Long!"),
|
||||
|
||||
// email: Yup.string().email("Invalid email"),
|
||||
});
|
||||
})
|
||||
|
||||
|
||||
|
||||
const ContactModal = ({ open, onClose, contactId, initialValues, onSave }) => {
|
||||
const classes = useStyles();
|
||||
const isMounted = useRef(true);
|
||||
const classes = useStyles()
|
||||
const isMounted = useRef(true)
|
||||
|
||||
const initialState = {
|
||||
name: "",
|
||||
number: "",
|
||||
email: "",
|
||||
};
|
||||
}
|
||||
|
||||
const [contact, setContact] = useState(initialState);
|
||||
const [contact, setContact] = useState(initialState)
|
||||
const [phone, setPhone] = useState('')
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
isMounted.current = false;
|
||||
};
|
||||
}, []);
|
||||
isMounted.current = false
|
||||
}
|
||||
}, [])
|
||||
|
||||
// useEffect(() => {
|
||||
// console.log('1 Contact: ', contact)
|
||||
|
@ -103,64 +103,66 @@ const ContactModal = ({ open, onClose, contactId, initialValues, onSave }) => {
|
|||
const fetchContact = async () => {
|
||||
if (initialValues) {
|
||||
|
||||
if (initialValues?.number)
|
||||
setPhone(initialValues.number)
|
||||
|
||||
setContact(prevState => {
|
||||
return { ...prevState, ...initialValues };
|
||||
});
|
||||
return { ...prevState, ...initialValues }
|
||||
})
|
||||
}
|
||||
|
||||
if (!contactId) return;
|
||||
if (!contactId) return
|
||||
|
||||
try {
|
||||
const { data } = await api.get(`/contacts/${contactId}`);
|
||||
const { data } = await api.get(`/contacts/${contactId}`)
|
||||
|
||||
if (isMounted.current) {
|
||||
|
||||
setPhone(data.number)
|
||||
|
||||
setContact(data);
|
||||
setContact(data)
|
||||
}
|
||||
|
||||
} catch (err) {
|
||||
toastError(err);
|
||||
toastError(err)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
fetchContact();
|
||||
}, [contactId, open, initialValues]);
|
||||
fetchContact()
|
||||
}, [contactId, open, initialValues])
|
||||
|
||||
const handleClose = () => {
|
||||
onClose();
|
||||
setContact(initialState);
|
||||
};
|
||||
onClose()
|
||||
console.log('INITIAL STATE: ', initialState)
|
||||
setContact(initialState)
|
||||
}
|
||||
|
||||
const handleSaveContact = async values => {
|
||||
|
||||
values = { ...values, number: phone };
|
||||
|
||||
console.log('submit values', values)
|
||||
values = { ...values, number: phone }
|
||||
|
||||
try {
|
||||
if (contactId) {
|
||||
await api.put(`/contacts/${contactId}`, values);
|
||||
handleClose();
|
||||
await api.put(`/contacts/${contactId}`, values)
|
||||
handleClose()
|
||||
} else {
|
||||
const { data } = await api.post("/contacts", values);
|
||||
const { data } = await api.post("/contacts", values)
|
||||
if (onSave) {
|
||||
onSave(data);
|
||||
onSave(data)
|
||||
}
|
||||
handleClose();
|
||||
handleClose()
|
||||
}
|
||||
toast.success(i18n.t("contactModal.success"));
|
||||
toast.success(i18n.t("contactModal.success"))
|
||||
} catch (err) {
|
||||
toastError(err);
|
||||
toastError(err)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
const handleChange = (event) => {
|
||||
|
||||
const regex = /^[0-9\b]+$/; // Regular expression to match only numbers
|
||||
const regex = /^[0-9\b]+$/ // Regular expression to match only numbers
|
||||
|
||||
setPhone(event.target.value);
|
||||
setPhone(event.target.value)
|
||||
|
||||
setTimeout(() => {
|
||||
|
||||
|
@ -174,9 +176,9 @@ const ContactModal = ({ open, onClose, contactId, initialValues, onSave }) => {
|
|||
|
||||
setPhone(newValue)
|
||||
|
||||
}, 100);
|
||||
}, 100)
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={classes.root}>
|
||||
|
@ -192,12 +194,12 @@ const ContactModal = ({ open, onClose, contactId, initialValues, onSave }) => {
|
|||
validationSchema={ContactSchema}
|
||||
onSubmit={(values, actions) => {
|
||||
setTimeout(() => {
|
||||
handleSaveContact(values);
|
||||
actions.setSubmitting(false);
|
||||
}, 400);
|
||||
handleSaveContact(values)
|
||||
actions.setSubmitting(false)
|
||||
}, 400)
|
||||
}}
|
||||
>
|
||||
{({ values, errors, touched, isSubmitting }) => (
|
||||
{({ values, errors, touched, isSubmitting, resetForm }) => (
|
||||
<Form>
|
||||
<DialogContent dividers>
|
||||
<Typography variant="subtitle1" gutterBottom>
|
||||
|
@ -298,7 +300,9 @@ const ContactModal = ({ open, onClose, contactId, initialValues, onSave }) => {
|
|||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button
|
||||
onClick={handleClose}
|
||||
onClick={()=>{
|
||||
handleClose()
|
||||
}}
|
||||
color="secondary"
|
||||
disabled={isSubmitting}
|
||||
variant="outlined"
|
||||
|
@ -328,7 +332,7 @@ const ContactModal = ({ open, onClose, contactId, initialValues, onSave }) => {
|
|||
</Formik>
|
||||
</Dialog>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
)
|
||||
}
|
||||
|
||||
export default ContactModal;
|
||||
export default ContactModal
|
||||
|
|
|
@ -1,256 +1,154 @@
|
|||
import React, { useState, useEffect, useContext } from "react";
|
||||
import { useHistory } from "react-router-dom";
|
||||
import React, { useState, useEffect, useContext } from "react"
|
||||
import { useHistory } from "react-router-dom"
|
||||
|
||||
import Button from "@material-ui/core/Button";
|
||||
import TextField from "@material-ui/core/TextField";
|
||||
import Dialog from "@material-ui/core/Dialog";
|
||||
import Button from "@material-ui/core/Button"
|
||||
import TextField from "@material-ui/core/TextField"
|
||||
import Dialog from "@material-ui/core/Dialog"
|
||||
|
||||
import DialogActions from "@material-ui/core/DialogActions";
|
||||
import DialogContent from "@material-ui/core/DialogContent";
|
||||
import DialogTitle from "@material-ui/core/DialogTitle";
|
||||
// import Autocomplete, {
|
||||
// createFilterOptions,
|
||||
// } from "@material-ui/lab/Autocomplete";
|
||||
// import CircularProgress from "@material-ui/core/CircularProgress";
|
||||
import DialogActions from "@material-ui/core/DialogActions"
|
||||
import DialogContent from "@material-ui/core/DialogContent"
|
||||
import DialogTitle from "@material-ui/core/DialogTitle"
|
||||
import Autocomplete, {
|
||||
createFilterOptions,
|
||||
} from "@material-ui/lab/Autocomplete"
|
||||
import CircularProgress from "@material-ui/core/CircularProgress"
|
||||
|
||||
import { i18n } from "../../translate/i18n";
|
||||
import api from "../../services/api";
|
||||
import ButtonWithSpinner from "../ButtonWithSpinner";
|
||||
import ContactModal from "../ContactModal";
|
||||
import toastError from "../../errors/toastError";
|
||||
import { AuthContext } from "../../context/Auth/AuthContext";
|
||||
import { i18n } from "../../translate/i18n"
|
||||
import api from "../../services/api"
|
||||
import ButtonWithSpinner from "../ButtonWithSpinner"
|
||||
import ContactModal from "../ContactModal"
|
||||
import toastError from "../../errors/toastError"
|
||||
import { AuthContext } from "../../context/Auth/AuthContext"
|
||||
|
||||
// const filter = createFilterOptions({
|
||||
// trim: true,
|
||||
// });
|
||||
const filter = createFilterOptions({
|
||||
trim: true,
|
||||
})
|
||||
|
||||
const NewTicketModal = ({ modalOpen, onClose }) => {
|
||||
const history = useHistory();
|
||||
const history = useHistory()
|
||||
|
||||
// const [options, setOptions] = useState([]);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [searchParam, setSearchParam] = useState("");
|
||||
const [selectedContact, setSelectedContact] = useState(null);
|
||||
// const [newContact, setNewContact] = useState({});
|
||||
const [contactModalOpen, setContactModalOpen] = useState(false);
|
||||
const { user } = useContext(AuthContext);
|
||||
const [options, setOptions] = useState([])
|
||||
const [loading, setLoading] = useState(false)
|
||||
const [searchParam, setSearchParam] = useState("")
|
||||
const [selectedContact, setSelectedContact] = useState(null)
|
||||
const [newContact, setNewContact] = useState({})
|
||||
const [contactModalOpen, setContactModalOpen] = useState(false)
|
||||
const { user } = useContext(AuthContext)
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
|
||||
const regex = /^[0-9\b]+$/; // Regular expression to match only numbers
|
||||
if (searchParam && !searchParam.match(regex)) return
|
||||
|
||||
if (searchParam && searchParam.length > 9) {
|
||||
setSelectedContact({})
|
||||
}
|
||||
else {
|
||||
setSelectedContact(null)
|
||||
if (!modalOpen || searchParam.length < 3) {
|
||||
setLoading(false)
|
||||
return
|
||||
}
|
||||
setLoading(true)
|
||||
const delayDebounceFn = setTimeout(() => {
|
||||
const fetchContacts = async () => {
|
||||
try {
|
||||
const { data } = await api.get("contacts", {
|
||||
params: { searchParam },
|
||||
})
|
||||
setOptions(data.contacts)
|
||||
setLoading(false)
|
||||
} catch (err) {
|
||||
setLoading(false)
|
||||
toastError(err)
|
||||
}
|
||||
}
|
||||
|
||||
if (!modalOpen || searchParam.length < 5) {
|
||||
setLoading(false);
|
||||
return;
|
||||
}
|
||||
// setLoading(true);
|
||||
// const delayDebounceFn = setTimeout(() => {
|
||||
// const fetchContacts = async () => {
|
||||
// try {
|
||||
// const { data } = await api.get("contacts", {
|
||||
// params: { searchParam },
|
||||
// });
|
||||
|
||||
// // console.log('data.contacts: ', data.contacts)
|
||||
|
||||
// setOptions(data.contacts);
|
||||
// setLoading(false);
|
||||
// } catch (err) {
|
||||
// setLoading(false);
|
||||
// toastError(err);
|
||||
// }
|
||||
|
||||
// };
|
||||
|
||||
// fetchContacts();
|
||||
// }, 500);
|
||||
|
||||
// return () => clearTimeout(delayDebounceFn);
|
||||
}, [searchParam, modalOpen]);
|
||||
fetchContacts()
|
||||
}, 500)
|
||||
return () => clearTimeout(delayDebounceFn)
|
||||
}, [searchParam, modalOpen])
|
||||
|
||||
const handleClose = () => {
|
||||
onClose();
|
||||
setSearchParam("");
|
||||
setSelectedContact(null);
|
||||
};
|
||||
onClose()
|
||||
setSearchParam("")
|
||||
setSelectedContact(null)
|
||||
}
|
||||
|
||||
const handleSaveTicket = async contactId => {
|
||||
|
||||
if (!contactId) return
|
||||
setLoading(true)
|
||||
try {
|
||||
|
||||
const { data: data0 } = await api.get("/contacts/", { params: { searchParam, pageNumber: "1" }, });
|
||||
|
||||
if (data0 && data0.contacts.length > 0) {
|
||||
console.log('-----> data: ', data0.contacts[0].id)
|
||||
contactId = data0.contacts[0].id
|
||||
}
|
||||
else {
|
||||
console.log('NO CONTACT whith this searchParam: ', searchParam)
|
||||
|
||||
const values = {
|
||||
name: searchParam,
|
||||
number: searchParam,
|
||||
};
|
||||
|
||||
const { data: data1 } = await api.post("/contacts", values);
|
||||
|
||||
console.log('data1: ', data1)
|
||||
|
||||
contactId = data1.id
|
||||
|
||||
}
|
||||
|
||||
const { data: ticket } = await api.post("/tickets", {
|
||||
contactId: contactId,
|
||||
userId: user.id,
|
||||
status: "open",
|
||||
});
|
||||
|
||||
window.location.reload();
|
||||
history.push(`/tickets/${ticket.id}`);
|
||||
window.location.reload();
|
||||
|
||||
setLoading(false);
|
||||
handleClose();
|
||||
|
||||
})
|
||||
history.push(`/tickets/${ticket.id}`)
|
||||
} catch (err) {
|
||||
setLoading(false);
|
||||
toastError(err);
|
||||
toastError(err)
|
||||
}
|
||||
|
||||
|
||||
|
||||
// if (!contactId) return;
|
||||
// setLoading(true);
|
||||
// try {
|
||||
// const { data: ticket } = await api.post("/tickets", {
|
||||
// contactId: contactId,
|
||||
// userId: user.id,
|
||||
// status: "open",
|
||||
// });
|
||||
|
||||
// window.location.reload();
|
||||
// history.push(`/tickets/${ticket.id}`);
|
||||
// window.location.reload();
|
||||
|
||||
// } catch (err) {
|
||||
// toastError(err);
|
||||
// }
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
const handleChange = (number) => {
|
||||
|
||||
const regex = /^[0-9\b]+$/; // Regular expression to match only numbers
|
||||
|
||||
setSearchParam(number)
|
||||
|
||||
setTimeout(() => {
|
||||
|
||||
let newValue = ''
|
||||
|
||||
for (const char of number) {
|
||||
|
||||
// console.log('char: ', char)
|
||||
|
||||
if (char.match(regex)) {
|
||||
newValue += char
|
||||
}
|
||||
}
|
||||
|
||||
// console.log('newValue: ', newValue)
|
||||
|
||||
setSearchParam(newValue)
|
||||
|
||||
}, 30);
|
||||
|
||||
};
|
||||
|
||||
setLoading(false)
|
||||
handleClose()
|
||||
}
|
||||
|
||||
// const handleSelectOption = (e, newValue) => {
|
||||
|
||||
|
||||
// if (newValue?.number) {
|
||||
|
||||
// console.log('newValue: ', newValue)
|
||||
|
||||
// setSelectedContact(newValue);
|
||||
|
||||
// setSelectedContact(newValue)
|
||||
// } else if (newValue?.name) {
|
||||
|
||||
// // console.log('newValue?.name: ', newValue?.name)
|
||||
|
||||
// const regex = /^[0-9\b]+$/; // Regular expression to match only numbers
|
||||
|
||||
// if (newValue.name.match(regex)) {
|
||||
|
||||
// console.log('==========> newValue.name', newValue.name)
|
||||
// setNewContact({ name: newValue.name, number: newValue.name });
|
||||
|
||||
// }
|
||||
// else {
|
||||
|
||||
// setNewContact({ name: newValue.name });
|
||||
// setContactModalOpen(true);
|
||||
|
||||
// }
|
||||
|
||||
|
||||
// setNewContact({ name: newValue.name })
|
||||
// setContactModalOpen(true)
|
||||
// }
|
||||
// };
|
||||
// }
|
||||
|
||||
const handleSelectOption = (e, newValue) => {
|
||||
if (newValue?.number) {
|
||||
setSelectedContact(newValue)
|
||||
} else if (newValue?.name) {
|
||||
|
||||
if (/^-?\d+(\.\d+)?$/.test(newValue?.name)){
|
||||
setNewContact({ number: newValue.name })
|
||||
}
|
||||
else{
|
||||
setNewContact({ name: newValue.name })
|
||||
}
|
||||
|
||||
setContactModalOpen(true)
|
||||
}
|
||||
}
|
||||
|
||||
const handleCloseContactModal = () => {
|
||||
setContactModalOpen(false);
|
||||
};
|
||||
setContactModalOpen(false)
|
||||
}
|
||||
|
||||
const handleAddNewContactTicket = contact => {
|
||||
handleSaveTicket(contact.id);
|
||||
};
|
||||
handleSaveTicket(contact.id)
|
||||
}
|
||||
|
||||
// const createAddContactOption = (filterOptions, params) => {
|
||||
// const filtered = filter(filterOptions, params);
|
||||
const createAddContactOption = (filterOptions, params) => {
|
||||
const filtered = filter(filterOptions, params)
|
||||
|
||||
// if (params.inputValue !== "" && !loading && searchParam.length >= 3) {
|
||||
// filtered.push({
|
||||
// name: `${params.inputValue}`,
|
||||
// });
|
||||
// }
|
||||
if (params.inputValue !== "" && !loading && searchParam.length >= 3) {
|
||||
filtered.push({
|
||||
name: `${params.inputValue}`,
|
||||
})
|
||||
}
|
||||
|
||||
// return filtered;
|
||||
// };
|
||||
return filtered
|
||||
}
|
||||
|
||||
// const renderOption = option => {
|
||||
// if (option.number) {
|
||||
// return `${option.name} - ${option.number}`;
|
||||
// } else {
|
||||
// return `${i18n.t("newTicketModal.add")} ${option.name}`;
|
||||
// }
|
||||
// };
|
||||
const renderOption = option => {
|
||||
if (option.number) {
|
||||
return `${option.name} - ${option.number}`
|
||||
} else {
|
||||
return `${i18n.t("newTicketModal.add")} ${option.name}`
|
||||
}
|
||||
}
|
||||
|
||||
// const renderOptionLabel = option => {
|
||||
// if (option.number) {
|
||||
// return `${option.name} - ${option.number}`;
|
||||
// } else {
|
||||
// return `${option.name}`;
|
||||
// }
|
||||
// };
|
||||
const renderOptionLabel = option => {
|
||||
if (option.number) {
|
||||
return `${option.name} - ${option.number}`
|
||||
} else {
|
||||
return `${option.name}`
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<ContactModal
|
||||
open={contactModalOpen}
|
||||
// initialValues={newContact}
|
||||
initialValues={newContact}
|
||||
onClose={handleCloseContactModal}
|
||||
onSave={handleAddNewContactTicket}
|
||||
></ContactModal>
|
||||
|
@ -258,29 +156,7 @@ const NewTicketModal = ({ modalOpen, onClose }) => {
|
|||
<DialogTitle id="form-dialog-title">
|
||||
{i18n.t("newTicketModal.title")}
|
||||
</DialogTitle>
|
||||
|
||||
<DialogContent dividers>
|
||||
|
||||
<TextField
|
||||
label={i18n.t("newTicketModal.fieldLabel")}
|
||||
variant="outlined"
|
||||
autoFocus
|
||||
|
||||
value={searchParam}
|
||||
onChange={e => handleChange(e.target.value)}
|
||||
|
||||
// onChange={e => setSearchParam(e.target.value)}
|
||||
onKeyPress={e => {
|
||||
if (loading || !selectedContact) return;
|
||||
else if (e.key === "Enter") {
|
||||
handleSaveTicket(selectedContact.id);
|
||||
}
|
||||
}}
|
||||
|
||||
/>
|
||||
</DialogContent>
|
||||
|
||||
{/* <DialogContent dividers>
|
||||
<Autocomplete
|
||||
options={options}
|
||||
loading={loading}
|
||||
|
@ -301,9 +177,9 @@ const NewTicketModal = ({ modalOpen, onClose }) => {
|
|||
autoFocus
|
||||
onChange={e => setSearchParam(e.target.value)}
|
||||
onKeyPress={e => {
|
||||
if (loading || !selectedContact) return;
|
||||
if (loading || !selectedContact) return
|
||||
else if (e.key === "Enter") {
|
||||
handleSaveTicket(selectedContact.id);
|
||||
handleSaveTicket(selectedContact.id)
|
||||
}
|
||||
}}
|
||||
InputProps={{
|
||||
|
@ -320,7 +196,7 @@ const NewTicketModal = ({ modalOpen, onClose }) => {
|
|||
/>
|
||||
)}
|
||||
/>
|
||||
</DialogContent> */}
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button
|
||||
onClick={handleClose}
|
||||
|
@ -343,7 +219,7 @@ const NewTicketModal = ({ modalOpen, onClose }) => {
|
|||
</DialogActions>
|
||||
</Dialog>
|
||||
</>
|
||||
);
|
||||
};
|
||||
)
|
||||
}
|
||||
|
||||
export default NewTicketModal;
|
||||
export default NewTicketModal
|
||||
|
|
|
@ -105,8 +105,10 @@ const useAuth = () => {
|
|||
const handleLogout = async () => {
|
||||
setLoading(true);
|
||||
|
||||
console.log('USER: ', user)
|
||||
|
||||
try {
|
||||
await api.delete("/auth/logout");
|
||||
await api.delete(`/auth/logout/${user.id}`);
|
||||
setIsAuth(false);
|
||||
setUser({});
|
||||
localStorage.removeItem("token");
|
||||
|
|
|
@ -280,7 +280,7 @@ const messages = {
|
|||
},
|
||||
newTicketModal: {
|
||||
title: "Criar Ticket",
|
||||
fieldLabel: "Digite o numero para criar um ticket",
|
||||
fieldLabel: "Digite o numero/nome para criar um ticket",
|
||||
add: "Adicionar",
|
||||
buttons: {
|
||||
ok: "Salvar",
|
||||
|
@ -491,6 +491,7 @@ const messages = {
|
|||
"A criação do usuário foi desabilitada pelo administrador.",
|
||||
ERR_NO_PERMISSION: "Você não tem permissão para acessar este recurso.",
|
||||
ERR_DUPLICATED_CONTACT: "Já existe um contato com este número.",
|
||||
ERR_NO_ADD_CONTACT: "Não é permitido adicionar um novo contado na agenda.",
|
||||
ERR_NO_SETTING_FOUND: "Nenhuma configuração encontrada com este ID.",
|
||||
ERR_NO_CONTACT_FOUND: "Nenhum contato encontrado com este ID.",
|
||||
ERR_NO_TICKET_FOUND: "Nenhum tíquete encontrado com este ID.",
|
||||
|
|
Loading…
Reference in New Issue