Files
Codewalkers/packages/web/src/components/review/CommentThread.tsx
Lukas May da4152264c feat(web): Pipeline visualization, phase content editing, and review tab
Pipeline view groups phases by dependency depth with DAG visualization.
Phase detail panel with Tiptap rich content editor and auto-save.
Code review tab with diff viewer and comment threads (dummy data).
Centralized live updates hook replaces scattered subscription boilerplate.
Extract agent output parsing into shared utility. Inbox detail panel,
account cards, and agent action components.
2026-02-09 22:33:40 +01:00

73 lines
2.4 KiB
TypeScript

import { Check, RotateCcw } from "lucide-react";
import { Button } from "@/components/ui/button";
import type { ReviewComment } from "./types";
interface CommentThreadProps {
comments: ReviewComment[];
onResolve: (commentId: string) => void;
onUnresolve: (commentId: string) => void;
}
export function CommentThread({ comments, onResolve, onUnresolve }: CommentThreadProps) {
return (
<div className="space-y-2">
{comments.map((comment) => (
<div
key={comment.id}
className={`rounded border p-2.5 text-xs space-y-1.5 ${
comment.resolved
? "border-green-200 dark:border-green-900 bg-green-50/50 dark:bg-green-950/10"
: "border-border bg-card"
}`}
>
<div className="flex items-center justify-between gap-2">
<div className="flex items-center gap-1.5">
<span className="font-semibold text-foreground">{comment.author}</span>
<span className="text-muted-foreground">
{formatTime(comment.createdAt)}
</span>
{comment.resolved && (
<span className="flex items-center gap-0.5 text-green-600 text-[10px] font-medium">
<Check className="h-3 w-3" />
Resolved
</span>
)}
</div>
<div>
{comment.resolved ? (
<Button
variant="ghost"
size="sm"
className="h-6 px-1.5 text-[10px]"
onClick={() => onUnresolve(comment.id)}
>
<RotateCcw className="h-3 w-3 mr-0.5" />
Reopen
</Button>
) : (
<Button
variant="ghost"
size="sm"
className="h-6 px-1.5 text-[10px]"
onClick={() => onResolve(comment.id)}
>
<Check className="h-3 w-3 mr-0.5" />
Resolve
</Button>
)}
</div>
</div>
<p className="text-foreground/90 leading-relaxed whitespace-pre-wrap">
{comment.body}
</p>
</div>
))}
</div>
);
}
function formatTime(iso: string): string {
const d = new Date(iso);
return d.toLocaleTimeString(undefined, { hour: "2-digit", minute: "2-digit" });
}