diff --git a/src/components/tickets/tickets-table.tsx b/src/components/tickets/tickets-table.tsx
index 2723554..f6344a8 100644
--- a/src/components/tickets/tickets-table.tsx
+++ b/src/components/tickets/tickets-table.tsx
@@ -4,9 +4,8 @@ import { useEffect, useRef, useState } from "react"
import { useRouter } from "next/navigation"
import { format, formatDistanceToNowStrict } from "date-fns"
import { ptBR } from "date-fns/locale"
-import { type LucideIcon, Code, FileText, Mail, MessageCircle, MessageSquare, Phone } from "lucide-react"
-import type { Ticket, TicketChannel } from "@/lib/schemas/ticket"
+import type { Ticket } from "@/lib/schemas/ticket"
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"
import { Badge } from "@/components/ui/badge"
import { Card, CardContent } from "@/components/ui/card"
@@ -25,26 +24,10 @@ import { cn } from "@/lib/utils"
import { deriveServerOffset, toServerTimestamp } from "@/components/tickets/ticket-timer.utils"
import { getTicketStatusLabel, getTicketStatusTextClass } from "@/lib/ticket-status-style"
-const channelLabel: Record
= {
- EMAIL: "E-mail",
- WHATSAPP: "WhatsApp",
- CHAT: "Chat",
- PHONE: "Telefone",
- API: "API",
- MANUAL: "Manual",
-}
-
-const channelIcon: Record = {
- EMAIL: Mail,
- WHATSAPP: MessageCircle,
- CHAT: MessageSquare,
- PHONE: Phone,
- API: Code,
- MANUAL: FileText,
-}
-
-const cellClass = "px-4 py-4 align-middle text-sm text-neutral-700 whitespace-normal first:pl-5 last:pr-6"
-const channelIconBadgeClass = "inline-flex size-8 items-center justify-center rounded-full border border-slate-200 bg-slate-50 text-neutral-700"
+const cellClass =
+ "px-3 py-4 sm:px-4 xl:px-3 xl:py-3 align-middle text-sm text-neutral-700 whitespace-normal " +
+ "first:pl-3 last:pr-3 sm:first:pl-4 sm:last:pr-4 xl:first:pl-4 xl:last:pr-4"
+const borderedCellClass = `${cellClass} xl:border-l xl:border-slate-200`
const categoryChipClass = "inline-flex items-center gap-1 rounded-full bg-slate-200/60 px-2.5 py-1 text-[11px] font-medium text-neutral-700"
const tableRowClass =
"group border-b border-slate-100 text-sm transition-colors hover:bg-slate-100/70 last:border-none"
@@ -76,16 +59,16 @@ function AssigneeCell({ ticket }: { ticket: Ticket }) {
.join("")
return (
-
+
{initials}
-
-
+
+
{ticket.assignee.name}
-
+
{ticket.assignee.teams?.[0] ?? "Agente"}
@@ -137,166 +120,172 @@ export function TicketsTable({ tickets, enteringIds }: TicketsTableProps) {
return (
-
-
+
+
-
- Ticket
-
-
- Assunto
-
-
- Fila
-
-
- Canal
-
-
- Empresa
-
-
- Prioridade
-
-
- Status
-
-
- Tempo
-
-
- Responsável
-
-
- Atualizado
-
-
-
-
- {safeTickets.map((ticket) => {
- const ChannelIcon = channelIcon[ticket.channel] ?? MessageCircle
- const rowClass = cn(
- `${tableRowClass} cursor-pointer`,
- enteringIds?.has(ticket.id) ? "recent-ticket-enter" : undefined,
- )
+
+ Ticket
+
+
+ Assunto
+
+
+ Empresa
+
+
+ Prioridade
+
+
+ Fila
+
+
+ Status
+
+
+ Tempo
+
+
+ Responsável
+
+
+ Atualizado
+
+
+
+
+ {safeTickets.map((ticket) => {
+ const rowClass = cn(
+ `${tableRowClass} cursor-pointer`,
+ enteringIds?.has(ticket.id) ? "recent-ticket-enter" : undefined,
+ )
- return (
- router.push(`/tickets/${ticket.id}`)}
- onKeyDown={(event) => {
- if (event.key === "Enter" || event.key === " ") {
- event.preventDefault()
- router.push(`/tickets/${ticket.id}`)
- }
- }}
- >
-
-
-
- #{ticket.reference}
-
-
+ return (
+ router.push(`/tickets/${ticket.id}`)}
+ onKeyDown={(event) => {
+ if (event.key === "Enter" || event.key === " ") {
+ event.preventDefault()
+ router.push(`/tickets/${ticket.id}`)
+ }
+ }}
+ >
+
+
+
+ #{ticket.reference}
+
+
+ {ticket.queue ?? "Sem fila"}
+
+
+
+
+
+
+ {ticket.subject}
+
+
+ {ticket.summary ?? "Sem resumo"}
+
+
+ {ticket.category ? (
+
+ {ticket.category.name}
+ {ticket.subcategory ? (
+
+ {" "}
+ • {ticket.subcategory.name}
+
+ ) : null}
+
+ ) : (
+ Sem categoria
+ )}
+
+
+
+
+
+
+ {ticket.requester.name}
+
+
+ {((ticket.company ?? null) as { name?: string } | null)?.name ?? "—"}
+
+
+
+
+ event.stopPropagation()}
+ onKeyDown={(event) => event.stopPropagation()}
+ >
+
+
+
+
+
{ticket.queue ?? "Sem fila"}
-
-
-
-
-
- {ticket.subject}
-
-
- {ticket.summary ?? "Sem resumo"}
-
-
- {ticket.requester.name}
- {ticket.category ? (
-
- {ticket.category.name}
- {ticket.subcategory ? • {ticket.subcategory.name} : null}
-
- ) : (
- Sem categoria
- )}
-
-
-
-
-
- {ticket.queue ?? "Sem fila"}
-
-
-
-
- Canal {channelLabel[ticket.channel]}
-
-
-
-
-
-
-
- {((ticket.company ?? null) as { name?: string } | null)?.name ?? "—"}
-
-
-
- event.stopPropagation()}
- onKeyDown={(event) => event.stopPropagation()}
- >
-
-
-
-
-
-
- {getTicketStatusLabel(ticket.status)}
-
- {ticket.metrics?.timeWaitingMinutes ? (
-
- Em espera há {ticket.metrics.timeWaitingMinutes} min
+
+
+
+
+ {getTicketStatusLabel(ticket.status)}
- ) : null}
-
-
-
-
- {formatDuration(getWorkedMs(ticket))}
- {ticket.workSummary?.activeSession ? (
- Em andamento
- ) : null}
-
-
-
-
-
-
-
-
- {`há cerca de ${formatDistanceToNowStrict(ticket.updatedAt, { locale: ptBR })}`}
-
-
- {format(ticket.updatedAt, "dd/MM/yyyy HH:mm")}
-
-
-
-
+ {ticket.metrics?.timeWaitingMinutes ? (
+
+ Em espera há {ticket.metrics.timeWaitingMinutes} min
+
+ ) : null}
+
+
+
+
+ {formatDuration(getWorkedMs(ticket))}
+ {ticket.workSummary?.activeSession ? (
+ Em andamento
+ ) : null}
+
+
+
+
+
+
+
+
+ {`há ${formatDistanceToNowStrict(ticket.updatedAt, { locale: ptBR })}`}
+
+
+ {format(ticket.updatedAt, "dd/MM/yyyy HH:mm")}
+
+
+
+
)
})}
-
+
{safeTickets.length === 0 && (
diff --git a/src/components/ui/sidebar.tsx b/src/components/ui/sidebar.tsx
index 5b52761..6dc820f 100644
--- a/src/components/ui/sidebar.tsx
+++ b/src/components/ui/sidebar.tsx
@@ -27,9 +27,9 @@ import {
const SIDEBAR_COOKIE_NAME = "sidebar_state"
const SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7
-const SIDEBAR_WIDTH = "16rem"
-const SIDEBAR_WIDTH_MOBILE = "18rem"
-const SIDEBAR_WIDTH_ICON = "3rem"
+const SIDEBAR_WIDTH = "clamp(12rem, 15vw + 1.5rem, 16.5rem)"
+const SIDEBAR_WIDTH_MOBILE = "18rem"
+const SIDEBAR_WIDTH_ICON = "3rem"
const SIDEBAR_KEYBOARD_SHORTCUT = "b"
type SidebarContextProps = {
@@ -314,17 +314,17 @@ function SidebarRail({ className, ...props }: React.ComponentProps<"button">) {
)
}
-function SidebarInset({ className, ...props }: React.ComponentProps<"main">) {
- return (
-
+function SidebarInset({ className, ...props }: React.ComponentProps<"main">) {
+ return (
+
)
}
diff --git a/src/lib/ticket-status-style.ts b/src/lib/ticket-status-style.ts
index c402a89..0b4a522 100644
--- a/src/lib/ticket-status-style.ts
+++ b/src/lib/ticket-status-style.ts
@@ -19,7 +19,7 @@ const META: Record = {
summaryTone: "muted",
chipClass: "bg-slate-100 text-neutral-700 ring-1 ring-slate-200",
badgeClass: "border border-slate-200 bg-slate-100 text-neutral-700",
- tableTextClass: "text-neutral-600",
+ tableTextClass: "text-slate-700",
dotClass: "bg-slate-400",
},
AWAITING_ATTENDANCE: {
@@ -27,7 +27,7 @@ const META: Record = {
summaryTone: "info",
chipClass: "bg-sky-100 text-sky-700 ring-1 ring-sky-200",
badgeClass: "border border-sky-200 bg-sky-100 text-sky-700",
- tableTextClass: "text-sky-700",
+ tableTextClass: "text-[#0a4760]",
dotClass: "bg-sky-500",
},
PAUSED: {
@@ -35,7 +35,7 @@ const META: Record = {
summaryTone: "warning",
chipClass: "bg-amber-100 text-amber-800 ring-1 ring-amber-200",
badgeClass: "border border-amber-200 bg-amber-50 text-amber-700",
- tableTextClass: "text-amber-700",
+ tableTextClass: "text-[#7a5901]",
dotClass: "bg-amber-400",
},
RESOLVED: {
@@ -43,7 +43,7 @@ const META: Record = {
summaryTone: "success",
chipClass: "bg-emerald-100 text-emerald-700 ring-1 ring-emerald-200",
badgeClass: "border border-emerald-200 bg-emerald-50 text-emerald-700",
- tableTextClass: "text-emerald-700",
+ tableTextClass: "text-[#1f6a45]",
dotClass: "bg-emerald-500",
},
}