fix(select): evitar value vazio em Select (fila) no novo ticket; feat(timeline): nomes/avatares do ator e mensagens PT-BR; feat(ui): skeletons para lista e recentes; grid de anexos e legendas; melhorias de cards/padding
This commit is contained in:
parent
44c98fec4a
commit
da1633a30e
6 changed files with 59 additions and 23 deletions
|
|
@ -10,7 +10,8 @@ import {
|
|||
|
||||
import type { TicketWithDetails } from "@/lib/schemas/ticket"
|
||||
import { cn } from "@/lib/utils"
|
||||
import { Card, CardContent } from "@/components/ui/card"
|
||||
import { Card, CardContent } from "@/components/ui/card"
|
||||
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"
|
||||
import { Separator } from "@/components/ui/separator"
|
||||
|
||||
const timelineIcons: Record<string, ComponentType<{ className?: string }>> = {
|
||||
|
|
@ -48,20 +49,32 @@ export function TicketTimeline({ ticket }: TicketTimelineProps) {
|
|||
<Icon className="size-4" />
|
||||
</span>
|
||||
<div className="flex flex-col gap-2">
|
||||
<div className="flex flex-wrap items-center gap-x-3 gap-y-1">
|
||||
<div className="flex flex-wrap items-center gap-x-3 gap-y-1">
|
||||
<span className="text-sm font-medium text-foreground">
|
||||
{timelineLabels[entry.type] ?? entry.type}
|
||||
</span>
|
||||
<span className="text-xs text-muted-foreground">
|
||||
{format(entry.createdAt, "dd MMM yyyy HH:mm", { locale: ptBR })}
|
||||
</span>
|
||||
</div>
|
||||
{entry.payload?.actorName ? (
|
||||
<span className="flex items-center gap-1 text-xs text-muted-foreground">
|
||||
<Avatar className="size-5">
|
||||
<AvatarImage src={entry.payload.actorAvatar} alt={entry.payload.actorName} />
|
||||
<AvatarFallback>
|
||||
{entry.payload.actorName.split(' ').slice(0,2).map((p:string)=>p[0]).join('').toUpperCase()}
|
||||
</AvatarFallback>
|
||||
</Avatar>
|
||||
por {entry.payload.actorName}
|
||||
</span>
|
||||
) : null}
|
||||
<span className="text-xs text-muted-foreground">
|
||||
{format(entry.createdAt, "dd MMM yyyy HH:mm", { locale: ptBR })}
|
||||
</span>
|
||||
</div>
|
||||
{(() => {
|
||||
const p: any = entry.payload || {}
|
||||
let message: string | null = null
|
||||
if (entry.type === "STATUS_CHANGED" && (p.toLabel || p.to)) message = `Status alterado para ${p.toLabel || p.to}`
|
||||
if (entry.type === "ASSIGNEE_CHANGED" && (p.assigneeName || p.assigneeId)) message = `Responsável alterado${p.assigneeName ? ` para ${p.assigneeName}` : ""}`
|
||||
if (entry.type === "QUEUE_CHANGED" && (p.queueName || p.queueId)) message = `Fila alterada${p.queueName ? ` para ${p.queueName}` : ""}`
|
||||
if (entry.type === "CREATED" && (p.requesterName)) message = `Criado por ${p.requesterName}`
|
||||
if (!message) return null
|
||||
return (
|
||||
<div className="rounded-lg border border-dashed bg-card px-3 py-2 text-sm text-muted-foreground">
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue