152 lines
4.1 KiB
JavaScript
152 lines
4.1 KiB
JavaScript
|
|
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,
|
||
|
|
};
|
||
|
|
}
|