Each page.tsx was 750-780 LOC. Extracted React components to _components/ and custom hooks to _hooks/ next to each page.tsx. All three pages are now under 215 LOC (well within the 500 LOC hard cap). Zero behavior changes. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
70 lines
2.8 KiB
TypeScript
70 lines
2.8 KiB
TypeScript
'use client'
|
|
|
|
import { Escalation, priorityColors, priorityLabels, statusColors, statusLabels, categoryLabels, formatDate } from './types'
|
|
|
|
interface CardProps {
|
|
escalation: Escalation
|
|
onClick: () => void
|
|
}
|
|
|
|
export function EscalationCard({ escalation, onClick }: CardProps) {
|
|
return (
|
|
<div
|
|
onClick={onClick}
|
|
className={`bg-white rounded-xl border-2 p-6 cursor-pointer hover:shadow-md transition-shadow ${
|
|
escalation.priority === 'critical' ? 'border-red-300' :
|
|
escalation.priority === 'high' ? 'border-orange-300' :
|
|
escalation.status === 'resolved' || escalation.status === 'closed' ? 'border-green-200' : 'border-gray-200'
|
|
}`}
|
|
>
|
|
<div className="flex items-start justify-between">
|
|
<div className="flex-1">
|
|
<div className="flex items-center gap-2 mb-2 flex-wrap">
|
|
<span className={`px-2 py-1 text-xs rounded-full ${priorityColors[escalation.priority]}`}>
|
|
{priorityLabels[escalation.priority]}
|
|
</span>
|
|
{escalation.category && (
|
|
<span className="px-2 py-1 text-xs rounded-full bg-purple-100 text-purple-700">
|
|
{categoryLabels[escalation.category] || escalation.category}
|
|
</span>
|
|
)}
|
|
<span className={`px-2 py-1 text-xs rounded-full ${statusColors[escalation.status]}`}>
|
|
{statusLabels[escalation.status]}
|
|
</span>
|
|
</div>
|
|
<h3 className="text-lg font-semibold text-gray-900">{escalation.title}</h3>
|
|
{escalation.description && (
|
|
<p className="text-sm text-gray-500 mt-1 line-clamp-2">{escalation.description}</p>
|
|
)}
|
|
</div>
|
|
<svg className="w-5 h-5 text-gray-400 ml-3 flex-shrink-0 mt-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5l7 7-7 7" />
|
|
</svg>
|
|
</div>
|
|
|
|
<div className="mt-4 grid grid-cols-2 gap-4 text-sm">
|
|
{escalation.assignee && (
|
|
<div>
|
|
<span className="text-gray-500">Zugewiesen: </span>
|
|
<span className="font-medium text-gray-700">{escalation.assignee}</span>
|
|
</div>
|
|
)}
|
|
{escalation.due_date && (
|
|
<div>
|
|
<span className="text-gray-500">Frist: </span>
|
|
<span className="font-medium text-gray-700">{formatDate(escalation.due_date)}</span>
|
|
</div>
|
|
)}
|
|
<div>
|
|
<span className="text-gray-500">Erstellt: </span>
|
|
<span className="font-medium text-gray-700">{formatDate(escalation.created_at)}</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="mt-4 pt-4 border-t border-gray-100">
|
|
<span className="text-xs text-gray-400 font-mono">{escalation.id}</span>
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|