redesign: ticket detail — cleaner transaction cards, system events as timeline
- System events now render as subtle timeline entries (icon dot + text) instead of heavy bordered boxes - Message cards are cleaner: rounded avatars, no card borders, just typography and spacing. Internal badge is subtler. - Removed border/shadow from message cards — cleaner, more modern Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -125,9 +125,8 @@ function TransactionCard({
|
|||||||
|
|
||||||
if (isSystem) {
|
if (isSystem) {
|
||||||
let message = tx.transaction_type;
|
let message = tx.transaction_type;
|
||||||
if (tx.transaction_type === "Create") {
|
if (tx.transaction_type === "Create") message = "Ticket created";
|
||||||
message = "Ticket created";
|
else if (tx.transaction_type === "StatusChange") {
|
||||||
} else if (tx.transaction_type === "StatusChange") {
|
|
||||||
const oldLabel = tx.old_value ? statusLabel(tx.old_value) : "?";
|
const oldLabel = tx.old_value ? statusLabel(tx.old_value) : "?";
|
||||||
const newLabel = tx.new_value ? statusLabel(tx.new_value) : "?";
|
const newLabel = tx.new_value ? statusLabel(tx.new_value) : "?";
|
||||||
message = `Status changed from ${oldLabel} to ${newLabel}`;
|
message = `Status changed from ${oldLabel} to ${newLabel}`;
|
||||||
@@ -135,60 +134,45 @@ function TransactionCard({
|
|||||||
message = tx.new_value ? `Assigned to ${userLabel(users, tx.new_value)}` : "Unassigned";
|
message = tx.new_value ? `Assigned to ${userLabel(users, tx.new_value)}` : "Unassigned";
|
||||||
} else if (tx.transaction_type === "CustomFieldChange") {
|
} else if (tx.transaction_type === "CustomFieldChange") {
|
||||||
const fieldName = tx.field ? customFieldLabels[tx.field] ?? "Custom field" : "Custom field";
|
const fieldName = tx.field ? customFieldLabels[tx.field] ?? "Custom field" : "Custom field";
|
||||||
message = tx.new_value
|
message = tx.new_value ? `${fieldName} set to ${tx.new_value}` : `${fieldName} cleared`;
|
||||||
? `${fieldName} set to ${tx.new_value}`
|
|
||||||
: `${fieldName} cleared`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="grid grid-cols-[28px_minmax(0,1fr)] gap-3 px-6 py-3">
|
<div className="flex items-center gap-3 px-8 py-2.5">
|
||||||
<div className="flex justify-center">
|
<div className="flex h-5 w-5 shrink-0 items-center justify-center rounded-full bg-muted/40">
|
||||||
<span className="mt-1 flex h-5 w-5 items-center justify-center rounded bg-muted text-muted-foreground">
|
<CircleIcon className="h-2.5 w-2.5 text-muted-foreground/60" />
|
||||||
<BotIcon className="h-3.5 w-3.5" />
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div className="rounded-md border border-border bg-muted/55 px-3 py-2 text-sm">
|
|
||||||
<div className="flex flex-wrap items-center gap-x-2 gap-y-1">
|
|
||||||
<span className="font-medium text-foreground">{message}</span>
|
|
||||||
<span className="text-xs text-muted-foreground">{timeAgo}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
<span className="text-xs text-muted-foreground">{message}</span>
|
||||||
|
<span className="text-[10px] text-muted-foreground/50">{timeAgo}</span>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<article className="grid grid-cols-[28px_minmax(0,1fr)] gap-3 px-6 py-4">
|
<div className="px-8 py-3">
|
||||||
|
<div className="flex items-start gap-3">
|
||||||
<div
|
<div
|
||||||
className="flex h-7 w-7 items-center justify-center rounded-md text-[11px] font-semibold text-white"
|
className="flex h-7 w-7 shrink-0 items-center justify-center rounded-full text-[11px] font-semibold text-white"
|
||||||
style={{ backgroundColor: getInitialColor(userLabel(users, tx.creator_id)) }}
|
style={{ backgroundColor: getInitialColor(userLabel(users, tx.creator_id)) }}
|
||||||
>
|
>
|
||||||
{getInitial(userLabel(users, tx.creator_id))}
|
{getInitial(userLabel(users, tx.creator_id))}
|
||||||
</div>
|
</div>
|
||||||
<div className="overflow-hidden rounded-md border border-border bg-card shadow-sm">
|
<div className="min-w-0 flex-1">
|
||||||
<div className="flex flex-wrap items-center justify-between gap-2 border-b border-border bg-muted/35 px-3 py-2">
|
<div className="flex items-baseline gap-2">
|
||||||
<div className="flex items-center gap-2">
|
<span className="text-sm font-semibold text-foreground">{userLabel(users, tx.creator_id)}</span>
|
||||||
{isMessage ? (
|
|
||||||
<MessageSquareIcon className="h-3.5 w-3.5 text-muted-foreground" />
|
|
||||||
) : (
|
|
||||||
<FileTextIcon className="h-3.5 w-3.5 text-muted-foreground" />
|
|
||||||
)}
|
|
||||||
<span className="text-sm font-semibold text-foreground">
|
|
||||||
{userLabel(users, tx.creator_id)}
|
|
||||||
</span>
|
|
||||||
{isInternal && (
|
{isInternal && (
|
||||||
<span className="rounded bg-amber-500/12 px-1.5 py-0.5 text-[10px] font-semibold uppercase text-amber-700 dark:text-amber-300">
|
<span className="rounded bg-amber-500/10 px-1 py-0 text-[10px] font-semibold text-amber-600 dark:text-amber-400">
|
||||||
Internal
|
Internal
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
|
<span className="text-[11px] text-muted-foreground/50">{timeAgo}</span>
|
||||||
</div>
|
</div>
|
||||||
<span className="text-xs text-muted-foreground">{timeAgo}</span>
|
<p className="mt-1.5 whitespace-pre-wrap text-sm leading-relaxed text-foreground/90">
|
||||||
</div>
|
|
||||||
<p className="whitespace-pre-wrap px-3 py-3 text-sm leading-6 text-foreground">
|
|
||||||
{body}
|
{body}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</article>
|
</div>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user