FEAT: Ajustado espaço delimitador da tela de chat e conversas ativas
This commit is contained in:
parent
bff4e18094
commit
7dc07c2a80
@ -23,6 +23,29 @@ function ChannelBadge({ channel }) {
|
||||
);
|
||||
}
|
||||
|
||||
function PresenceDot({ status }) {
|
||||
const color =
|
||||
status === 'online'
|
||||
? '#16a34a'
|
||||
: status === 'away'
|
||||
? '#e5a22a'
|
||||
: '#dc2626';
|
||||
|
||||
return (
|
||||
<span
|
||||
aria-hidden="true"
|
||||
style={{
|
||||
width: 10,
|
||||
height: 10,
|
||||
borderRadius: 999,
|
||||
background: color,
|
||||
boxShadow: `0 0 0 3px ${color}22`,
|
||||
flex: '0 0 auto',
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export function ChatConversationList({
|
||||
contacts,
|
||||
activeContactId,
|
||||
@ -37,7 +60,10 @@ export function ChatConversationList({
|
||||
borderRadius: '28px',
|
||||
padding: '1rem',
|
||||
display: 'grid',
|
||||
gridTemplateRows: 'auto minmax(0, 1fr)',
|
||||
gap: '0.85rem',
|
||||
height: isMobile ? 'auto' : 'min(760px, calc(100vh - 190px))',
|
||||
minHeight: 0,
|
||||
}}
|
||||
>
|
||||
<div>
|
||||
@ -52,6 +78,9 @@ export function ChatConversationList({
|
||||
display: 'grid',
|
||||
gap: '0.75rem',
|
||||
gridTemplateColumns: isMobile ? '1fr' : '1fr',
|
||||
overflowY: 'auto',
|
||||
minHeight: 0,
|
||||
paddingRight: '0.15rem',
|
||||
}}
|
||||
>
|
||||
{contacts.map((contact) => {
|
||||
@ -74,7 +103,12 @@ export function ChatConversationList({
|
||||
}}
|
||||
>
|
||||
<div style={{ display: 'flex', justifyContent: 'space-between', gap: '1rem' }}>
|
||||
<strong>{contact.name}</strong>
|
||||
<span style={{ display: 'inline-flex', alignItems: 'center', gap: '0.5rem', minWidth: 0 }}>
|
||||
<PresenceDot status={contact.status} />
|
||||
<strong style={{ overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
|
||||
{contact.name}
|
||||
</strong>
|
||||
</span>
|
||||
<span style={{ fontSize: '0.82rem', color: 'var(--color-text-soft)' }}>
|
||||
{contact.time}
|
||||
</span>
|
||||
|
||||
@ -179,6 +179,40 @@ function AttachmentPreview({ file, onRemove }) {
|
||||
);
|
||||
}
|
||||
|
||||
function ContactPresence({ contact }) {
|
||||
const status = contact.status || 'offline';
|
||||
const color =
|
||||
status === 'online'
|
||||
? '#16a34a'
|
||||
: status === 'away'
|
||||
? '#e5a22a'
|
||||
: '#dc2626';
|
||||
const label = status === 'online' ? 'Online agora' : contact.lastSeen || 'Offline';
|
||||
|
||||
return (
|
||||
<span
|
||||
style={{
|
||||
display: 'inline-flex',
|
||||
alignItems: 'center',
|
||||
gap: '0.5rem',
|
||||
color: 'var(--color-text-soft)',
|
||||
}}
|
||||
>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
style={{
|
||||
width: 10,
|
||||
height: 10,
|
||||
borderRadius: 999,
|
||||
background: color,
|
||||
boxShadow: `0 0 0 3px ${color}22`,
|
||||
}}
|
||||
/>
|
||||
{label}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
export function ChatWindow({
|
||||
contact,
|
||||
messages,
|
||||
@ -217,8 +251,10 @@ export function ChatWindow({
|
||||
borderRadius: '28px',
|
||||
overflow: 'hidden',
|
||||
display: 'grid',
|
||||
gridTemplateRows: 'auto 1fr auto',
|
||||
minHeight: 680,
|
||||
gridTemplateRows: 'auto minmax(0, 1fr) auto',
|
||||
height: isMobile ? 'auto' : 'min(760px, calc(100vh - 190px))',
|
||||
minHeight: isMobile ? 640 : 0,
|
||||
minWidth: 0,
|
||||
}}
|
||||
>
|
||||
<header
|
||||
@ -233,9 +269,7 @@ export function ChatWindow({
|
||||
>
|
||||
<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>
|
||||
<ContactPresence contact={contact} />
|
||||
</div>
|
||||
|
||||
<div
|
||||
@ -286,6 +320,7 @@ export function ChatWindow({
|
||||
gap: '0.9rem',
|
||||
alignContent: 'start',
|
||||
overflowY: 'auto',
|
||||
minHeight: 0,
|
||||
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))',
|
||||
}}
|
||||
|
||||
@ -40,13 +40,20 @@ function getPreviewFromMessage(message) {
|
||||
|
||||
function normalizeChat(chat) {
|
||||
const id = getSerializedId(chat.id);
|
||||
const lastActivitySeconds = chat.timestamp ? Math.floor(Date.now() / 1000) - chat.timestamp : null;
|
||||
const isRecentlyActive = lastActivitySeconds !== null && lastActivitySeconds < 300;
|
||||
|
||||
return {
|
||||
id,
|
||||
name: getContactName(chat),
|
||||
channel: 'WhatsApp',
|
||||
status: 'online',
|
||||
status: isRecentlyActive ? 'online' : 'away',
|
||||
area: chat.assignment?.area_id ? String(chat.assignment.area_id) : 'Suporte',
|
||||
lastSeen: chat.timestamp ? `Visto as ${formatTime(chat.timestamp)}` : 'Online agora',
|
||||
lastSeen: isRecentlyActive
|
||||
? 'Online agora'
|
||||
: chat.timestamp
|
||||
? `Visto as ${formatTime(chat.timestamp)}`
|
||||
: 'Sem atividade recente',
|
||||
preview: chat.preview || chat.lastMessage?.body || '',
|
||||
time: formatTime(chat.timestamp) || 'Agora',
|
||||
unread: chat.unreadCount || 0,
|
||||
|
||||
@ -103,7 +103,7 @@ export function ChatPage() {
|
||||
display: 'grid',
|
||||
gridTemplateColumns,
|
||||
gap: '1rem',
|
||||
alignItems: 'start',
|
||||
alignItems: 'stretch',
|
||||
}}
|
||||
>
|
||||
<ChatConversationList
|
||||
@ -113,7 +113,7 @@ export function ChatPage() {
|
||||
isMobile={isMobile}
|
||||
/>
|
||||
|
||||
<div style={{ display: 'grid', gap: '1rem', minWidth: 0 }}>
|
||||
<div style={{ display: 'grid', gap: '1rem', minWidth: 0, alignContent: 'start' }}>
|
||||
<ChatWindow
|
||||
contact={activeContact}
|
||||
messages={messages}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user