omnichannel-frontend/src/modules/chat/components/ChatWindow.jsx

212 lines
5.7 KiB
React
Raw Normal View History

import { useEffect, useRef } from 'react';
export function ChatWindow({
contact,
messages,
selectedArea,
setSelectedArea,
draft,
setDraft,
onSend,
onToggleTransfer,
isReplying,
isMobile = false,
}) {
const messagesRef = useRef(null);
useEffect(() => {
const container = messagesRef.current;
if (!container) {
return;
}
container.scrollTo({
top: container.scrollHeight,
behavior: 'smooth',
});
}, [messages, isReplying]);
return (
<section
style={{
background: '#fff',
border: '1px solid var(--color-border)',
borderRadius: '28px',
overflow: 'hidden',
display: 'grid',
gridTemplateRows: 'auto 1fr auto',
minHeight: 680,
}}
>
<header
style={{
padding: '1.25rem 1.5rem',
borderBottom: '1px solid var(--color-border)',
display: 'grid',
gridTemplateColumns: isMobile ? '1fr' : 'minmax(0, 1fr) auto',
gap: '1rem',
alignItems: 'center',
}}
>
<div>
<strong style={{ display: 'block', fontSize: '1.15rem' }}>{contact.name}</strong>
<span style={{ color: 'var(--color-text-soft)' }}>
{contact.status === 'online' ? 'Online' : 'Offline'} {contact.lastSeen}
</span>
</div>
<div
style={{
display: 'flex',
gap: '0.7rem',
flexWrap: 'wrap',
justifyContent: isMobile ? 'stretch' : 'flex-end',
}}
>
<select
value={selectedArea}
onChange={(event) => setSelectedArea(event.target.value)}
style={{
border: '1px solid var(--color-border)',
borderRadius: '14px',
padding: '0.8rem 0.95rem',
background: '#fff',
fontWeight: 600,
}}
>
<option>Suporte</option>
<option>Financeiro</option>
<option>Comercial</option>
</select>
<button
type="button"
onClick={onToggleTransfer}
style={{
border: 'none',
borderRadius: '14px',
padding: '0.8rem 1rem',
background: 'rgba(0, 49, 80, 0.08)',
color: 'var(--color-primary)',
fontWeight: 700,
}}
>
Transferir
</button>
</div>
</header>
<div
ref={messagesRef}
style={{
padding: '1.5rem',
display: 'grid',
gap: '0.9rem',
alignContent: 'start',
overflowY: 'auto',
background:
'radial-gradient(circle at top left, rgba(0, 164, 183, 0.06), transparent 22%), linear-gradient(180deg, rgba(245, 248, 251, 0.8), rgba(255, 255, 255, 0.95))',
}}
>
{messages.map((message) => {
const isAgent = message.sender === 'agent';
const isSystem = message.sender === 'system';
if (isSystem) {
return (
<div
key={message.id}
style={{
justifySelf: 'center',
padding: '0.7rem 1rem',
borderRadius: '999px',
background: 'rgba(0, 49, 80, 0.08)',
color: 'var(--color-primary)',
fontSize: '0.88rem',
fontWeight: 600,
}}
>
{message.text}
</div>
);
}
return (
<div
key={message.id}
style={{
justifySelf: isAgent ? 'end' : 'start',
maxWidth: isMobile ? '88%' : '72%',
padding: '0.95rem 1rem',
borderRadius: isAgent ? '18px 18px 6px 18px' : '18px 18px 18px 6px',
background: isAgent ? 'var(--color-primary)' : '#edf1f5',
color: isAgent ? '#fff' : 'var(--color-text)',
boxShadow: 'var(--shadow-md)',
}}
>
{message.text}
</div>
);
})}
{isReplying ? (
<div
style={{
justifySelf: 'start',
padding: '0.8rem 0.95rem',
borderRadius: '18px 18px 18px 6px',
background: '#edf1f5',
color: 'var(--color-text-soft)',
fontWeight: 600,
}}
>
Digitando...
</div>
) : null}
</div>
<footer
style={{
padding: '1rem 1.25rem 1.25rem',
borderTop: '1px solid var(--color-border)',
display: 'grid',
gridTemplateColumns: isMobile ? '1fr' : '1fr auto',
gap: '0.75rem',
}}
>
<input
type="text"
value={draft}
onChange={(event) => setDraft(event.target.value)}
onKeyDown={(event) => {
if (event.key === 'Enter') {
onSend();
}
}}
placeholder="Escreva sua mensagem..."
style={{
border: '1px solid var(--color-border)',
borderRadius: '18px',
padding: '0.95rem 1rem',
background: '#fff',
outline: 'none',
}}
/>
<button
type="button"
onClick={onSend}
style={{
border: 'none',
borderRadius: '18px',
padding: '0.95rem 1.2rem',
background: 'linear-gradient(135deg, var(--color-primary), #0b5a86)',
color: '#fff',
fontWeight: 700,
}}
>
Enviar
</button>
</footer>
</section>
);
}