feat: scaffold tickets experience
This commit is contained in:
commit
2230590e57
79 changed files with 16055 additions and 0 deletions
65
web/src/components/tickets/ticket-timeline.tsx
Normal file
65
web/src/components/tickets/ticket-timeline.tsx
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
import { format } from "date-fns"\nimport type { ComponentType } from "react"
|
||||
import { ptBR } from "date-fns/locale"
|
||||
import {
|
||||
IconClockHour4,
|
||||
IconNote,
|
||||
IconSquareCheck,
|
||||
IconUserCircle,
|
||||
} from "@tabler/icons-react"
|
||||
|
||||
import type { TicketWithDetails } from "@/lib/schemas/ticket"
|
||||
import { cn } from "@/lib/utils"
|
||||
import { Card, CardContent } from "@/components/ui/card"
|
||||
import { Separator } from "@/components/ui/separator"
|
||||
|
||||
const timelineIcons: Record<string, ComponentType<{ className?: string }>> = {
|
||||
CREATED: IconUserCircle,
|
||||
STATUS_CHANGED: IconSquareCheck,
|
||||
ASSIGNEE_CHANGED: IconUserCircle,
|
||||
COMMENT_ADDED: IconNote,
|
||||
}
|
||||
|
||||
interface TicketTimelineProps {
|
||||
ticket: TicketWithDetails
|
||||
}
|
||||
|
||||
export function TicketTimeline({ ticket }: TicketTimelineProps) {
|
||||
return (
|
||||
<Card className="border-none shadow-none">
|
||||
<CardContent className="space-y-6">
|
||||
{ticket.timeline.map((entry, index) => {
|
||||
const Icon = timelineIcons[entry.type] ?? IconClockHour4
|
||||
const isLast = index === ticket.timeline.length - 1
|
||||
return (
|
||||
<div key={entry.id} className="relative pl-10">
|
||||
{!isLast && (
|
||||
<span className="absolute left-[17px] top-6 h-full w-px bg-border" aria-hidden />
|
||||
)}
|
||||
<span className="absolute left-0 top-0 flex size-8 items-center justify-center rounded-full bg-muted text-muted-foreground">
|
||||
<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">
|
||||
<span className="text-sm font-medium text-foreground">
|
||||
{entry.type.replaceAll("_", " ")}
|
||||
</span>
|
||||
<span className="text-xs text-muted-foreground">
|
||||
{format(entry.createdAt, "dd MMM yyyy HH:mm", { locale: ptBR })}
|
||||
</span>
|
||||
</div>
|
||||
{entry.payload ? (
|
||||
<div className="rounded-lg border border-dashed bg-card px-3 py-2 text-sm text-muted-foreground">
|
||||
<pre className="whitespace-pre-wrap leading-relaxed">
|
||||
{JSON.stringify(entry.payload, null, 2)}
|
||||
</pre>
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</CardContent>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue