feat(chat): adiciona separador de dias e melhora layout do header
- Adiciona separador de data entre mensagens de dias diferentes (estilo WhatsApp) - Mostra "Hoje", "Ontem" ou data completa (ex: "segunda-feira, 15 de dezembro") - Separa hostname da maquina em linha propria no header - Hostname com truncate e tooltip para nomes longos 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
2293a0275a
commit
300179279a
1 changed files with 61 additions and 14 deletions
|
|
@ -53,6 +53,40 @@ function formatTime(timestamp: number) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function formatDateSeparator(timestamp: number) {
|
||||||
|
const date = new Date(timestamp)
|
||||||
|
const today = new Date()
|
||||||
|
const yesterday = new Date(today)
|
||||||
|
yesterday.setDate(yesterday.getDate() - 1)
|
||||||
|
|
||||||
|
const isToday = date.toDateString() === today.toDateString()
|
||||||
|
const isYesterday = date.toDateString() === yesterday.toDateString()
|
||||||
|
|
||||||
|
if (isToday) return "Hoje"
|
||||||
|
if (isYesterday) return "Ontem"
|
||||||
|
|
||||||
|
return date.toLocaleDateString("pt-BR", {
|
||||||
|
weekday: "long",
|
||||||
|
day: "2-digit",
|
||||||
|
month: "long",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function getDateKey(timestamp: number) {
|
||||||
|
return new Date(timestamp).toDateString()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Componente separador de data (estilo WhatsApp)
|
||||||
|
function DateSeparator({ timestamp }: { timestamp: number }) {
|
||||||
|
return (
|
||||||
|
<div className="flex items-center justify-center py-2">
|
||||||
|
<div className="rounded-full bg-slate-200/80 px-3 py-1 text-xs font-medium text-slate-600">
|
||||||
|
{formatDateSeparator(timestamp)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
type ChatSession = {
|
type ChatSession = {
|
||||||
ticketId: string
|
ticketId: string
|
||||||
ticketRef: number
|
ticketRef: number
|
||||||
|
|
@ -661,16 +695,22 @@ export function ChatWidget() {
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
{activeSession && (
|
{activeSession && (
|
||||||
<a
|
<div className="flex flex-col">
|
||||||
href={`/tickets/${activeTicketId}`}
|
<a
|
||||||
target="_blank"
|
href={`/tickets/${activeTicketId}`}
|
||||||
rel="noopener noreferrer"
|
target="_blank"
|
||||||
className="group flex items-center gap-1 text-xs text-slate-500 hover:text-slate-900 transition-colors"
|
rel="noopener noreferrer"
|
||||||
>
|
className="group flex items-center gap-1 text-xs text-slate-500 hover:text-slate-900 transition-colors"
|
||||||
<span>#{activeSession.ticketRef}</span>
|
>
|
||||||
{machineHostname && <span> - {machineHostname}</span>}
|
<span>#{activeSession.ticketRef}</span>
|
||||||
<ExternalLink className="size-3 opacity-0 group-hover:opacity-100 transition-opacity" />
|
<ExternalLink className="size-3 opacity-0 group-hover:opacity-100 transition-opacity" />
|
||||||
</a>
|
</a>
|
||||||
|
{machineHostname && (
|
||||||
|
<span className="max-w-[140px] truncate text-xs text-slate-400" title={machineHostname}>
|
||||||
|
{machineHostname}
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -757,16 +797,22 @@ export function ChatWidget() {
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div className="space-y-3">
|
<div className="space-y-3">
|
||||||
{messages.map((msg) => {
|
{messages.map((msg, index) => {
|
||||||
const isOwn = String(msg.authorId) === String(viewerId)
|
const isOwn = String(msg.authorId) === String(viewerId)
|
||||||
const bodyText = msg.body?.trim() ?? ""
|
const bodyText = msg.body?.trim() ?? ""
|
||||||
const shouldShowBody =
|
const shouldShowBody =
|
||||||
bodyText.length > 0 &&
|
bodyText.length > 0 &&
|
||||||
!(bodyText === "[Anexo]" && (msg.attachments?.length ?? 0) > 0)
|
!(bodyText === "[Anexo]" && (msg.attachments?.length ?? 0) > 0)
|
||||||
|
|
||||||
|
// Verificar se precisa mostrar separador de data
|
||||||
|
const prevMsg = index > 0 ? messages[index - 1] : null
|
||||||
|
const showDateSeparator = !prevMsg || getDateKey(msg.createdAt) !== getDateKey(prevMsg.createdAt)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div key={msg.id}>
|
||||||
key={msg.id}
|
{showDateSeparator && <DateSeparator timestamp={msg.createdAt} />}
|
||||||
className={cn("flex gap-2", isOwn ? "flex-row-reverse" : "flex-row")}
|
<div
|
||||||
|
className={cn("flex gap-2", isOwn ? "flex-row-reverse" : "flex-row")}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className={cn(
|
className={cn(
|
||||||
|
|
@ -803,6 +849,7 @@ export function ChatWidget() {
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
<div ref={messagesEndRef} />
|
<div ref={messagesEndRef} />
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue