feat(ticket): refine repair report and history timeline UI
This commit is contained in:
@@ -0,0 +1,92 @@
|
||||
'use client';
|
||||
|
||||
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
|
||||
import type { TicketActor, TicketDetail } from '@/types';
|
||||
|
||||
import { TicketStatusBadge } from '../../components/TicketStatusBadge';
|
||||
|
||||
function formatDate(value: string | null | undefined) {
|
||||
if (!value) return '-';
|
||||
return new Intl.DateTimeFormat('en-IN', {
|
||||
dateStyle: 'medium',
|
||||
timeStyle: 'short',
|
||||
}).format(new Date(value));
|
||||
}
|
||||
|
||||
function OverviewMeta({
|
||||
label,
|
||||
value,
|
||||
}: {
|
||||
label: string;
|
||||
value: string | number | null | undefined;
|
||||
}) {
|
||||
return (
|
||||
<div className="space-y-1">
|
||||
<p className="text-xs text-muted-foreground">{label}</p>
|
||||
<p className="text-sm font-medium">{value ?? '-'}</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function PersonMeta({
|
||||
label,
|
||||
person,
|
||||
}: {
|
||||
label: string;
|
||||
person: TicketActor | null | undefined;
|
||||
}) {
|
||||
return (
|
||||
<div className="space-y-1">
|
||||
<p className="text-xs text-muted-foreground">{label}</p>
|
||||
{person ? (
|
||||
<div className="min-w-0">
|
||||
<p className="truncate text-sm font-medium">{person.name || '-'}</p>
|
||||
{person.email && (
|
||||
<p className="truncate text-xs text-muted-foreground">
|
||||
{person.email}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
) : (
|
||||
<p className="text-sm font-medium">-</p>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export function TicketOverviewCard({ ticket }: { ticket: TicketDetail }) {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader className="flex flex-row items-center justify-between gap-4">
|
||||
<CardTitle className="text-base">Overview</CardTitle>
|
||||
<TicketStatusBadge status={ticket.status} />
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-6">
|
||||
<div className="grid gap-5 md:grid-cols-[180px_minmax(0,1fr)]">
|
||||
<div className="space-y-1">
|
||||
<p className="text-xs text-muted-foreground">AI Detections</p>
|
||||
<p className="text-3xl font-semibold leading-none">
|
||||
{ticket.ai_result?.detection_count ?? '-'}
|
||||
</p>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
Completed {formatDate(ticket.ai_result?.completed_at)}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="grid gap-4 sm:grid-cols-2">
|
||||
<PersonMeta label="Uploaded By" person={ticket.uploader} />
|
||||
<PersonMeta label="Assigned To" person={ticket.worker} />
|
||||
<PersonMeta
|
||||
label="Assigned By"
|
||||
person={ticket.worker?.assigned_by}
|
||||
/>
|
||||
<OverviewMeta
|
||||
label="Assigned At"
|
||||
value={formatDate(ticket.worker?.assigned_at)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user