73 lines
2.4 KiB
TypeScript
73 lines
2.4 KiB
TypeScript
// frontend/src/components/tickets/TicketListRow.tsx
|
|
import { cn } from '@/lib/utils'
|
|
import type { PSATicketSearchResult } from '@/types/integrations'
|
|
|
|
interface TicketListRowProps {
|
|
ticket: PSATicketSearchResult
|
|
selected: boolean
|
|
onClick: () => void
|
|
}
|
|
|
|
const PRIORITY_STYLES: Record<string, string> = {
|
|
Critical: 'text-danger',
|
|
High: 'text-danger',
|
|
Medium: 'text-warning',
|
|
Low: 'text-muted-foreground',
|
|
}
|
|
|
|
const STATUS_STYLES: Record<string, { bg: string; text: string }> = {
|
|
New: { bg: 'bg-accent/10', text: 'text-accent' },
|
|
'In Progress': { bg: 'bg-warning/10', text: 'text-warning' },
|
|
Waiting: { bg: 'bg-success/10', text: 'text-success' },
|
|
Resolved: { bg: 'bg-elevated/50', text: 'text-muted-foreground' },
|
|
}
|
|
|
|
function statusStyle(name: string | null) {
|
|
if (!name) return { bg: 'bg-elevated', text: 'text-muted-foreground' }
|
|
return STATUS_STYLES[name] ?? { bg: 'bg-elevated', text: 'text-muted-foreground' }
|
|
}
|
|
|
|
export function TicketListRow({ ticket, selected, onClick }: TicketListRowProps) {
|
|
const { bg, text } = statusStyle(ticket.status_name)
|
|
const priorityClass = PRIORITY_STYLES[ticket.priority_name ?? ''] ?? 'text-muted-foreground'
|
|
|
|
return (
|
|
<div
|
|
role="button"
|
|
tabIndex={0}
|
|
onClick={onClick}
|
|
onKeyDown={e => e.key === 'Enter' && onClick()}
|
|
className={cn(
|
|
'flex items-center gap-3 px-4 py-2.5 cursor-pointer transition-colors border-b border-default text-sm',
|
|
selected ? 'bg-accent/5' : 'hover:bg-elevated'
|
|
)}
|
|
>
|
|
{/* ID */}
|
|
<span className="w-12 shrink-0 text-accent text-xs font-mono">#{ticket.id}</span>
|
|
|
|
{/* Summary */}
|
|
<span className="flex-1 truncate text-primary font-medium">{ticket.summary}</span>
|
|
|
|
{/* Company */}
|
|
<span className="w-32 shrink-0 truncate text-muted-foreground text-xs hidden md:block">
|
|
{ticket.company_name ?? '—'}
|
|
</span>
|
|
|
|
{/* Board */}
|
|
<span className="w-28 shrink-0 truncate text-muted-foreground text-xs hidden lg:block">
|
|
{ticket.board_name ?? '—'}
|
|
</span>
|
|
|
|
{/* Status badge */}
|
|
<span className={cn('shrink-0 px-1.5 py-0.5 rounded text-[11px] font-medium', bg, text)}>
|
|
{ticket.status_name ?? '—'}
|
|
</span>
|
|
|
|
{/* Priority */}
|
|
<span className={cn('w-14 shrink-0 text-xs text-right', priorityClass)}>
|
|
{ticket.priority_name ?? '—'}
|
|
</span>
|
|
</div>
|
|
)
|
|
}
|