diff --git a/src/components/Chat/Chats.jsx b/src/components/Chat/Chats.jsx index c3aa070..af8ea84 100644 --- a/src/components/Chat/Chats.jsx +++ b/src/components/Chat/Chats.jsx @@ -26,8 +26,6 @@ function Chats({ filter, userUuid, userRole, idToken }) { useChatsWebSocket(userUuid, setWebSocket, setNotification) - console.log("At the beginning dispatch", dispatch) - useEffect(() => { setIsLoading(true); fetchInitialChats().then(() => { @@ -35,25 +33,6 @@ function Chats({ filter, userUuid, userRole, idToken }) { }); }, [userUuid]); - /*DEBUG*/ - useEffect(() => { - console.log("isLoading", isLoading) - }, [isLoading]); - - useEffect(() => { - console.log("chats", chats) - }, [chats]); - - useEffect(() => { - console.log("dispatch", dispatch) - }, [dispatch]); - - useEffect(() => { - console.log("userUUID", userUuid) - }, [userUuid]); - /*END DEBUG*/ - - const handleFireClick = () => { selectChat([]); markDispatch(!dispatch); diff --git a/src/components/Profile/EditProfile/ClientTagsModal.jsx b/src/components/Profile/EditProfile/ClientTagsModal.jsx new file mode 100644 index 0000000..56a4d00 --- /dev/null +++ b/src/components/Profile/EditProfile/ClientTagsModal.jsx @@ -0,0 +1,100 @@ +import { useState, useEffect } from 'react'; +import { FaTag } from 'react-icons/fa'; +import { FaChevronDown } from "react-icons/fa"; + +const ClientTagsModal = ({ onClientTypeChange, clientTypeInitial }) => { + + console.log('clientTypeInitial al inicio', clientTypeInitial); + const [isVisible, setIsVisible] = useState(false); + const [selectedCheck, setSelectedCheck] = useState(clientTypeInitial || []); + const optionTags = [ + { label: 'Comprador frecuente', value: 'comprador_frecuente' }, + { label: 'Nuevo cliente', value: 'nuevo_cliente' }, + { label: 'Cliente VIP', value: 'cliente_vip' }, + { label: 'Carrito abandonado', value: 'carrito_abandonado' }, + { label: 'Interesado en promociones', value: 'interesado_promociones' }, + { label: 'Cliente insatisfecho', value: 'cliente_insatisfecho' }, + { label: 'Consulta sobre producto específico', value: 'consulta_producto' }, + { label: 'Consulta sobre envío', value: 'consulta_envio' }, + { label: 'Consulta sobre devolución', value: 'consulta_devolucion' }, + { label: 'Recomendación de productos', value: 'recomendacion_productos' }, + { label: 'Registro a newsletter', value: 'registro_newsletter' }, + { label: 'Consulta sobre métodos de pago', value: 'consulta_metodos_pago' }, + { label: 'Potencial cliente', value: 'potencial_cliente' }, + { label: 'Cliente de redes sociales', value: 'cliente_redes_sociales' }, + { label: 'Cliente referido', value: 'cliente_referido' }, + { label: 'Interés en categorías específicas', value: 'interes_categorias' }, + { label: 'Feedback positivo', value: 'feedback_positivo' }, + { label: 'Feedback negativo', value: 'feedback_negativo' }, + { label: 'Solicitante de información adicional', value: 'solicitante_info' }, + { label: 'Clientes con historial de devoluciones', value: 'clientes_devoluciones' } + ]; + + useEffect(() => { + onClientTypeChange(selectedCheck); + }, [selectedCheck]); + + const controlChecked = (index) => { + const tag = optionTags[index]; + const isChecked = selectedCheck.some((item) => item.value === tag.value); + + if (isChecked) { + setSelectedCheck((prevSelectedCheck) => + prevSelectedCheck.filter((item) => item.value !== tag.value) + ); + } else { + setSelectedCheck((prevSelectedCheck) => [...prevSelectedCheck, tag]); + } + } + + console.log('selectedCheck', selectedCheck); + + + const toggleVisibility = () => { + setIsVisible(!isVisible); + }; + + + return ( +
+
+ +
+ +
+
+ {isVisible && ( +
+ {optionTags.map((tag, index) => ( + + ))} +
+ )} +
+ + ) +} + +export default ClientTagsModal \ No newline at end of file diff --git a/src/components/Profile/EditProfileModal.jsx b/src/components/Profile/EditProfileModal.jsx index 5785398..a378c1b 100644 --- a/src/components/Profile/EditProfileModal.jsx +++ b/src/components/Profile/EditProfileModal.jsx @@ -3,17 +3,19 @@ import React, { useEffect, useState } from "react"; import { IoMdCloseCircleOutline } from "react-icons/io"; import { FaChevronDown } from "react-icons/fa"; import { useChat } from "../../logic/ChatContext"; +import ClientTagsModal from "./EditProfile/ClientTagsModal"; const EditProfileModal = ({ isOpen, onClose, onSubmit, data, agent_id }) => { - - const { selectChat, selectedChat } = useChat(); + + const { selectChat, selectedChat } = useChat(); const [formData, setFormData] = useState({ - name: "", - address: "", - email: "", - msg: selectedChat.msg, - client_type: "", - user_number: "", + name: data.name || "", + address: data.address || "", + email: data.email || "", + msg: selectedChat.msg || "", + client_type: data.client_type || [], + user_number: data.user_number || "", + agent_id: agent_id, }); const handleChange = (e) => { @@ -23,14 +25,21 @@ const EditProfileModal = ({ isOpen, onClose, onSubmit, data, agent_id }) => { }); }; + const handleClientTypeChange = (selectedCheck) => { + setFormData((prevFormData) => ({ + ...prevFormData, + client_type: selectedCheck, + })); + }; + formData.agent_id = agent_id + useEffect(() => { setFormData(data); }, [data]); - + if (!isOpen) return null; - return (
@@ -78,27 +87,11 @@ const EditProfileModal = ({ isOpen, onClose, onSubmit, data, agent_id }) => { className="shadow appearance-none border rounded w-full py-2 px-3 text-textPrimary leading-tight focus:outline-none focus:shadow-outline" />
-
- -
- -
- -
-
+
+
(meta_id, reason para métricas) + // TODO: POST => (meta_id, reason para métricas) setConfirmModalData(serializedFormData); const response = await fetch( @@ -139,14 +139,14 @@ const useProfileModal = (userUuid, idToken, role, externalIsLoading, externalSet const handleReactivateUser = async () => { try { actualSetIsLoading(true); - + const payload1 = { meta_id: selectedChat.contact, agent_id: userUuid, field: "active", field_state: "true", }; - + // PUT to change conversation state to active await axios.put( `${process.env.REACT_APP_BACKOFFICE_API_URL}/agents/change-conversation-state`, @@ -158,12 +158,12 @@ const useProfileModal = (userUuid, idToken, role, externalIsLoading, externalSet }, } ); - + const payload2 = { meta_id: selectedChat.contact, agent_id: userUuid }; - + await axios.put( `${process.env.REACT_APP_BACKOFFICE_API_URL}/users/set-user-state?state=agent`, payload2, @@ -174,7 +174,7 @@ const useProfileModal = (userUuid, idToken, role, externalIsLoading, externalSet }, } ); - + handleCloseConfirmModal(); } catch (error) { console.error("Error during reactivation", error); @@ -186,6 +186,7 @@ const useProfileModal = (userUuid, idToken, role, externalIsLoading, externalSet } const handleOpenModal = () => { + {console.log("Showing edit profile modal")} (async () => { actualSetIsLoading(true); //TODO: PUT THE CORRECT ADMIN VALUE @@ -211,7 +212,7 @@ const useProfileModal = (userUuid, idToken, role, externalIsLoading, externalSet name: name || "", address: address || "", email: email || "", - client_type: msg || "", + client_type: msg || [], meta_id: meta_id, }); } else { @@ -220,7 +221,7 @@ const useProfileModal = (userUuid, idToken, role, externalIsLoading, externalSet name: "", address: "", email: "", - client_type: "", + client_type: [], meta_id: selectedChat.contact, }); } @@ -230,7 +231,7 @@ const useProfileModal = (userUuid, idToken, role, externalIsLoading, externalSet name: "", address: "", email: "", - client_type: "", + client_type: [], meta_id: selectedChat.contact, }); } @@ -244,42 +245,57 @@ const useProfileModal = (userUuid, idToken, role, externalIsLoading, externalSet setShowModal(false); }; + const formatClientTypeDescription = (clientTypes) => { + if (!clientTypes || clientTypes.length === 0) return ''; + if (clientTypes.length === 1) return clientTypes[0].label; + return `${clientTypes[0].label} + ${clientTypes.length - 1} más`; + } + const handleSubmitModalData = async (formData) => { - actualSetIsLoading(true); - console.log("This is the current selectedChat", selectedChat); - const updatedChat = { - address: formData.address, - contact: formData.meta_id, - email: formData.email, - imgUrl: selectedChat.imgUrl, - messaging_product: selectedChat.messaging_product, - msg: formData.client_type, - name: formData.name !== "" ? formData.name : formData.meta_id, - pp: selectedChat.pp, - time: selectedChat.time, - unreadMsgs: selectedChat.unreadMsgs, - }; - updateChat(updatedChat) - - const response = await fetch( - `${process.env.REACT_APP_BACKOFFICE_API_URL}/users/save-user-information`, - { - method: "PUT", - headers: { - "Content-Type": "application/json", - 'Authorization': `Bearer ${idToken}` - }, - body: JSON.stringify(formData), + console.log("This is formData in the moment of sending", formData) + console.log("This is client type", formData.client_type) + + try { + actualSetIsLoading(true); + const clientTypeDescription = formatClientTypeDescription(formData.client_type); + console.log("This is the current selectedChat", selectedChat); + const updatedChat = { + address: formData.address, + contact: formData.meta_id, + email: formData.email, + imgUrl: selectedChat.imgUrl, + messaging_product: selectedChat.messaging_product, + name: formData.name !== "" ? formData.name : formData.meta_id, + pp: selectedChat.pp, + time: selectedChat.time, + unreadMsgs: selectedChat.unreadMsgs, + msg: clientTypeDescription, + }; + updateChat(updatedChat) + + const response = await fetch( + `${process.env.REACT_APP_BACKOFFICE_API_URL}/users/save-user-information`, + { + method: "PUT", + headers: { + "Content-Type": "application/json", + 'Authorization': `Bearer ${idToken}` + }, + body: JSON.stringify(formData), + } + ); + if (response.ok) { + console.log("Submission successful"); + actualSetIsLoading(false); + } else { + actualSetIsLoading(false); + console.error("Submission failed"); } - ); - if (response.ok) { - console.log("Submission successful"); + setShowModal(false); + } catch (error) { actualSetIsLoading(false); - } else { - console.error("Submission failed"); - actualSetIsLoading(true); + console.error('Submission failed', error) } - setShowModal(false); }; return { diff --git a/src/logic/TimeConversion.js b/src/logic/TimeConversion.js index 6a768e9..f3adbe7 100644 --- a/src/logic/TimeConversion.js +++ b/src/logic/TimeConversion.js @@ -8,24 +8,20 @@ const addFiveHours = (dateTimeString) => { }; function formatDateTime(dateTimeString, source) { - console.log("Original dateTimeString:", dateTimeString); moment.locale('es'); const normalizeTime = (timeStr) => { if (timeStr.includes('.')) { const normalized = timeStr.replace(/\.\s*m\./gi, '').replace('a', 'AM').replace('p', 'PM'); - console.log("Normalized timeStr:", normalized); return normalized; } return timeStr; }; const normalizedTime = normalizeTime(dateTimeString); - console.log("Normalized dateTimeString:", normalizedTime); if (/^\d{1,2}:\d{2}:\d{2} (\w+)\.? m\.$/i.test(dateTimeString) || /^\d{1,2}:\d{2}:\d{2} (AM|PM)$/i.test(normalizedTime)) { const formattedTime = moment(normalizedTime, "hh:mm:ss A").format("hh:mm A"); - console.log("Formatted time:", formattedTime); return formattedTime; } @@ -33,10 +29,8 @@ function formatDateTime(dateTimeString, source) { if(source === 'websocket_messages'){ formattedDateTime = moment(dateTimeString).add(5, 'hours').format("hh:mm A"); - console.log("Formatted dateTime:", formattedDateTime); } else { formattedDateTime = moment(dateTimeString).format("DD/MMMM hh:mm A"); - console.log("Formatted dateTime:", formattedDateTime); } return formattedDateTime; diff --git a/tailwind.config.js b/tailwind.config.js index 402f126..189d28d 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -12,6 +12,10 @@ module.exports = { bounce: { '0%, 100%': { transform: 'translateX(0)' }, '50%': { transform: 'translateX(-25%)' }, + }, + slideDown: { + '0%': { transform: 'translateY(-100%)', opacity: 0 }, + '100%': { transform: 'translateY(0)', opacity: 1 }, } }, screens: { @@ -20,7 +24,8 @@ module.exports = { animation: { 'fade-in-out': 'fadeInOut 2s infinite', 'flash': 'flash 1s ease-in-out infinite', - 'bounce': 'bounce 0.5s ease-in-out' + 'bounce': 'bounce 0.5s ease-in-out', + 'slideDown': 'slideDown 0.5s ease-in-out' }, colors: {