feat(jobs): step-by-step timeline on the detail page
The job_status_history table was already being populated on every
transition; the detail page just rendered a flat list with date only.
Replaced it with a proper vertical timeline:
- Card title moved from 'Aşama Geçmişi' to 'Akış Geçmişi' since we
now include side-trips (revision requests), not just forward steps.
- Vertical guide line with a coloured node per entry: emerald for
a normal step completion, rose for a revision request. Spotting a
bounced prova in the history is a glance.
- Revision rows get an inline 'Düzeltme talebi' pill; the '[Düzeltme
talebi]' prefix is stripped from the visible note so the actual
feedback text reads cleanly.
- Always rendered (with an empty-state line) so the card position
doesn't move around as the case progresses.
This commit is contained in:
@@ -259,33 +259,55 @@ export default async function JobDetailPage({
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
{history.length > 0 && (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Aşama Geçmişi</CardTitle>
|
||||
<CardDescription>Tamamlanan aşamaların kaydı.</CardDescription>
|
||||
<CardTitle>Akış Geçmişi</CardTitle>
|
||||
<CardDescription>
|
||||
İşin aşama transition'ları, kim yaptı ve hangi notla.
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<ol className="space-y-3">
|
||||
{history.map((h) => (
|
||||
<li key={h.$id} className="border-l-2 border-primary/30 pl-4">
|
||||
{history.length === 0 ? (
|
||||
<p className="text-muted-foreground text-sm">
|
||||
Henüz aşama tamamlanmadı.
|
||||
</p>
|
||||
) : (
|
||||
<ol className="relative space-y-4 border-l-2 border-border pl-6">
|
||||
{history.map((h) => {
|
||||
const isRevision = h.note?.startsWith("[Düzeltme talebi]");
|
||||
return (
|
||||
<li key={h.$id} className="relative">
|
||||
<span
|
||||
className={`absolute -left-[1.85rem] mt-1.5 size-3 rounded-full ring-2 ring-background ${
|
||||
isRevision ? "bg-rose-500" : "bg-emerald-500"
|
||||
}`}
|
||||
aria-hidden
|
||||
/>
|
||||
<div className="flex flex-wrap items-baseline gap-2">
|
||||
<span className="font-medium">{JOB_STEP_LABELS[h.step]}</span>
|
||||
<span className="text-muted-foreground text-xs">
|
||||
<span className="font-medium">
|
||||
{JOB_STEP_LABELS[h.step]}
|
||||
</span>
|
||||
{isRevision && (
|
||||
<span className="rounded bg-rose-100 px-1.5 py-0.5 text-xs font-medium text-rose-700 dark:bg-rose-950 dark:text-rose-300">
|
||||
Düzeltme talebi
|
||||
</span>
|
||||
)}
|
||||
<span className="text-muted-foreground text-xs tabular-nums">
|
||||
{dateFormatter.format(new Date(h.completedAt))}
|
||||
</span>
|
||||
</div>
|
||||
{h.note && (
|
||||
<p className="text-muted-foreground mt-1 whitespace-pre-wrap text-sm">
|
||||
{h.note}
|
||||
{h.note.replace(/^\[Düzeltme talebi\]\s*/, "")}
|
||||
</p>
|
||||
)}
|
||||
</li>
|
||||
))}
|
||||
);
|
||||
})}
|
||||
</ol>
|
||||
)}
|
||||
</CardContent>
|
||||
</Card>
|
||||
)}
|
||||
|
||||
<div>
|
||||
<Button asChild variant="outline">
|
||||
|
||||
Reference in New Issue
Block a user