omnichannel-frontend/src/modules/chat/hooks/useChat.js

152 lines
4.1 KiB
JavaScript
Raw Normal View History

import { useEffect, useMemo, useRef, useState } from 'react';
import {
attendantsByArea,
chatContacts,
getMockReply,
transferAreas,
} from '../services/chatMocks';
function buildInitialMessages() {
return chatContacts.reduce((acc, contact) => {
acc[contact.id] = contact.messages;
return acc;
}, {});
}
export function useChat() {
const [contacts, setContacts] = useState(chatContacts);
const [activeContactId, setActiveContactId] = useState(chatContacts[0].id);
const [messagesByContact, setMessagesByContact] = useState(buildInitialMessages);
const [draft, setDraft] = useState('');
const [selectedArea, setSelectedArea] = useState(chatContacts[0].area);
const [isTransferOpen, setIsTransferOpen] = useState(false);
const [transferArea, setTransferArea] = useState('Suporte');
const [transferAttendant, setTransferAttendant] = useState(attendantsByArea.Suporte[0]);
const [transferNote, setTransferNote] = useState('');
const [isReplying, setIsReplying] = useState(false);
const replyTimeoutRef = useRef(null);
const activeContact = useMemo(
() => contacts.find((contact) => contact.id === activeContactId) || contacts[0],
[contacts, activeContactId],
);
const messages = messagesByContact[activeContactId] || [];
const attendants = attendantsByArea[transferArea] || [];
useEffect(() => {
setSelectedArea(activeContact.area);
}, [activeContact]);
useEffect(() => {
setTransferAttendant(attendants[0] || '');
}, [transferArea]);
useEffect(() => {
return () => {
if (replyTimeoutRef.current) {
window.clearTimeout(replyTimeoutRef.current);
}
};
}, []);
function updateContactPreview(contactId, preview) {
setContacts((current) =>
current.map((contact) =>
contact.id === contactId ? { ...contact, preview, time: 'Agora', unread: 0 } : contact,
),
);
}
function sendMessage() {
const trimmed = draft.trim();
if (!trimmed) {
return;
}
const newMessage = {
id: Date.now(),
sender: 'agent',
text: trimmed,
};
setMessagesByContact((current) => ({
...current,
[activeContactId]: [...(current[activeContactId] || []), newMessage],
}));
updateContactPreview(activeContactId, trimmed);
setDraft('');
setIsReplying(true);
replyTimeoutRef.current = window.setTimeout(() => {
const reply = {
id: Date.now() + 1,
sender: 'customer',
text: getMockReply(activeContact.name),
};
setMessagesByContact((current) => ({
...current,
[activeContactId]: [...(current[activeContactId] || []), reply],
}));
setContacts((current) =>
current.map((contact) =>
contact.id === activeContactId
? { ...contact, preview: reply.text, time: 'Agora', unread: contact.unread + 1 }
: contact,
),
);
setIsReplying(false);
}, 1400);
}
function submitTransfer() {
const note = transferNote.trim();
const transferMessage = note
? `Transferencia solicitada para ${transferArea} com ${transferAttendant}. Obs: ${note}`
: `Transferencia solicitada para ${transferArea} com ${transferAttendant}.`;
setMessagesByContact((current) => ({
...current,
[activeContactId]: [
...(current[activeContactId] || []),
{ id: Date.now() + 2, sender: 'system', text: transferMessage },
],
}));
setContacts((current) =>
current.map((contact) =>
contact.id === activeContactId ? { ...contact, area: transferArea } : contact,
),
);
setSelectedArea(transferArea);
setIsTransferOpen(false);
setTransferNote('');
}
return {
contacts,
activeContact,
activeContactId,
setActiveContactId,
messages,
draft,
setDraft,
sendMessage,
isReplying,
selectedArea,
setSelectedArea,
isTransferOpen,
setIsTransferOpen,
transferArea,
setTransferArea,
transferAreas,
attendants,
transferAttendant,
setTransferAttendant,
transferNote,
setTransferNote,
submitTransfer,
};
}