feat(devices,custom-fields,csat,portal):\n- Editor de campos personalizados (inclui multiselect) e exibição no detalhe\n- Campos personalizados disponíveis nas colunas/templates de exportação\n- Move cópia de e-mail para ícone inline abaixo do nome do dispositivo\n- Portal: banner para avaliar último chamado e CSAT no detalhe\n- Tickets list inclui campos de CSAT para detectar pendências

This commit is contained in:
codex-bot 2025-11-04 14:12:21 -03:00
parent 06deb99bcd
commit c2c5707a97
7 changed files with 299 additions and 14 deletions

View file

@ -84,6 +84,13 @@ export function PortalTicketList() {
)
}
const lastResolvedNoCsat = useMemo(() => {
const resolved = (tickets as Ticket[])
.filter((t) => t.status === "RESOLVED" && (t.csatScore == null))
.sort((a, b) => (b.resolvedAt?.getTime?.() ?? 0) - (a.resolvedAt?.getTime?.() ?? 0))
return resolved[0] ?? null
}, [tickets])
return (
<div className="space-y-4">
<div className="flex items-center justify-between">
@ -92,6 +99,14 @@ export function PortalTicketList() {
<p className="text-sm text-neutral-600">Acompanhe seus tickets e veja as últimas atualizações.</p>
</div>
</div>
{lastResolvedNoCsat ? (
<div className="rounded-xl border border-amber-200 bg-amber-50 px-4 py-3 text-sm text-amber-800">
Como foi seu último atendimento? Avalie o chamado #{lastResolvedNoCsat.reference}.{' '}
<Link href={`/portal/tickets/${lastResolvedNoCsat.id}#csat`} className="font-semibold underline">
Avaliar agora
</Link>
</div>
) : null}
<div className="grid gap-4">
{(tickets as Ticket[]).map((ticket) => (
<PortalTicketCard key={ticket.id} ticket={ticket} />